Best JavaScript code snippet using playwright-internal
Evaluator.js
Source:Evaluator.js
...91 function getVariable(strVarName)92 {93 var retVal;9495 debugAssert(strVarName);96 97 if (arrVars == null || arrVars == undefined)98 throw "Variable values are not supplied!";99100 retVal = arrVars[strVarName];101 if (retVal == undefined || retVal == null)102 throw "Variable [" + strVarName + "] not defined";103104 debugAssert(strVarName + " - " + retVal);105 return retVal;106 }107108 // postfix function evaluator109 function EvaluateExpression()110 {111 var intIndex;112 var myStack;113 var strTok, strOp;114 var objOp1, objOp2, objTmp1, objTmp2;115 var dblNo, dblVal1, dblVal2;116 var parrExp;117118 if (arrPostFix == null || arrPostFix == undefined)119 ParseExpression();120 if (arrPostFix.length == 0)121 throw "Unable to parse the expression!";122123 parrExp = arrPostFix;124 if (parrExp == null || parrExp == undefined)125 {126 throw "Invalid postfix expression!";127 return;128 }129 if (parrExp.length == 0)130 {131 throw "Invalid postfix expression!";132 return;133 }134135 intIndex = 0;136 myStack = new Stack();137 while (intIndex < parrExp.length)138 {139 strTok = parrExp[intIndex];140 switch (strTok)141 {142 case ARG_TERMINAL :143 myStack.Push(strTok);144 break;145 case UNARY_NEG :146 if (myStack.IsEmpty())147 throw "No operand to negate!";148149 objOp1 = null;150 objOp2 = null;151 objOp1 = myStack.Pop();152 if (IsVariable(objOp1))153 objOp1 = getVariable(objOp1);154155 dblNo = ToNumber(objOp1);156 if (isNaN(dblNo))157 throw "Not a numaric value!";158 else159 {160 dblNo = (0 - dblNo);161 myStack.Push(dblNo);162 }163 break;164 case "!" :165 if (myStack.IsEmpty())166 throw "No operand on stack!";167168 objOp1 = null;169 objOp2 = null;170 objOp1 = myStack.Pop();171 if (IsVariable(objOp1))172 objOp1 = getVariable(objOp1);173174 objOp1 = ToBoolean(objOp1);175 if (objOp1 == null)176 throw "Not a boolean value!";177 else178 myStack.Push(!objOp1);179 break;180 case "*" :181 case "/" :182 case "%" :183 case "^" :184 if (myStack.IsEmpty() || myStack.Size() < 2)185 throw "Stack is empty, can not perform [" + strTok + "]";186 objOp1 = null;187 objOp2 = null;188 objTmp = null;189 objOp2 = myStack.Pop();190 objOp1 = myStack.Pop();191 if (IsVariable(objOp1))192 objOp1 = getVariable(objOp1);193 if (IsVariable(objOp2))194 objOp2 = getVariable(objOp2);195196 dblVal1 = ToNumber(objOp1);197 dblVal2 = ToNumber(objOp2);198 if (isNaN(dblVal1) || isNaN(dblVal2))199 throw "Either one of the operand is not a number can not perform [" +200 strTok + "]";201 if (strTok == "^")202 myStack.Push(Math.pow(dblVal1, dblVal2));203 else if (strTok == "*")204 myStack.Push((dblVal1 * dblVal2));205 else if (strTok == "/")206 myStack.Push((dblVal1 / dblVal2));207 else208 {209 debugAssert (dblVal1 + " - " + dblVal2);210 myStack.Push((dblVal1 % dblVal2));211 }212 break;213 case "+" :214 case "-" :215 if (myStack.IsEmpty() || myStack.Size() < 2)216 throw "Stack is empty, can not perform [" + strTok + "]";217 objOp1 = null;218 objOp2 = null;219 objTmp1 = null;220 objTmp2 = null;221 strOp = ((strTok == "+") ? "Addition" : "Substraction");222 objOp2 = myStack.Pop();223 objOp1 = myStack.Pop();224 if (IsVariable(objOp1))225 objOp1 = getVariable(objOp1);226 if (IsVariable(objOp2))227 objOp2 = getVariable(objOp2);228229 if (IsBoolean(objOp1) || IsBoolean(objOp2))230 throw "Can not perform " + strOp + " with boolean values!";231 else if (isDate(objOp1, dtFormat) && isDate(objOp1, dtFormat))232 throw strOp + " of two dates not supported!";233 else if (typeof(objOp1) == "object" || typeof(objOp1) == "object")234 throw strOp + " of two objects not supported!";235 else if (typeof(objOp1) == "undefined" || typeof(objOp1) == "undefined")236 throw strOp + " of two undefined not supported!";237 else if (IsNumber(objOp1) && IsNumber(objOp2))238 {239 // Number addition240 dblVal1 = ToNumber(objOp1);241 dblVal2 = ToNumber(objOp2);242 if (strTok == "+")243 myStack.Push((dblVal1 + dblVal2));244 else245 myStack.Push((dblVal1 - dblVal2));246 }247 else248 {249 if (strTok == "+")250 myStack.Push((objOp1 + objOp2));251 else252 throw strOP + " not supported for strings!"253 }254 break;255 case "=" :256 case "<" :257 case ">" :258 case "<>" :259 case "<=" :260 case ">=" :261 if (myStack.IsEmpty() || myStack.Size() < 2)262 throw "Stack is empty, can not perform [" + strTok + "]";263 objOp1 = null;264 objOp2 = null;265 objTmp1 = null;266 objTmp2 = null;267 objOp2 = myStack.Pop();268 objOp1 = myStack.Pop();269 if (IsVariable(objOp1))270 objOp1 = getVariable(objOp1);271 if (IsVariable(objOp2))272 objOp2 = getVariable(objOp2);273274 if (IsNumber(objOp1) && IsNumber(objOp2))275 {276 dblVal1 = ToNumber(objOp1);277 dblVal2 = ToNumber(objOp2);278 if (strTok == "=")279 myStack.Push((dblVal1 == dblVal2));280 else if (strTok == "<>")281 myStack.Push((dblVal1 != dblVal2));282 else if (strTok == ">")283 myStack.Push((dblVal1 > dblVal2));284 else if (strTok == "<")285 myStack.Push((dblVal1 < dblVal2));286 else if (strTok == "<=")287 myStack.Push((dblVal1 <= dblVal2));288 else if (strTok == ">=")289 myStack.Push((dblVal1 >= dblVal2));290 }291 else if (IsBoolean(objOp1) && IsBoolean(objOp2) &&292 (strTok == "=" || strTok == "<>"))293 {294 objTmp1 = ToBoolean(objOp1);295 objTmp2 = ToBoolean(objOp2);296 if (strTok == "=")297 myStack.Push((objTmp1 == objTmp2));298 else if (strTok == "<>")299 myStack.Push((objTmp1 != objTmp2));300 }301 else if (isDate(objOp1, dtFormat) &&302 isDate(objOp2, dtFormat))303 {304 if (typeof(objOp1) == "string")305 objTmp1 = getDateFromFormat(objOp1, dtFormat);306 else307 objTmp1 = objOp1;308 if (typeof(objOp1) == "string")309 objTmp2 = getDateFromFormat(objOp2, dtFormat);310 else311 objTmp2 = objOp2;312 if (strTok == "=")313 myStack.Push((objTmp1 == objTmp2));314 else if (strTok == "<>")315 myStack.Push((objTmp1 != objTmp2));316 else if (strTok == ">")317 myStack.Push((objTmp1 > objTmp2));318 else if (strTok == "<")319 myStack.Push((objTmp1 < objTmp2));320 else if (strTok == "<=")321 myStack.Push((objTmp1 <= objTmp2));322 else if (strTok == ">=")323 myStack.Push((objTmp1 >= objTmp2));324 }325 else if ((typeof(objOp1) == "string" &&326 typeof(objOp2) == "string") &&327 (strTok == "=" || strTok == "<>"))328 {329 if (strTok == "=")330 myStack.Push((objOp1 == objOp2));331 else if (strTok == "<>")332 myStack.Push((objOp1 != objOp2));333 }334 else335 throw "For " + strTok +336 " operator LHS & RHS should be of same data type!";337 break;338 case "&" :339 case "|" :340 if (myStack.IsEmpty() || myStack.Size() < 2)341 throw "Stack is empty, can not perform [" + strTok + "]";342 objOp1 = null;343 objOp2 = null;344 objTmp1 = null;345 objTmp2 = null;346 objOp2 = myStack.Pop();347 objOp1 = myStack.Pop();348 if (IsVariable(objOp1))349 objOp1 = getVariable(objOp1);350 if (IsVariable(objOp2))351 objOp2 = getVariable(objOp2);352353 if (IsBoolean(objOp1) && IsBoolean(objOp2))354 {355 objTmp1 = ToBoolean(objOp1);356 objTmp2 = ToBoolean(objOp2);357 if (strTok == "&")358 myStack.Push((objTmp1 && objTmp2));359 else if (strTok == "|")360 myStack.Push((objTmp1 || objTmp2));361 }362 else363 throw "Logical operator requires LHS & RHS of boolean type!";364 break;365 default :366 // Handle functions and operands367 if (IsNumber(strTok) || IsBoolean(strTok) ||368 isDate(strTok, dtFormat) || typeof(strTok) == "number"369 || typeof(strTok) == "boolean" || typeof(strTok) == "object"370 || IsVariable(strTok))371 {372 myStack.Push(strTok);373 break;374 }375 else376 HandleFunctions(strTok, myStack, dtFormat, arrVars);377 }378 intIndex++;379 }380 if (myStack.IsEmpty() || myStack.Size() > 1)381 throw "Unable to evaluate expression!";382 else383 return myStack.Pop();384 }385386 /*------------------------------------------------------------------------------387 * NAME : InFixToPostFix388 * PURPOSE : Convert an Infix expression into a postfix (RPN) equivalent389 * PARAMETERS : Infix expression element array390 * RETURNS : array containing postfix expression element tokens391 *----------------------------------------------------------------------------*/392 function InFixToPostFix(arrToks)393 {394 var myStack;395 var intCntr, intIndex;396 var strTok, strTop, strNext, strPrev;397 var blnStart;398399 blnStart = false;400 intIndex = 0;401 arrPFix = new Array();402 myStack = new Stack();403404 // Infix to postfix converter405 for (intCntr = 0; intCntr < arrToks.length; intCntr++)406 {407 strTok = arrToks[intCntr];408 debugAssert ("Processing token [" + strTok + "]");409 switch (strTok)410 {411 case "(" :412 if (myStack.Size() > 0 && IsFunction(myStack.Get(0)))413 {414 arrPFix[intIndex] = ARG_TERMINAL;415 intIndex++;416 }417 myStack.Push(strTok);418 break;419 case ")" :420 blnStart = true;421 debugAssert("Stack.Pop [" + myStack.toString());422 while (!myStack.IsEmpty())423 {424 strTok = myStack.Pop();425 if (strTok != "(")426 {427 arrPFix[intIndex] = strTok;428 intIndex++;429 }430 else431 {432 blnStart = false;433 break;434 }435 }436 if (myStack.IsEmpty() && blnStart)437 throw "Unbalanced parenthesis!";438 break;439 case "," :440 if (myStack.IsEmpty()) break;441 debugAssert("Pop stack till opening bracket found!")442 while (!myStack.IsEmpty())443 {444 strTok = myStack.Get(0);445 if (strTok == "(") break;446 arrPFix[intIndex] = myStack.Pop();447 intIndex++;448 }449 break;450 case "!" :451 case "-" :452 // check for unary negative operator.453 if (strTok == "-")454 {455 strPrev = null;456 if (intCntr > 0)457 strPrev = arrToks[intCntr - 1];458 strNext = arrToks[intCntr + 1];459 if (strPrev == null || IsOperator(strPrev) || strPrev == "(")460 {461 debugAssert("Unary negation!")462 strTok = UNARY_NEG;463 }464 }465 case "^" :466 case "*" :467 case "/" :468 case "%" :469 case "+" :470 // check for unary + addition operator, we need to ignore this.471 if (strTok == "+")472 {473 strPrev = null;474 if (intCntr > 0)475 strPrev = arrToks[intCntr - 1];476 strNext = arrToks[intCntr + 1];477 if (strPrev == null || IsOperator(strPrev) || strPrev == "(")478 {479 debugAssert("Unary add, Skipping");480 break;481 }482 }483 case "&" :484 case "|" :485 case ">" :486 case "<" :487 case "=" :488 case ">=" :489 case "<=" :490 case "<>" :491 strTop = "";492 if (!myStack.IsEmpty()) strTop = myStack.Get(0);493 if (myStack.IsEmpty() || (!myStack.IsEmpty() && strTop == "("))494 {495 debugAssert("Empty stack pushing operator [" + strTok + "]");496 myStack.Push(strTok);497 }498 else if (Precedence(strTok) > Precedence(strTop))499 {500 debugAssert("[" + strTok +501 "] has higher precedence over [" +502 strTop + "]");503 myStack.Push(strTok);504 }505 else506 {507 // Pop operators with precedence >= operator strTok508 while (!myStack.IsEmpty())509 {510 strTop = myStack.Get(0);511 if (strTop == "(" || Precedence(strTop) < Precedence(strTok))512 {513 debugAssert ("[" + strTop +514 "] has lesser precedence over [" +515 strTok + "]")516 break;517 }518 else519 {520 arrPFix[intIndex] = myStack.Pop();521 intIndex++;522 }523 }524 myStack.Push(strTok);525 }526 break;527 default :528 if (!IsFunction(strTok))529 {530 debugAssert("Token [" + strTok + "] is a variable/number!");531 // Token is an operand532 if (IsNumber(strTok))533 strTok = ToNumber(strTok);534 else if (IsBoolean(strTok))535 strTok = ToBoolean(strTok);536 else if (isDate(strTok, dtFormat))537 strTok = getDateFromFormat(strTok, dtFormat);538539 arrPFix[intIndex] = strTok;540 intIndex++;541 break;542 }543 else544 {545 strTop = "";546 if (!myStack.IsEmpty()) strTop = myStack.Get(0);547 if (myStack.IsEmpty() || (!myStack.IsEmpty() && strTop == "("))548 {549 debugAssert("Empty stack pushing operator [" + strTok + "]");550 myStack.Push(strTok);551 }552 else if (Precedence(strTok) > Precedence(strTop))553 {554 debugAssert("[" + strTok +555 "] has higher precedence over [" +556 strTop + "]");557 myStack.Push(strTok);558 }559 else560 {561 // Pop operators with precedence >= operator in strTok562 while (!myStack.IsEmpty())563 {564 strTop = myStack.Get(0);565 if (strTop == "(" || Precedence(strTop) < Precedence(strTok))566 {567 debugAssert ("[" + strTop +568 "] has lesser precedence over [" +569 strTok + "]")570 break;571 }572 else573 {574 arrPFix[intIndex] = myStack.Pop();575 intIndex++;576 }577 }578 myStack.Push(strTok);579 }580 }581 break;582 }583 debugAssert("Stack : " + myStack.toString() + "\n" +584 "RPN Exp : " + arrPFix.toString());585586 }587588 // Pop remaining operators from stack.589 while (!myStack.IsEmpty())590 {591 arrPFix[intIndex] = myStack.Pop();592 intIndex++;593 }594 return arrPFix;595 }596}597598/*------------------------------------------------------------------------------599 * NAME : HandleFunctions600 * PURPOSE : Execute built-in functions601 * PARAMETERS : pstrTok - The current function name602 * pStack - Operand stack603 * RETURNS : Nothing, the result is pushed back onto the stack.604 *----------------------------------------------------------------------------*/605function HandleFunctions(pstrTok, pStack, pdtFormat, parrVars)606{607 var varTmp, varTerm, objTmp;608 var objOp1, objOp2;609 var arrArgs;610 var intCntr;611612 if (!IsFunction(pstrTok))613 throw "Unsupported function token [" + pstrTok + "]";614615 varTmp = pstrTok.toUpperCase();616 arrArgs = new Array();617 while (!pStack.IsEmpty())618 {619 varTerm = ARG_TERMINAL;620 varTerm = pStack.Pop();621 if (varTerm != ARG_TERMINAL)622 arrArgs[arrArgs.length] = varTerm;623 else624 break;625 }626627 switch (varTmp)628 {629 case "DATE" :630 varTerm = new Date();631 pStack.Push(formatDate(varTerm, pdtFormat));632 break;633 case "ACOS" :634 case "ASIN" :635 case "ATAN" :636 throw "Function [" + varTmp + "] is not implemented!";637 break;638 case "ABS" :639 case "CHR" :640 case "COS" :641 case "FIX" :642 case "HEX" :643 case "LOG" :644 case "ROUND" :645 case "SIN" :646 case "SQRT" :647 case "TAN" :648 if (arrArgs.length < 1)649 throw varTmp + " requires atleast one argument!";650 else if (arrArgs.length > 1)651 throw varTmp + " requires only one argument!";652 varTerm = arrArgs[0];653 if (IsVariable(varTerm))654 {655 objTmp = parrVars[varTerm];656 if (objTmp == undefined || objTmp == null)657 throw "Variable [" + varTerm + "] not defined";658 else659 varTerm = objTmp;660 }661 if (!IsNumber(varTerm))662 throw varTmp + " operates on numeric operands only!";663 else664 {665 objTmp = ToNumber(varTerm);666 if (varTmp == "ABS")667 pStack.Push(Math.abs(objTmp));668 else if (varTmp == "CHR")669 pStack.Push(String.fromCharCode(objTmp));670 else if (varTmp == "COS")671 pStack.Push(Math.cos(objTmp));672 else if (varTmp == "FIX")673 pStack.Push(Math.floor(objTmp));674 else if (varTmp == "HEX")675 pStack.Push(objTmp.toString(16));676 else if (varTmp == "LOG")677 pStack.Push(Math.log(objTmp));678 else if (varTmp == "ROUND")679 pStack.Push(Math.round(objTmp));680 else if (varTmp == "SIN")681 pStack.Push(Math.sin(objTmp));682 else if (varTmp == "SQRT")683 pStack.Push(Math.sqrt(objTmp));684 else if (varTmp == "TAN")685 pStack.Push(Math.tan(objTmp));686 }687 break;688 case "ASC" :689 if (arrArgs.length > 1)690 throw varTmp + " requires only one argument!";691 else if (arrArgs.length < 1)692 throw varTmp + " requires atleast one argument!";693 varTerm = arrArgs[0];694 if (IsVariable(varTerm))695 {696 objTmp = parrVars[varTerm];697 if (objTmp == undefined || objTmp == null)698 throw "Variable [" + varTerm + "] not defined";699 else700 varTerm = objTmp;701 }702 if (IsNumber(varTerm) || IsBoolean(varTerm) || 703 isDate(varTerm, pdtFormat) || typeof(varTerm) != "string")704 throw varTmp + " requires a string type operand!";705 else706 pStack.Push(varTerm.charCodeAt(0));707 break;708 case "LCASE" :709 case "UCASE" :710 case "CDATE" :711 if (arrArgs.length < 1)712 throw varTmp + " requires atleast one argument!";713 else if (arrArgs.length > 1)714 throw varTmp + " requires only one argument!";715716 varTerm = arrArgs[0];717 if (IsVariable(varTerm))718 {719 objTmp = parrVars[varTerm];720 if (objTmp == undefined || objTmp == null)721 throw "Variable [" + varTerm + "] not defined";722 else723 varTerm = objTmp;724 }725726 if (varTmp == "CDATE" && !isDate(varTerm, pdtFormat))727 throw "CDate can not convert [" + varTerm + "] to a valid date!";728 else if (typeof(varTerm) == "number" || typeof(varTerm) != "string")729 throw varTmp + " requires a string type operand!";730 else731 {732 if (varTmp == "LCASE")733 pStack.Push(varTerm.toLowerCase());734 else if (varTmp == "UCASE")735 pStack.Push(varTerm.toUpperCase());736 else if (varTmp == "CDATE")737 {738 objTmp = getDateFromFormat(varTerm, pdtFormat);739 pStack.Push(new Date(objTmp));740 }741 }742 break;743 case "LEFT" :744 case "RIGHT" :745 if (arrArgs.length < 2)746 throw varTmp + " requires atleast two arguments!";747 else if (arrArgs.length > 2)748 throw varTmp + " requires only two arguments!";749750 for (intCntr = 0; intCntr < arrArgs.length; intCntr++)751 {752 varTerm = arrArgs[intCntr];753 if (IsVariable(varTerm))754 {755 objTmp = parrVars[varTerm];756 if (objTmp == undefined || objTmp == null)757 throw "Variable [" + varTerm + "] not defined";758 else759 varTerm = objTmp;760 }761 if (intCntr == 0 && !IsNumber(varTerm))762 throw varTmp + " oprator requires numaric length!";763 arrArgs[intCntr] = varTerm;764 }765 varTerm = new String(arrArgs[1]);766 objTmp = ToNumber(arrArgs[0]);767 if (varTmp == "LEFT")768 pStack.Push(varTmp.substring(0, objTmp));769 else770 pStack.Push(varTmp.substr((varTerm.length - objTmp), objTmp));771 break;772 case "MID" :773 case "IIF" :774 if (arrArgs.length < 3)775 throw varTmp + " requires atleast three arguments!";776 else if (arrArgs.length > 3)777 throw varTmp + " requires only three arguments!";778779 for (intCntr = 0; intCntr < arrArgs.length; intCntr++)780 {781 varTerm = arrArgs[intCntr];782 if (IsVariable(varTerm))783 {784 objTmp = parrVars[varTerm];785 if (objTmp == undefined || objTmp == null)786 throw "Variable [" + varTerm + "] not defined";787 else788 varTerm = objTmp;789 }790 if (varTerm == "MID" && intCntr <= 1 && !IsNumber(varTerm))791 throw varTmp + " oprator requires numaric lengths!";792 else if (varTerm == "IIF" && intCntr == 2 && !IsBoolean(varTerm))793 throw varTmp + " oprator requires boolean condition!";794 arrArgs[intCntr] = varTerm;795 }796 if (varTmp == "MID")797 {798 varTerm = new String(arrArgs[2]);799 objOp1 = ToNumber(arrArgs[1]);800 objOp2 = ToNumber(arrArgs[0]);801 pStack.Push(varTerm.substring(objOp1, objOp2));802 }803 else804 {805 varTerm = ToBoolean(arrArgs[2]);806 objOp1 = arrArgs[1];807 objOp2 = arrArgs[0];808 if (varTerm)809 pStack.Push(objOp1);810 else811 pStack.Push(objOp2);812 }813 break;814815 case "AVG" :816 case "MAX" :817 case "MIN" :818 if (arrArgs.length < 2)819 throw varTmp + " requires atleast two operands!";820821 objTmp = 0;822 for (intCntr = 0; intCntr < arrArgs.length; intCntr++)823 {824 varTerm = arrArgs[intCntr];825 if (IsVariable(varTerm))826 {827 objTmp = parrVars[varTerm];828 if (objTmp == undefined || objTmp == null)829 throw "Variable [" + varTerm + "] not defined";830 else831 varTerm = objTmp;832 }833 if (!IsNumber(varTerm))834 throw varTmp + " requires numaric operands only!";835836 varTerm = ToNumber(varTerm);837 if (varTmp == "AVG")838 objTmp += varTerm;839 else if (varTmp == "MAX" && objTmp < varTerm)840 objTmp = varTerm;841 else if (varTmp == "MIN")842 {843 if (intCntr == 1) 844 objTmp = varTerm;845 else if (objTmp > varTerm)846 objTmp = varTerm;847 }848 }849 if (varTmp == "AVG")850 pStack.Push(objTmp/arrArgs.length);851 else852 pStack.Push(objTmp);853 break;854 }855}856857858/*------------------------------------------------------------------------------859 * NAME : IsNumber860 * PURPOSE : Checks whether the specified parameter is a number.861 * RETURNS : True - If supplied parameter can be succesfully converted to a number862 * False - Otherwise863 *----------------------------------------------------------------------------*/864function IsNumber(pstrVal)865{866 var dblNo = Number.NaN;867868 dblNo = new Number(pstrVal);869 if (isNaN(dblNo))870 return false;871 return true;872}873874/*------------------------------------------------------------------------------875 * NAME : IsBoolean876 * PURPOSE : Checks whether the specified parameter is a boolean value.877 * PARAMETERS : pstrVal - The string to be checked.878 * RETURNS : True - If supplied parameter is a boolean constant879 * False - Otherwise880 *----------------------------------------------------------------------------*/881function IsBoolean(pstrVal)882{883 var varType = typeof(pstrVal);884 var strTmp = null;885886 if (varType == "boolean") return true;887 if (varType == "number" || varType == "function" || varType == undefined)888 return false;889 if (IsNumber(pstrVal)) return false;890 if (varType == "object")891 {892 strTmp = pstrVal.toString();893 if (strTmp.toUpperCase() == "TRUE" || strTmp.toUpperCase() == "FALSE")894 return true;895 }896 if (pstrVal.toUpperCase() == "TRUE" || pstrVal.toUpperCase() == "FALSE")897 return true;898 return false;899}900901/*------------------------------------------------------------------------------902 * NAME : IsVariable903 * PURPOSE : Checks whether the specified parameter is a user defined variable.904 * RETURNS : True - If supplied parameter identifies a user defined variable905 * False - Otherwise 906 *----------------------------------------------------------------------------*/907function IsVariable(pstrVal)908{909 if (lstArithOps.indexOf(pstrVal) >= 0 || lstLogicOps.indexOf(pstrVal) >=0 ||910 lstCompaOps.indexOf(pstrVal) >= 0 || 911 (typeof(pstrVal) == "string" && (pstrVal.toUpperCase() == "TRUE" || 912 pstrVal.toUpperCase() == "FALSE" || parseDate(pstrVal) != null)) || 913 typeof(pstrVal) == "number" || typeof(pstrVal) == "boolean" || 914 typeof(pstrVal) == "object" || IsNumber(pstrVal) || IsFunction(pstrVal))915 return false;916 return true;917}918919/*------------------------------------------------------------------------------920 * NAME : ToNumber921 * PURPOSE : Converts the supplied parameter to numaric type.922 * PARAMETERS : pobjVal - The string to be converted to equvalent number.923 * RETURNS : numaric value if string represents a number924 * THROWS : Exception if string can not be converted 925 *----------------------------------------------------------------------------*/926function ToNumber(pobjVal)927{928 var dblRet = Number.NaN;929930 if (typeof(pobjVal) == "number")931 return pobjVal;932 else933 {934 dblRet = new Number(pobjVal);935 return dblRet.valueOf();936 }937}938939/*------------------------------------------------------------------------------940 * NAME : ToBoolean941 * PURPOSE : Converts the supplied parameter to boolean value942 * PARAMETERS : pobjVal - The parameter to be converted.943 * RETURNS : Boolean value944 *----------------------------------------------------------------------------*/945function ToBoolean(pobjVal)946{947 var dblNo = Number.NaN;948 var strTmp = null;949950 if (pobjVal == null || pobjVal == undefined)951 throw "Boolean value is not defined!";952 else if (typeof(pobjVal) == "boolean")953 return pobjVal;954 else if (typeof(pobjVal) == "number")955 return (pobjval > 0);956 else if (IsNumber(pobjVal))957 {958 dblNo = ToNumber(pobjVal);959 if (isNaN(dblNo)) 960 return null;961 else962 return (dblNo > 0);963 }964 else if (typeof(pobjVal) == "object")965 {966 strTmp = pobjVal.toString();967 if (strTmp.toUpperCase() == "TRUE")968 return true;969 else if (strTmp.toUpperCase() == "FALSE")970 return false;971 else972 return null;973 }974 else if (typeof(pobjVal) == "string")975 {976 if (pobjVal.toUpperCase() == "TRUE")977 return true;978 else if (pobjVal.toUpperCase() == "FALSE")979 return false;980 else981 return null;982 }983 else984 return null;985}986987/*------------------------------------------------------------------------------988 * NAME : Precedence989 * PURPOSE : Returns the precedence of a given operator990 * PARAMETERS : pstrTok - The operator token whose precedence is to be returned.991 * RETURNS : Integer992 *----------------------------------------------------------------------------*/993function Precedence(pstrTok)994{995 var intRet = 0;996997 switch (pstrTok)998 {999 case "+" :1000 case "-" :1001 intRet = 5;1002 break;1003 case "*" :1004 case "/" :1005 case "%" :1006 intRet = 6;1007 break;1008 case "^" :1009 intRet = 7;1010 break;1011 case UNARY_NEG :1012 case "!" :1013 intRet = 10;1014 break;1015 case "(" :1016 intRet = 99;1017 break;1018 case "&" :1019 case "|" :1020 intRet = 3;1021 break;1022 case ">" :1023 case ">=" :1024 case "<" :1025 case "<=" :1026 case "=" :1027 case "<>" :1028 intRet = 4;1029 break;1030 default :1031 if (IsFunction(pstrTok))1032 intRet = 9;1033 else1034 intRet = 0;1035 break;1036 }1037 debugAssert ("Precedence of " + pstrTok + " is " + intRet);1038 return intRet;1039}10401041/*------------------------------------------------------------------------------1042 * NAME : debugAssert1043 * PURPOSE : Shows a messagebox displaying supplied message1044 * PARAMETERS : pObject - The object whose string representation is to be displayed.1045 * RETURNS : Nothing1046 *----------------------------------------------------------------------------*/1047function debugAssert(pObject)1048{1049 if (DEBUG_ON)1050 alert (pObject.toString())
...
asnjwk.js
Source:asnjwk.js
...26var DEBUG_BREAK_ON_ERROR = false;27function debugLog(message) {28 console.log(message);29}30function debugAssert(b, message) {31 if (!b) {32 if (DEBUG_BREAK_ON_ERROR) {33 debugger;34 }35 //console.log(message || 'Assertion failed', { 'StackTrace': getStackTrace(my.debugAssert) });36 debugLog(message || 'Assertion failed');37 }38}39function hexDump(abv, idx, len) {40 var hexDigits = "0123456789ABCDEF";41 function hexByte(b) {42 return hexDigits.charAt((b >> 4) & 0xF) + hexDigits.charAt(b & 0xF);43 }44 var start = idx || 0;45 var end = len ? start + len : abv.length;46 var s = "";47 if (end > abv.length) return s;48 for (var i = start; i < end; ++i) {49 s += hexByte(abv[i]);50 }51 return s;52}53//================================================================================54// abvStream.js55/** @type {{Util:Object}} */56var AbvStream = (function () {57function My(input, position) {58 if (input instanceof AbvStream) {59 DEBUG && debugAssert(!position);60 this.abv = input.abv;61 this.position = input.position;62 } else {63 this.abv = input;64 this.position = position || 0;65 }66}67My.prototype = {68 readByte: function () {69 return this.abv[this.position++];70 },71 72 writeByte: function (byte) {73 DEBUG && debugAssert(this.getRemaining() >= 1);74 this.abv[this.position++] = byte;75 },76 77 peekByte: function (position) {78 DEBUG && debugAssert(position >= 0 && position <= this.abv.length);79 return this.abv[position];80 },81 82 copyBytes: function(srcAbv, srcOffset, nBytes) {83 DEBUG && debugAssert(this.getRemaining() >= nBytes);84 var dstU8 = new Uint8Array(this.abv.buffer, this.position, nBytes);85 var srcU8 = new Uint8Array(srcAbv.buffer, srcOffset, nBytes);86 dstU8.set(srcU8);87 this.position += nBytes;88 },89 90 seek: function (position) {91 DEBUG && debugAssert(position >= 0 && position <= this.abv.length);92 this.position = position;93 },94 skip: function (bytesToSkip) {95 DEBUG && debugAssert(bytesToSkip <= this.getRemaining());96 this.position += bytesToSkip;97 },98 getPosition: function () {99 return this.position;100 },101 102 setPosition: function (position) {103 DEBUG && debugAssert(position <= this.abv.length);104 this.position = position;105 },106 getRemaining: function () {107 return this.abv.length - this.position;108 },109 getLength: function () {110 return this.abv.length;111 },112 isEndOfStream: function () {113 return this.position >= this.abv.length;114 },115 116 show: function () {117 var output = "AbvStream: pos ";118 output += this.getPosition().toString() + " of " + this.getLength().toString();119 return output;120 }121};122return My;123}());124//================================================================================125// asn1.js126/** @enum {number} */127var tagClass = {128 UNIVERSAL: 0,129 APPLICATION: 1,130 CONTEXT_SPECIFIC: 2,131 PRIVATE: 3,132 };133/** @enum {number} */134var tagVal = {135 BER: 0,136 BOOLEAN: 1,137 INTEGER: 2,138 BIT_STRING: 3,139 OCTET_STRING: 4,140 NULL: 5,141 OBJECT_IDENTIFIER: 6,142 OBJECT_DESCRIPTOR: 7,143 INSTANCE_OF_EXTERNAL: 8,144 REAL: 9,145 ENUMERATED: 10,146 EMBEDDED_PPV: 11,147 UTF8_STRING: 12,148 RELATIVE_OID: 13,149 // 14 & 15 undefined150 SEQUENCE: 16,151 SET: 17,152 NUMERIC_STRING: 18,153 PRINTABLE_STRING: 19,154 TELETEX_STRING: 20,155 T61_STRING: 20,156 VIDEOTEX_STRING: 21,157 IA5_STRING: 22,158 UTC_TIME: 23,159 GENERALIZED_TIME: 24,160 GRAPHIC_STRING: 25,161 VISIBLE_STRING: 26,162 ISO64_STRING: 26,163 GENERAL_STRING: 27,164 UNIVERSAL_STRING: 28,165 CHARACTER_STRING: 29,166 BMP_STRING: 30167 };168/** @const */169var tagText = [];170tagText[tagVal.BER ] = 'BER';171tagText[tagVal.BOOLEAN ] = 'BOOLEAN';172tagText[tagVal.INTEGER ] = 'INTEGER';173tagText[tagVal.BIT_STRING ] = 'BIT STRING';174tagText[tagVal.OCTET_STRING ] = 'OCTET STRING';175tagText[tagVal.NULL ] = 'NULL';176tagText[tagVal.OBJECT_IDENTIFIER ] = 'OBJECT IDENTIFIER';177tagText[tagVal.OBJECT_DESCRIPTOR ] = 'ObjectDescriptor';178tagText[tagVal.INSTANCE_OF_EXTERNAL] = 'INSTANCE OF, EXTERNAL';179tagText[tagVal.REAL ] = 'REAL';180tagText[tagVal.ENUMERATED ] = 'ENUMERATED';181tagText[tagVal.EMBEDDED_PPV ] = 'EMBEDDED PPV';182tagText[tagVal.UTF8_STRING ] = 'UTF8String';183tagText[tagVal.RELATIVE_OID ] = 'RELATIVE-OID';184tagText[tagVal.SEQUENCE ] = 'SEQUENCE';185tagText[tagVal.SET ] = 'SET, SET OF';186tagText[tagVal.NUMERIC_STRING ] = 'NumericString';187tagText[tagVal.PRINTABLE_STRING ] = 'PrintableString';188tagText[tagVal.TELETEX_STRING ] = 'TeletexString, T61String';189tagText[tagVal.VIDEOTEX_STRING ] = 'VideotexString';190tagText[tagVal.IA5_STRING ] = 'IA5String';191tagText[tagVal.UTC_TIME ] = 'UTCTime';192tagText[tagVal.GENERALIZED_TIME ] = 'GeneralizedTime';193tagText[tagVal.GRAPHIC_STRING ] = 'GraphicString';194tagText[tagVal.VISIBLE_STRING ] = 'VisibleString, ISO64String';195tagText[tagVal.GENERAL_STRING ] = 'GeneralString';196tagText[tagVal.UNIVERSAL_STRING ] = 'UniversalString';197tagText[tagVal.CHARACTER_STRING ] = 'CHARACTER STRING';198tagText[tagVal.BMP_STRING ] = 'BMPString';199/**200 * Asn1Token201 * @param {ArrayBufferView=} abv The backing store.202 * @param {Object=} parent The parent token (optional).203 * @param {boolean=} constr bit 6 of the identifier byte (optional).204 * @param {?number=} tag bits 1-5 of the identifier byte (optional).205 * @param {?number=} didx index of the token's data in the source Uint8Array (optional).206 * @param {?number=} dlen length the data in bytes (optional).207 * @constructor208 */209var Asn1Token = function(abv, parent, constr, tag, didx, dlen) {210 this._data = abv; // the backing data store211 this._parent = parent || undefined; // the parent token212 this._constructed = constr || false; // bit 6 of the identifier byte213 this._tagClass = tagClass.UNIVERSAL; // bits 7-8 of the identifier byte 214 this._tag = tag || 0; // bits 1-5 of the identifier byte 215 this._dataIdx = didx || 0; // index of the token's data in the source Uint8Array 216 this._dataLen = dlen || 0; // length the data in bytes217};218Asn1Token.prototype = {219 _child: undefined, // the first child of the current token, if present 220 _next: undefined, // the next sibling of the current token, if present 221 get data() {222 DEBUG && debugAssert(this._data);223 return new Uint8Array(224 this._data.buffer.slice(this._dataIdx, this._dataIdx + this._dataLen)225 );226 },227 228 get backingStore() {return this._data;},229 230 get constructed() {return this._constructed;},231 set constructed(c) {this._constructed = c !=0 ? true : false;},232 233 get tagClass() {return this._tagClass;},234 set tagClass(c) {this._tagClass = c;},235 236 get tag() {return this._tag;},237 set tag(c) {this._tag = c;},238 239 get dataIdx() {return this._dataIdx;},240 set dataIdx(c) {this._dataIdx = c;},241 242 get dataLen() {return this._dataLen;},243 set dataLen(c) {this._dataLen = c;},244 245 get child() {return this._child;},246 set child(c) {247 this._child = c;248 this._child.parent = this;249 },250 251 get next() {return this._next;},252 set next(c) {this._next = c;},253 254 get parent() {return this._parent;},255 set parent(c) {this._parent = c;},256 257 // Returns the payload size of the eventual encoding of this asn1token.258 get payloadLen() {259 var payloadLen = 0;260 if (this._child) {261 var child = this._child;262 while (child) {263 payloadLen += child.length;264 child = child.next;265 }266 // Special handling for bit string. In X.509 they always have a zero267 // padding byte prepended.268 if (this._tag == tagVal.BIT_STRING) {269 payloadLen++;270 }271 } else { // no children272 switch (this._tag) {273 case tagVal.INTEGER: {274 // NOTE: NOT handling negative integers or non-byte multiple275 payloadLen = this._dataLen;276 // If the MSBit of the fitst byte is set, an extra zero byte277 // will be prepended to the data.278 if (this._data[this._dataIdx] >> 7)279 payloadLen++;280 break;281 }282 case tagVal.BIT_STRING: {283 // For X.509 bit strings are always a byte-multiple, and284 // always have a zero padding byte prepended.285 payloadLen = this._dataLen + 1;286 break;287 }288 case tagVal.OCTET_STRING: {289 payloadLen = this._dataLen;290 break;291 }292 case tagVal.NULL: {293 payloadLen = 0;294 break;295 }296 case tagVal.OBJECT_IDENTIFIER: {297 // Only handling RSA Encryption OID.298 if (oidIsRsaEncryption(this._data, this._dataIdx, this._dataLen)) {299 payloadLen = 9;300 } else {301 DEBUG && debugAssert("Non RSA OID found");302 }303 break;304 }305 case tagVal.SET:306 case tagVal.SEQUENCE: {307 DEBUG && debugAssert(false, "found constructed type " + tagText[this._tag] + " with no children");308 break;309 }310 default: {311 DEBUG && debugAssert(false, "unhandled type " + tagText[this._tag]);312 break;313 }314 }315 }316 return payloadLen;317 },318 319 // Returns the total size of the eventual encoding of this asn1token.320 get length() {321 return derLength(this.payloadLen);322 },323 324 // Returns a Uint8Array representing the DER encoding of this asn1token.325 get der() {326 var encodingLength = this.length;327 if (!encodingLength) {328 DEBUG && debugLog("der: found zero length");329 return undefined;330 }331 var output = new Uint8Array(encodingLength);332 DEBUG && debugLog("created abv of length " + encodingLength);333 var stream = new AbvStream(output);334 if (!buildDer(this, stream)) {335 DEBUG && debugLog("der: buildDer failed");336 return undefined;337 }338 return output;339 },340 341 get nChildren() {342 var nChildren = 0;343 var token = this._child;344 while (token) {345 nChildren++;346 token = token.next;347 }348 return nChildren;349 }350 351};352// Returns the size of the eventual encoding of an Asn1Token with the given353// payload length. The returned size counts the header byte, length bytes,354// and payload.355function derLength(payloadLength) {356 var x;357 if (payloadLength > 127) {358 x = payloadLength;359 while (x) {360 x >>= 8;361 ++payloadLength;362 }363 }364 return payloadLength + 2;365}366// Writes an ASN.1 header byte and encoded length to a stream367function writeDerHeaderAndLength(asn1node, stream) {368 var tagByte = (asn1node.tagClass << 6) | (asn1node.constructed << 5) | asn1node.tag;369 stream.writeByte(tagByte);370 var payloadLen = asn1node.payloadLen;371 if (payloadLen < 128) {372 stream.writeByte(payloadLen);373 } else {374 // find length of length and write it375 var x = payloadLen;376 var nBytesInLen = 0;377 while (x) {378 ++nBytesInLen;379 x >>= 8;380 }381 stream.writeByte(0x80 | nBytesInLen);382 // write the multi-byte length383 for (var i=0; i < nBytesInLen; ++i) {384 var byteShift = nBytesInLen-i-1;385 stream.writeByte((payloadLen >> (byteShift * 8)) & 0xff);386 }387 }388}389// Builds a DER encoding of an Asn1Token, writing the bytes to the current390// position of the input stream.391function buildDer(node, stream) {392 writeDerHeaderAndLength(node, stream);393 if (node.child) {394 // Special handling for bit string, prepend a zero byte.395 if (node.tag == tagVal.BIT_STRING) {396 stream.writeByte(0);397 }398 var child = node._child;399 while (child) {400 if (!buildDer(child, stream)) {401 return false;402 }403 child = child.next;404 }405 }406 else { // primitive node407 switch (node.tag) {408 case tagVal.INTEGER: {409 // If the MSBit of the fitst byte is set, an extra zero byte410 // will be prepended to the data.411 if (node.backingStore[node.dataIdx] >> 7) {412 stream.writeByte(0);413 }414 stream.copyBytes(node.backingStore, node.dataIdx, node.dataLen);415 break;416 }417 case tagVal.BIT_STRING: {418 // For X.509 bit strings are always a byte-multiple, and419 // always have a zero padding byte prepended.420 stream.writeByte(0);421 stream.copyBytes(node.backingStore, node.dataIdx, node.dataLen);422 break;423 }424 case tagVal.OCTET_STRING: {425 stream.copyBytes(node.backingStore, node.dataIdx, node.dataLen);426 break;427 }428 case tagVal.NULL: {429 break;430 }431 case tagVal.OBJECT_IDENTIFIER: {432 // We only handle RSA Encryption OID.433 DEBUG && debugAssert(oidIsRsaEncryption(node.backingStore, node.dataIdx, node.dataLen));434 stream.copyBytes(node.backingStore, node.dataIdx, node.dataLen);435 break;436 }437 case tagVal.SET:438 case tagVal.SEQUENCE: {439 DEBUG && debugAssert(false, "found constructed type " + tagText[node.tag] + " with no children");440 break;441 }442 default: {443 DEBUG && debugAssert(false, "unhandled type " + tagText[node.tag]);444 break;445 }446 }447 }448 return true;449}450// var Asn1Token = function(abv, parent, constr, tag, didx, dlen)451var NodeFactory = {452 createSequenceNode: function() {453 return new Asn1Token(null, null, true, tagVal.SEQUENCE, null, null);454 },455 createOidNode: function(data) {456 return new Asn1Token(data, null, false, tagVal.OBJECT_IDENTIFIER, 0, data ? data.length : 0);457 },458 createNullNode: function() {459 return new Asn1Token(null, null, false, tagVal.NULL, null, null);460 },461 createBitStringNode: function(data) {462 return new Asn1Token(data, null, false, tagVal.BIT_STRING, 0, data ? data.length : 0);463 // might need to set constructed later464 },465 createIntegerNode: function(data) {466 return new Asn1Token(data, null, false, tagVal.INTEGER, 0, data ? data.length : 0);467 },468 createOctetStringNode: function(data) {469 return new Asn1Token(data, null, false, tagVal.OCTET_STRING, 0, data ? data.length : 0);470 }471};472/**473 * Builder474 * @param {Object} rootNode The root node.475 * @constructor476 */477var Builder = function(rootNode) {478 this._rootNode = rootNode;479 this._currentNode = rootNode;480};481Builder.prototype = {482 addChild: function(childNode) {483 this.addTo(this._currentNode, childNode);484 },485 addSibling: function(siblingNode) {486 this.addTo(this._currentNode.parent, siblingNode);487 },488 addTo: function(parentNode, childNode) {489 this._currentNode = childNode;490 this._currentNode.parent = parentNode;491 if (!parentNode.child) {492 parentNode.child = childNode;493 }494 else {495 var node = parentNode.child;496 while (node.next) {497 node = node.next;498 }499 node.next = childNode;500 }501 },502 addToParent: function(parentNode, childNode) {503 if (this.findNode(parentNode)) {504 this.addTo(parentNode, childNode);505 }506 },507 findNode: function(node) {508 var parentNode = this._currentNode;509 while (parentNode) {510 if (node == parentNode) {511 return true;512 }513 parentNode = parentNode.parent;514 }515 return false;516 }517};518function decodeTagByte(stream) {519 var tag = stream.readByte();520 if ((tag & 0x1F) == 0x1F) {521 var newTag = 0;522 while (tag & 0x80) {523 newTag <<= 8;524 newTag |= tag & 0x7F;525 }526 tag = newTag;527 }528 return tag;529}530function decodeLength(stream) {531 var buf = stream.readByte(),532 len = buf & 0x7F;533 if (len == buf)534 return len;535 // Refuse encoded lengths > 3 bytes and ensure encoded length is nonzero.536 if ( (len > 3) || (len === 0) ) {537 return -1;538 }539 buf = 0;540 for (var i = 0; i < len; ++i)541 buf = (buf << 8) | stream.readByte();542 return buf;543}544function hasContent(stream, tag, len) {545 if (tag & 0x20)546 return true; // constructed547 if ((tag < tagVal.BIT_STRING) || (tag > tagVal.OCTET_STRING))548 return false;549 var s = new AbvStream(stream);550 if (tag == tagVal.BIT_STRING)551 s.skip(1); // BitString unused bits, must be in [0, 7]552 var subTag = s.readByte();553 if ((subTag >> 6) & 0x01)554 return false; // not (universal or context)555 var subLength = decodeLength(s);556 var isContent = ((s.getPosition() - stream.getPosition()) + subLength == len);557 return isContent;558}559var asn1ParseRecursionDepth = 0,560 asn1ParseMaxRecursionDepth = 8;561function asn1Parse(rootToken, start, len) {562 var abv = rootToken.backingStore,563 stream = new AbvStream(abv, start),564 tokenEndIdx = start + len,565 token = rootToken,566 tagByte,567 tokenTag,568 tokenLength,569 tokenStartIdx,570 subIdx,571 subLength,572 curIdx;573 574 if (asn1ParseRecursionDepth++ > asn1ParseMaxRecursionDepth) {575 DEBUG && debugLog("asn1Parse max recursion depth exceeded");576 return undefined;577 }578 579 DEBUG && debugLog("==================== asn1Parse ENTER ====================");580 DEBUG && debugLog(stream.show() + ", len = " + len);581 582 while (stream.getPosition() < tokenEndIdx) {583 584 DEBUG && debugAssert(!stream.isEndOfStream());585 586 DEBUG && debugLog("---- token ----");587 DEBUG && debugLog(stream.show());588 589 tokenStartIdx = stream.getPosition();590 // The first byte of the token is the tagByte.591 tagByte = decodeTagByte(stream);592 tokenTag = tagByte & 0x1F;593 if (tokenTag < 0 || tokenTag > 30) {594 DEBUG && debugLog("Invalid tag found at position " + (stream.getPosition() - 1));595 return undefined;596 }597 598 // The next few bytes are the data length (vle)....
cShapeContainer.gs
Source:cShapeContainer.gs
1var cShapeContainer = function() {2 var pChildren = new collection();3 this.children = function() {4 return pChildren;5 };6 this.xSerial = 0;7 this.serial = function() {8 return this.xSerial;9 };10 this.xParent = null;11 this.parent = function(){12 return this.xParent;13 }14};15cShapeContainer.prototype.debug = function (s){16 this.children().forEach(17 function (sc) {18 DebugPrint(fixOptional(s,''),'child',sc.id(),'target',sc.target(),'myspace',sc.mySpace(),sc.text());19 sc.debug('parent:'+sc.id());20 }21 );22}23// create--24cShapeContainer.prototype.create = function(rt,pr,rplot,dss){25 this.xScType = isUndefined(this.xDataRow=pr) ? SCTYPES.sctframe : SCTYPES.sctdata;26 this.scType = function() {27 return this.xScType;28 };29 this.dataRow = function() {30 return this.xDataRow;31 };32 DebugAssert ( (this.xDataRow && this.xScType == SCTYPES.sctdata) ||33 (!this.xDataRow && this.xScType == SCTYPES.sctframe),'mismatchdata/type'); 34 this.xRoot = rt;35 this.root = function() {36 return this.xRoot;37 };38 this.xWhere = rplot;39 this.where = function() {40 return this.xWhere;41 };42 this.xDsets = dss;43 this.xSerial = (this.root().xSerial ++);44 return this;45};46cShapeContainer.prototype.valid = function() {47 return this.parent();48};49cShapeContainer.prototype.dSets = function() {50 return this.root().xDsets;51};52cShapeContainer.prototype.plot = function() {53 return this.where();54};55// target..if parent is confirmed use the parents ID, otherwise go to the data. If blank, use the frame as the target56cShapeContainer.prototype.target = function() {57 var s;58 return this.valid() ? 59 this.parent().id() : 60 (s=this.fetchKey("Target")) ? 61 s :62 this.root().id();63};64cShapeContainer.prototype.isFrame =function () {65 return this.scType()==SCTYPES.sctframe;66};67cShapeContainer.prototype.isData =function() {68 return this.scType()==SCTYPES.sctdata;69};70cShapeContainer.prototype.assertData = function(sExtra) {71 if (this.dataRow()) {72 DebugAssert( this.isData() ,'expected a data item ' +fixOptional(sExtra,''));73 }74 else {75 DebugAssert ( this.isFrame(),'expected a frame ' +fixOptional(sExtra,'')); 76 }77 return this.dataRow();78};79cShapeContainer.prototype.isRounded = function(s) {80 return s == SHAPETYPES.stRoundedRectangularCallout || s == SHAPETYPES.stRoundedRectangle;81}82cShapeContainer.prototype.whichShape = function(s) {83 switch(LCase(s)) {84 case "pentagon" :85 return SHAPETYPES.stPentagon;86 case "rectangle":87 return SHAPETYPES.stRectangle;88 case "rounded rectangle":89 return SHAPETYPES.stRoundedRectangle;90 case "chevron":91 return SHAPETYPES.stChevron;92 case "notched right arrow":93 return SHAPETYPES.stNotchedRightArrow;94 case "right arrow":95 return SHAPETYPES.stRightArrow;96 case "right arrow callout":97 return SHAPETYPES.stRightArrowCallout;98 case "rectangular callout":99 return SHAPETYPES.stRectangularCallout;100 case "rounded rectangular callout":101 return SHAPETYPES.stRoundedRectangularCallout;102 case "none":103 return SHAPETYPES.stNone;104 case "line callout accent bar":105 return SHAPETYPES.stLineCallout2AccentBar;106 default:107 MsgBox ("Used default - cant find shape " + s);108 return SHAPETYPES.stDefault;109 }110};111cShapeContainer.prototype.startScale = function() {112 return this.xStartScale;113};114cShapeContainer.prototype.finishScale = function() {115 return this.xFinishScale;116};117cShapeContainer.prototype.paramStartDate = function() {118 var s = makeKey(this.paramCell("containers", "start date", "value").toString());119 var dsmallest=0;120 if (s == "automatic" ) {121 this.dSets().dataSet("data").rows().forEach(122 function(dr,drIndex){123 var d = dr.value("activate");124 if((d && d < dsmallest) || !dsmallest) {125 dsmallest=d;126 }127 }128 );129 return dsmallest;130 }131 else {132 return this.param("containers", "start date", "value");133 }134};135cShapeContainer.prototype.paramFinishDate = function() {136 var s = makeKey(this.paramCell("containers", "finish date", "value").toString());137 var dbiggest=0;138 if (s == "automatic" ) {139 this.dSets().dataSet("data").rows().forEach(140 function(dr,drIndex){141 var d = dr.value("deactivate");142 if((d && d > dbiggest) || !dbiggest) {143 dbiggest=d;144 }145 }146 );147 return dbiggest;148 }149 else {150 return this.param("containers", "finish date", "value");151 }152};153cShapeContainer.prototype.activate = function() {154 if (this.isFrame()) {155 return this.startScale() ? this.startScale() : this.paramStartDate(); 156 }157 else {158 var mind = this.root().activate();159 return this.dateGiven('activate') ? 160 (this.fieldData("activate") < mind ?161 mind : 162 this.fieldData("activate") ) :163 mind; 164 }165};166cShapeContainer.prototype.deActivate = function() {167 if (this.isFrame()) {168 return this.finishScale() ? this.finishScale() : this.paramFinishDate(); 169 }170 else {171 var maxd = this.root().deActivate();172 return this.dateGiven('deActivate') ? 173 (this.fieldData("deActivate") > maxd ?174 maxd : this.fieldData("deActivate") ) :175 maxd; 176 }177};178cShapeContainer.prototype.text = function() {179 return this.assertData('text') ? this.dataRow().toString("Description") : this.paramTitle();180};181cShapeContainer.prototype.calloutText = function() {182 return this.assertData('callOutText') ? this.dataRow().toString("Callout") : '';183};184cShapeContainer.prototype.sequence = function() {185 return this.fieldData("sequence");186};187cShapeContainer.prototype.cost = function() {188 var x = this.fieldData("cost");189 return x ? x : 0 ;190};191cShapeContainer.prototype.custom = function() {192 return this.fieldData("custom");193};194cShapeContainer.prototype.fieldData = function(s) {195 return this.assertData() ? this.dataRow().value(s) : null ;196};197cShapeContainer.prototype.dateGiven = function(s) {198 return IsDate( this.fieldData(s));199};200cShapeContainer.prototype.fetchKey = function(s) {201 return this.isData() ? 202 makeKey(this.dataRow().value(s)) : 203 ECONSTANTS.frameID ;204};205cShapeContainer.prototype.paramShapeCalloutTemplate = function(s) {206 return this.assertData('paramShapeCalloutTemplate') ? this.fixupCustomCell("callout format").where() : null ;207};208cShapeContainer.prototype.fixupCustomCell = function(sid) {209 var cc= this.paramCustomCell(sid);210 return cc ? cc : this.timeBasedRow().cell(sid) ;211};212cShapeContainer.prototype.id = function() {213 return this.fetchKey("id");214};215cShapeContainer.prototype.myWidth = function() {216 return this.isData() ? 217 this.root().shape().width() * this.duration() / this.root().duration() :218 this.paramFrameWidth();219};220cShapeContainer.prototype.myLeft = function() {221 222 return this.root().shape() ? 223 this.root().shape().left() + 224 (this.activate()- this.root().activate() ) / 225 this.root().duration() * this.root().shape().width() :226 this.paramFrameLeft();227};228cShapeContainer.prototype.duration = function() {229 return this.deActivate() - this.activate();230};231cShapeContainer.prototype.paramGap = function() {232 return this.fixupCustomCell("gap").value();233};234cShapeContainer.prototype.paramCalloutHeightAbove = function() {235 return this.fixupCustomCell("callout % height").value();236};237cShapeContainer.prototype.paramCalloutMaxWidth = function() {238 return this.fixupCustomCell("callout % width").value();239};240cShapeContainer.prototype.paramCalloutPosition = function() {241 return this.fixupCustomCell("callout position").value();242};243cShapeContainer.prototype.paramExpansion = function() {244 return isStringTrue(this.fixupCustomCell("allow expansion").value());245};246cShapeContainer.prototype.timeBasedRow = function() {247// try to figure out characteristics for a shape based on dates248 var self = this;249 var rdr = null;250 this.dSets().dataSet("roadmap colors").rows().forEach(251 function (dr) {252 var sd = dr.value("decommission from");253 var fd = dr.value("decommission to");254 var datafd = self.deActivate();255 if ( (!self.dateGiven("deactivate") && (!sd || !fd)) ||256 (datafd >= sd && datafd <= fd) ){257 return(rdr = dr);258 }259 }260 );261 if(!rdr)262 MsgBox ("Could not find time based parameter for deactivate date " + 263 CStr(self.deActivate()) + " ID " + self.id());264 return rdr;265};266cShapeContainer.prototype.paramHeight = function() {267 return this.fixupCustomCell("height").value();268};269cShapeContainer.prototype.paramFrameWidth = function() {270 return this.param("containers", "width", "value");271};272cShapeContainer.prototype.paramFrameLeft = function() {273 return this.param("containers", "left", "value");274};275cShapeContainer.prototype.paramFrameTop = function() {276 return this.param("containers", "top", "value");277};278cShapeContainer.prototype.paramTitle = function() {279 return this.param("options", "title", "value");280};281cShapeContainer.prototype.paramExpansion = function() {282 return isStringTrue(this.fixupCustomCell("allow expansion").value());283};284cShapeContainer.prototype.paramShapeTemplate = function(s) {285 return this.assertData('paramShapeTemplate') ? 286 this.fixupCustomCell("format").where() : 287 this.paramRange("containers", "frame", "format");288};289cShapeContainer.prototype.paramShapeType = function() {290 return this.isFrame() ? 291 this.whichShape(this.param("containers", "frame", "value")):292 this.whichShape(this.fixupCustomCell("shape").toString());293};294cShapeContainer.prototype.paramShapeCalloutType = function() {295 var cc;296 return this.isData() ? 297 (cc = this.fixupCustomCell("callout") ? whichShape(cc.toString()) : SHAPETYPES.stNone) :298 SHAPETYPES.stNone299};300cShapeContainer.prototype.chartProportion = function() {301 return this.param("options", "chart proportion", "value");302};303cShapeContainer.prototype.paramYesNo = function(dsn,rid,sid) {304 return isStringTrue(this.param(dsn, rid, sid));305};306cShapeContainer.prototype.param = function(dsn,rid,sid) {307 return this.paramCell(dsn, rid, sid).value();308};309cShapeContainer.prototype.paramCell = function(dsn,rid,sid) {310 return this.dSets().dataSet(makeKey(dsn)).cell(rid,sid);311};312cShapeContainer.prototype.paramRange = function(dsn,rid,sid) {313 return this.paramCell(dsn,rid,sid).where();314};315cShapeContainer.prototype.chartProportion = function() {316 return (this.param("options", "chart proportion", "value"));317};318// how many branches in my tree319cShapeContainer.prototype.treeLength = function() {320 var ht = 1;321 this.children().forEach(322 function (sc) {323 ht += sc.treeLength();324 }325 );326 return ht;327}328cShapeContainer.prototype.myGapAfterMe = function() {329 return this.paramGap();330};331cShapeContainer.prototype.myGapBeforeChildren = function() {332 return this.children().count() ? this.paramGap() : 0;333};334cShapeContainer.prototype.myExpansion = function() {335 return this.paramExpansion() ? true : this.biggestBranch() > 1 ;336};337cShapeContainer.prototype.mySpace = function() {338 var ht = 0;339 340 if (!this.children().count()){341 ht= this.paramHeight() + this.myGapAfterMe();342 }343 else {344 if (this.myExpansion()){345 ht += this.myGapBeforeChildren();346 this.children().forEach(347 function (sc,scIndex) {348 ht += sc.mySpace();349 }350 );351 ht += this.myGapAfterMe();352 }353 else354 ht = this.paramHeight() + this.myGapAfterMe();355 }356 return ht;357};358cShapeContainer.prototype.myShapeHeight = function() {359 return this.mySpace() - this.myGapAfterMe();360};361cShapeContainer.prototype.biggestBranch = function() {362 var ht = this.children().count();363 this.children().forEach(364 function (sc,scIndex) {365 if (( t = sc.biggestBranch()) > ht) ht = t;366 }367 );368 return ht;369};370cShapeContainer.prototype.find = function(vId) {371 var scFound = this.childExists(vId);372 if (!scFound) {373 this.children().forEach(374 function (sc,scIndex) {375 if (!scFound) scFound = sc.find(vId);376 }377 );378 }379 return scFound;380};381cShapeContainer.prototype.childExists = function(vId,complain) {382 return this.children().item(vId,fixOptional(complain,false));383}384cShapeContainer.prototype.paramCustomCell = function(sValue,complain) {385 var sCustom = this.fieldData("Custom");386 if (sCustom) {387 var p = this.paramCell("Custom Bars", sCustom, sValue);388 if (!p && fixOptional (complain,true)) {389 MsgBox ("could not find custom format definition |" + 390 sCustom + "|" + sValue + "| in parameter sheet");391 }392 return p;393 }394};395cShapeContainer.prototype.shape = function() {396 return this.xShape;397};398cShapeContainer.prototype.shapeType = function() {399 return this.xShapeType;400};401cShapeContainer.prototype.shapeTemplate = function(shp,ptWhere) {402 var where = !isUndefined(ptWhere) ? ptWhere : this.paramShapeTemplate();403 var sh = fixOptional(shp,this.shape());404 // minimize api calls again405 var wn = WorkSheetName(WorkSheet(where));406 var rn = where.getRow();407 var cn = where.getColumn();408 sh.setBackgroundColor(sheetCache(wn,'getBackgroundColors').getValue(rn,cn));409 sh.setColor(sheetCache(wn,'getFontColors').getValue(rn,cn));410 sh.setTextAlign(sheetCache(wn,'getHorizontalAlignments').getValue(rn,cn));411 sh.setVerticalAlign(sheetCache(wn,'getVerticalAlignments').getValue(rn,cn));412 sh.setFontSize(sheetCache(wn,'getFontSizes').getValue(rn,cn)) ;413 return this;414}415cShapeContainer.prototype.makeShape = function (xTop) {416 var self = this;417 // this would be a frame418 if (isUndefined(xTop)) xTop = self.paramFrameTop() + this.paramHeight() / 2;;419 // none shapes are made invisible but take space420 if ((this.xShapeType = self.paramShapeType()) == SHAPETYPES.stNone) 421 this.xShapeType = SHAPETYPES.stDefault;422 //this is the most complex part - creating the shapes of the correct size and placing them in the right spot423 self.xShape = self.addShape(this.xShapeType,self.paramFrameLeft(),xTop, self.paramFrameWidth(), this.myShapeHeight());424 self.shapeTemplate();425 426 self.shape()427 .setText(self.text())428 .setVisible (self.paramShapeType() != SHAPETYPES.stNone);429 430 if (self.isData()){431 self.shape()432 .setLeft(self.myLeft())433 .setWidth(self.myWidth());434 }435 self.shape().commit();436 437 //this is where it gets tricky438 var xNextTop = self.shape().top();439 if(this.myExpansion()) {440 //if we are allowing expansion of targets then need to make a gap to accommodate my children441 xNextTop += self.myGapBeforeChildren();442 }443 self.children().forEach(444 function (sc) {445 sc.makeShape(xNextTop);446 xNextTop += sc.mySpace();447 }448 ); 449};450cShapeContainer.prototype.springClean=function(){451 DebugAssert (this.scType() == SCTYPES.sctframe, 'spring clean should start at root');452 this.associate();453 // probably dont need this in gapps454 //deleteAllShapes Plot, nameStub455};456cShapeContainer.prototype.associate=function(){457//one off reassociation of items from the root to be children of their target458//no need for recursion since to start with all are associated with the top level frame459 var self = this;460 self.children().forEach(461 function (scParent) {462 self.children().forEach(463 function (scChild,i) {464 if(scChild.target() == scParent.id()){465 scParent.children().add (scChild, scChild.id());466 //confirm the parent as found467 scChild.xParent = scParent;468 } 469 }470 )471 }472 );473 //now all we need to do is clean up the children of the frame474 for (var n = this.children().count(); n > 0 ; n--) {475 var scChild = this.children().item(n);476 if (!scChild.valid()) {477 //we get here because we didnt find a target yet478 if(scChild.target() != this.id()) {479 //and it wasnt the frame.. so480 MsgBox("Did not find target " + scChild.target() + " for ID " + scChild.id());481 }482 // confirm the frame as the parent483 scChild.xParent = this;484 }485 else {486 //remove from the frames children as already now child of someone else487 this.children().remove (n);488 }489 //belt and braces490 DebugAssert (scChild.valid(),'logic failure in associate');491 }492 return this;493}; 494cShapeContainer.prototype.createScale = function(){495 var tickType = makeKey(this.param("containers", "ticks", "value"));496 if (tickType == "automatic") tickType = this.autoScale(tickType);497 return ( this.xScaleDates = this.createTicks(tickType));498 499};500cShapeContainer.prototype.scaleDates = function(){501 return this.xScaleDates;502}503cShapeContainer.prototype.createTicks = function(s){504 505 var oTicks = this.limitofScale(s, this.activate(), this.deActivate());506 //patch in new scale507 this.xStartScale = oTicks.start;508 this.xFinishScale = oTicks.finish;509 var p = this.paramFrameLeft();510 var dheight = this.paramHeight();511 var ft = this.paramRange("containers", "ticks", "format");512 var ftop = this.paramFrameTop() ;513 if (ftop < 0) {514 MsgBox ("not enough room for scale - try changing the top parameter");515 ftop = 0;516 }517 var tScaleDates = [];518 var xcds = oTicks.start;519 var ticks=0;520 var p =this.paramFrameLeft();521 while (xcds < oTicks.finish) {522 ticks++;523 DebugAssert( ticks <= ECONSTANTS.maxTicks,524 "no room to show scale " + s + " :choose another scale");525 // get end date of the tick for this start date526 var oSub = this.limitofScale(s, xcds, xcds);527 DebugAssert (oSub.finish > xcds, ' got confused calculating scale');528 var w = this.myWidth() * (oSub.finish-oSub.start) / (oTicks.finish-oTicks.start+.0001);529 var shp = this.addShape(SHAPETYPES.stRectangle, p, ftop, w, dheight)530 .setText(oSub.finishText);531 532 this.shapeTemplate(shp,ft);533 shp.commit();534 p += shp.width();535 tScaleDates.push( oSub);536 xcds = addDays(oSub.finish, 1);537 }538 if (ticks){539 return tScaleDates;540 }541 542}543cShapeContainer.prototype.autoScale = function(){544 DebugAssert( this.scType() == SCTYPES.sctframe,'unexpected type wants dates');545 var idealTicks = ECONSTANTS.maxTicks * 0.5;546 var tickDiff = ECONSTANTS.maxTicks + 1;547 var s;548 var sBest ='unknown';549 for ( s in {"weeks":0, "months":0, "quarters":0, "halfyears":0,"years":0} ) {550 var ob = this.limitofScale(s, this.activate(), this.deActivate());551 if( Abs(idealTicks - ob.ticks) < tickDiff ){552 sBest = s;553 tickDiff = Abs(idealTicks - ob.ticks);554 }555 }556 DebugAssert( tickDiff <= ECONSTANTS.maxTicks,"Couldnt find a feasible automatic scale to use for roadmap"); 557 return sBest;558};559cShapeContainer.prototype.limitofScale = function(s, sd, fd) {560 var obj = {};561 obj['start'] = null;562 obj['finish'] = null;563 obj['ticks'] = 0;564 obj['finishText'] = '';565 obj['startText'] = '';566 switch (s) {567 case "weeks":568 obj.start = addDays(sd, -(sd.getDay() % 7), -1);569 obj.finish = addDays(fd, 6 - (fd.getDay() % 7), 1);570 obj.ticks = Math571 .floor((1 + daysDiff(obj.start, obj.finish)) / 7);572 obj.startText = niceDate(obj.start);573 obj.finishText = niceDate(obj.finish);574 return obj;575 576 case "months":577 obj.start = new Date(sd.getFullYear(), sd.getMonth(), 1);578 obj.finish = addDays(new Date(fd.getFullYear(),579 fd.getMonth() + 1, 1), -1, 1);580 obj.ticks = Math581 .floor((1 + daysDiff(obj.start, obj.finish)) / 30);582 obj.startText = ECONSTANTS.mths[obj.start.getMonth()] + '-'583 + padYear(obj.start);584 obj.finishText = ECONSTANTS.mths[obj.finish.getMonth()] + '-'585 + padYear(obj.finish);586 return obj;587 588 case "quarters":589 obj.start = new Date(sd.getFullYear(), sd.getMonth()590 - (sd.getMonth() % 3), 1);591 obj.finish = addDays(new Date(fd.getFullYear(), fd.getMonth()592 + 3 - (fd.getMonth() % 3), 1), -1, 1);593 obj.ticks = Math594 .floor((1 + daysDiff(obj.start, obj.finish)) / 90);595 obj.startText = 'Q'596 + (1 + Math.floor(obj.start.getMonth() / 3)).toString()597 + padYear(obj.start);598 obj.finishText = obj.startText;599 return obj;600 601 case "halfyears":602 obj.start = new Date(sd.getFullYear(), sd.getMonth()603 - (sd.getMonth() % 6), 1);604 obj.finish = addDays(new Date(fd.getFullYear(), fd.getMonth()605 + 6 - (fd.getMonth() % 6), 1), -1, 1);606 obj.ticks = Math607 .floor((1 + daysDiff(obj.start, obj.finish)) / 183);608 obj.startText = 'H'609 + (1 + Math.floor(obj.start.getMonth() / 6)).toString()610 + padYear(obj.start);611 obj.finishText = obj.startText;612 return obj;613 614 case "years":615 obj.start = new Date(sd.getFullYear(), 0, 1);616 obj.finish = addDays(617 new Date(fd.getFullYear() + 1, 0, 1), -1, 1);618 obj.ticks = Math619 .floor((1 + daysDiff(obj.start, obj.finish)) / 365);620 obj.startText = obj.start.getFullYear().toString();621 obj.finishText = obj.startText;622 return obj;623 624 default:625 DebugAssert(false, 'unknown scale ' + s);626 return null;627 }628};629cShapeContainer.prototype.needSwapBar = function(y) {630 var sorder = LCase(this.param("options", "sort bar order", "value"));631 var self = this;632 var bAscending = ( sorder == "ascending");633 if (sorder != "none") {634 var mOrder = LCase(self.param("options", "sort bars by", "value"));635 switch(mOrder){636 case "original":637 return (self.serial() > y.serial() && bAscending) || 638 (self.serial() < y.serial() && !bAscending);639 case "sequence":640 return (self.sequence() > y.sequence() && bAscending) || 641 (self.sequence() < y.sequence() && !bAscending);642 case "activate":643 return (self.activate() > y.activate() && bAscending) || 644 (self.activate() < y.activate() && !bAscending);645 case "deActivate":646 return (self.deActivate() > y.deActivate() && bAscending) || 647 (self.deActivate() < y.deActivate() && !bAscending);648 case "duration":649 return (self.duration() > y.duration() && bAscending) || 650 (self.duration() < y.duration() && !bAscending);651 case "id":652 return (self.id() > y.id() && bAscending) || 653 (self.id() < y.id() && !bAscending);654 655 case "description":656 return (self.description() > y.id() && bAscending) || 657 (self.description() < y.id() && !bAscending);658 default:659 DebugAssert(false,'unknown sort order ' +mOrder);660 }661 }662 return false;663};664function needSwap (x,y) {665 var xLen = x.treeLength();666 var yLen = y.treeLength();667 var sorder = x.param("options", "sort target popularity", "value");668 var bSwapBar = x.needSwapBar(y);669 switch(LCase(sorder)) {670 case "ascending popularity":671 return (xLen < yLen) || (xLen == yLen && bSwapBar);672 case "ascending popularity":673 return (xLen > yLen) || (xLen == yLen && bSwapBar);674 case "no popularity sort":675 return bSwapBar; 676 default:677 DebugAssert(false,'unknown popularity sort ' + sorder);678 }679 return false; 680};681cShapeContainer.prototype.sortChildren = function(){682 if (this.children().count()) {683 this.children().forEach(684 function (sc) {685 sc.sortChildren (needSwap);686 }687 );688 this.children().sort(needSwap);689 }690};691cShapeContainer.prototype.addShape = 692 function (shapeType,shapeLeft,shapeTop,shapeWidth,shapeHeight){693 return (new cShape(shapeType == SHAPETYPES.stPanel))694 .setWidth(shapeWidth)695 .setHeight(shapeHeight)696 .setTop(shapeTop)697 .setLeft(shapeLeft)698 .setRounded(this.isRounded(shapeType));699};700cShapeContainer.prototype.makeChart = function () {701 this.xChartContainer = new cChartContainer(this.root());702 this.xChartContainer.makeChart();703 return this;704};705cShapeContainer.prototype.chartStyle = function () {706 switch(LCase(this.param("options", "chart style", "value"))) {707 case "shale":708 return SCHARTTYPES.ctShale;709 case "column stacked":710 return SCHARTTYPES.ctColumnStacked;711 case "line":712 return SCHARTTYPES.ctLine;713 case "bar":714 return SCHARTTYPES.ctBar;715 case "column":716 return SCHARTTYPES.ctColumn;717 default:718 return SCHARTTYPES.ctDefault719 }720};721cShapeContainer.prototype.chartCostTreatment = function () {722 switch(LCase(this.fixupCustomCell("chart cost treatment").toString())) {723 case "annual":724 return STREATS.stcAnnual725 case "duration":726 return STREATS.stcDuration727 case "one off at start":728 return STREATS.stcOneOffStart729 case "one off at finish":730 return STREATS.stcOneOffFinish731 default:732 return STREATS.stcDefault733 }734};735cShapeContainer.prototype.groupContainers = function () {736 showPanel();737//todo738};739cShapeContainer.prototype.traceability = function () {740//todo741};742cShapeContainer.prototype.doShapeCallouts = function () {743//TODO...
usefulColors.gs
Source:usefulColors.gs
1//this is all about colors2var VBCOLORS = Object.freeze(3{vbBlue: 16711680, 4 vbWhite: 16777215,5 vbBlack: 0,6 vbGreen: 65280,7 vbYellow: 65535,8 vbRed:2559 }10);11var ECOMPARECOLOR = Object.freeze (12{13 whiteX : 95.047,14 whiteY : 100,15 whiteZ : 108.883,16 eccieDe2000 : 21000,17 beige: 1000930118}19);20function speedTest() {21 useTimer('x','10000 iterations of color comparison').start();22 for (var i = 1 ; i <= 10000 ;i++) {23 compareColors (i, VBCOLORS.vbWhite - i);24 }25 useTimer('x').stop();26 return useTimer().report();27} 28function testCompareSpeed() {29 Logger.log(speedTest());30}31function beigeness(rgbColor) {32 return compareColors (rgbColor, ECOMPARECOLOR.beige);33}34function RGB(r,g,b) {35 return Math.round(r) + (Math.round(g) << 8) + (Math.round(b) << 16) ;36}37function rgbRed(rgbColor) {38 return rgbColor % 0x100;39}40function rgbGreen(rgbColor) {41 return Math.floor(rgbColor / 0x100) % 0x100;42}43function rgbBlue(rgbColor) {44 return Math.floor(rgbColor / 0x10000) % 0x100;45}46function heatmapColor(min , max, value) {47 return rampLibraryRGB("heatmap", min, max, value);48}49function rgbToHTMLHex(rgbColor) {50 // just swap the colors round for rgb to bgr as bit representation is reversed51 return "#" + maskFormat(RGB(rgbBlue(rgbColor), 52 rgbGreen(rgbColor), rgbRed(rgbColor)).toString(16), "000000");53}54function rgbToHex(rgbColor) {55 // this is just a convenience pass throuh .. i originally screwed up the camel case 56 return rgbToHTMLHex(rgbColor);57}58function rampLibraryHex (sName, min , max, value , optBrighten) {59 return rgbToHTMLHex(rampLibraryRGB (sName, min , max, value , optBrighten));60}61function maskFormat(sIn , f ) {62 var s = Trim(sIn);63 if (Len(s) < Len(f)) {64 s = Left(f, Len(f) - Len(s)) + s ;65 }66 return s;67}68function lumRGB(rgbCom, brighten) {69 var x = rgbCom * brighten;70 return x > 255 ? 255 : 71 x < 0 ? 0 : x;72}73function contrastRatio(rgbColorA, rgbColorB) {74 var lumA = w3Luminance(rgbColorA);75 var lumB = w3Luminance(rgbColorB);76 return (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);77}78function makeColorProps (rgbColor) {79 return new colorProps().populate(rgbColor);80}81function colorProps() {82 return this;83}84colorProps.prototype.populate = function (rgbColor) {85 var p = this;86 //store the source color87 p.rgb = rgbColor;88 89 //split the components90 p.red = rgbRed(rgbColor);91 p.green = rgbGreen(rgbColor);92 p.blue = rgbBlue(rgbColor);93 94 //the html hex rgb equivalent95 p.htmlHex = rgbToHTMLHex(rgbColor);96 97 //the w3 algo for luminance98 p.luminance = w3Luminance(rgbColor);99 100 //determine whether black or white background101 if (p.luminance < 0.5) 102 p.textColor = VBCOLORS.vbWhite;103 else104 p.textColor = VBCOLORS.vbBlack;105 106 //contrast ratio - to comply with w3 recs 1.4 should be at least 10:1 for text107 p.contrastRatio = contrastRatio(p.textColor, p.rgb);108 109 //cmyk - just an estimate110 p.black = Math.min(Math.min(1 - p.red / 255, 1 - p.green / 255), 1 - p.blue / 255);111 if (p.black < 1) {112 p.cyan = (1 - p.red / 255 - p.black) / (1 - p.black);113 p.magenta = (1 - p.green / 255 - p.black) / (1 - p.black);114 p.yellow = (1 - p.blue / 255 - p.black) / (1 - p.black);115 }116 // calculate hsl + hsv and other wierd things117 var p2 = rgbToHsl(p.rgb);118 p.hue = p2.hue;119 p.saturation = p2.saturation;120 p.lightness = p2.lightness;121 122 p.value = rgbToHsv(p.rgb).value;123 124 p2 = rgbToXyz(p.rgb);125 p.x = p2.x;126 p.y = p2.y;127 p.z = p2.z;128 129 p2 = rgbToLab(p.rgb);130 p.LStar = p2.LStar;131 p.aStar = p2.aStar;132 p.bStar = p2.bStar;133 134 p2 = rgbToLch(p.rgb);135 p.cStar = p2.cStar;136 p.hStar = p2.hStar;137 return p;138}139function w3Luminance (rgbColor) {140// this is based on141// http://en.wikipedia.org/wiki/Luma_(video)142 return (0.2126 * Math.pow((rgbRed(rgbColor)/255),2.2)) +143 (0.7152 * Math.pow((rgbGreen(rgbColor)/255),2.2)) +144 (0.0722 * Math.pow((rgbBlue(rgbColor)/255),2.2)) ;145}146function cellProperty (r,p) {147 // makes it compatible with VBA version148 switch(p) {149 case "background-color":150 return sheetCache(r,"getBackgroundColors").getValues(r);151 case "color":152 return sheetCache(r,"getFontColor").getValues(r);153 154 case "font-size":155 return sheetCache(r,"getFontSize").getValues(r);156 default:157 DebugAssert (false, "unknown cellproperty request " + p);158 }159}160function cellCss(r, p ) {161 return p + ":" + cellProperty(r, p) + ";" ;162}163function rgbExpose(r , g , b ) {164 // redundadnt .. just for compatibility with vba165 return RGB(r, g, b) ;166}167function htmlHexToRgb(htmlHex){168 var s = LTrim(RTrim(htmlHex));169 s = (Left(s, 1) == "#" ? '' : '#') + s;170 DebugAssert (Len(s) > 1 && Left(s, 1) == "#", "invalid hex color" + htmlHex);171 // -- need to find equivalent ---172 var x = parseInt(Right(s, Len(s) - 1),16);173 // these are purposefully reversed since byte order is different in unix174 return RGB(rgbBlue(x), rgbGreen(x), rgbRed(x));175}176function hslToRgb(p) {177 // from // http://www.easyrgb.com/178 var x1 , x2 , h, s , l , 179 red , green , blue ;180 181 h = p.hue / 360;182 s = p.saturation / 100;183 l = p.lightness / 100;184 185 if (s == 0) {186 return RGB (l * 255, l * 255, l * 255);187 }188 else {189 if (l < 0.5 )190 x2 = l * (1 + s);191 else192 x2 = (l + s) - (l * s);193 194 x1 = 2 * l - x2;195 196 red = 255 * hueToRgb(x1, x2, h + (1 / 3));197 green = 255 * hueToRgb(x1, x2, h);198 blue = 255 * hueToRgb(x1, x2, h - (1 / 3));199 return RGB (red, green, blue);200 }201}202function hueToRgb(a , b , h ) {203 // from // http://www.easyrgb.com/204 if (h < 0) h = h + 1;205 if (h > 1) h = h - 1;206 DebugAssert (h >= 0 && h <= 1,"hue outside range 0-1:" + h);207 if (6 * h < 1) 208 return a + (b - a) * 6 * h;209 else {210 if (2 * h < 1) 211 return b;212 else {213 if (3 * h < 2) 214 return a + (b - a) * ((2 / 3) - h) * 6;215 else216 return a;217 }218 } 219}220function hexColorOf(r) {221 return cellProperty(r,"color") ;222}223function colorizeCell(target, c ) {224 225 if (Len(c) > 1 && Left(c, 1) == "#") {226 p = makeColorProps(htmlHexToRgb(c));227 //target.Interior.Color = p.rgb228 //target.Font.Color = p.textColor229 }230}231function rampLibraryRGB(ramp, min , max, value , optBrighten) {232 var brighten = fixOptional (optBrighten, 1);233 234 if (IsArray(ramp)) {235 // ramp colors have been passed here236 return colorRamp(min, max, value, ramp,undefined , brighten);237 }238 else {239 240 switch(Trim(LCase(ramp))) {241 case "heatmaptowhite":242 return colorRamp(min, max, value, 243 [VBCOLORS.vbBlue, VBCOLORS.vbGreen, VBCOLORS.vbYellow, 244 VBCOLORS.vbRed, VBCOLORS.vbWhite],undefined , 245 brighten);246 case "heatmap":247 return colorRamp(min, max, value, 248 [VBCOLORS.vbBlue, VBCOLORS.vbGreen, VBCOLORS.vbYellow, 249 VBCOLORS.vbRed], undefined, 250 brighten); 251 case "blacktowhite":252 return colorRamp(min, max, value, 253 [VBCOLORS.vbBlack, VBCOLORS.vbWhite], undefined, 254 brighten); 255 case "whitetoblack":256 return colorRamp(min, max, value, 257 [VBCOLORS.vbWhite, VBCOLORS.vbBlack],undefined , 258 brighten); 259 case "hotinthemiddle":260 return colorRamp(min, max, value, 261 [VBCOLORS.vbBlue, VBCOLORS.vbGreen, 262 VBCOLORS.vbYellow,VBCOLORS.vbRed,VBCOLORS.vbGreen,263 VBCOLORS.vbBlue], undefined, 264 brighten); 265 case "candylime":266 return colorRamp(min, max, value, 267 [RGB(255, 77, 121), RGB(255, 121, 77), 268 RGB(255, 210, 77), RGB(210, 255, 77)], undefined, 269 brighten); 270 271 case "heatcolorblind":272 return colorRamp(min, max, value, 273 [VBCOLORS.vbBlack,VBCOLORS.vbBlue, VBCOLORS.vbRed, 274 VBCOLORS.vbWhite], undefined, 275 brighten); 276 case "gethotquick":277 return colorRamp(min, max, value, 278 [VBCOLORS.vbBlue,VBCOLORS.vbGreen, VBCOLORS.vbYellow, 279 VBCOLORS.vbRed],[0, 0.1, 0.25, 1] , 280 brighten); 281 case "greensweep":282 return colorRamp(min, max, value, 283 [RGB(153, 204, 51), RGB(51, 204, 179)] 284 ,undefined , 285 brighten); 286 case "terrain":287 return colorRamp(min, max, value, 288 [VBCOLORS.vbBlack, RGB(0, 46, 184), RGB(0, 138, 184), 289 RGB(0, 184, 138), 290 RGB(138, 184, 0), RGB(184, 138, 0), 291 RGB(138, 0, 184), VBCOLORS.vbWhite] 292 ,undefined , 293 brighten); 294 case "terrainnosea":295 return colorRamp(min, max, value, 296 [VBCOLORS.vbGreen, RGB(0, 184, 138), 297 RGB(138, 184, 0), RGB(184, 138, 0), 298 RGB(138, 0, 184), VBCOLORS.vbWhite] 299 , undefined, 300 brighten); 301 302 303 304 case "greendollar":305 return colorRamp(min, max, value, 306 [RGB(225, 255, 235), 307 RGB(2, 202, 69)], undefined, 308 brighten);309 310 case "lightblue":311 return colorRamp(min, max, value, 312 [RGB(230, 237, 246), 313 RGB(163, 189, 271)], undefined, 314 brighten);315 316 case "lightorange":317 return colorRamp(min, max, value, 318 [rgb(253, 233, 217), 319 rgb(244, 132, 40)], undefined, 320 brighten);321 322 default:323 DebugAssert(false,"Unknown library entry " + ramp) ;324 }325 }326 327}328function colorRamp(min, max , value , mileStones , fractionStones, optBrighten) {329 // color ramp given or default330 var brighten = fixOptional ( optBrighten,1);331 var ms = IsMissing(mileStones) ? 332 [VBCOLORS.vbBlue,VBCOLORS.vbGreen,VBCOLORS.vbYellow, 333 VBCOLORS.vbRed,VBCOLORS.vbRed,VBCOLORS.vbWhite] :334 mileStones;335 DebugAssert( ms.length , "No milestone colors specified");336 // only 1 milestone - thats the color337 if (ms.length == 1) return ms[lb];338 // fractions of range at which to apply these colors339 var fs = [];340 if (!IsMissing(fractionStones)) {341 DebugAssert( fractionStones.length == ms.length, "no of fractions must equal number of steps" );342 fs = fractionStones;343 }344 else {345 // equal proportions346 fs[0]=0;347 for (var i = 1 ; i < ms.length ; i++ ) fs[i] = i/(ms.length-1) ;348 }349 // now calculate the color350 var spread = max - min;351 DebugAssert (spread >= 0 , "min is greater than max for color spread");352 var ratio = (value - min) / spread;353 DebugAssert (ratio >= 0 && ratio <= 1, "couldnt calculate ratio for color spread");354 //find which slot this value belongs in355 for (var i = 1; i < ms.length;i++) {356 if (ratio <= fs[i]) {357 var r = (ratio - fs[i - 1]) / (fs[i] - fs[i - 1]);358 var red = rgbRed(ms[i - 1]) + (rgbRed(ms[i]) - rgbRed(ms[i - 1])) * r;359 var blue = rgbBlue(ms[i - 1]) + (rgbBlue(ms[i]) - rgbBlue(ms[i - 1])) * r;360 var green = rgbGreen(ms[i - 1]) + (rgbGreen(ms[i]) - rgbGreen(ms[i - 1])) * r;361 return RGB(lumRGB(red, brighten), 362 lumRGB(green, brighten), 363 lumRGB(blue, brighten));364 }365 }366 367 DebugAssert (false,"ColorRamp failed to work - dont know why");368}369function rgbToHsl (RGBcolor) {370 //from // http://www.easyrgb.com/371 var r , g , b , d , dr , dg , db , mn , mx , p ={};372 r = rgbRed(RGBcolor) / 255 ;373 g = rgbGreen(RGBcolor) / 255;374 b = rgbBlue(RGBcolor) / 255;375 mn = Math.min(Math.min(r, g), b);376 mx = Math.max(Math.max(r, g), b);377 d = mx - mn;378 379 //HSL sets here380 p.hue = 0;381 p.saturation = 0;382 //lightness383 p.lightness = (mx + mn) / 2;384 385 if (d != 0) {386 // saturation387 if (p.lightness < 0.5)388 p.saturation = d / (mx + mn) ;389 else390 p.saturation = d / (2 - mx - mn) ; 391 // hue392 dr = (((mx - r) / 6) + (d / 2)) / d ;393 dg = (((mx - g) / 6) + (d / 2)) / d ;394 db = (((mx - b) / 6) + (d / 2)) / d ;395 396 if (r == mx) 397 p.hue = db - dg ;398 else 399 if(g == mx) 400 p.hue = (1 / 3) + dr - db ;401 else402 p.hue = (2 / 3) + dg - dr ;403 404 405 //force between 0 and 1406 if (p.hue < 0) p.hue = p.hue + 1 ;407 if (p.hue > 1) p.hue = p.hue - 1 ;408 if (!(p.hue >= 0 && p.hue <= 1)) p.hue = 0; // " invalid hue " + p.hue + ":" + JSON.stringify(p));409 410 }411 p.hue = p.hue * 360 ;412 p.saturation = p.saturation * 100 ;413 p.lightness = p.lightness * 100 ;414 return p;415 416}417function rgbToHsv(rgbColor){418 // adapted from // http://www.easyrgb.com/419 420 var r = rgbRed(rgbColor) / 255;421 var g = rgbGreen(rgbColor) / 255;422 var b = rgbBlue(rgbColor) / 255;423 var mn = Math.min(r, g, b);424 var mx = Math.max(r, g, b);425 426 // this is the same as hsl and hsv are the same.427 var p = rgbToHsl(rgbColor);428 429 // HSV sets here430 p.value = mx;431 432 return p;433}434function xyzCorrection(v) {435 if (v > 0.04045) 436 return Math.pow( ((v + 0.055) / 1.055) , 2.4);437 else438 return v / 12.92 ;439 440}441function xyzCieCorrection(v) {442 return v > 0.008856 ? Math.pow(v , 1 / 3) : (7.787 * v) + (16 / 116);443}444function rgbToXyz(rgbColor) {445 // adapted from // http://www.easyrgb.com/446 var r = xyzCorrection(rgbRed(rgbColor) / 255) * 100;447 var g = xyzCorrection(rgbGreen(rgbColor) / 255) * 100;448 var b = xyzCorrection(rgbBlue(rgbColor) / 255) * 100;449 var p = new colorProps();450 p.x = r * 0.4124 + g * 0.3576 + b * 0.1805;451 p.y = r * 0.2126 + g * 0.7152 + b * 0.0722;452 p.z = r * 0.0193 + g * 0.1192 + b * 0.9505;453 return p;454}455function rgbToLab(rgbColor) {456 // adapted from // http://www.easyrgb.com/457 var p = rgbToXyz(rgbColor);458 459 var x = xyzCieCorrection(p.x / ECOMPARECOLOR.whiteX);460 var y = xyzCieCorrection(p.y / ECOMPARECOLOR.whiteY);461 var z = xyzCieCorrection(p.z / ECOMPARECOLOR.whiteZ);462 p.LStar = (116 * y) - 16;463 p.aStar = 500 * (x - y);464 p.bStar = 200 * (y - z);465 return p;466}467function compareColorProps (p1, p2 , optCompareType) {468 469 switch (fixOptional(optCompareType, ECOMPARECOLOR.eccieDe2000)) {470 case ECOMPARECOLOR.eccieDe2000:471 var t= cieDe2000(p1, p2);472 p1 = p2 = null;473 return t;474 475 default:476 DebugAssert (false, "unknown color comparision " + optCompareType);477 }478 479}480function compareColors(rgb1, rgb2 , optCompareType) {481 return compareColorProps(makeColorProps(rgb1),makeColorProps(rgb2));482 483}484function cieDe2000(p1, p2 ) {485 // calculates the distance between 2 colors using CIEDE200486 // see http://www.ece.rochester.edu/~gsharma/cieDe2000/cieDe2000noteCRNA.pdf487 488 var kp = Math.pow(25 , 7), kl = 1,kc = 1, kh = 1;489 490 // calculate c & g values491 var c1 = Math.sqrt(Math.pow(p1.aStar , 2) + Math.pow(p1.bStar , 2));492 var c2 = Math.sqrt(Math.pow(p2.aStar , 2) + Math.pow(p2.bStar , 2));493 var c = (c1 + c2) / 2;494 var g = 0.5 * (1 - Math.sqrt(Math.pow(c , 7) / (Math.pow(c , 7) + kp)));495 //adjusted ab*496 var a1 = (1 + g) * p1.aStar;497 var a2 = (1 + g) * p2.aStar;498 // adjusted cs499 var c1Tick = Math.sqrt(a1 *a1 + p1.bStar *p1.bStar);500 var c2Tick = Math.sqrt(a2 *a2 + p2.bStar * p2.bStar);501 //adjusted h502 var h1 = computeH(a1, p1.bStar);503 var h2 = computeH(a2, p2.bStar);504 505 // deltas506 var dh;507 if (h2 - h1 > 180) 508 dh = h2 - h1 - 360;509 else if (h2 - h1 < -180) 510 dh = h2 - h1 + 360 ;511 else 512 dh = h2 - h1;513 514 var dl = p2.LStar - p1.LStar;515 var dc = c2Tick - c1Tick;516 var dBigH = (2 * Math.sqrt(c1Tick * c2Tick) * Math.sin(toRadians(dh / 2)));517 // averages518 var lTickAvg = (p1.LStar + p2.LStar) / 2;519 var cTickAvg = (c1Tick + c2Tick) / 2;520 var hTickAvg;521 if (c1Tick * c2Tick == 0)522 hTickAvg = h1 + h2;523 524 else if (Math.abs(h2 - h1) <= 180) 525 hTickAvg = (h1 + h2) / 2;526 527 else if (h2 + h1 < 360) 528 hTickAvg = (h1 + h2) / 2 + 180;529 530 else 531 hTickAvg = (h1 + h2) / 2 - 180;532 533 534 var l50 = Math.pow(lTickAvg - 50,2);535 var sl = 1 + (0.015 * l50 / Math.sqrt(20 + l50));536 537 var sc = 1 + 0.045 * cTickAvg;538 var t = 1 - 0.17 * Math.cos(toRadians(hTickAvg - 30)) + 0.24 * 539 Math.cos(toRadians(2 * hTickAvg)) + 0.32 * 540 Math.cos(toRadians(3 * hTickAvg + 6)) - 0.2 * 541 Math.cos(toRadians(4 * hTickAvg - 63));542 var sh = 1 + 0.015 * cTickAvg * t;543 var dTheta = 30 * Math.exp(-1 * Math.pow((hTickAvg - 275) / 25 , 2));544 var rc = 2 * Math.sqrt(Math.pow(cTickAvg , 7) / (Math.pow(cTickAvg , 7) + kp));545 var rt = -Math.sin(toRadians(2 * dTheta)) * rc;546 var dlk = dl / sl / kl;547 var dck = dc / sc / kc;548 var dhk = dBigH / sh / kh;549 return Math.sqrt(dlk *dlk + dck *dck + dhk *dhk + rt * dck * dhk);550 551}552function computeH(a , b ) {553 if (a == 0 && b == 0)554 return 0;555 else if (b < 0) 556 return fromRadians(Atan2(a,b)) + 360 ;557 else558 return fromRadians(Atan2(a,b)) ; 559}560function lchToLab (p) { 561 var h = toRadians(p.hStar);562 p.aStar = Math.cos(h) * p.cStar;563 p.bStar = Math.sin(h) * p.cStar;564 return p;565}566function labxyzCorrection(x ) {567 if (Math.pow(x , 3) > 0.008856)568 return Math.pow(x , 3);569 else570 return (x - 16 / 116) / 7.787; 571}572function lchToRgb(p) {573 return xyzToRgb(labToXyz(lchToLab(p)));574}575function labToXyz(p) {576 577 p.y = (p.LStar + 16) / 116;578 p.x = p.aStar / 500 + p.y;579 p.z = p.y - p.bStar / 200;580 581 p.x = labxyzCorrection(p.x) * ECOMPARECOLOR.whiteX;582 p.y = labxyzCorrection(p.y) * ECOMPARECOLOR.whiteY;583 p.z = labxyzCorrection(p.z) * ECOMPARECOLOR.whiteZ;584 return p;585}586function xyzrgbCorrection(x) {587 if (x > 0.0031308) 588 return 1.055 * (Math.pow(x , (1 / 2.4))) - 0.055;589 else590 return 12.92 * x;591 592}593function xyzToRgb(p) {594 var x = p.x / 100, y = p.y / 100 ,z = p.z / 100;595 596 var x1 = x * 0.8951 + y * 0.2664 + z * -0.1614;597 var y1 = x * -0.7502 + y * 1.7135 + z * 0.0367;598 var z1 = x * 0.0389 + y * -0.0685 + z * 1.0296;599 600 var x2 = x1 * 0.98699 + y1 * -0.14705 + z1 * 0.15997;601 var y2 = x1 * 0.43231 + y1 * 0.51836 + z1 * 0.04929;602 var z2 = x1 * -0.00853 + y1 * 0.04004 + z1 * 0.96849;603 r = xyzrgbCorrection(x2 * 3.240479 + y2 * -1.53715 + z2 * -0.498535);604 g = xyzrgbCorrection(x2 * -0.969256 + y2 * 1.875992 + z2 * 0.041556);605 b = xyzrgbCorrection(x2 * 0.055648 + y2 * -0.204043 + z2 * 1.057311);606 607 var c = RGB(Math.min(255, Math.max(0, CLng(r * 255))), 608 Math.min(255, Math.max(0, CLng(g * 255))), 609 Math.min(255, Math.max(0, CLng(b * 255))));610 return c;611}612function rgbToLch(rgbColor) {613 //convert from cieL*a*b* to cieL*CH614 //adapted from http://www.brucelindbloom.com/index.html?Equations.html615 var p = rgbToLab(rgbColor);616 if (rgbColor == 0 )617 p.hStar = 0 ;618 else {619 p.hStar =Atan2(p.aStar, p.bStar);620 if (p.hStar > 0) 621 p.hStar = fromRadians(p.hStar);622 else623 p.hStar = 360 - fromRadians(Math.abs(p.hStar));624 625 }626 p.cStar = Math.sqrt(p.aStar * p.aStar + p.bStar * p.bStar);627 return p;628}629function colorPropBigger(a, b, byProp) {630 DebugAssert (a.hasOwnProperty(byProp) && b.hasOwnProperty(byProp),"unknown color prop in sort " + byProp);631 return a[byProp] > b[byProp];632}633function rgbWashout(rgbColor) {634 var p = makeColorProps(rgbColor);635 p.saturation = p.saturation * 0.2;636 p.lightness = p.lightness * 0.9;637 return hslToRgb(p)638}639function sortColorProp(pArray, byProp,optDescending ) {640 descending = fixOptional (optDescending ,false) ? -1 : 1;641 return pArray.sort (function (a,b) {642 var result = a[byProp] > b[byProp] ? 1 : a[byProp] < b[byProp] ? -1 : 0 ;643 return descending * result ; } );644}645function makeAPalette(rgbColor, optModel, optiType, optHowMany, optDescending) {646 647 var model = fixOptional(optModel, "lch");648 var iType = fixOptional(optiType, "hue");649 var howMany = fixOptional(optHowMany, 5);650 var ph,ps,pl,pf,h,pv,a=[],g;651 652 653 if (model == "lch") {654 ph = "hStar", ps = "cStar", pl = "LStar", pf = lchToRgb;655 }656 else {657 ph = "hue", ps = "saturation", pl = "lightness", pf = hslToRgb;658 }659 660 var top = (iType == "hue" ? 360 : 100);661 g = top / howMany;662 pv = (iType == "hue" ? ph : (iType == "saturation" ? ps : pl));663 var p = makeColorProps(rgbColor); 664 h = p[pv];665 666 // do a number of equally spaced props and store in array667 for (var i =0;i < howMany ;i++ ) {668 if (h > top) h -= top;669 // store new value670 p[pv] =h;671 // convert back to rgb and redo672 p =makeColorProps(pf(p));673 a.push(p);674 // make a new copy675 p = makeColorProps(p.rgb);676 h += g;677 }678 679 return sortColorProp (a, pv, optDescending);680 681}682function arrayLength(a) {683 return a.length;...
badges.gs
Source:badges.gs
1// this is how to create a badge environment from a spreadsheet2// there are multiple sheets required3// badges, collections, questions, questionsets, panelsets4// all data will be stored in given scripdb5function makeBadgesFromSheet(db) {6 var cdb=new cBadgeDb(db);7 var dSets = new cDataSets();8 // get the data for each interesting sheet9 var interesting = [ "badges", "collections", "questions", "questionsets", "panelsets" ]10 for (var i = 0; i<interesting.length;i++ ) {11 dSets.init (wholeSheet(interesting[i]),undefined,interesting[i],true,undefined,true,"id"); 12 }13 // check all references exist in all the right places14 var nErrs = 0;15 nErrs += validateIdIsIn( dSets.dataSet("panelsets").column("collections") , dSets.dataSet("collections"));16 nErrs += validateIdIsIn( dSets.dataSet("collections").column("badges") , dSets.dataSet("badges"));17 nErrs += validateIdIsIn( dSets.dataSet("badges").column("questionsets") , dSets.dataSet("questionsets"));18 nErrs += validateIdIsIn( dSets.dataSet("questionsets").column("questions") , dSets.dataSet("questions"));19 if (!nErrs) {20 tryToast("so far so good .. all references were valid - now working on scriptdb..");21 makeTheQuestions (dSets.dataSet("questions"), cdb);22 makeTheQuestionSets (dSets.dataSet("questionsets"), cdb);23 makeTheBadges (dSets.dataSet("badges"), cdb);24 makeTheCollections (dSets.dataSet("collections"), cdb);25 makeThePanelSets (dSets.dataSet("panelsets"), cdb);26 tryToast("all is good .. your badge data has been moved to the scriptDB");27 }28 else {29 MsgBox("you need to fix " + nErrs + " reference errors before you can continue");30 }31 32}33// this checks that items mentioned in idColumn exist in inSet34function validateIdIsIn(idColumn, inSet) {35 var missing = 0;36 idColumn.rows().forEach(37 function(cc) {38 var a = Split(cc.toString());39 for (var i=0;i<a.length;i++) {40 if (!inSet.exists(a[i],false)) { 41 tryToast(a[i] + " from " + idColumn.parent().name() + " doesn't exist in " + inSet.name() );42 ++missing;43 }44 }45 }46 )47 return missing;48 49}50function makeTheQuestions(dSet,pdb) {51 // delete all existing ones52 pdb.remove(undefined, EBADGES.question);53 try {54 dSet.rows().forEach( 55 function (dr) {56 pdb.save (new cQuestion (57 { id : dr.value("id"),58 options : Split(dr.toString("options")),59 title : dr.value("title"),60 answers: Split(dr.value("answers")),61 type: EBADGES[dr.value("type")],62 randomize : dr.value("randomize") == "yes"63 } ), 64 EBADGES.question);65 }66 );67 }68 catch(err) {69 DebugAssert(false, err + " failed to write a question to scriptdb ");70 }71}72 73function makeTheQuestionSets(dSet,pdb) {74 // delete all existing ones75 pdb.remove(undefined, EBADGES.questionSet);76 try {77 dSet.rows().forEach( 78 function (dr) {79 pdb.save (new cQuestionSet (80 { id : dr.value("id"),81 pass : dr.value("pass"),82 questions: Split(dr.value("questions")),83 randomize : dr.value("randomize") == "yes"84 } ), 85 EBADGES.questionSet);86 }87 );88 }89 catch(err) {90 DebugAssert(false, err + " failed to write a questionset to scriptdb ");91 }92}93function makeTheBadges (dSet,pdb) {94 // delete all existing ones95 pdb.remove(undefined, EBADGES.badges);96 97 try {98 dSet.rows().forEach( 99 function (dr) {100 pdb.save (new cBadge (101 { name : dr.value("id"),102 image: dr.value("image"),103 description: dr.value("description"),104 criteria: dr.value("criteria"),105 issuer: {106 origin: dr.value("issuer_origin"),107 org: dr.value("issuer_org"),108 name: dr.value("issuer_name"),109 contact: dr.value("issuer_contact"),110 }111 },112 getQuestionSetObject (pdb,dr.value("questionsets")).data),113 EBADGES.badge);114 }115 );116 }117 catch(err) {118 DebugAssert(false, err + " failed to write a badge to scriptdb ");119 }120}121function makeTheCollections (dSet,pdb) {122 // delete all existing ones123 pdb.remove(undefined,EBADGES.badgeCollection);124 125 try {126 dSet.rows().forEach( 127 function (dr) {128 var c = new collection (undefined, undefined, dr.value("id")); 129 var a = Split(dr.value("badges"));130 for (var i=0;i<a.length;i++) {131 addBadgesToCollection (pdb, c , a[i]);132 }133 pdb.save (c);134 }135 );136 }137 catch(err) {138 DebugAssert(false, err + " failed to write a collection to scriptdb ");139 }140}141function makeThePanelSets (dSet,pdb) {142 // delete all existing ones143 pdb.remove(undefined,EBADGES.panelSet);144 145 try {146 dSet.rows().forEach( 147 function (dr) {148 var c = new collection (undefined, undefined, dr.value("id")); 149 var a = Split(dr.value("collections"));150 for (var i=0;i<a.length;i++) {151 addCollectionsToPanel (pdb, c , a[i]);152 }153 pdb.save (c,EBADGES.panelSet);154 }155 );156 }157 catch(err) {158 DebugAssert(false, err + " failed to write a panelset to scriptdb ");159 }160}161function getQuestionSetObject(bdb,id) {162 var q = bdb.get({id:id},EBADGES.questionSet);163 DebugAssert(q.hasNext(), "missing questionset " + id);164 return q.next();165}166function addBadgesToCollection ( bdb,c, id) {167 return addItems (bdb,c,id,EBADGES.badge);168}169function addCollectionsToPanel ( bdb,c, id) {170 return addItems (bdb,c,id,EBADGES.badgeCollection);171}172function addItems ( bdb,c, id ,type) {173 var o = bdb.get({id: id}, type);174 175 while (o.hasNext()) {176 var r = o.next();177 c.add (type== EBADGES.badge? r.data : r.id,r.id,false);178 }179 return c;180}181function getQuestionObject(bdb,id) {182 var q = bdb.get({id:id},EBADGES.question);183 DebugAssert(q.hasNext(), "missing questions " + id);184 return q.next();185}186function cQuestion(p) {187 var params = p || {};188 this.q = {189 id: params.id || "defaultquestion",190 title: params.title || "Where is the record of which badges I have earned ?",191 randomize: params.hasOwnProperty("randomize") ? params.randomize : true,192 options: params.options || ["There is no record","In my Mozilla backpack","In a cookie","On this site"],193 answers: params.answers || [0],194 type: params.type || EBADGES.single195 }196 197 this.name = function() {198 return this.q.id;199 }200 201 this.items = function() {202 return this.q;203 } 204 205 return this;206}207function cQuestionSet(p) {208 var params = p || {};209 this.q = {210 id: params.id || "defaultquestionset",211 randomize: params.hasOwnProperty("randomize") ? params.randomize : true,212 questions: params.questions || ["defaultquestion"],213 pass: params.pass || 1214 }215 216 this.name = function() {217 return this.q.id;218 }219 this.items = function() {220 return this.q;221 }222 return this;223}224function cBadge(p,optQuestionSet) {225 var params = p || {};226 var questionSet = fixOptional(optQuestionSet,null);227 var name = fixOptional( params.name , "xliberationbadge");228 return { badge: {229 "version": "0.5.0",230 "name": name ,231 "image": params.image || "img/" + name + ".png",232 "description": params.description || name,233 "criteria": params.criteria || "criteria/" + name + ".html",234 "issuer": {235 "origin": (params.issuer && params.issuer.origin) || "http://xliberation.com",236 "name": (params.issuer && params.issuer.name) || "xliberation",237 "org": (params.issuer && params.issuer.org) || "Excel Liberation",238 "contact": (params.issuer && params.issuer.contact) || "bruce@mcpher.com"239 },240 },241 "questionSet": questionSet242 };243 ...
phantompage.js
Source:phantompage.js
...68 this.loadListener = null;69 };70 LoadedStateMachine.prototype.onLoadStarted = function() {71 debugLog('LoadedStateMachine onLoadStarted');72 debugAssert(this.lastLoadedStatus !== null);73 this.lastLoadedStatus = null;74 };75 LoadedStateMachine.prototype.onLoadFinished = function(status) {76 debugLog('LoadedStateMachine onLoadFinished', status);77 debugAssert(this.lastLoadedStatus === null);78 debugAssert(status !== null);79 this.lastLoadedStatus = status;80 if (this.loadListener) {81 var callback = this.loadListener;82 this.loadListener = null;83 callback(status);84 }85 };86 LoadedStateMachine.prototype.waitForLoaded = function() {87 var promise = new kew.Promise();88 if (this.lastLoadedStatus !== null) {89 promise.resolve(this.lastLoadedStatus);90 } else {91 debugAssert(this.loadListener === null);92 this.loadListener = function(status) {93 promise.resolve(status);94 };95 }96 return promise;97 };98 /**99 @constructor100 @struct101 @param {!phantomjs.Page} page102 */103 phantompage.Navigator = function(page) {104 /** @type {!phantomjs.Page} */105 this.page = page;106 // Set the user agent to be Chrome, not PhantomJS107 this.page.settings.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36';108 // defaults to true; shouldn't break logins but should avoid excess network traffic109 this.page.settings.loadImages = false;110 this.page.settings.resourceTimeout = 5000; // ms111 // Replaced for unit testing112 this.eventLoopDefer = function(callback) {113 setTimeout(callback, 0);114 };115 // Aliasing setTimeout as an object property raises Illegal Invocation116 this.eventLoopDelay = function(callback, delayMs) {117 return setTimeout(callback, delayMs);118 };119 this.statusCodes = {};120 // maintain state about if we are navigating or not121 this.navigating = false;122 this.navigateListener = null;123 this.loadedState = new LoadedStateMachine();124 var self = this;125 self.page.onNavigationRequested = function(url, type, willNavigate, main) {126 debugLog('Navigator onNavigationRequested:', url, type, willNavigate, main);127 if (willNavigate && main) {128 self.navigating = true;129 }130 };131 self.page.onInitialized = function() {132 debugLog('Navigator onInitialized; navigating:', self.navigating);133 debugAssert(self.navigating === true);134 self.navigating = false;135 if (self.navigateListener) {136 var callback = self.navigateListener;137 self.navigateListener = null;138 // transfer the navigate listener to the load listener139 var navigationEnded = self.waitForNavigationEnd();140 navigationEnded.then(callback);141 }142 };143 self.page.onLoadStarted = function() {144 self.loadedState.onLoadStarted();145 };146 self.page.onLoadFinished = function(status) {147 self.loadedState.onLoadFinished(status);148 };149 self.page.onResourceReceived = function(resource) {150 if (resource.stage == 'end') {151 debugLog('onResourceReceived', resource.url, resource.status);152 self.statusCodes[resource.url] = resource.status;153 }154 };155 };156 phantompage.Navigator.prototype.waitForNavigationEnd = function() {157 var self = this;158 var waitForLoaded = self.loadedState.waitForLoaded();159 var waitDone = waitForLoaded.then(function(status) {160 // run the event loop to give JS time to redirect161 debugLog('loaded done; running event loop');162 var deferred = new kew.Promise();163 self.eventLoopDefer(function() {164 if (self.navigating) {165 debugLog('still navigating; calling waitForNavigate()');166 deferred.resolve(self.waitForNavigate());167 } else {168 debugLog('navigation done; resolving promise');169 deferred.resolve(status);170 }171 });172 return deferred;173 });174 return waitDone;175 };176 /**177 @param {string} url178 @return {!kew.Promise.<string>}179 */180 phantompage.Navigator.prototype.open = function(url) {181 var result = this.waitForNavigate();182 this.page.open(url, function(status) {183 debugLog('page.open callback status:', status);184 });185 return result;186 };187 phantompage.Navigator.prototype.isNavigating = function() {188 return this.navigating;189 };190 phantompage.Navigator.prototype.getPageData = function() {191 return {192 url: this.page.url,193 statusCode: this.statusCodes[this.page.url]194 };195 };196 phantompage.Navigator.prototype.waitForNavigate = function() {197 var self = this;198 debugAssert(self.navigateListener === null);199 var promise = new kew.Promise();200 self.navigateListener = function(status) {201 promise.resolve(status);202 };203 return promise;204 };205 if (typeof module !== 'undefined' && module.exports) {206 module.exports = phantompage;207 }...
cChartContainer.gs
Source:cChartContainer.gs
1//create a chart to append to roadmap2var cChartContainer = function (rt) {3 var pScRoot = rt;4 this.xChart = null;5 this.root = function () {6 return pScRoot;7 };8 this.chart = function () {9 return this.xChart;10 };11 return this;12};13cChartContainer.prototype.makeChart = function () {14 var rt = this.root();15 var shp = rt.shape();16 17 if (rt.chartStyle() != SCHARTTYPES.ctNone) {18 // the size of the chart will be a proportion of the roadmap size in parameter sheet19 var chtHeight = shp.height() * rt.chartProportion();20 // add a panel under the roadamap to contain the chart21 this.xChart = rt.addShape(SHAPETYPES.stPanel, shp.left(), shp.top() + shp.height(), 22 shp.width(), chtHeight );23 // create the google table24 this.xBuilder = 25 DebugAssert( Charts.newDataTable() , 'failed to create a data table builder');26 // add the roadmap data27 this.chartArray = [];28 this.makeAxes()29 .makeSeries();30 31 // transpose if necesay32 var chartArray = arrayTranspose(this.chartArray);33 // build a table34 this.xBuilder.addColumn(Charts.ColumnType.STRING,chartArray[0][0]) ;35 for (var i=0 ; i < chartArray[0].length ;i++) 36 this.xBuilder.addColumn(Charts.ColumnType.NUMBER, chartArray[0][i+1]) ;37 38 // do the rows39 for (var i=1 ; i < chartArray.length ;i++) { 40 this.xBuilder.addRow( chartArray[i]) ;41 }42 // now build it43 this.xDataTable = DebugAssert( this.xBuilder.build() , 'failed to build a data table');44 // create the appropriate type of chart45 this.xChartBuilder = rt.chartStyle() == SCHARTTYPES.ctShale ? 46 DebugAssert( Charts.newAreaChart(), 'failed to build area chart') :47 rt.chartStyle() == SCHARTTYPES.ctColumnStacked || rt.chartStyle() == SCHARTTYPES.ctColumn ? 48 DebugAssert( Charts.newColumnChart(), 'failed to build column chart') :49 rt.chartStyle() == SCHARTTYPES.ctLine ? 50 DebugAssert( Charts.newLineChart(), 'failed to build Line chart') :51 rt.chartStyle() == SCHARTTYPES.ctBar? 52 DebugAssert( Charts.newBarChart(), 'failed to build Bar chart') :53 DebugAssert (false,'unknown chart type ' + rt.chartStyle());54 55 var stacked = rt.chartStyle() == SCHARTTYPES.ctColumnStacked ;56 57 // tweak it58 if (stacked) {59 this.xChartObject = this.xChartBuilder60 .setDataTable(this.xDataTable)61 .setTitle(rt.text())62 .setStacked()63 .setDimensions(shp.width(), chtHeight)64 .setLegendPosition(Charts.Position.BOTTOM)65 .build();66 }67 else {68 this.xChartObject = this.xChartBuilder69 .setDataTable(this.xDataTable)70 .setTitle(rt.text())71 .setDimensions(shp.width(), chtHeight)72 .setLegendPosition(Charts.Position.BOTTOM)73 .build();74 75 }76 // add it to the panel and commit to the api77 this.xChart.box().add(this.xChartObject);78 this.xChart.commit();79 }80 return this;81};82cChartContainer.prototype.makeAxes = function () {83 var oArray = this.root().scaleDates();84 //var builder = this.xBuilder;85 var v = new Array(oArray.length+1);86 v[0] = "Periods";87 for (var i=0; i < oArray.length ; i++){88 v[i+1] = oArray[i].finishText;89 }90 this.chartArray.push(v);91 return this;92};93cChartContainer.prototype.makeSeries = function ( scParent ) {94 // its recursive, do the children first95 var sc = fixOptional (scParent, this.root());96 var self = this;97 sc.children().forEach(function(child){98 self.makeSeries( child);99 }100 );101 if (!IsEmpty(sc.cost())) {102 if ( sc.isData() && sc.cost() ){103 // add data for this series104 self.makeValues(sc);105 }106 }107};108cChartContainer.prototype.makeValues = function ( sc){109 //this calcultes the values based on the rules for treatment of the cost110 var dsd = this.dLater(sc.activate(), sc.activate(), sc.root().activate());111 var dfd = this.dEarlier(sc.deActivate(), sc.deActivate(), sc.root().deActivate());112 var dur = dfd - dsd;113 var bDone = false;114 var oArray = this.root().scaleDates();115 var v = new Array(oArray.length+1);116 117 for (i=0; i < oArray.length ; i++){118 var sd = oArray[i].start;119 var fd = oArray[i].finish;120 var efd = this.dEarlier(fd, sc.deActivate(), fd);121 var esd = this.dLater(sd, sc.activate(), sd);122 var p=0;123 //proportion of annual cost occurring in this period124 if ( esd > fd || efd < sd || bDone ) {125 p =0;126 } 127 else {128 switch (sc.chartCostTreatment()) {129 case STREATS.stcAnnual:130 p = (efd - esd) / (DateSerial(Year(fd), 12, 31) - DateSerial(Year(fd), 1, 1) );131 break;132 case STREATS.stcDuration:133 p = (efd - esd + 1) / dur;134 break;135 case STREATS.stcOneOffStart:136 p = 1;137 bDone = True;138 break;139 case STREATS.stcOneOffFinish:140 if (efd < fd ) {141 p=1;142 bDone = true;143 }144 else {145 p=0;146 }147 break; 148 default:149 DebugAssert ( false,'unknown chart cost treatment' );150 break;151 }152 DebugAssert ( p>=0,'some deactivate/activate dates must be reversed' );153 }154 v[i+1] =p* sc.cost();155 }156 v[0] = sc.text();157 this.chartArray.push(v);158 return this;159};160cChartContainer.prototype.dEarlier = function (a,b,missing){161 var ea = a ? a : missing;162 var eb = b ? b : missing;163 return ea > eb ? eb : ea;164};165cChartContainer.prototype.dLater = function (a,b,missing){166 var ea = a ? a : missing;167 var eb = b ? b : missing;168 return ea < eb ? eb : ea;...
assert.test.js
Source:assert.test.js
...4test("debugAssert with NODE_ENV = development", t => {5 const oldEnv = process.env.NODE_ENV;6 process.env.NODE_ENV = "development";7 try {8 t.throws(() => debugAssert(false, "it failed"), { message: "Assertion failed: it failed" });9 t.is(debugAssert(true, "it failed"), undefined);10 }11 finally {12 process.env.NODE_ENV = oldEnv;13 }14});15test("debugAssert with NODE_ENV = production", t => {16 const oldEnv = process.env.NODE_ENV;17 process.env.NODE_ENV = "production";18 try {19 t.is(debugAssert(false, "it failed"), undefined);20 t.is(debugAssert(true, "it failed"), undefined);21 }22 finally {23 process.env.NODE_ENV = oldEnv;24 }...
Using AI Code Generation
1const { debugAssert } = require('@playwright/test/lib/utils/debug');2const { test } = require('@playwright/test');3test('test', async ({ page }) => {4 debugAssert(page, 'page is not defined');5});6 × test (1s)7 at Object.debugAssert (playwright-test/node_modules/@playwright/test/lib/utils/debug.js:22:11)8 at Object.<anonymous> (playwright-test/test.js:5:3)9 1 failed (1s)10 1 passed (1s)11const { debug } = require('@playwright/test');12debug('Hello World!');13const { debug } = require('@playwright/test/lib/utils/debug');14debug('Hello World!');15const { test, debug } = require('@playwright/test');16test('test', async ({ page }) => {17 debug('Page is loaded');18});19 × test (1s)20 at Object.<anonymous> (playwright-test/test
Using AI Code Generation
1const { debugAssert } = require('@playwright/test');2const { debugAssert } = require('@playwright/test');3const { debugAssert } = require('@playwright/test');4const { debugAssert } = require('@playwright/test');5const { debugAssert } = require('@playwright/test');6const { debugAssert } = require('@playwright/test');7const { debugAssert } = require('@playwright/test');8const { debugAssert } = require('@playwright/test');9const { debugAssert } = require('@playwright/test');10const { debugAssert } = require('@playwright/test');11const { debugAssert } = require('@playwright/test');12const { debugAssert } = require('@playwright/test');13const { debugAssert } = require('@playwright/test');14const { debugAssert } = require('@playwright/test');15const { debugAssert } = require('@playwright/test');16const { debugAssert } = require('@playwright/test');17const { debugAssert } = require('@playwright/test');18const { debugAssert } = require('@playwright/test');19const { debug
Using AI Code Generation
1const { debugAssert } = require('playwright/lib/server/debug');2const { assert } = require('console');3const { debugAssert } = require('playwright/lib/server/debug');4const { assert } = require('console');5const { debugAssert } = require('playwright/lib/server/debug');6const { assert } = require('console');7const { debugAssert } = require('playwright/lib/server/debug');8const { assert } = require('console');9const { debugAssert } = require('playwright/lib/server/debug');10const { assert } = require('console');11const { debugAssert } = require('playwright/lib/server/debug');12const { assert } = require('console');13const { debugAssert } = require('playwright/lib/server/debug');14const { assert } = require('console');15const { debugAssert } = require('playwright/lib/server/debug');16const { assert } = require('console');17const { debugAssert } = require('playwright/lib/server/debug');18const { assert } = require('console');19const { debugAssert } = require('playwright/lib/server/debug');20const { assert } = require('console');21const { debugAssert } = require('playwright/lib/server/debug');22const { assert } = require('console');23const { debugAssert } = require('playwright/lib/server/debug');24const { assert } = require('console');25const { debugAssert } = require('playwright/lib/server/debug');26const { assert } = require('console');27const { debugAssert } = require('playwright/lib/server/debug');28const { assert } = require('console');29const { debugAssert } = require('
Using AI Code Generation
1const { debugAssert } = require('playwright-core/lib/utils/debug');2debugAssert(false, 'This is a debugAssert test');3const { debugError } = require('playwright-core/lib/utils/debug');4debugError('This is a debugError test');5const { debugLog } = require('playwright-core/lib/utils/debug');6debugLog('This is a debugLog test');7const { debugWarn } = require('playwright-core/lib/utils/debug');8debugWarn('This is a debugWarn test');9const { debugTrace } = require('playwright-core/lib/utils/debug');10debugTrace('This is a debugTrace test');11const { debugInfo } = require('playwright-core/lib/utils/debug');12debugInfo('This is a debugInfo test');13const { debugAssert } = require('playwright-core/lib/utils/debug');14debugAssert(false, 'This is a debugAssert test');15const { debugError } = require('playwright-core/lib/utils/debug');16debugError('This is a debugError test');17const { debugLog } = require('playwright-core/lib/utils/debug');18debugLog('This is a debugLog test');19const { debugWarn } = require('playwright-core/lib/utils/debug');20debugWarn('This is a debugWarn test');21const { debugTrace } = require('playwright-core/lib/utils/debug');22debugTrace('This is a debugTrace test');23const { debugInfo } = require('playwright-core/lib/utils/debug');24debugInfo('This is a debugInfo test');25const { debugAssert } = require('playwright-core/lib/utils/debug');26debugAssert(false, 'This is a debugAssert test');
Using AI Code Generation
1const { debugAssert } = require('@playwright/test/lib/utils/debugAssert');2debugAssert(false, 'this is an error message');3debugAssert(false, 'this is an error message', 'this is an error message');4debugAssert(false, 'this is an error message', 'this is an error message', 'this is an error message');5debugAssert(false, 'this is an error message', 'this is an error message', 'this is an error message', 'this is an error message');6debugAssert(false, 'this is an error message', 'this is an error message', 'this is an error message', 'this is an error message', 'this is an error message');
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!