1/* 2 * This file is part of LimeSurvey 3 * Copyright (C) 2007-2013 The LimeSurvey Project Team / Carsten Schmitz 4 * All rights reserved. 5 * License: GNU/GPL License v2 or later, see LICENSE.php 6 * LimeSurvey is free software. This version may have been modified pursuant 7 * to the GNU General Public License, and as distributed it includes or 8 * is derivative of works licensed under the GNU General Public License or 9 * other free or open source software licenses. 10 * See COPYRIGHT.php for copyright notices and details. 11 * 12 * Core JavaScript functions needed by ExpressionManager 13 * @author Thomas M. White (TMSWhite) 14 * @author Denis Chenu (Shnoulle) 15 * 16 * Portion from php.js licensed under the MIT licenses. 17 * Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io) 18 * and Contributors (http://phpjs.org/authors) 19 */ 20 21/** 22 * Default event to trigger on answer part 23 * Launch function according to anser-item type 24 * @todo : checkconditions/fixnum_checkconditions in this function 25 **/ 26/* text/number item */ 27$(document).on("keyup change",".answer-item textarea:not([onkeyup]),.answer-item :text:not([onkeyup])",function(event){ 28 if($(this).data("number"))// data-type ? 29 { 30 fixnum_checkconditions($(this).val(), $(this).attr('name'), 'text', 'keyup', $(this).data("integer")) 31 } 32 else 33 { 34 checkconditions($(this).val(), $(this).attr('name'), 'text', 'keyup') 35 } 36}); 37/* select/dropdown item */ 38$(document).on("change",".select-item select:not([onchange]),.dropdown-item select:not([onchange])",function(event){ 39 checkconditions($(this).val(), $(this).attr('name'), 'select-one', 'change') 40}); 41/* radio/button item */ 42$(document).on("change",".radio-item :radio:not([onclick]), .button-item :radio:not([onclick])",function(event){ 43 checkconditions($(this).val(), $(this).attr('name'), 'radio', 'click') 44}); 45/* checkbox item */ 46$(document).on("change",".checkbox-item :checkbox:not([onclick]),.button-item :checkbox:not([onclick])",function(event){ 47 checkconditions($(this).val(), $(this).attr('name'), 'checkbox', 'click') 48}); 49 50/** 51 * For number 52 */ 53var pad = function(num,places) { 54 var zero = places - num.toString().length + 1; 55 return Array(+(zero > 0 && zero)).join("0") + num; 56} 57/** 58 * All EM function (see em_core_helper.php) 59 */ 60function LEMcount() 61{ 62 // takes variable number of arguments - returns count of those arguments that are not null/empty 63 var result=0; 64 for (i=0;i<arguments.length;++i) { 65 var arg = arguments[i]; 66 if (arg !== '') { 67 ++result; 68 } 69 } 70 return result; 71} 72 73function LEMunique() 74{ 75 var uniqs = new Array(); 76 for (i=0;i<arguments.length;++i) { 77 var arg = arguments[i]; 78 if (trim(arg)=='') 79 continue; 80 if (typeof uniqs[arg] !== 'undefined') 81 return false; 82 uniqs[arg] = 1; 83 } 84 return true; 85} 86 87function LEMcountif() 88{ 89 // takes variable number of arguments - returns count of those arguments that match the first parameter 90 var result=0; 91 var match=arguments[0]; 92 for (i=1;i<arguments.length;++i) { 93 var arg = arguments[i]; 94 if (arg == match) { 95 ++result; 96 } 97 } 98 return result; 99} 100 101function LEMcountifop() 102{ 103 // takes variable number of arguments - returns count of answered questions which meet the criteria (arg op value) 104 var result=0; 105 var op=arguments[0]; 106 var value=arguments[1]; 107 if (op == 'RX') { 108 var reg = new RegExp(value.substr(1,value.length-2)); 109 } 110 for (i=2;i<arguments.length;++i) { 111 var arg = arguments[i]; 112 switch(op) 113 { 114 case '==': case 'eq': if (arg == value) { ++result; } break; 115 case '>=': case 'ge': if (arg >= value) { ++result; } break; 116 case '>': case 'gt': if (arg > value) { ++result; } break; 117 case '<=': case 'le': if (arg <= value) { ++result; } break; 118 case '<': case 'lt': if (arg < value) { ++result; } break; 119 case '!=': case 'ne': if (arg != value) { ++result; } break; 120 case 'RX': { 121 try { 122 if (reg.test(arg)) { 123 ++result; 124 } 125 } 126 catch (err) { 127 return false;
128 } 129 } 130 } 131 } 132 return result; 133} 134 135function LEMsumifop() 136{ 137 // takes variable number of arguments - returns sum of answered questions which meet the criteria (arg op value) 138 var result=0; 139 var op=arguments[0]; 140 var value=arguments[1]; 141 if (op == 'RX') { 142 var reg = new RegExp(value.substr(1,value.length-2)); 143 } 144 for (i=2;i<arguments.length;++i) { 145 var arg = arguments[i] || 0; 146 if (LEMis_numeric(arg)){ 147 try{ 148 arg = new Decimal(arg); 149 } catch(e){ 150 arg = new Decimal(arg.toString().replace(/,/,'.')); 151 } 152 } 153 else if(arg === true){ 154 arg=1; 155 } 156 157 switch(op) { 158 case '==': case 'eq': if (arg == value) { result += arg; } break; 159 case '>=': case 'ge': if (arg >= value) { result += arg; } break; 160 case '>': case 'gt': if (arg > value) { result += arg; } break; 161 case '<=': case 'le': if (arg <= value) { result += arg; } break; 162 case '<': case 'lt': if (arg < value) { result += arg; } break; 163 case '!=': case 'ne': if (arg != value) { result += arg; } break; 164 case 'RX': { 165 try { 166 if (reg.test(arg)) { 167 result += arg; 168 } 169 } 170 catch (err) { 171 return false; 172 } 173 } 174 } 175 } 176 return result; 177} 178 179function LEMpi() 180{ 181 return Math.PI; 182} 183 184function LEMsum() 185{ 186 // takes variable number of arguments, returns their sum 187 var result= new Decimal(0); 188 for (i=0;i<arguments.length;++i) { 189 var arg = arguments[i] || 0; 190 if (LEMis_numeric(arg)){ 191 try{ 192 arg = new Decimal(arg); 193 } catch(e){ 194 arg = new Decimal(arg.toString().replace(/,/,'.')); 195 } 196 //create decimal checks! 197 result = result.add(arg); 198 } else if(arg === true){ 199 result = result.add(1); 200 } 201 } 202 return result.toString(); 203} 204 205function LEMintval(a) 206{ 207 if (isNaN(a)) { 208 return NaN; 209 } 210 return Math.floor(+a); 211} 212 213function LEMis_null(a) 214{ 215 return (a == null); 216} 217 218function LEMis_float(a) 219{ 220 if (!LEMis_numeric(a)) 221 { 222 return false; 223 } 224 var num = new Number(a); 225 // should this only return true if there is a non-zero decimal part to the number? 226 return (Math.floor(num) != num); 227} 228 229/** 230 * Test if mixed_var is in integer value (no matter the real type) 231 */ 232function LEMis_int(mixed_var) 233{ 234 try { 235 var iCheckValue = new Decimal(mixed_var) 236 } 237 catch (err) { 238 return false; 239 } 240 return iCheckValue.isInteger(); 241} 242/** 243 * Test if mixed_var is a PHP numeric value 244 * From: http://phpjs.org/functions/is_numeric/ 245 */ 246function LEMis_numeric(mixed_var) 247{ 248 var isNumericRegex = new RegExp(/^(-)?\d*(,|\.)?\d*$/); 249 return ( ( ( typeof mixed_var === 'string' && isNumericRegex.test(mixed_var)) || typeof mixed_var === 'number') && mixed_var !== '' && !isNaN(mixed_var)); 250 // var whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000"; 251 // return (typeof mixed_var === 'number' || (typeof mixed_var === 'string' && whitespace.indexOf(mixed_var.slice(-1)) === -1)) && mixed_var !== '' && !isNaN(mixed_var); 252} 253 254function LEMis_string(a) 255{ 256 return isNaN(a); 257} 258 259/** 260 * Find the closest matching numerical input values in a list an replace it by the 261 * corresponding value within another list 262 * 263 * @author Johannes Weberhofer, 2013 264 * 265 * @param numeric fValueToReplace 266 * @param numeric iStrict - 1 for exact matches only otherwise interpolation the 267 * closest value should be returned 268 * @param string sTranslateFromList - comma seperated list of values to translate from 269 * @param string sTranslateToList - comma seperated list of values to translate to 270 * @return numeric 271 */ 272function LEMconvert_value( fValueToReplace, iStrict, sTranslateFromList, sTranslateToList) 273{ 274 if ( isNaN(fValueToReplace) || (iStrict==null) || (sTranslateFromList==null) || (sTranslateToList==null) ) 275 { 276 return null; 277 } 278 aFromValues = sTranslateFromList.split(","); 279 aToValues = sTranslateToList.split(","); 280 if ( (aFromValues.length > 0) && (aFromValues.length == aToValues.length) ) 281 { 282 fMinimumDiff = null; 283 iNearestIndex = 0; 284 for ( i = 0; i < aFromValues.length; i++) { 285 if ( isNaN(aFromValues[i]) ) { 286 // break processing when non-numeric variables are about to be processed 287 return null; 288 } 289 fCurrentDiff = Math.abs(aFromValues[i] - fValueToReplace); 290 if (fCurrentDiff === 0) { 291 return aToValues[i]; 292 } else if (i === 0) { 293 fMinimumDiff = fCurrentDiff; 294 } else if ( fMinimumDiff > fCurrentDiff ) { 295 fMinimumDiff = fCurrentDiff; 296 iNearestIndex = i; 297 } 298 } 299 if ( iStrict != 1 ) { 300 return aToValues[iNearestIndex]; 301 } 302 } 303 return null; 304} 305 306/** 307 * return float value of mixedVar (near like PHP floatval) 308 * @param mixed mixedVar 309 * @return float 310 * @see: https://locutus.io/php/floatval/ 311 * original by: Michael White (https://getsprink.com) 312 * note 1: The native parseFloat() method of JavaScript returns NaN 313 * note 1: when it encounters a string before an int or float value. 314 * example 1: floatval('150.03_page-section') 315 * returns 1: 150.03 316 * example 2: floatval('page: 3') 317 * returns 2: 0 318 * example 3: floatval('-50 + 8') 319 * returns 3: -50 320 */ 321function LEMfloatval(mixedVar) 322{ 323 return (parseFloat(mixedVar) || 0) 324} 325/** 326 * If $test is true, return $iftrue, else return $iffalse 327 * @param mixed testDone 328 * @param mixed ifTrue 329 * @param mixed ifFalse 330 * @return mixed 331 */ 332function LEMif(testDone,ifTrue,ifFalse) 333{ 334 if(testDone && testDone !== '0') { // so consistent with PHP 335 return ifTrue; 336 } 337 if (typeof ifFalse == "undefined") { // Pre ES6 (else, just add ifFalse = '' in function call 338 return ''; 339 } 340 return ifFalse; 341} 342 343/** 344 * Returns comma separated list of non-null values 345 */ 346 347function LEMlist() 348{ 349 // takes variable number of arguments 350 var result=""; 351 var joiner = ', '; 352 j=1; // keep track of how many non-null values seen 353 for (i=0;i<arguments.length;++i) { 354 var arg = arguments[i]; 355 if (arg !== '') { 356 if (j > 1) { 357 result += joiner + arg;
358 } 359 else { 360 result += arg; 361 } 362 ++j; 363 } 364 } 365 return result; 366} 367 368/** 369 * Implementation of listifop( cmpAttr, op, value, retAttr, glue, sgqa1, ..., sgqaN ) 370 * Returns a list of retAttr from sgqa1...sgqaN which pass the critiera (cmpAttr op value) 371 */ 372function LEMlistifop() 373{ 374 // takes variable number of arguments 375 var result = ""; 376 var cmpAttr = arguments[0]; 377 var op = arguments[1]; 378 var value = arguments[2]; 379 var retAttr = arguments[3]; 380 var glue = arguments[4]; 381 382 var validAttributes = "/code|gid|grelevance|gseq|jsName|mandatory|NAOK|qid|qseq|question|readWrite|relevanceStatus|relevance|rowdivid|sgqa|shown|type|valueNAOK|value/"; 383 384 if ( ! cmpAttr.match( validAttributes ) ) { 385 return cmpAttr +" not recognized ?!"; 386 } 387 if ( ! retAttr.match( validAttributes ) ) { 388 return retAttr +" not recognized ?!"; 389 } 390 391 if ( op == 'RX' ) { 392 var reg = new RegExp( value.substr( 1, value.length-2 ) ); 393 } 394 395 for ( i=5; i < arguments.length; ++i ) { 396 var sgqa = arguments[i]; 397 var cmpVal = LEMval( sgqa +"."+ cmpAttr ); // Equal to LimeExpressionManager::GetVarAttribute($sgqa,$cmpAttr,null,-1,-1) ? 398 var match = false; 399 400 switch(op) 401 { 402 case '==': case 'eq': match = (cmpVal == value); break; 403 case '>=': case 'ge': match = (cmpVal >= value); break; 404 case '>': case 'gt': match = (cmpVal > value); break; 405 case '<=': case 'le': match = (cmpVal <= value); break; 406 case '<': case 'lt': match = (cmpVal < value); break; 407 case '!=': case 'ne': match = (cmpVal != value); break; 408 case 'RX': try { match = reg.test( cmpVal ); } 409 catch (err) { return "Invalid RegEx"; } break; 410 } 411 412 if ( match ) { 413 retVal = LEMval( sgqa +"."+ retAttr ); // Equal to LimeExpressionManager::GetVarAttribute($sgqa,$retAttr,null,-1,-1) ? 414 if ( result != "" ) { 415 result += glue; 416 } 417 result += retVal; 418 } 419 } 420 421 return result; 422} 423 424/** 425 * Returns Natural logarithm of a number 426 */ 427 428function LEMlog() 429{ 430 // takes variable number of arguments 431 if (arguments.length < 1) { 432 return NaN; 433 } 434 var base=Math.exp(1); 435 if(arguments.length>1){ 436 base = arguments[1]; 437 if (isNaN(base)) { return NaN;} 438 if (base<=0 ) { return NaN;} 439 base=Math.abs(parseFloat(arguments[1])); 440 } 441 if(base==Math.exp(1)){// Not needed 442 return Math.log(arguments[0]); 443 }else{ 444 return Math.log(arguments[0])/Math.log(base); 445 } 446} 447 448/** 449 * max like php in LimeSurvey, start by https://github.com/kvz/locutus/blob/master/src/php/math/max.js 450 * @see https://bugs.limesurvey.org/view.php?id=14337 451 * Review for ExpressionManager 452 **/ 453function LEMmax () { 454 // original at: http://locutus.io/php/max/ 455 // original by: Onno Marsman (https://twitter.com/onnomarsman) 456 // revised by: Denis Chenu for LimeSurvey specific 457 // note 1: Long code cause we're aiming for maximum PHP compatibility 458 // example 1: max(1, 3, 5, 6, 7,'') 459 // returns 1: 7 460 // example 2: max(1, 'hello','') 461 // returns 2: 'hello' 462 // example 3: max('hello', 1,'') 463 // returns 3: 'hello' 464 // example 4: max('2hello', 1,'') 465 // returns 4: '2hello' 466 // example 5: max('1hello', 2,'') 467 // returns 5: 2 468 // example 6: max(-1, -2,'') 469 // returns 6: -1 470 471 var ar 472 var retVal 473 var i = 0 474 var n = 0 475 var argv = arguments 476 var argc = argv.length 477 478 var _compare = function (current, next) { 479 if(next === '') { 480 return -1; 481 } 482 if(current === '') { 483 return 1; 484 } 485 if (current === next) { 486 return 0 487 } 488 if (isNaN(next) && !isNaN(current)) { 489 return (next.toString() > current.toString() ? 1 : -1) 490 } 491 if (isNaN(current) && !isNaN(next)) { 492 return (next.toString() > current.toString() ? 1 : -1) 493 } 494 495 return (next > current ? 1 : -1) 496 } 497 498 if (argc === 0) { 499 return ''; 500 } 501 if (argc === 1) { 502 return argv[0]; 503 } 504 505 ar = argv 506 retVal = ar[0] 507 for (i = 1, n = ar.length; i < n; ++i) { 508 if (_compare(retVal, ar[i]) === 1) { 509 retVal = ar[i] 510 } 511 } 512 513 return retVal 514} 515/** 516 * min like php in LimeSurvey : https://github.com/kvz/locutus/blob/master/src/php/math/min.js 517 * @see https://bugs.limesurvey.org/view.php?id=14337 518 * Review for ExpressionManager 519 **/ 520function LEMmin () { 521 // original at: http://locutus.io/php/max/ 522 // original by: Onno Marsman (https://twitter.com/onnomarsman) 523 // revised by: Denis Chenu for LimeSurvey specific 524 // note 1: Long code cause we're aiming for maximum PHP compatibility 525 // example 1: min(1, 3, 5, 6, 7) 526 // returns 1: 1 527 // example 2: max(1, 'hello') 528 // returns 2: 1 529 // example 3: max('hello', 1) 530 // returns 3: 1 531 // example 4: max('2hello', 1) 532 // returns 4: 1 533 // example 5: max('1hello', 2) 534 // returns 5: '1hello' 535 // example 6: min(-1, -2) 536 // returns 6: -2 537 // example 7: min(-1, '') 538 // returns 7: '' 539 540 var ar 541 var retVal 542 var i = 0 543 var n = 0 544 var argv = arguments 545 var argc = argv.length 546 547 var _compare = function (current, next) { 548 if(next === '') { 549 return -1; 550 } 551 if(current === '') { 552 return 1; 553 } 554 if (current === next) { 555 return 0; 556 } 557 if (isNaN(next) && !isNaN(current)) { 558 return 1; 559 } 560 if (isNaN(current) && !isNaN(next)) { 561 return -1 562 } 563 564 return (next > current ? 1 : -1) 565 } 566 567 if (argc === 0) { 568 return ''; 569 } 570 if (argc === 1) { 571 return argv[0]; 572 } 573 574 ar = argv 575 retVal = ar[0] 576 577 for (i = 1, n = ar.length; i < n; ++i) { 578 if (_compare(retVal, ar[i]) === -1) { 579 retVal = ar[i] 580 } 581 } 582 583 return retVal 584} 585 586 /** 587 * Returns concatenates list 588 */ 589function LEMjoin() 590{ 591 var result=""; 592 for (i=0;i<arguments.length;++i) { 593 result += arguments[i]; 594 } 595 return result; 596} 597 598/** 599 * Returns concatenates list with first argument as the separator 600 */ 601function LEMimplode() 602{ 603 // takes variable number of arguments 604 var result=""; 605 if (arguments.length <= 1) { 606 return ""; 607 } 608 var joiner = arguments[0]; 609 for (i=1;i<arguments.length;++i) { 610 var arg = arguments[i]; 611 if (i > 1) { 612 result += joiner + arg;
613 } 614 else { 615 result += arg; 616 } 617 } 618 return result; 619} 620 621/* 622 * Returns true if within matches the pattern. Pattern must start and end with the '/' character 623 */ 624function LEMregexMatch(sRegExp,within) 625{ 626 try { 627 var flags = sRegExp.replace(/.*\/([gimy]*)$/, '$1'); 628 var pattern = sRegExp.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1').trim(); 629 var reg = new RegExp(pattern, flags); // Note that the /u flag crashes IE11 630 var decodedValue = html_entity_decode(within); 631 return reg.test(decodedValue); 632 } 633 catch (err) { 634 return false; 635 } 636} 637 638function LEMstrlen(a) 639{ 640 var str = new String(a); 641 return str.length; 642} 643 644function LEMstr_replace (search, replace, subject) { 645 // Copied From: http://phpjs.org/functions 646 var i = 0, 647 j = 0, 648 temp = '', 649 repl = '', 650 sl = 0, 651 fl = 0, 652 f = [].concat(search), 653 r = [].concat(replace), 654 s = subject, 655 ra = Object.prototype.toString.call(r) === '[object Array]', 656 sa = Object.prototype.toString.call(s) === '[object Array]'; 657 s = [].concat(s); 658 for (i = 0, sl = s.length; i < sl; i++) { 659 if (s[i] === '') { 660 continue; 661 } 662 for (j = 0, fl = f.length; j < fl; j++) { 663 temp = s[i] + ''; 664 repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0]; 665 s[i] = (temp).split(f[j]).join(repl); 666 } 667 } 668 return sa ? s : s[0]; 669} 670 671 672 673function LEMstrpos(haystack,needle,offset) 674{ 675 var haystack = haystack + ''; 676 var needle = needle + ''; 677 var index = 0; 678 if ((index = haystack.indexOf(needle, offset)) !== -1) { 679 return index; 680 } 681 return false; 682} 683 684function LEMempty(v) 685{ 686 if (v === "" || v === false) { 687 return true; 688 } 689 return false; 690} 691 692function LEMbool(v) 693{ 694 bool = new Boolean(v); 695 if (v.valueOf() && v != 'false') { 696 return true; // fix for JavaScript native processing that considers the value "false" to be true 697 } 698 return false; 699} 700 701/** 702 * Match even if different types - especially true vs. 1, and false vs. 0 or blank 703 */ 704function LEMeq(a,b) 705{ 706 if ((a==="true" && b==="1") || (a==="1" && b==="true")) { 707 return true; 708 } 709 if ((a==="false" && (b==="0" || b==="")) || ((a==="0" || a==="") && b ==="false")) { 710 return true; 711 } 712 return a==b; 713} 714 715/** 716 * Return the value for data element jsName, treating it as blank if its question is irrelevant on the current page. 717 * Also convert the string 'false' to '' to cope with a JavaScript type casting issue 718 */ 719function LEMval(alias) 720{ 721 // first find out whether it is using a suffix 722 var str = new String(alias); 723 var varName = alias; 724 var suffix = 'code'; // the default 725 var value = ""; 726 if (str == '') return ''; 727 newval = str; 728 if (LEMradix === ',') { 729 newval = str.split(',').join('.'); 730 } 731 var checkNumericRegex = new RegExp(/^[-0-9,\.]*$/); 732 if(checkNumericRegex.test(newval)){ 733 try{ 734 newval = new Decimal(newval); 735 } catch(e){ 736 if(e) 737 newval = new Decimal(newval.toString().replace(/,/,'.')); 738 } 739 } 740 if (newval == parseFloat(newval)) { 741 if (newval.length > 0 && newval[0]==0) { 742 return newval; // so keep 0 prefixes on numbers 743 } 744 return +newval; 745 } 746 747 if (str.match(/^INSERTANS:/)) { 748 suffix = 'shown'; 749 varName = varName.substr(10); 750 } 751 else if (str.match(/\.(code|gid|grelevance|gseq|jsName|mandatory|NAOK|qid|qseq|question|readWrite|relevanceStatus|relevance|rowdivid|sgqa|shown|type|valueNAOK|value)$/)) { 752 varName = str.replace(/\.(code|gid|grelevance|gseq|jsName|mandatory|NAOK|qid|qseq|question|readWrite|relevanceStatus|relevance|rowdivid|sgqa|shown|type|valueNAOK|value)$/,'') 753 suffix = str.replace(/^(.+)\./,''); 754 } 755 756 jsName = LEMalias2varName[varName]; 757 attr = LEMvarNameAttr[jsName]; 758 if ((suffix.match(/^code|NAOK|shown|valueNAOK|value$/)) && attr.qid!='') { 759 if (!LEMval(varName + '.relevanceStatus')) { 760 return ''; 761 } 762 } 763 var whichJsName; // correct name whether on- or off-page 764 var onSamePage; // Tag if value is on same page or not ( 765 if (LEMmode=='survey' || (LEMmode=='group' && attr.gseq == LEMgseq) || (LEMmode=='question' && attr.qid == LEMqid)) 766 { 767 whichJsName = (typeof attr.jsName_on === 'undefined') ? attr.jsName : attr.jsName_on; 768 onSamePage=true; 769 } 770 else 771 { 772 whichJsName = attr.jsName; 773 onSamePage=false; 774 } 775 776 if (whichJsName === null || typeof document.getElementById(whichJsName) === 'undefined' || document.getElementById(whichJsName) === null) { 777 an_error = true; // this line is here to make debugging easier 778 return ''; 779 } 780 781 // values should always be stored encoded with htmlspecialchars() 782 switch (suffix) { 783 case 'relevanceStatus': { 784 grel = qrel = sgqarel = 1; 785 if (!(typeof attr.gseq === 'undefined') && !(document.getElementById('relevanceG' + attr.gseq) === null)) { 786 if(typeof attr.type === 'undefined' || attr.type!="*")// Equation question don't test visibility of group ( child of bug #08315). 787 grel = parseInt(document.getElementById('relevanceG' + attr.gseq).value); 788 } 789 if (!(typeof attr.qid === 'undefined') && !(document.getElementById('relevance' + attr.qid) === null)) { 790 qrel = parseInt(document.getElementById('relevance' + attr.qid).value); 791 } 792 if (!(typeof attr.rowdivid === 'undefined') && !(document.getElementById('relevance' + attr.rowdivid) === null)) { 793 sgqarel = parseInt(document.getElementById('relevance' + attr.rowdivid).value); 794 } 795 return (grel && qrel && sgqarel); 796 } 797 case 'shown': { 798 value = htmlspecialchars_decode(document.getElementById(whichJsName).value); 799 var shown=""; 800 switch(attr.type) 801 { 802 case 'G': //GENDER drop-down list 803 case 'Y': //YES/NO radio-buttons 804 case 'C': //ARRAY (YES/UNCERTAIN/NO) radio-buttons 805 case 'E': //ARRAY (Increase/Same/Decrease) radio-buttons 806 shown = (typeof attr.answers[value] === 'undefined') ? '' : attr.answers[value]; 807 break; 808 case '!': //List - dropdown 809 case 'L': //LIST drop-down/radio-button list 810 case 'O': //LIST WITH COMMENT drop-down/radio-button list + textarea 811 case 'H': //ARRAY (Flexible) - Column Format 812 case 'F': //ARRAY (Flexible) - Row Format 813 case 'R': //RANKING STYLE 814 if (attr.type == 'O' && varName.match(/comment$/)) { 815 answer = htmlentities(value); 816 } 817 else if ((attr.type == 'L' || attr.type == '!') && varName.match(/_other$/)) { 818 answer = htmlentities(value); 819 } 820 else { 821 which_ans = '0~' + value; 822 if (attr.answers === undefined || typeof attr.answers[which_ans] === 'undefined') { 823 answer = value; 824 } 825 else { 826 answerParts = attr.answers[which_ans].split('|'); 827 answerParts.shift(); // remove the first element 828 answer = answerParts.join('|'); 829 } 830 } 831 shown = answer; 832 break; 833 case '1': //Array (Flexible Labels) dual scale // need scale 834 prefix = (attr.jsName.match(/_1$/)) ? '1' : '0'; 835 which_ans = prefix + '~' + value; 836 if (attr.answers === undefined || typeof attr.answers[which_ans] === 'undefined') { 837 answer = ''; 838 } 839 else { 840 answerParts = attr.answers[which_ans].split('|'); 841 answerParts.shift(); // remove the first element 842 answer = answerParts.join('|'); 843 } 844 shown = answer; 845 break; 846 case 'N': //NUMERICAL QUESTION TYPE 847 case 'K': //MULTIPLE NUMERICAL QUESTION 848 case 'A': //ARRAY (5 POINT CHOICE) radio-buttons 849 case 'B': //ARRAY (10 POINT CHOICE) radio-buttons 850 case ':': //ARRAY (Multi Flexi) 1 to 10 851 case '5': //5 POINT CHOICE radio-buttons 852 case 'Q': //MULTIPLE SHORT TEXT 853 case ';': //ARRAY (Multi Flexi) Text 854 case 'S': //SHORT FREE TEXT 855 case 'T': //LONG FREE TEXT 856 case 'U': //HUGE FREE TEXT 857 case 'D': //DATE 858 case '*': //Equation 859 case 'I': //Language Question 860 case '|': //File Upload 861 case 'X': //BOILERPLATE QUESTION 862 shown = htmlentities(value); 863 break; 864 case 'M': //Multiple choice checkbox 865 case 'P': //Multiple choice with comments checkbox + text 866 if (typeof attr.question === 'undefined' || value == '') { 867 shown = ''; 868 } 869 else { 870 if (attr.type == 'P' && varName.match(/comment$/)) { 871 try { 872 var numtest = new Decimal(value); 873 shown = parseFloat(numtest.valueOf()); 874 } 875 catch(e) { 876 shown = htmlentities(value); 877 } 878 } 879 else { 880 shown = htmlspecialchars_decode(attr.question); 881 } 882 } 883 break; 884 } 885 return shown; 886 } 887 case 'gid': 888 return attr.gid; 889 case 'grelevance': 890 return attr.grelevance; 891 case 'mandatory': 892 return attr.mandatory; 893 case 'qid': 894 return attr.qid; 895 case 'question': 896 return htmlspecialchars_decode(attr.question); 897 case 'readWrite': 898 return attr.readWrite; 899 case 'relevance': 900 return htmlspecialchars_decode(attr.relevance); 901 case 'sgqa': 902 return attr.sgqa; 903 case 'type': 904 return attr.type; 905 case 'gseq': 906 return attr.gseq; 907 case 'qseq': 908 return attr.qseq; 909 case 'jsName': 910 return whichJsName; 911 case 'code': 912 case 'NAOK': 913 case 'value': 914 case 'valueNAOK': 915 { 916 value = htmlspecialchars_decode(document.getElementById(whichJsName).value); 917 if (value === '') { 918 return ''; 919 } 920 // Always htmlentities user entered values, see #13928 921 switch(attr.type) 922 { 923 case '!': //List - dropdown 924 case 'L': //LIST drop-down/radio-button list 925 case 'O': //LIST WITH COMMENT drop-down/radio-button list + textarea 926 case 'H': //ARRAY (Flexible) - Column Format 927 case 'F': //ARRAY (Flexible) - Row Format 928 case 'R': //RANKING STYLE 929 if (attr.type == 'O' && varName.match(/comment$/)) { 930 value = htmlentities(value); 931 } 932 else if ((attr.type == 'L' || attr.type == '!') && varName.match(/_other$/)) { 933 value = htmlentities(value); 934 } 935 break; 936 case 'N': //NUMERICAL QUESTION TYPE 937 case 'K': //MULTIPLE NUMERICAL QUESTION 938 case 'Q': //MULTIPLE SHORT TEXT 939 case ';': //ARRAY (Multi Flexi) Text 940 case 'S': //SHORT FREE TEXT 941 case 'T': //LONG FREE TEXT 942 case 'U': //HUGE FREE TEXT 943 case 'D': //DATE 944 case '*': //Equation 945 case '|': //File Upload (unsure need to be htmlentities ?) 946 value = htmlentities(value); 947 break; 948 case 'M': //Multiple choice checkbox 949 case 'P': //Multiple choice with comments checkbox + text 950 if (attr.type == 'P' && varName.match(/comment$/)) { 951 value = htmlentities(value); 952 } 953 break; 954 case 'A': //ARRAY (5 POINT CHOICE) radio-buttons 955 case 'B': //ARRAY (10 POINT CHOICE) radio-buttons 956 case ':': //ARRAY (Multi Flexi) 1 to 10 957 case '5': //5 POINT CHOICE radio-buttons 958 case 'I': //Language Question 959 case 'X': //BOILERPLATE QUESTION 960 default: 961 // Nothing to update 962 } 963 964 if (suffix == 'value' || suffix == 'valueNAOK') { 965 // if in assessment mode, this returns the assessment value 966 // in non-assessment mode, this is identical to .code 967 switch (attr.type) { 968 case '!': //List - dropdown 969 case 'L': //LIST drop-down/radio-button list 970 case 'O': //LIST WITH COMMENT drop-down/radio-button list + textarea 971 case 'H': //ARRAY (Flexible) - Column Format 972 case 'F': //ARRAY (Flexible) - Row Format 973 case 'R': //RANKING STYLE 974 if (attr.type == 'O' && varName.match(/comment$/)) { 975// value = value; 976 } 977 else if ((attr.type == 'L' || attr.type == '!') && varName.match(/_other$/)) { 978// value = value; 979 } 980 else { 981 which_ans = '0~' + value; 982 if (attr.answers === undefined || typeof attr.answers[which_ans] === 'undefined') { 983 value = ''; 984 } 985 else { 986 answerParts = attr.answers[which_ans].split('|'); 987 value = answerParts[0]; 988 } 989 } 990 break; 991 case '1': //Array (Flexible Labels) dual scale // need scale 992 prefix = (attr.jsName.match(/_1$/)) ? '1' : '0'; 993 which_ans = prefix + '~' + value; 994 if (attr.answers === undefined || typeof attr.answers[which_ans] === 'undefined') { 995 value = ''; 996 } 997 else { 998 answerParts = attr.answers[which_ans].split('|'); 999 value = answerParts[0]; 1000 } 1001 break; 1002 case 'N': //NUMERICAL QUESTION TYPE 1003 case 'K': //MULTIPLE NUMERICAL QUESTION 1004 1005 } 1006 } 1007 1008 if (typeof attr.onlynum !== 'undefined' && attr.onlynum==1) { 1009 if(value=="") { 1010 return ""; 1011 } 1012 1013 var checkNumericRegex = new RegExp(/^(-)?[0-9]*(,|\.)[0-9]*$/); 1014 /* Set as number if regexp is OK AND lenght is > 1 (then not fix [-.,] #14533 and no need to fix single number) */ 1015 if( checkNumericRegex.test(value) && value.length > 1 ) 1016 { 1017 var length = value.length; 1018 var firstLetterIsNull = value.split("").shift() === '0'; 1019 // @todo : use . or , according to LEMradix ! 1020 try{ 1021 var numtest = new Decimal(value); 1022 } catch(e){ 1023 var numtest = new Decimal(value.toString().replace(/,/,'.')); 1024 // Error can still happen maybe but d
1024on't catch to know (and fix) it 1025 } 1026 value = numtest.valueOf(); 1027 if(value.length < length && firstLetterIsNull){ 1028 value = str_repeat('0', length).substr(0,(length - value.length))+''+value.toString(); 1029 } 1030 value = Number(value); /* If it's a number : always return a number */ 1031 } 1032 if(LSvar.bNumRealValue) { 1033 return value; 1034 } 1035 return Number(value); 1036 } 1037 1038 // convert content in date questions to standard format yy-mm-dd to facilitate use in EM (comparisons, min/max etc.) 1039 else if (attr.type=='D') { 1040 // get date format pattern of referenced question 1041 var sdatetimePattern=$(jsName.replace(/java/g, '#dateformat')).val(); 1042 if (sdatetimePattern == ''){ 1043 sdatetimePattern=$(jsName.replace(/java/g, '#dateformat')).text(); 1044 } 1045 // if empty (eg., variable on a previous page), set default format yy-mm-dd HH:MM 1046 sdatetimePattern = sdatetimePattern == ''? 'YYYY-MM-DD HH:mm': sdatetimePattern; 1047 1048 if (sdatetimePattern==null) { 1049 sdatetimePattern=""; 1050 } 1051 if (value=='INVALID') { 1052 value=""; 1053 } 1054 else { 1055 value= moment(value,sdatetimePattern).format('YYYY-MM-DD HH:mm'); 1056 } 1057 return value; 1058 } 1059 else if (isNaN(value)) { 1060 if (value==='false') { 1061 return ''; // so Boolean operations will treat it as false. In JavaScript, Boolean("false") is true since "false" is not a zero-length string 1062 } 1063 return value; 1064 } 1065 else if(!isNaN(parseFloat(value)) && isFinite(value)) 1066 { 1067 var length = value.length; 1068 var firstLetterIsNull = value.split("").shift() === '0'; 1069 try{ 1070 var numtest = new Decimal(value); 1071 } catch(e){ 1072 var numtest = new Decimal(value.toString().replace(/,/,'.')); 1073 } 1074 if(numtest.valueOf().length < length && firstLetterIsNull){ 1075 value = value.toString(); /* return string as it is */ 1076 } else { 1077 value = Number(numtest.valueOf()); /* If it's a number : always return a number */ 1078 } 1079 } 1080 1081 return value; 1082 } 1083 case 'rowdivid': 1084 if (typeof attr.rowdivid === 'undefined' || attr.rowdivid == '') { 1085 return ''; 1086 } 1087 return attr.rowdivid; 1088 default: 1089 return 'Unknown Attribute: ' . suffix; 1090 } 1091} 1092 1093 1094/** Display number with comma as radix separator, if needed 1095 */ 1096function LEMfixnum(value) 1097{ 1098 if (LEMradix===',') { 1099 var newval = String(value); 1100 if (!isNaN(parseFloat(newval)) && isFinite(newval)) { 1101 newval= newval.split('.').join(','); 1102 return newval; 1103 } 1104 return value; // unchanged 1105 } 1106 return value; 1107} 1108 1109/* 1110 * Remove HTML and PHP tags from string 1111 */ 1112function LEMstrip_tags(htmlString) 1113{ 1114 var tmp = document.createElement("DIV"); 1115 tmp.innerHTML = htmlString; 1116 return tmp.textContent||tmp.innerText; 1117} 1118 1119/** 1120 * Compute sample standard deviation of the input variables 1121 */ 1122function LEMstddev() 1123{ 1124 vals = new Array(); 1125 j = 0; 1126 for (i=0;i<arguments.length;++i) { 1127 if (LEMis_numeric(arguments[i])) { 1128 vals[j++] = arguments[i]; 1129 } 1130 } 1131 count = vals.length; 1132 if (count <= 1) { 1133 return 0; // what should default value be? 1134 } 1135 sum = 0; 1136 for (i=0;i<vals.length;++i) { 1137 sum += vals[i]; 1138 } 1139 mean = sum / count; 1140 1141 sumsqmeans = 0; 1142 for (i=0;i<vals.length;++i) { 1143 sumsqmeans += (vals[i] - mean) * (vals[i] - mean); 1144 } 1145 stddev = Math.sqrt(sumsqmeans / (count-1)); 1146 return stddev; 1147} 1148 1149function LEMstrtoupper(s) 1150{ 1151 return s.toUpperCase(); 1152} 1153 1154function LEMstrtolower(s) 1155{ 1156 return s.toLowerCase(); 1157} 1158 1159/* 1160 * return true if any of the arguments are not relevant 1161 */ 1162function LEManyNA() 1163{ 1164 for (i=0;i<arguments.length;++i) { 1165 var arg = arguments[i]; 1166 if (arg.match(/\.NAOK$/)) { 1167 continue; 1168 } 1169 if (typeof LEMalias2varName[arg] === 'undefined') { 1170 continue; // default is OK (e.g. for questions with dot notation suffix 1171 } 1172 jsName = LEMalias2varName[arg]; 1173 if (typeof LEMvarNameAttr[jsName] === 'undefined') { 1174 continue; // default is OK (e.g. for questions with dot notation suffix) 1175 } 1176 attr = LEMvarNameAttr[jsName]; 1177 if (!LEMval(attr.sgqa + '.relevanceStatus')) { 1178 return true; 1179 } 1180 } 1181 return false;
1182} 1183 1184/* Set the tabIndex for all potentially visible form elements, and capture the TAB and SHIFT-TAB keys so can 1185 * control navigation when elements appear and disappear. 1186 */ 1187function LEMsetTabIndexes() 1188{ 1189 if (typeof tabIndexesSet == 'undefined') { 1190 $(document).on('keydown',"#limesurvey :input[type!=hidden][id!=runonce]",function(event){ 1191 var keyCode = event.keyCode || event.which; 1192 if (keyCode == 9) { 1193 // see bug #08590 : lauch checkcondition only for text input. Not needed for radio or checkbox 1194 // Not sure it's really needed actually, it's a blur event for text and change for select 1195 // Can use $(this)[0].type 1196 if($(this).attr('type')=="text") 1197 { 1198 $(this).triggerHandler("keyup"); 1199 } 1200 if($(this).is('select')) 1201 { 1202 $(this).triggerHandler("change"); 1203 } 1204 $(this).focus(); 1205 return true; 1206 } 1207 }); 1208 tabIndexesSet = true; 1209 } 1210} 1211 1212/** Function to set color coding for Other option in multiple choice questions so that it gets filled in if selected 1213 */ 1214function LEMflagMandOther(sgqa,checked) 1215{ 1216 if (checked) { 1217 if ($.trim($('#java'+sgqa).val()) == '') { 1218 $('#answer'+sgqa).addClass('em_sq_validation error').removeClass('good'); 1219 } 1220 else { 1221 $('#answer'+sgqa).addClass('em_sq_validation good').removeClass('error'); 1222 } 1223 } 1224 else { 1225 $('#answer'+sgqa).addClass('em_sq_validation good').removeClass('error'); 1226 } 1227} 1228 1229/* The following functions are courtesy of phpjs.org */ 1230/* 1231 * More info at: http://phpjs.org 1232 * 1233 * This is version: 3.26 1234 * php.js is copyright 2011 Kevin van Zonneveld. 1235 * 1236 * Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld 1237 * (http://kevin.vanzonneveld.net), Onno Marsman, Theriault, Michael White 1238 * (http://getsprink.com), Waldo Malqui Silva, Paulo Freitas, Jack, Jonas 1239 * Raoni Soares Silva (http://www.jsfromhell.com), Philip Peterson, Legaev 1240 * Andrey, Ates Goral (http://magnetiq.com), Alex, Ratheous, Martijn Wieringa, 1241 * Rafal Kukawski (http://blog.kukawski.pl), lmeyrick 1242 * (https://sourceforge.net/projects/bcmath-js/), Nate, Philippe Baumann, 1243 * Enrique Gonzalez, Webtoolkit.info (http://www.webtoolkit.info/), Carlos R. 1244 * L. Rodrigues (http://www.jsfromhell.com), Ash Searle 1245 * (http://hexmen.com/blog/), Jani Hartikainen, travc, Ole Vrijenhoek, 1246 * Erkekjetter, Michael Grier, Rafal Kukawski (http://kukawski.pl), Johnny 1247 * Mast (http://www.phpvrouwen.nl), T.Wild, d3x, 1248 * http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript, 1249 * Rafal Kukawski (http://blog.kukawski.pl/), stag019, pilus, WebDevHobo 1250 * (http://webdevhobo.blogspot.com/), marrtins, GeekFG 1251 * (http://geekfg.blogspot.com), Andrea Giammarchi 1252 * (http://webreflection.blogspot.com), Arpad Ray (mailto:[email protected]), 1253 * gorthaur, Paul Smith, Tim de Koning (http://www.kingsquare.nl), Joris, Oleg 1254 * Eremeev, Steve Hilder, majak, gettimeofday, KELAN, Josh Fraser 1255 * (http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/), 1256 * Marc Palau, Kevin van Zonneveld (http://kevin.vanzonneveld.net/), Martin 1257 * (http://www.erlenwiese.de/), Breaking Par Consulting Inc 1258 * (http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7), 1259 * Chris, Mirek Slugen, saulius, Alfonso Jimenez 1260 * (http://www.alfonsojimenez.com), Diplom@t (http://difane.com/), felix, 1261 * Mailfaker (http://www.weedem.fr/), Tyler Akins (http://rumkin.com), Caio 1262 * Ariede (http://caioariede.com), Robin, Kankrelune 1263 * (http://www.webfaktory.info/), Karol Kowalski, Imgen Tata 1264 * (http://www.myipdf.com/), mdsjack (http://www.mdsjack.bo.it), Dreamer, 1265 * Felix Geisendoerfer (http://www.debuggable.com/felix), Lars Fischer, AJ, 1266 * David, Aman Gupta, Michael White, Public Domain 1267 * (http://www.json.org/json2.js), Steven Levithan 1268 * (http://blog.stevenlevithan.com), Sakimori, Pellentesque Malesuada, 1269 * Thunder.m, Dj (http://phpjs.org/functions/htmlentities:425#comment_134018), 1270 * Steve Clay, David James, Francois, class_exists, nobbler, T. Wild, Itsacon 1271 * (http://www.itsacon.net/), date, Ole Vrijenhoek (http://www.nervous.nl/), 1272 * Fox, Raphael (Ao RUDLER), Marco, noname, Mateusz "loonquawl" Zalega, Frank 1273 * Forte, Arno, ger, mktime, john (http://www.jd-tech.net), Nick Kolosov 1274 * (http://sammy.ru), marc andreu, Scott Cariss, Douglas Crockford 1275 * (http://javascript.crockford.com), madipta, Slawomir Kaniecki, 1276 * ReverseSyntax, Nathan, Alex Wilson, kenneth, Bayron Guevara, Adam Wallner
1277 * (http://web2.bitbaro.hu/), paulo kuong, jmweb, Lincoln Ramsay, djmix, 1278 * Pyerre, Jon Hohle, Thiago Mata (http://thiagomata.blog.com), lmeyrick 1279 * (https://sourceforge.net/projects/bcmath-js/this.), Linuxworld, duncan, 1280 * Gilbert, Sanjoy Roy, Shingo, sankai, Oskar Larsson Högfeldt 1281 * (http://oskar-lh.name/), Denny Wardhana, 0m3r, Everlasto, Subhasis Deb, 1282 * josh, jd, Pier Paolo Ramon (http://www.mastersoup.com/), P, merabi, Soren 1283 * Hansen, Eugene Bulkin (http://doubleaw.com/), Der Simon 1284 * (http://innerdom.sourceforge.net/), echo is bad, Ozh, XoraX 1285 * (http://www.xorax.info), EdorFaus, JB, J A R, Marc Jansen, Francesco, LH, 1286 * Stoyan Kyosev (http://www.svest.org/), nord_ua, omid 1287 * (http://phpjs.org/functions/380:380#comment_137122), Brad Touesnard, MeEtc 1288 * (http://yass.meetcweb.com), Peter-Paul Koch 1289 * (http://www.quirksmode.org/js/beat.html), Olivier Louvignes 1290 * (http://mg-crea.com/), T0bsn, Tim Wiel, Bryan Elliott, Jalal Berrami, 1291 * Martin, JT, David Randall, Thomas Beaucourt (http://www.webapp.fr), taith, 1292 * vlado houba, Pierre-Luc Paour, Kristof Coomans (SCK-CEN Belgian Nucleair 1293 * Research Centre), Martin Pool, Kirk Strobeck, Rick Waldron, Brant Messenger 1294 * (http://www.brantmessenger.com/), Devan Penner-Woelk, Saulo Vallory, Wagner 1295 * B. Soares, Artur Tchernychev, Valentina De Rosa, Jason Wong 1296 * (http://carrot.org/), Christoph, Daniel Esteban, strftime, Mick@el, rezna, 1297 * Simon Willison (http://simonwillison.net), Anton Ongson, Gabriel Paderni, 1298 * Marco van Oort, penutbutterjelly, Philipp Lenssen, Bjorn Roesbeke 1299 * (http://www.bjornroesbeke.be/), Bug?, Eric Nagel, Tomasz Wesolowski, 1300 * Evertjan Garretsen, Bobby Drake, Blues (http://tech.bluesmoon.info/), Luke 1301 * Godfrey, Pul, uestla, Alan C, Ulrich, Rafal Kukawski, Yves Sucaet,
1302 * sowberry, Norman "zEh" Fuchs, hitwork, Zahlii, johnrembo, Nick Callen, 1303 * Steven Levithan (stevenlevithan.com), ejsanders, Scott Baker, Brian Tafoya 1304 * (http://www.premasolutions.com/), Philippe Jausions 1305 * (http://pear.php.net/user/jausions), Aidan Lister 1306 * (http://aidanlister.com/), Rob, e-mike, HKM, ChaosNo1, metjay, strcasecmp, 1307 * strcmp, Taras Bogach, jpfle, Alexander Ermolaev 1308 * (http://snippets.dzone.com/user/AlexanderErmolaev), DxGx, kilops, Orlando, 1309 * dptr1988, Le Torbi, James (http://www.james-bell.co.uk/), Pedro Tainha 1310 * (http://www.pedrotainha.com), James, Arnout Kazemier 1311 * (http://www.3rd-Eden.com), Chris McMacken, gabriel paderni, Yannoo, 1312 * FGFEmperor, baris ozdil, Tod Gentille, Greg Frazier, jakes, 3D-GRAF, Allan 1313 * Jensen (http://www.winternet.no), Howard Yeend, Benjamin Lupton, davook, 1314 * daniel airton wermann (http://wermann.com.br), Atli Ãór, Maximusya, Ryan 1315 * W Tenney (http://ryan.10e.us), Alexander M Beedie, fearphage 1316 * (http://http/my.opera.com/fearphage/), Nathan Sepulveda, Victor, Matteo, 1317 * Billy, stensi, Cord, Manish, T.J. Leahy, Riddler 1318 * (http://www.frontierwebdev.com/), Rafal Kukawski, FremyCompany, Matt 1319 * Bradley, Tim de Koning, Luis Salazar (http://www.freaky-media.com/), Diogo 1320 * Resende, Rival, Andrej Pavlovic, Garagoth, Le Torbi 1321 * (http://www.letorbi.de/), Dino, Josep Sanz (http://www.ws3.es/), rem, 1322 * Russell Walker (http://www.nbill.co.uk/), Jamie Beck 1323 * (http://www.terabit.ca/), setcookie, Michael, YUI Library: 1324 * http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Blues at 1325 * http://hacks.bluesmoon.info/strftime/strftime.js, Ben 1326 * (http://benblume.co.uk/), DtTvB 1327 * (http://dt.in.th/2008-09-16.string-length-in-bytes.html), Andreas, William, 1328 * meo, incidence, Cagri Ekin, Amirouche, Amir Habibi 1329 * (http://www.residence-mixte.com/), Luke Smith (http://lucassmith.name), 1330 * Kheang Hok Chin (http://www.distantia.ca/), Jay Klehr, Lorenzo Pisani, 1331 * Tony, Yen-Wei Liu, Greenseed, mk.keck, Leslie Hoare, dude, booeyOH, Ben 1332 * Bryan 1333 * 1334 * Dual licensed under the MIT (MIT-LICENSE.txt) 1335 * and GPL (GPL-LICENSE.txt) licenses. 1336 * 1337 * Permission is hereby granted, free of charge, to any person obtaining a 1338 * copy of this software and associated documentation files (the 1339 * "Software"), to deal in the Software without restriction, including 1340 * without limitation the rights to use, copy, modify, merge, publish, 1341 * distribute, sublicense, and/or sell copies of the Software, and to 1342 * permit persons to whom the Software is furnished to do so, subject to 1343 * the following conditions: 1344 * 1345 * The above copyright notice and this permission notice shall be included 1346 * in all copies or substantial portions of the Software. 1347 * 1348 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1349 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1350 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1351 * IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES 1352 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1353 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 1354 * OTHER DEALINGS IN THE SOFTWARE. 1355 */ 1356 1357function is_bool (mixed_var) { 1358 // Returns true if variable is a boolean 1359 // 1360 // version: 1107.2516 1361 // discuss at: http://phpjs.org/functions/is_bool 1362 // + original by: Onno Marsman 1363 // * example 1: is_bool(false); 1364 // * returns 1: true 1365 // * example 2: is_bool(0); 1366 // * returns 2: false 1367 return (typeof mixed_var === 'boolean'); 1368} 1369 1370function addslashes (str) { 1371 // Escapes single quote, double quotes and backslash characters in a string with backslashes 1372 // 1373 // version: 1107.2516 1374 // discuss at: http://phpjs.org/functions/addslashes 1375 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1376 // + improved by: Ates Goral (http://magnetiq.com) 1377 // + improved by: marrtins 1378 // + improved by: Nate 1379 // + improved by: Onno Marsman 1380 // + input by: Denny Wardhana 1381 // + improved by: Brett Zamir (http://brett-zamir.me) 1382 // + improved by: Oskar Larsson Högfeldt (http://oskar-lh.name/) 1383 // * example 1: addslashes("kevin's birthday"); 1384 // * returns 1: 'kevin\'s birthday' 1385 return (str + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0'); 1386} 1387 1388function html_entity_decode (string, quote_style) { 1389 // Convert all HTML entities to their applicable characters 1390 // 1391 // version: 1107.2516 1392 // discuss at: http://phpjs.org/functions/html_entity_decode 1393 // + original by: john (http://www.jd-tech.net) 1394 // + input by: ger 1395 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1396 // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1397 // + bugfixed by: Onno Marsman 1398 // + improved by: marc andreu 1399 // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1400 // + input by: Ratheous 1401 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1402 // + input by: Nick Kolosov (http://sammy.ru) 1403 // + bugfixed by: Fox 1404 // - depends on: get_html_translation_table 1405 // * example 1: html_entity_decode('Kevin & van Zonneveld'); 1406 // * returns 1: 'Kevin & van Zonneveld' 1407 // * example 2: html_entity_decode('&lt;'); 1408 // * returns 2: '<' 1409 var hash_map = {}, 1410 symbol = '', 1411 tmp_str = '', 1412 entity = ''; 1413 tmp_str = string.toString(); 1414 1415 if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) { 1416 return false;
1417 } 1418 1419 // fix & problem 1420 // http://phpjs.org/functions/get_html_translation_table:416#comment_97660 1421 delete(hash_map['&']); 1422 hash_map['&'] = '&'; 1423 1424 for (symbol in hash_map) { 1425 entity = hash_map[symbol]; 1426 tmp_str = tmp_str.split(entity).join(symbol); 1427 } 1428 tmp_str = tmp_str.split(''').join("'"); 1429 1430 return tmp_str; 1431} 1432 1433function htmlentities (string, quote_style, charset, double_encode) { 1434 // Convert all applicable characters to HTML entities 1435 // 1436 // version: 1107.2516 1437 // discuss at: http://phpjs.org/functions/htmlentities 1438 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1439 // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1440 // + improved by: nobbler 1441 // + tweaked by: Jack 1442 // + bugfixed by: Onno Marsman 1443 // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1444 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1445 // + input by: Ratheous 1446 // + improved by: RafaÅ Kukawski (http://blog.kukawski.pl) 1447 // - depends on: get_html_translation_table 1448 // * example 1: htmlentities('Kevin & van Zonneveld'); 1449 // * returns 1: 'Kevin & van Zonneveld' 1450 // * example 2: htmlentities("foo'bar","ENT_QUOTES"); 1451 // * returns 2: 'foo'bar' 1452 var hash_map = {}, 1453 symbol = '', 1454 entity = '', 1455 self = this; 1456 string += ''; 1457 double_encode = !!double_encode || double_encode == null; 1458 1459 if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) { 1460 return false; 1461 } 1462 hash_map["'"] = '''; 1463 1464 if (double_encode) { 1465 for (symbol in hash_map) { 1466 entity = hash_map[symbol]; 1467 string = string.split(symbol).join(entity); 1468 } 1469 } else { 1470 string = string.replace(/([\s\S]*?)(&(?:#\d+|#x[\da-f]+|[a-z][\da-z]*);|$)/g, function (ignore, text, entity) { 1471 return self.htmlentities(text, quote_style, charset) + entity; 1472 }); 1473 } 1474 1475 return string; 1476} 1477 1478function get_html_translation_table (table, quote_style) { 1479 // Returns the internal translation table used by htmlspecialchars and htmlentities 1480 // 1481 // version: 1107.2516 1482 // discuss at: http://phpjs.org/functions/get_html_translation_table 1483 // + original by: Philip Peterson 1484 // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1485 // + bugfixed by: noname 1486 // + bugfixed by: Alex 1487 // + bugfixed by: Marco 1488 // + bugfixed by: madipta 1489 // + improved by: KELAN 1490 // + improved by: Brett Zamir (http://brett-zamir.me) 1491 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1492 // + input by: Frank Forte 1493 // + bugfixed by: T.Wild 1494 // + input by: Ratheous 1495 // % note: It has been decided that we're not going to add global 1496 // % note: dependencies to php.js, meaning the constants are not 1497 // % note: real constants, but strings instead. Integers are also supported if someone 1498 // % note: chooses to create the constants themselves. 1499 // * example 1: get_html_translation_table('HTML_SPECIALCHARS'); 1500 // * returns 1: {'"': '"', '&': '&', '<': '<', '>': '>'} 1501 var entities = {}, 1502 hash_map = {}, 1503 decimal = 0, 1504 symbol = ''; 1505 var constMappingTable = {}, 1506 constMappingQuoteStyle = {}; 1507 var useTable = {}, 1508 useQuoteStyle = {}; 1509 1510 // Translate arguments 1511 constMappingTable[0] = 'HTML_SPECIALCHARS'; 1512 constMappingTable[1] = 'HTML_ENTITIES'; 1513 constMappingQuoteStyle[0] = 'ENT_NOQUOTES'; 1514 constMappingQuoteStyle[2] = 'ENT_COMPAT'; 1515 constMappingQuoteStyle[3] = 'ENT_QUOTES'; 1516 1517 useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS'; 1518 useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT'; 1519 1520 if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') { 1521 throw new Error("Table: " + useTable + ' not supported'); 1522 // return false;
1523 } 1524 1525 entities['38'] = '&'; 1526 if (useTable === 'HTML_ENTITIES') { 1527 entities['160'] = ' '; 1528 entities['161'] = '¡'; 1529 entities['162'] = '¢'; 1530 entities['163'] = '£'; 1531 entities['164'] = '¤'; 1532 entities['165'] = '¥'; 1533 entities['166'] = '¦'; 1534 entities['167'] = '§'; 1535 entities['168'] = '¨'; 1536 entities['169'] = '©'; 1537 entities['170'] = 'ª'; 1538 entities['171'] = '«'; 1539 entities['172'] = '¬'; 1540 entities['173'] = '­'; 1541 entities['174'] = '®'; 1542 entities['175'] = '¯'; 1543 entities['176'] = '°'; 1544 entities['177'] = '±'; 1545 entities['178'] = '²'; 1546 entities['179'] = '³'; 1547 entities['180'] = '´'; 1548 entities['181'] = 'µ'; 1549 entities['182'] = '¶'; 1550 entities['183'] = '·'; 1551 entities['184'] = '¸'; 1552 entities['185'] = '¹'; 1553 entities['186'] = 'º'; 1554 entities['187'] = '»'; 1555 entities['188'] = '¼'; 1556 entities['189'] = '½'; 1557 entities['190'] = '¾'; 1558 entities['191'] = '¿'; 1559 entities['192'] = 'À'; 1560 entities['193'] = 'Á'; 1561 entities['194'] = 'Â'; 1562 entities['195'] = 'Ã'; 1563 entities['196'] = 'Ä'; 1564 entities['197'] = 'Å'; 1565 entities['198'] = 'Æ'; 1566 entities['199'] = 'Ç'; 1567 entities['200'] = 'È'; 1568 entities['201'] = 'É'; 1569 entities['202'] = 'Ê'; 1570 entities['203'] = 'Ë'; 1571 entities['204'] = 'Ì'; 1572 entities['205'] = 'Í'; 1573 entities['206'] = 'Î'; 1574 entities['207'] = 'Ï'; 1575 entities['208'] = 'Ð'; 1576 entities['209'] = 'Ñ'; 1577 entities['210'] = 'Ò'; 1578 entities['211'] = 'Ó'; 1579 entities['212'] = 'Ô'; 1580 entities['213'] = 'Õ'; 1581 entities['214'] = 'Ö'; 1582 entities['215'] = '×'; 1583 entities['216'] = 'Ø'; 1584 entities['217'] = 'Ù'; 1585 entities['218'] = 'Ú'; 1586 entities['219'] = 'Û'; 1587 entities['220'] = 'Ü'; 1588 entities['221'] = 'Ý'; 1589 entities['222'] = 'Þ'; 1590 entities['223'] = 'ß'; 1591 entities['224'] = 'à'; 1592 entities['225'] = 'á'; 1593 entities['226'] = 'â'; 1594 entities['227'] = 'ã'; 1595 entities['228'] = 'ä'; 1596 entities['229'] = 'å'; 1597 entities['230'] = 'æ'; 1598 entities['231'] = 'ç'; 1599 entities['232'] = 'è'; 1600 entities['233'] = 'é'; 1601 entities['234'] = 'ê'; 1602 entities['235'] = 'ë'; 1603 entities['236'] = 'ì'; 1604 entities['237'] = 'í'; 1605 entities['238'] = 'î'; 1606 entities['239'] = 'ï'; 1607 entities['240'] = 'ð'; 1608 entities['241'] = 'ñ'; 1609 entities['242'] = 'ò'; 1610 entities['243'] = 'ó'; 1611 entities['244'] = 'ô'; 1612 entities['245'] = 'õ'; 1613 entities['246'] = 'ö'; 1614 entities['247'] = '÷'; 1615 entities['248'] = 'ø'; 1616 entities['249'] = 'ù'; 1617 entities['250'] = 'ú'; 1618 entities['251'] = 'û'; 1619 entities['252'] = 'ü'; 1620 entities['253'] = 'ý'; 1621 entities['254'] = 'þ'; 1622 entities['255'] = 'ÿ'; 1623 } 1624 1625 if (useQuoteStyle !== 'ENT_NOQUOTES') { 1626 entities['34'] = '"'; 1627 } 1628 if (useQuoteStyle === 'ENT_QUOTES') { 1629 entities['39'] = '''; 1630 } 1631 entities['60'] = '<'; 1632 entities['62'] = '>'; 1633 1634 1635 // ascii decimals to real symbols 1636 for (decimal in entities) { 1637 symbol = String.fromCharCode(decimal); 1638 hash_map[symbol] = entities[decimal]; 1639 } 1640 1641 return hash_map; 1642} 1643 1644function htmlspecialchars (string, quote_style, charset, double_encode) { 1645 // Convert special characters to HTML entities 1646 // 1647 // version: 1107.2516 1648 // discuss at: http://phpjs.org/functions/htmlspecialchars 1649 // + original by: Mirek Slugen 1650 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1651 // + bugfixed by: Nathan 1652 // + bugfixed by: Arno 1653 // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1654 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1655 // + input by: Ratheous 1656 // + input by: Mailfaker (http://www.weedem.fr/) 1657 // + reimplemented by: Brett Zamir (http://brett-zamir.me) 1658 // + input by: felix 1659 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1660 // % note 1: charset argument not supported 1661 // * example 1: htmlspecialchars("<a href='test'>Test</a>", 'ENT_QUOTES'); 1662 // * returns 1: '<a href='test'>Test</a>' 1663 // * example 2: htmlspecialchars("ab\"c'd", ['ENT_NOQUOTES', 'ENT_QUOTES']); 1664 // * returns 2: 'ab"c'd' 1665 // * example 3: htmlspecialchars("my "&entity;" is still here", null, null, false); 1666 // * returns 3: 'my "&entity;" is still here' 1667 var optTemp = 0, 1668 i = 0, 1669 noquotes = false;
vendor: 6,630 bytes, lines 1670-1831
1670 if (typeof quote_style === 'undefined' || quote_style === null) { 1671 quote_style = 3; // default for PHP is 2 - using 3 as default for LimeSurvey 1672 } 1673 string = string.toString(); 1674 if (double_encode !== false) { // Put this first to avoid double-encoding 1675 string = string.replace(/&/g, '&'); 1676 } 1677 string = string.replace(/</g, '<').replace(/>/g, '>'); 1678 1679 var OPTS = { 1680 'ENT_NOQUOTES': 0, 1681 'ENT_HTML_QUOTE_SINGLE': 1, 1682 'ENT_HTML_QUOTE_DOUBLE': 2, 1683 'ENT_COMPAT': 2, 1684 'ENT_QUOTES': 3, 1685 'ENT_IGNORE': 4 1686 }; 1687 if (quote_style === 0) { 1688 noquotes = true; 1689 } 1690 if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags 1691 quote_style = [].concat(quote_style); 1692 for (i = 0; i < quote_style.length; i++) { 1693 // Resolve string input to bitwise e.g. 'ENT_IGNORE' becomes 4 1694 if (OPTS[quote_style[i]] === 0) { 1695 noquotes = true; 1696 } 1697 else if (OPTS[quote_style[i]]) { 1698 optTemp = optTemp | OPTS[quote_style[i]]; 1699 } 1700 } 1701 quote_style = optTemp; 1702 } 1703 if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) { 1704 string = string.replace(/'/g, '''); 1705 } 1706 if (!noquotes) { 1707 string = string.replace(/"/g, '"'); 1708 } 1709 1710 return string; 1711} 1712 1713function htmlspecialchars_decode (string, quote_style) { 1714 // Convert special HTML entities back to characters 1715 // 1716 // version: 1107.2516 1717 // discuss at: http://phpjs.org/functions/htmlspecialchars_decode 1718 // + original by: Mirek Slugen 1719 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1720 // + bugfixed by: Mateusz "loonquawl" Zalega 1721 // + input by: ReverseSyntax 1722 // + input by: Slawomir Kaniecki 1723 // + input by: Scott Cariss 1724 // + input by: Francois 1725 // + bugfixed by: Onno Marsman 1726 // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1727 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1728 // + input by: Ratheous 1729 // + input by: Mailfaker (http://www.weedem.fr/) 1730 // + reimplemented by: Brett Zamir (http://brett-zamir.me) 1731 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1732 // * example 1: htmlspecialchars_decode("<p>this -> "</p>", 'ENT_NOQUOTES'); 1733 // * returns 1: '<p>this -> "</p>' 1734 // * example 2: htmlspecialchars_decode("&quot;"); 1735 // * returns 2: '"' 1736 var optTemp = 0, 1737 i = 0, 1738 noquotes = false; 1739 if (typeof quote_style === 'undefined') { 1740 quote_style = 3; // default for PHP is 2 - using 3 as default for LimeSurvey 1741 } 1742 string = string.toString().replace(/</g, '<').replace(/>/g, '>'); 1743 var OPTS = { 1744 'ENT_NOQUOTES': 0, 1745 'ENT_HTML_QUOTE_SINGLE': 1, 1746 'ENT_HTML_QUOTE_DOUBLE': 2, 1747 'ENT_COMPAT': 2, 1748 'ENT_QUOTES': 3, 1749 'ENT_IGNORE': 4 1750 }; 1751 if (quote_style === 0) { 1752 noquotes = true; 1753 } 1754 if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags 1755 quote_style = [].concat(quote_style); 1756 for (i = 0; i < quote_style.length; i++) { 1757 // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4 1758 if (OPTS[quote_style[i]] === 0) { 1759 noquotes = true; 1760 } else if (OPTS[quote_style[i]]) { 1761 optTemp = optTemp | OPTS[quote_style[i]]; 1762 } 1763 } 1764 quote_style = optTemp; 1765 } 1766 if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) { 1767 string = string.replace(/�*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should 1768 // string = string.replace(/'|�*27;/g, "'"); // This would also be useful here, but not a part of PHP 1769 } 1770 if (!noquotes) { 1771 string = string.replace(/"/g, '"'); 1772 } 1773 // Put this in last place to avoid escape being double-decoded 1774 string = string.replace(/&/g, '&'); 1775 1776 return string; 1777} 1778 1779function ltrim (str, charlist) { 1780 // Strips whitespace from the beginning of a string 1781 // 1782 // version: 1107.2516 1783 // discuss at: http://phpjs.org/functions/ltrim 1784 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1785 // + input by: Erkekjetter 1786 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1787 // + bugfixed by: Onno Marsman 1788 // * example 1: ltrim(' Kevin van Zonneveld '); 1789 // * returns 1: 'Kevin van Zonneveld ' 1790 charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1'); 1791 var re = new RegExp('^[' + charlist + ']+', 'g'); 1792 return (str + '').replace(re, ''); 1793} 1794 1795function nl2br(str, is_xhtml) { 1796 // discuss at: http://phpjs.org/functions/nl2br/ 1797 // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1798 // improved by: Philip Peterson 1799 // improved by: Onno Marsman 1800 // improved by: Atli Ãór 1801 // improved by: Brett Zamir (http://brett-zamir.me) 1802 // improved by: Maximusya 1803 // bugfixed by: Onno Marsman 1804 // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1805 // input by: Brett Zamir (http://brett-zamir.me) 1806 // example 1: nl2br('Kevin\nvan\nZonneveld'); 1807 // returns 1: 'Kevin<br />\nvan<br />\nZonneveld' 1808 // example 2: nl2br("\nOne\nTwo\n\nThree\n", false); 1809 // returns 2: '<br>\nOne<br>\nTwo<br>\n<br>\nThree<br>\n' 1810 // example 3: nl2br("\nOne\nTwo\n\nThree\n", true); 1811 // returns 3: '<br />\nOne<br />\nTwo<br />\n<br />\nThree<br />\n' 1812 1813 var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br ' + '/>' : '<br>'; // Adjust comment to avoid issue on phpjs.org display 1814 1815 return (str + '') 1816 .replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2'); 1817} 1818 1819function number_format (number, decimals, dec_point, thousands_sep) { 1820 // http://kevin.vanzonneveld.net 1821 // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) 1822 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1823 // + bugfix by: Michael White (http://getsprink.com) 1824 // + bugfix by: Benjamin Lupton 1825 // + bugfix by: Allan Jensen (http://www.winternet.no) 1826 // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) 1827 // + bugfix by: Howard Yeend 1828 // + revised by: Luke Smith (http://lucassmith.name) 1829 // + bugfix by: Diogo Resende 1830 // + bugfix by: Rival 1831 // + input by: Kheang Hok Chin (http://www.distantia.ca
1831/) 1832 // + improved by: davook 1833 // + improved by: Brett Zamir (http://brett-zamir.me) 1834 // + input by: Jay Klehr 1835 // + improved by: Brett Zamir (http://brett-zamir.me) 1836 // + input by: Amir Habibi (http://www.residence-mixte.com/) 1837 // + bugfix by: Brett Zamir (http://brett-zamir.me) 1838 // + improved by: Theriault 1839 // + input by: Amirouche 1840 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1841 // * example 1: number_format(1234.56); 1842 // * returns 1: '1,235' 1843 // * example 2: number_format(1234.56, 2, ',', ' '); 1844 // * returns 2: '1 234,56' 1845 // * example 3: number_format(1234.5678, 2, '.', ''); 1846 // * returns 3: '1234.57' 1847 // * example 4: number_format(67, 2, ',', '.'); 1848 // * returns 4: '67,00' 1849 // * example 5: number_format(1000); 1850 // * returns 5: '1,000' 1851 // * example 6: number_format(67.311, 2); 1852 // * returns 6: '67.31' 1853 // * example 7: number_format(1000.55, 1); 1854 // * returns 7: '1,000.6' 1855 // * example 8: number_format(67000, 5, ',', '.'); 1856 // * returns 8: '67.000,00000' 1857 // * example 9: number_format(0.9, 0); 1858 // * returns 9: '1' 1859 // * example 10: number_format('1.20', 2); 1860 // * returns 10: '1.20' 1861 // * example 11: number_format('1.20', 4); 1862 // * returns 11: '1.2000' 1863 // * example 12: number_format('1.2000', 3); 1864 // * returns 12: '1.200' 1865 // * example 13: number_format('1 000,50', 2, '.', ' '); 1866 // * returns 13: '100 050.00' 1867 // Strip all characters but numerical ones. 1868 number = (number + '').replace(/[^0-9+\-Ee.]/g, ''); 1869 var n = !isFinite(+number) ? 0 : +number, 1870 prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), 1871 sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, 1872 dec = (typeof dec_point === 'undefined') ? '.' : dec_point, 1873 s = '', 1874 toFixedFix = function (n, prec) { 1875 var k = Math.pow(10, prec); 1876 return '' + Math.round(n * k) / k; 1877 }; 1878 // Fix for IE parseFloat(0.55).toFixed(0) = 0; 1879 s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.'); 1880 if (s[0].length > 3) { 1881 s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep); 1882 } 1883 if ((s[1] || '').length < prec) { 1884 s[1] = s[1] || ''; 1885 s[1] += new Array(prec - s[1].length + 1).join('0'); 1886 } 1887 return s.join(dec); 1888} 1889 1890function quoted_printable_decode (str) { 1891 // Convert a quoted-printable string to an 8 bit string 1892 // 1893 // version: 1107.2516 1894 // discuss at: http://phpjs.org/functions/quoted_printable_decode 1895 // + original by: Ole Vrijenhoek 1896 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1897 // + reimplemented by: Theriault 1898 // + improved by: Brett Zamir (http://brett-zamir.me) 1899 // + bugfixed by: Theriault 1900 // * example 1: quoted_printable_decode('a=3Db=3Dc'); 1901 // * returns 1: 'a=b=c' 1902 // * example 2: quoted_printable_decode('abc =20\r\n123 =20\r\n'); 1903 // * returns 2: 'abc \r\n123 \r\n' 1904 // * example 3: quoted_printable_decode('012345678901234567890123456789012345678901234567890123456789012345678901234=\r\n56789'); 1905 // * returns 3: '01234567890123456789012345678901234567890123456789012345678901234567890123456789' 1906 // * example 4: quoted_printable_decode("Lorem ipsum dolor sit amet=23, consectetur adipisicing elit"); 1907 // * returns 4: Lorem ipsum dolor sit amet#, consectetur adipisicing elit 1908 // Removes softline breaks 1909 var RFC2045Decode1 = /=\r\n/gm, 1910 // Decodes all equal signs followed by two hex digits 1911 RFC2045Decode2IN = /=([0-9A-F]{2})/gim, 1912 // the RFC states against decoding lower case encodings, but following apparent PHP behavior 1913 // RFC2045Decode2IN = /=([0-9A-F]{2})/gm, 1914 RFC2045Decode2OUT = function (sMatch, sHex) { 1915 return String.fromCharCode(parseInt(sHex, 16)); 1916 }; 1917 return str.replace(RFC2045Decode1, '').replace(RFC2045Decode2IN, RFC2045Decode2OUT); 1918} 1919 1920function quoted_printable_encode (str) { 1921 // + original by: Theriault 1922 // + improved by: Brett Zamir (http://brett-zamir.me) 1923 // + improved by: Theriault 1924 // * example 1: quoted_printable_encode('a=b=c'); 1925 // * returns 1: 'a=3Db=3Dc' 1926 // * example 2: quoted_printable_encode('abc \r\n123 \r\n'); 1927 // * returns 2: 'abc =20\r\n123 =20\r\n' 1928 // * example 3: quoted_printable_encode('0123456789012345678901234567890123456789012345678901234567890123456789012345'); 1929 // * returns 3: '012345678901234567890123456789012345678901234567890123456789012345678901234=\r\n5' 1930 // RFC 2045: 6.7.2: Octets with decimal values of 33 through 60 (bang to less-than) inclusive, and 62 through 126 (greater-than to tilde), inclusive, MAY be represented as the US-ASCII characters 1931 // PHP does not encode any of the above; as does this function. 1932 // RFC 2045: 6.7.3: Octets with values of 9 and 32 MAY be represented as US-ASCII TAB (HT) and
1932SPACE characters, respectively, but MUST NOT be so represented at the end of an encoded line 1933 // PHP does not encode spaces (octet 32) except before a CRLF sequence as stated above. PHP always encodes tabs (octet 9). This function replicates PHP. 1934 // RFC 2045: 6.7.4: A line break in a text body, represented as a CRLF sequence in the text canonical form, must be represented by a (RFC 822) line break 1935 // PHP does not encode a CRLF sequence, as does this function. 1936 // RFC 2045: 6.7.5: The Quoted-Printable encoding REQUIRES that encoded lines be no more than 76 characters long. If longer lines are to be encoded with the Quoted-Printable encoding, "soft" line breaks must be used. 1937 // PHP breaks lines greater than 76 characters; as does this function. 1938 var hexChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'], 1939 RFC2045Encode1IN = / \r\n|\r\n|[^!-<>-~ ]/gm, 1940 RFC2045Encode1OUT = function (sMatch) { 1941 // Encode space before CRLF sequence to prevent spaces from being stripped 1942 // Keep hard line breaks intact; CRLF sequences 1943 if (sMatch.length > 1) { 1944 return sMatch.replace(' ', '=20'); 1945 } 1946 // Encode matching character 1947 var chr = sMatch.charCodeAt(0); 1948 return '=' + hexChars[((chr >>> 4) & 15)] + hexChars[(chr & 15)]; 1949 }, 1950 // Split lines to 75 characters; the reason it's 75 and not 76 is because softline breaks are preceeded by an equal sign; which would be the 76th character. 1951 // However, if the last line/string was exactly 76 characters, then a softline would not be needed. PHP currently softbreaks anyway; so this function replicates PHP. 1952 RFC2045Encode2IN = /.{1,72}(?!\r\n)[^=]{0,3}/g, 1953 RFC2045Encode2OUT = function (sMatch) { 1954 if (sMatch.substr(sMatch.length - 2) === '\r\n') { 1955 return sMatch; 1956 } 1957 return sMatch + '=\r\n'; 1958 }; 1959 str = str.replace(RFC2045Encode1IN, RFC2045Encode1OUT).replace(RFC2045Encode2IN, RFC2045Encode2OUT); 1960 // Strip last softline break 1961 return str.substr(0, str.length - 3); 1962} 1963 1964function quotemeta (str) { 1965 // Quotes meta characters 1966 // 1967 // version: 1107.2516 1968 // discuss at: http://phpjs.org/functions/quotemeta 1969 // + original by: Paulo Freitas 1970 // * example 1: quotemeta(". + * ? ^ ( $ )"); 1971 // * returns 1: '\. \+ \* \? \^ \( \$ \)' 1972 return (str + '').replace(/([\.\\\+\*\?\[\^\]\$\(\)])/g, '\\$1'); 1973} 1974 1975function round (value, precision, mode) { 1976 // http://kevin.vanzonneveld.net 1977 // + original by: Philip Peterson 1978 // + revised by: Onno Marsman 1979 // + input by: Greenseed 1980 // + revised by: T.Wild 1981 // + input by: meo 1982 // + input by: William 1983 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1984 // + input by: Josep Sanz (http://www.ws3.es/) 1985 // + revised by: RafaÅ Kukawski (http://blog.kukawski.pl/) 1986 // % note 1: Great work. Ideas for improvement: 1987 // % note 1: - code more compliant with developer guidelines 1988 // % note 1: - for implementing PHP constant arguments look at 1989 // % note 1: the pathinfo() function, it offers the greatest 1990 // % note 1: flexibility & compatibility possible 1991 // * example 1: round(1241757, -3); 1992 // * returns 1: 1242000 1993 // * example 2: round(3.6); 1994 // * returns 2: 4 1995 // * example 3: round(2.835, 2); 1996 // * returns 3: 2.84 1997 // * example 4: round(1.1749999999999, 2); 1998 // * returns 4: 1.17 1999 // * example 5: round(58551.799999999996, 2); 2000 // * returns 5: 58551.8 2001 var m, f, isHalf, sgn; // helper variables 2002 precision |= 0; // making sure precision is integer 2003 m = Math.pow(10, precision); 2004 value *= m; 2005 sgn = (value > 0) | -(value < 0); // sign of the number 2006 isHalf = value % 1 === 0.5 * sgn; 2007 f = Math.floor(value); 2008 2009 if (isHalf) { 2010 switch (mode) { 2011 case 'PHP_ROUND_HALF_DOWN': 2012 value = f + (sgn < 0); // rounds .5 toward zero 2013 break; 2014 case 'PHP_ROUND_HALF_EVEN': 2015 value = f + (f % 2 * sgn); // rouds .5 towards the next even integer 2016 break; 2017 case 'PHP_ROUND_HALF_ODD': 2018 value = f + !(f % 2); // rounds .5 towards the next odd integer 2019 break; 2020 default: 2021 value = f + (sgn > 0); // rounds .5 away from zero 2022 } 2023 } 2024 2025 return (isHalf ? value : Math.round(value)) / m; 2026} 2027 2028function rtrim (str, charlist) { 2029 // Removes trailing whitespace 2030 // 2031 // version: 1107.2516 2032 // discuss at: http://phpjs.org/functions/rtrim 2033 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2034 // + input by: Erkekjetter 2035 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2036 // + bugfixed by: Onno Marsman 2037 // + input by: rem 2038 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 2039 // * example 1: rtrim(' Kevin van Zonneveld '); 2040 // * returns 1: ' Kevin van Zonneveld' 2041 charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\\$1'); 2042 var re = new RegExp('[' + charlist + ']+$', 'g'); 2043 return (str + '').replace(re, ''); 2044} 2045 2046function sprintf () { 2047 // Return a formatted string 2048 // 2049 // version: 1107.2516 2050 // discuss at: http://phpjs.org/functions/sprintf 2051 // + original by: Ash Searle (http://hexmen.com/blog/) 2052 // + namespaced by: Michael White (http://getsprink.com) 2053 // + tweaked by: Jack 2054 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2055 // + input by: Paulo Freitas 2056 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2057 // + input by: Brett Zamir (http://brett-zamir.me) 2058 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2059 // * example 1: sprintf("%01.2f", 123.1); 2060 // * returns 1: 123.10 2061 // * example 2: sprintf("[%10s]", 'monkey'); 2062 // * returns 2: '[ monkey]' 2063 // * example 3: sprintf("[%'#10s]", 'monkey'); 2064 // * returns 3: '[####monkey]' 2065 var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g; 2066 var a = arguments, 2067 i = 0, 2068 format = a[i++]; 2069 2070 // pad() 2071 var pad = function (str, len, chr, leftJustify) { 2072 if (!chr) { 2073 chr = ' '; 2074 } 2075 var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr); 2076 return leftJustify ? str + padding : padding + str; 2077 }; 2078 2079 // justify() 2080 var justify = function (value, prefix, leftJustify, minWidth, zeroPad, customPadChar) { 2081 var diff = minWidth - value.length; 2082 if (diff > 0) { 2083 if (leftJustify || !zeroPad) { 2084 value = pad(value, minWidth, customPadChar, leftJustify); 2085 } else { 2086 value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length); 2087 } 2088 } 2089 return value; 2090 }; 2091 2092 // formatBaseX() 2093 var formatBaseX = function (value, base, prefix, leftJustify, minWidth, precision, zeroPad) { 2094 // Note: casts negative numbers to positive ones 2095 var number = value >>> 0; 2096 prefix = prefix && number && { 2097 '2': '0b', 2098 '8': '0', 2099 '16': '0x' 2100 }[base] || ''; 2101 value = prefix + pad(number.toString(base), precision || 0, '0', false); 2102 return justify(value, prefix, leftJustify, minWidth, zeroPad); 2103 }; 2104 2105 // formatString() 2106 var formatString = function (value, leftJustify, minWidth, precision, zeroPad, customPadChar) { 2107 if (precision != null) { 2108 value = value.slice(0, precision); 2109 } 2110 return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar); 2111 }; 2112 2113 // doFormat() 2114 var doFormat = function (substring, valueIndex, flags, minWidth, _, precision, type) { 2115 var number; 2116 var prefix; 2117 var method; 2118 var textTransform; 2119 var value; 2120 2121 if (substring == '%%') { 2122 return '%'; 2123 } 2124 2125 // parse flags 2126 var leftJustify = false, 2127 positivePrefix = '', 2128 zeroPad = false, 2129 prefixBaseX = false, 2130 customPadChar = ' '; 2131 var flagsl = flags.length; 2132 for (var j = 0; flags && j < flagsl; j++) { 2133 switch (flags.charAt(j)) { 2134 case ' ': 2135 positivePrefix = ' '; 2136 break; 2137 case '+': 2138 positivePrefix = '+'; 2139 break; 2140 case '-': 2141 leftJustify = true; 2142 break;
2143 case "'": 2144 customPadChar = flags.charAt(j + 1); 2145 break; 2146 case '0': 2147 zeroPad = true; 2148 break; 2149 case '#': 2150 prefixBaseX = true; 2151 break; 2152 } 2153 } 2154 2155 // parameters may be null, undefined, empty-string or real valued 2156 // we want to ignore null, undefined and empty-string values 2157 if (!minWidth) { 2158 minWidth = 0; 2159 } else if (minWidth == '*') { 2160 minWidth = +a[i++]; 2161 } else if (minWidth.charAt(0) == '*') { 2162 minWidth = +a[minWidth.slice(1, -1)]; 2163 } else { 2164 minWidth = +minWidth; 2165 } 2166 2167 // Note: undocumented perl feature: 2168 if (minWidth < 0) { 2169 minWidth = -minWidth; 2170 leftJustify = true; 2171 } 2172 2173 if (!isFinite(minWidth)) { 2174 throw new Error('sprintf: (minimum-)width must be finite'); 2175 } 2176 2177 if (!precision) { 2178 precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : undefined; 2179 } else if (precision == '*') { 2180 precision = +a[i++]; 2181 } else if (precision.charAt(0) == '*') { 2182 precision = +a[precision.slice(1, -1)]; 2183 } else { 2184 precision = +precision; 2185 } 2186 2187 // grab value using valueIndex if required? 2188 value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++]; 2189 2190 switch (type) { 2191 case 's': 2192 return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar); 2193 case 'c': 2194 return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad); 2195 case 'b': 2196 return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad); 2197 case 'o': 2198 return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad); 2199 case 'x': 2200 return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad); 2201 case 'X': 2202 return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase(); 2203 case 'u': 2204 return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad); 2205 case 'i': 2206 case 'd': 2207 number = (+value) | 0; 2208 prefix = number < 0 ? '-' : positivePrefix; 2209 value = prefix + pad(String(Math.abs(number)), precision, '0', false); 2210 return justify(value, prefix, leftJustify, minWidth, zeroPad); 2211 case 'e': 2212 case 'E': 2213 case 'f': 2214 case 'F': 2215 case 'g': 2216 case 'G': 2217 number = +value; 2218 prefix = number < 0 ? '-' : positivePrefix; 2219 method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())]; 2220 textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2]; 2221 value = prefix + Math.abs(number)[method](precision); 2222 return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform](); 2223 default: 2224 return substring; 2225 } 2226 }; 2227 2228 return format.replace(regex, doFormat); 2229} 2230 2231function str_pad (input, pad_length, pad_string, pad_type) { 2232 // Returns input string padded on the left or right to specified length with pad_string 2233 // 2234 // version: 1107.2516 2235 // discuss at: http://phpjs.org/functions/str_pad 2236 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2237 // + namespaced by: Michael White (http://getsprink.com) 2238 // + input by: Marco van Oort 2239 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 2240 // * example 1: str_pad('Kevin van Zonneveld', 30, '-=', 'STR_PAD_LEFT'); 2241 // * returns 1: '-=-=-=-=-=-Kevin van Zonneveld' 2242 // * example 2: str_pad('Kevin van Zonneveld', 30, '-', 'STR_PAD_BOTH'); 2243 // * returns 2: '------Kevin van Zonneveld-----' 2244 var half = '', 2245 pad_to_go; 2246 2247 var str_pad_repeater = function (s, len) { 2248 var collect = '', 2249 i; 2250 2251 while (collect.length < len) { 2252 collect += s; 2253 } 2254 collect = collect.substr(0, len); 2255 2256 return collect; 2257 }; 2258 2259 input += ''; 2260 pad_string = pad_string !== undefined ? pad_string : ' '; 2261 2262 if (pad_type != 'STR_PAD_LEFT' && pad_type != 'STR_PAD_RIGHT' && pad_type != 'STR_PAD_BOTH') { 2263 pad_type = 'STR_PAD_RIGHT'; 2264 } 2265 if ((pad_to_go = pad_length - input.length) > 0) { 2266 if (pad_type == 'STR_PAD_LEFT') { 2267 input = str_pad_repeater(pad_string, pad_to_go) + input; 2268 } else if (pad_type == 'STR_PAD_RIGHT') { 2269 input = input + str_pad_repeater(pad_string, pad_to_go); 2270 } else if (pad_type == 'STR_PAD_BOTH') { 2271 half = str_pad_repeater(pad_string, Math.ceil(pad_to_go / 2)); 2272 input = half + input + half; 2273 input = input.substr(0, pad_length); 2274 } 2275 } 2276 2277 return input; 2278} 2279 2280function str_repeat (input, multiplier) { 2281 // Returns the input string repeat mult times 2282 // 2283 // version: 1107.2516 2284 // discuss at: http://phpjs.org/functions/str_repeat 2285 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2286 // + improved by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) 2287 // * example 1: str_repeat('-=', 10); 2288 // * returns 1: '-=-=-=-=-=-=-=-=-=-=' 2289 return new Array(multiplier + 1).join(input); 2290} 2291 2292function strcasecmp (f_string1, f_string2) { 2293 // Binary safe case-insensitive string comparison 2294 // 2295 // version: 1107.2516 2296 // discuss at: http://phpjs.org/functions/strcasecmp 2297 // + original by: Martijn Wieringa 2298 // + bugfixed by: Onno Marsman 2299 // * example 1: strcasecmp('Hello', 'hello'); 2300 // * returns 1: 0 2301 var string1 = (f_string1 + '').toLowerCase(); 2302 var string2 = (f_string2 + '').toLowerCase(); 2303 2304 if (string1 > string2) { 2305 return 1; 2306 } else if (string1 == string2) { 2307 return 0; 2308 } 2309 2310 return -1; 2311} 2312 2313function strcmp (str1, str2) { 2314 // Binary safe string comparison 2315 // 2316 // version: 1107.2516 2317 // discuss at: http://phpjs.org/functions/strcmp 2318 // + original by: Waldo Malqui Silva 2319 // + input by: Steve Hilder 2320 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2321 // + revised by: gorthaur 2322 // * example 1: strcmp( 'waldo', 'owald' ); 2323 // * returns 1: 1 2324 // * example 2: strcmp( 'owald', 'waldo' ); 2325 // * returns 2: -1 2326 return ((str1 == str2) ? 0 : ((str1 > str2) ? 1 : -1)); 2327} 2328 2329function strip_tags (input, allowed) { 2330 // Strips HTML and PHP tags from a string 2331 // 2332 // version: 1107.2516 2333 // discuss at: http://phpjs.org/functions/strip_tags 2334 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2335 // + improved by: Luke Godfrey 2336 // + input by: Pul 2337 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2338 // + bugfixed by: Onno Marsman 2339 // + input by: Alex 2340 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2341 // + input by: Marc Palau 2342 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2343 // + input by: Brett Zamir (http://brett-zamir.me) 2344 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2345 // + bugfixed by: Eric Nagel 2346 // + input by: Bobby Drake 2347 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2348 // + bugfixed by: Tomasz Wesolowski 2349 // + input by: Evertjan Garretsen 2350 // + revised by: RafaÅ Kukawski (http://blog.kukawski.pl/) 2351 // * example 1: strip_tags('<p>Kevin</p> <b>van</b> <i>Zonneveld</i>', '<i><b>'); 2352 // * returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>' 2353 // * example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>'); 2354 // * returns 2: '<p>Kevin van Zonneveld</p>' 2355 // * example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>"); 2356 // * returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>' 2357 // * example 4: strip_tags('1 < 5 5 > 1'); 2358 // * returns 4: '1 < 5 5 > 1'
2359 // * example 5: strip_tags('1 <br/> 1'); 2360 // * returns 5: '1 1' 2361 // * example 6: strip_tags('1 <br/> 1', '<br>'); 2362 // * returns 6: '1 1' 2363 // * example 7: strip_tags('1 <br/> 1', '<br><br/>'); 2364 // * returns 7: '1 <br/> 1' 2365 allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>) 2366 var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, 2367 commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi; 2368 return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) { 2369 return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''; 2370 }); 2371} 2372 2373function stripslashes (str) { 2374 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2375 // + improved by: Ates Goral (http://magnetiq.com) 2376 // + fixed by: Mick@el 2377 // + improved by: marrtins 2378 // + bugfixed by: Onno Marsman 2379 // + improved by: rezna 2380 // + input by: Rick Waldron 2381 // + reimplemented by: Brett Zamir (http://brett-zamir.me) 2382 // + input by: Brant Messenger (http://www.brantmessenger.com/) 2383 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 2384 // * example 1: stripslashes('Kevin\'s code'); 2385 // * returns 1: "Kevin's code" 2386 // * example 2: stripslashes('Kevin\\\'s code'); 2387 // * returns 2: "Kevin\'s code" 2388 return (str + '').replace(/\\(.?)/g, function (s, n1) { 2389 switch (n1) { 2390 case '\\': 2391 return '\\'; 2392 case '0': 2393 return '\u0000'; 2394 case '': 2395 return ''; 2396 default: 2397 return n1; 2398 } 2399 }); 2400} 2401 2402function stripos (f_haystack, f_needle, f_offset) { 2403 // Finds position of first occurrence of a string within another, case insensitive 2404 // 2405 // version: 1107.2516 2406 // discuss at: http://phpjs.org/functions/stripos 2407 // + original by: Martijn Wieringa 2408 // + revised by: Onno Marsman 2409 // * example 1: stripos('ABC', 'a'); 2410 // * returns 1: 0 2411 var haystack = (f_haystack + '').toLowerCase(); 2412 var needle = (f_needle + '').toLowerCase(); 2413 var index = 0; 2414 2415 if ((index = haystack.indexOf(needle, f_offset)) !== -1) { 2416 return index; 2417 } 2418 return false; 2419} 2420 2421function stristr (haystack, needle, bool) { 2422 // Finds first occurrence of a string within another, case insensitive 2423 // 2424 // version: 1107.2516 2425 // discuss at: http://phpjs.org/functions/stristr 2426 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2427 // + bugfxied by: Onno Marsman 2428 // * example 1: stristr('Kevin van Zonneveld', 'Van'); 2429 // * returns 1: 'van Zonneveld' 2430 // * example 2: stristr('Kevin van Zonneveld', 'VAN', true); 2431 // * returns 2: 'Kevin ' 2432 var pos = 0; 2433 2434 haystack += ''; 2435 pos = haystack.toLowerCase().indexOf((needle + '').toLowerCase()); 2436 if (pos == -1) { 2437 return false; 2438 } else { 2439 if (bool) { 2440 return haystack.substr(0, pos); 2441 } else { 2442 return haystack.slice(pos); 2443 } 2444 } 2445} 2446 2447function strrev (string) { 2448 // Reverse a string 2449 // 2450 // version: 1107.2516 2451 // discuss at: http://phpjs.org/functions/strrev 2452 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2453 // + bugfixed by: Onno Marsman 2454 // + reimplemented by: Brett Zamir (http://brett-zamir.me) 2455 // * example 1: strrev('Kevin van Zonneveld'); 2456 // * returns 1: 'dlevennoZ nav niveK' 2457 // * example 2: strrev('a\u0301haB') === 'Baha\u0301'; // combining 2458 // * returns 2: true 2459 // * example 3: strrev('A\uD87E\uDC04Z') === 'Z\uD87E\uDC04A'; // surrogates 2460 // * returns 2: true 2461 string = string + ''; 2462 2463 // Performance will be enhanced with the next two lines of code commented 2464 // out if you don't care about combining characters 2465 // Keep Unicode combining characters together with the character preceding 2466 // them and which they are modifying (as in PHP 6) 2467 // See http://unicode.org/reports/tr44/#Property_Table (Me+Mn) 2468 // We also add the low surrogate range at the beginning here so it will be 2469 // maintained with its preceding high surrogate 2470 var grapheme_extend = /(.)([\uDC00-\uDFFF\u0300-\u036F\u0483-\u0489\u
24700591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065E\u0670\u06D6-\u06DC\u06DE-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0901-\u0903\u093C\u093E-\u094D\u0951-\u0954\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C82\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D02\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F90-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B6-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAA\u1C24-\u1C37\u1DC0-\u1DE6\u1DFE\u1DFF\u20D0-\u20F0\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA67C\uA67D\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA926-\uA92D\uA947-\uA953\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uFB1E\uFE00-\uFE0F\uFE20-\uFE26]+)/g; 2471 string = string.replace(grapheme_extend, '$2$1'); // Temporarily reverse 2472 return string.split('').reverse().join(''); 2473} 2474 2475function strstr (haystack, needle, bool) { 2476 // Finds first occurrence of a string within another 2477 // 2478 // version: 1107.2516 2479 // discuss at: http://phpjs.org/functions/strstr 2480 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2481 // + bugfixed by: Onno Marsman 2482 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2483 // * example 1: strstr('Kevin van Zonneveld', 'van'); 2484 // * returns 1: 'van Zonneveld' 2485 // * example 2: strstr('Kevin van Zonneveld', 'van', true); 2486 // * returns 2: 'Kevin ' 2487 // * example 3: strstr('[email protected]', '@'); 2488 // * returns 3: '@example.com' 2489 // * example 4: strstr('[email protected]', '@', true); 2490 // * returns 4: 'name' 2491 var pos = 0; 2492 2493 haystack += ''; 2494 pos = haystack.indexOf(needle); 2495 if (pos == -1) { 2496 return false; 2497 } else { 2498 if (bool) { 2499 return haystack.substr(0, pos); 2500 } else { 2501 return haystack.slice(pos); 2502 } 2503 } 2504} 2505 2506function strtotime (text, now) { 2507 // discuss at: http://locutus.io/php/strtotime/ 2508 // original by: Caio Ariede (http://caioariede.com) 2509 // improved by: Kevin van Zonneveld (http://kvz.io) 2510 // improved by: Caio Ariede (http://caioariede.com) 2511 // improved by: A. MatÃas Quezada (http://amatiasq.com) 2512 // improved by: preuter 2513 // improved by: Brett Zamir (http://brett-zamir.me) 2514 // improved by: Mirko Faber 2515 // input by: David 2516 // bugfixed by: Wagner B. Soares 2517 // bugfixed by: Artur Tchernychev 2518 // bugfixed by: Stephan Bösch-Plepelits (http://github.com/plepe) 2519 // note 1: Examples all have a fixed timestamp to prevent 2520 // note 1: tests to fail because of variable time(zones) 2521 // example 1: strtotime('+1 day', 1129633200) 2522 // returns 1: 1129719600 2523 // example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200) 2524 // returns 2: 1130425202 2525 // example 3: strtotime('last month', 1129633200) 2526 // returns 3: 1127041200 2527 // example 4: strtotime('2009-05-04 08:30:00 GMT') 2528 // returns 4: 1241425800 2529 // example 5: strtotime('2009-05-04 08:30:00+00') 2530 // returns 5: 1241425800 2531 // example 6: strtotime('2009-05-04 08:30:00+02:00') 2532 // returns 6: 1241418600 2533 // example 7: strtotime('2009-05-04T08:30:00Z') 2534 // returns 7: 1241425800 2535 2536 var parsed 2537 var match 2538 var today 2539 var year 2540 var date 2541 var days 2542 var ranges 2543 var len 2544 var times 2545 var regex 2546 var i 2547 var fail = false 2548 2549 if (!text) { 2550 return fail 2551 } 2552 2553 // Unecessary spaces 2554 text = text.replace(/^\s+|\s+$/g, '') 2555 .replace(/\s{2,}/g, ' ') 2556 .replace(/[\t\r\n]/g, '') 2557 .toLowerCase() 2558 2559 // in contrast to php, js Date.parse function interprets: 2560 // dates given as yyyy-mm-dd as in timezone: UTC, 2561 // dates with "." or "-" as MDY instead of DMY 2562 // dates with two-digit years differently 2563 // etc...etc... 2564 // ...therefore we manually parse lots of common date formats 2565 var pattern = new RegExp([ 2566 '^(\\d{1,4})', 2567 '([\\-\\.\\/:])', 2568 '(\\d{1,2})', 2569 '([\\-\\.\\/:])', 2570 '(\\d{1,4})', 2571 '(?:\\s(\\d{1,2}):(\\d{2})?:?(\\d{2})?)?', 2572 '(?:\\s([A-Z]+)?)?$' 2573 ].join('')) 2574 match = text.match(pattern) 2575 2576 if (match && match[2] === match[4]) { 2577 if (match[1] > 1901) { 2578 switch (match[2]) { 2579 case '-': 2580 // YYYY-M-D 2581 if (match[3] > 12 || match[5] > 31) { 2582 return fail 2583 } 2584 2585 return new Date(match[1], parseInt(match[3], 10) - 1, match[5], 2586 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 2587 case '.': 2588 // YYYY.M.D is not parsed by strtotime() 2589 return fail 2590 case '/': 2591 // YYYY/M/D 2592 if (match[3] > 12 || match[5] > 31) { 2593 return fail 2594 } 2595 2596 return new Date(match[1], parseInt(match[3], 10) - 1, match[5], 2597 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 2598 } 2599 } else if (match[5] > 1901) { 2600 switch (match[2]) { 2601 case '-': 2602 // D-M-YYYY 2603 if (match[3] > 12 || match[1] > 31) { 2604 return fail 2605 } 2606 2607 return new Date(match[5], parseInt(match[3], 10) - 1, match[1], 2608 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 2609 case '.': 2610 // D.M.YYYY 2611 if (match[3] > 12 || match[1] > 31) { 2612 return fail 2613 } 2614 2615 return new Date(match[5], parseInt(match[3], 10) - 1, match[1], 2616 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 2617 case '/': 2618 // M/D/YYYY 2619 if (match[1] > 12 || match[3] > 31) { 2620 return fail 2621 } 2622 2623 return new Date(match[5], parseInt(match[1], 10) - 1, match[3], 2624 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 2625 } 2626 } else { 2627 switch (match[2]) { 2628 case '-': 2629 // YY-M-D 2630 if (match[3] > 12 || match[5] > 31 || (match[1] < 70 && match[1] > 38)) { 2631 return fail 2632 } 2633 2634 year = match[1] >= 0 && match[1] <= 38 ? +match[1] + 2000 : match[1] 2635 return new Date(year, parseInt(match[3], 10) - 1, match[5], 2636 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 2637 case '.': 2638 // D.M.YY or H.MM.SS 2639 if (match[5] >= 70) { 2640 // D.M.YY 2641 if (match[3] > 12 || match[1] > 31) { 2642 return fail 2643 } 2644 2645 return new Date(match[5], parseInt(match[3], 10) - 1, match[1], 2646 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 2647 } 2648 if (match[5] < 60 && !match[6]) { 2649 // H.MM.SS 2650 if (match[1] > 23 || match[3] > 59) { 2651 return fail 2652 } 2653 2654 today = new Date() 2655 return new Date(today.getFullYear(), today.getMonth(), today.getDate(), 2656 match[1] || 0, match[3] || 0, match[5] || 0, match[9] || 0) / 1000 2657 } 2658 2659 // invalid format, cannot be parsed 2660 return fail 2661 case '/': 2662 // M/D/YY 2663 if (match[1] > 12 || match[3] > 31 || (match[5] < 70 && match[5] > 38)) { 2664 return fail 2665 } 2666 2667 year = match[5] >= 0 && match[5] <= 38 ? +match[5] + 2000 : match[5] 2668 return new Date(year, parseInt(match[1], 10) - 1, match[3], 2669 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 2670 case ':': 2671 // HH:MM:SS 2672 if (match[1] > 23 || match[3] > 59 || match[5] > 59) { 2673 return fail 2674 } 2675 2676 today = new Date() 2677 return new Date(today.getFullYear(), today.getMonth(), today.getDate(), 2678 match[1] || 0, match[3] || 0, match[5] || 0) / 1000 2679 } 2680 } 2681 } 2682 2683 // other formats and "now" should be parsed by Date.parse() 2684 if (text === 'now') { 2685 return now === null || isNaN(now) 2686 ? new Date().getTime() / 1000 | 0 2687 : now | 0 2688 } 2689 if (!isNaN(parsed = Date.parse(text))) { 2690 return parsed / 1000 | 0 2691 } 2692 // Browsers !== Chrome have problems parsing ISO 8601 date strings, as they do 2693 // not accept lower case characters, space, or shortened time zones. 2694 // Therefore, fix these problems and try again. 2695 // Examples: 2696 // 2015-04-15 20:33:59+02 2697 // 2015-04-15 20:33:59z 2698 // 2015-04-15t20:33:59+02:00 2699 pattern = new RegExp([ 2700 '^([0-9]{4}-[0-9]{2}-[0-9]{2})', 2701 '[ t]', 2702 '([0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?)', 2703 '([\\+-][0-9]{2}(:[0-9]{2})?|z)' 2704 ].join('')) 2705 match = text.match(pattern) 2706 if (match) { 2707 // @todo: time zone information 2708 if (match[4] === 'z') { 2709 match[4] = 'Z' 2710 } else if (match[4].match(/^([\+-][0-9]{2})$/)) { 2711 match[4] = match[4] + ':00' 2712 } 2713 2714 if (!isNaN(parsed = Date.parse(match[1] + 'T' + match[2] + match[4]))) { 2715 return parsed / 1000 | 0 2716 } 2717 } 2718 2719 date = now ? new Date(now * 1000) : new Date() 2720 days = { 2721 'sun': 0, 2722 'mon': 1, 2723 'tue': 2, 2724 'wed': 3, 2725 'thu': 4, 2726 'fri': 5, 2727 'sat': 6 2728 } 2729 ranges = { 2730 'yea': 'FullYear', 2731 'mon': 'Month', 2732 'day': 'Date', 2733 'hou': 'Hours', 2734 'min': 'Minutes', 2735 'sec': 'Seconds' 2736 } 2737 2738 function lastNext (type, range, modifier) { 2739 var diff 2740 var day = days[range] 2741 2742 if (typeof day !== 'undefined') { 2743 diff = day - date.getDay() 2744 2745 if (diff === 0) { 2746 diff = 7 * modifier 2747 } else if (diff > 0 && type === 'last') { 2748 diff -= 7 2749 } else if (diff < 0 && type === 'next') { 2750 diff += 7 2751 } 2752 2753 date.setDate(date.getDate() + diff) 2754 } 2755 } 2756 2757 function process (val) { 2758 // @todo: Reconcile this with regex using \s, taking into account 2759 // browser issues with split and regexes 2760 var splt = val.split(' ') 2761 var type = splt[0] 2762 var range = splt[1].substring(0, 3) 2763 var typeIsNumber = /\d+/.test(type) 2764 var ago = splt[2] === 'ago' 2765 var num = (type === 'last' ? -1 : 1) * (ago ? -1 : 1) 2766 2767 if (typeIsNumber) { 2768 num *= parseInt(type, 10) 2769 } 2770 2771 if (ranges.hasOwnProperty(range) && !splt[1].match(/^mon(day|\.)?$/i)) { 2772 return date['set' + ranges[range]](date['get' + ranges[range]]() + num) 2773 } 2774 2775 if (range === 'wee') { 2776 return date.setDate(date.getDate() + (num * 7)) 2777 } 2778 2779 if (type === 'next' || type === 'last') { 2780 lastNext(type, range, num) 2781 } else if (!typeIsNumber) { 2782 return false 2783 } 2784 2785 return true 2786 } 2787
2788 times = '(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec' + 2789 '|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?' + 2790 '|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)' 2791 regex = '([+-]?\\d+\\s' + times + '|' + '(last|next)\\s' + times + ')(\\sago)?' 2792 2793 match = text.match(new RegExp(regex, 'gi')) 2794 if (!match) { 2795 return fail 2796 } 2797 2798 for (i = 0, len = match.length; i < len; i++) { 2799 if (!process(match[i])) { 2800 return fail 2801 } 2802 } 2803 2804 return (date.getTime() / 1000) 2805} 2806 2807function substr (str, start, len) { 2808 // Returns part of a string 2809 // 2810 // version: 909.322 2811 // discuss at: http://phpjs.org/functions/substr 2812 // + original by: Martijn Wieringa 2813 // + bugfixed by: T.Wild 2814 // + tweaked by: Onno Marsman 2815 // + revised by: Theriault 2816 // + improved by: Brett Zamir (http://brett-zamir.me) 2817 // % note 1: Handles rare Unicode characters if 'unicode.semantics' ini (PHP6) is set to 'on' 2818 // * example 1: substr('abcdef', 0, -1); 2819 // * returns 1: 'abcde' 2820 // * example 2: substr(2, 0, -6); 2821 // * returns 2: false 2822 // * example 3: ini_set('unicode.semantics', 'on'); 2823 // * example 3: substr('a\uD801\uDC00', 0, -1); 2824 // * returns 3: 'a' 2825 // * example 4: ini_set('unicode.semantics', 'on'); 2826 // * example 4: substr('a\uD801\uDC00', 0, 2); 2827 // * returns 4: 'a\uD801\uDC00' 2828 // * example 5: ini_set('unicode.semantics', 'on'); 2829 // * example 5: substr('a\uD801\uDC00', -1, 1); 2830 // * returns 5: '\uD801\uDC00' 2831 // * example 6: ini_set('unicode.semantics', 'on'); 2832 // * example 6: substr('a\uD801\uDC00z\uD801\uDC00', -3, 2); 2833 // * returns 6: '\uD801\uDC00z' 2834 // * example 7: ini_set('unicode.semantics', 'on'); 2835 // * example 7: substr('a\uD801\uDC00z\uD801\uDC00', -3, -1) 2836 // * returns 7: '\uD801\uDC00z' 2837 // Add: (?) Use unicode.runtime_encoding (e.g., with string wrapped in "binary" or "Binary" class) to 2838 // allow access of binary (see file_get_contents()) by: charCodeAt(x) & 0xFF (see https://developer.mozilla.org/En/Using_XMLHttpRequest ) or require conversion first? 2839 var i = 0, 2840 allBMP = true, 2841 es = 0, 2842 el = 0, 2843 se = 0, 2844 ret = ''; 2845 str += ''; 2846 var end = str.length; 2847 2848 // BEGIN REDUNDANT 2849 this.php_js = this.php_js || {}; 2850 this.php_js.ini = this.php_js.ini || {}; 2851 // END REDUNDANT 2852 switch ((this.php_js.ini['unicode.semantics'] && this.php_js.ini['unicode.semantics'].local_value.toLowerCase())) { 2853 case 'on': 2854 // Full-blown Unicode including non-Basic-Multilingual-Plane characters 2855 // strlen() 2856 for (i = 0; i < str.length; i++) { 2857 if (/[\uD800-\uDBFF]/.test(str.charAt(i)) && /[\uDC00-\uDFFF]/.test(str.charAt(i + 1))) { 2858 allBMP = false; 2859 break; 2860 } 2861 } 2862 2863 if (!allBMP) { 2864 if (start < 0) { 2865 for (i = end - 1, es = (start += end); i >= es; i--) { 2866 if (/[\uDC00-\uDFFF]/.test(str.charAt(i)) && /[\uD800-\uDBFF]/.test(str.charAt(i - 1))) { 2867 start--; 2868 es--; 2869 } 2870 } 2871 } else { 2872 var surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; 2873 while ((surrogatePairs.exec(str)) != null) { 2874 var li = surrogatePairs.lastIndex; 2875 if (li - 2 < start) { 2876 start++; 2877 } else { 2878 break; 2879 } 2880 } 2881 } 2882 2883 if (start >= end || start < 0) { 2884 return false; 2885 } 2886 if (len < 0) { 2887 for (i = end - 1, el = (end += len); i >= el; i--) { 2888 if (/[\uDC00-\uDFFF]/.test(str.charAt(i)) && /[\uD800-\uDBFF]/.test(str.charAt(i - 1))) { 2889 end--; 2890 el--; 2891 } 2892 } 2893 if (start > end) { 2894 return false;
2895 } 2896 return str.slice(start, end); 2897 } else { 2898 se = start + len; 2899 for (i = start; i < se; i++) { 2900 ret += str.charAt(i); 2901 if (/[\uD800-\uDBFF]/.test(str.charAt(i)) && /[\uDC00-\uDFFF]/.test(str.charAt(i + 1))) { 2902 se++; // Go one further, since one of the "characters" is part of a surrogate pair 2903 } 2904 } 2905 return ret; 2906 } 2907 break; 2908 } 2909 // Fall-through 2910 case 'off': 2911 // assumes there are no non-BMP characters; 2912 // if there may be such characters, then it is best to turn it on (critical in true XHTML/XML) 2913 default: 2914 if (start < 0) { 2915 start += end; 2916 } 2917 end = typeof len === 'undefined' ? end : (len < 0 ? len + end : len + start); 2918 // PHP returns false if start does not fall within the string. 2919 // PHP returns false if the calculated end comes before the calculated start. 2920 // PHP returns an empty string if start and end are the same. 2921 // Otherwise, PHP returns the portion of the string from start to end. 2922 return start >= str.length || start < 0 || start > end ? !1 : str.slice(start, end); 2923 } 2924 return undefined; // Please Netbeans 2925} 2926 2927function trim (str, charlist) { 2928// Strips whitespace from the beginning and end of a string 2929// 2930// version: 1107.2516 2931// discuss at: http://phpjs.org/functions/trim 2932// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2933// + improved by: mdsjack (http://www.mdsjack.bo.it) 2934// + improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev) 2935// + input by: Erkekjetter 2936// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2937// + input by: DxGx 2938// + improved by: Steven Levithan (http://blog.stevenlevithan.com) 2939// + tweaked by: Jack 2940// + bugfixed by: Onno Marsman 2941// * example 1: trim(' Kevin van Zonneveld '); 2942// * returns 1: 'Kevin van Zonneveld' 2943// * example 2: trim('Hello World', 'Hdle'); 2944// * returns 2: 'o Wor' 2945// * example 3: trim(16, 1); 2946// * returns 3: 6 2947var whitespace, l = 0, 2948i = 0; 2949str += ''; 2950 2951if (!charlist) { 2952// default list 2953whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000"; 2954} else { 2955// preg_quote custom list 2956charlist += ''; 2957whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1'); 2958} 2959 2960l = str.length; 2961for (i = 0; i < l; i++) { 2962if (whitespace.indexOf(str.charAt(i)) === -1) { 2963str = str.substring(i); 2964break; 2965} 2966} 2967 2968l = str.length; 2969for (i = l - 1; i >= 0; i--) { 2970if (whitespace.indexOf(str.charAt(i)) === -1) { 2971str = str.substring(0, i + 1); 2972break; 2973} 2974} 2975 2976return whitespace.indexOf(str.charAt(0)) === -1 ? str : ''; 2977} 2978 2979function ucwords (str) { 2980 // Uppercase the first character of every word in a string 2981 // 2982 // version: 1107.2516 2983 // discuss at: http://phpjs.org/functions/ucwords 2984 // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) 2985 // + improved by: Waldo Malqui Silva 2986 // + bugfixed by: Onno Marsman 2987 // + improved by: Robin 2988 // + input by: James (http://www.james-bell.co.uk/) 2989 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 2990 // * example 1: ucwords('kevin van zonneveld'); 2991 // * returns 1: 'Kevin Van Zonneveld' 2992 // * example 2: ucwords('HELLO WORLD'); 2993 // * returns 2: 'HELLO WORLD' 2994 return (str + '').replace(/^([a-z])|\s+([a-z])/g, function ($1) { 2995 return $1.toUpperCase(); 2996 }); 2997} 2998 2999function checkdate (m, d, y) { 3000 // Returns true(1) if it is a valid date in gregorian calendar 3001 // 3002 // version: 1107.2516 3003 // discuss at: http://phpjs.org/functions/checkdate 3004 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 3005 // + improved by: Pyerre 3006 // + improved by: Theriault 3007 // * example 1: checkdate(12, 31, 2000); 3008 // * returns 1: true 3009 // * example 2: checkdate(2, 29, 2001); 3010 // * returns 2: false 3011 // * example 3: checkdate(3, 31, 2008); 3012 // * returns 3: true 3013 // * example 4: checkdate(1, 390, 2000); 3014 // * returns 4: false 3015 return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate(); 3016} 3017 3018function date (format, timestamp) { 3019 // http://kevin.vanzonneveld.net 3020 // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) 3021 // + parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html) 3022 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 3023 // + improved by: MeEtc (http://yass.meetcweb.com) 3024 // + improved by: Brad Touesnard 3025 // + improved by: Tim Wiel 3026 // + improved by: Bryan Elliott 3027 // 3028 // + improved by: Brett Zamir (http://brett-zamir.me) 3029 // + improved by: David Randall 3030 // + input by: Brett Zamir (http://brett-zamir.me) 3031 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 3032 // + improved by: Brett Zamir (http://brett-zamir.me) 3033 // + improved by: Brett Zamir (http://brett-zamir.me) 3034 // + improved by: Theriault 3035 // + derived from: gettimeofday 3036 // + input by: majak 3037 // + bugfixed by: majak 3038 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 3039 // + input by: Alex 3040 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 3041 // + improved by: Theriault 3042 // + improved by: Brett Zamir (http://brett-zamir.me) 3043 // + improved by: Theriault 3044 // + improved by: Thomas Beaucourt (http://www.webapp.fr) 3045 // + improved by: JT 3046 // + improved by: Theriault 3047 // + improved by: RafaÅ Kukawski (http://blog.kukawski.pl) 3048 // + input by: Martin 3049 // + input by: Alex Wilson 3050 // % note 1: Uses global: php_js to store the default timezone 3051 // % note 2: Although the function potentially allows timezone info (see notes), it currently does not set 3052 // % note 2: per a timezone specified by date_default_timezone_set(). Implementers might use 3053 // % note 2: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function 3054 // % note 2: in order to adjust the dates in this function (or our other date functions!) accordingly 3055 // * example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400); 3056 // * returns 1: '09:09:40 m is month' 3057 // * example 2: date('F j, Y, g:i a', 1062462400); 3058 // * returns 2: 'September 2, 2003, 2:26 am' 3059 // * example 3: date('Y W o', 1062462400); 3060 // * returns 3: '2003 36 2003' 3061 // * example 4: x = date('Y m d', (new Date()).getTime()/1000); 3062 // * example 4: (x+'').length == 10 // 2009 01 09 3063 // * returns 4: true 3064 // * example 5: date('W', 1104534000); 3065 // * returns 5: '53' 3066 // * example 6: date('B t', 1104534000); 3067 // * returns 6: '999 31' 3068 // * example 7: date('W U', 1293750000.82); // 2010-12-31 3069 // * returns 7: '52 1293750000' 3070 // * example 8: date('W', 1293836400); // 2011-01-01 3071 // * returns 8: '52' 3072 // * example 9: date('W Y-m-d', 1293974054); // 2011-01-02 3073 // * returns 9: '52 2011-01-02' 3074 var that = this, 3075 jsdate, f, formatChr = /\\?([a-z])/gi, 3076 formatChrCb, 3077 // Keep this here (works, but for code commented-out 3078 // below for file size reasons) 3079 //, tal= [], 3080 _pad = function (n, c) { 3081 if ((n = n + '').length < c) { 3082 return new Array((++c) - n.length).join('0') + n; 3083 } 3084 return n; 3085 }, 3086 txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
3086November", "December"]; 3087 formatChrCb = function (t, s) { 3088 return f[t] ? f[t]() : s; 3089 }; 3090 f = { 3091 // Day 3092 d: function () { // Day of month w/leading 0; 01..31 3093 return _pad(f.j(), 2); 3094 }, 3095 D: function () { // Shorthand day name; Mon...Sun 3096 return f.l().slice(0, 3); 3097 }, 3098 j: function () { // Day of month; 1..31 3099 return jsdate.getDate(); 3100 }, 3101 l: function () { // Full day name; Monday...Sunday 3102 return txt_words[f.w()] + 'day'; 3103 }, 3104 N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun] 3105 return f.w() || 7; 3106 }, 3107 S: function () { // Ordinal suffix for day of month; st, nd, rd, th 3108 var j = f.j(); 3109 return j > 4 || j < 21 ? 'th' : {1: 'st', 2: 'nd', 3: 'rd'}[j % 10] || 'th'; 3110 }, 3111 w: function () { // Day of week; 0[Sun]..6[Sat] 3112 return jsdate.getDay(); 3113 }, 3114 z: function () { // Day of year; 0..365 3115 var a = new Date(f.Y(), f.n() - 1, f.j()), 3116 b = new Date(f.Y(), 0, 1); 3117 return Math.round((a - b) / 864e5) + 1; 3118 }, 3119 3120 // Week 3121 W: function () { // ISO-8601 week number 3122 var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3), 3123 b = new Date(a.getFullYear(), 0, 4); 3124 return _pad(1 + Math.round((a - b) / 864e5 / 7), 2); 3125 }, 3126 3127 // Month 3128 F: function () { // Full month name; January...December 3129 return txt_words[6 + f.n()]; 3130 }, 3131 m: function () { // Month w/leading 0; 01...12 3132 return _pad(f.n(), 2); 3133 }, 3134 M: function () { // Shorthand month name; Jan...Dec 3135 return f.F().slice(0, 3); 3136 }, 3137 n: function () { // Month; 1...12 3138 return jsdate.getMonth() + 1; 3139 }, 3140 t: function () { // Days in month; 28...31 3141 return (new Date(f.Y(), f.n(), 0)).getDate(); 3142 }, 3143 3144 // Year 3145 L: function () { // Is leap year?; 0 or 1 3146 return new Date(f.Y(), 1, 29).getMonth() === 1 | 0; 3147 }, 3148 o: function () { // ISO-8601 year 3149 var n = f.n(), 3150 W = f.W(), 3151 Y = f.Y(); 3152 return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9); 3153 }, 3154 Y: function () { // Full year; e.g. 1980...2010 3155 return jsdate.getFullYear(); 3156 }, 3157 y: function () { // Last two digits of year; 00...99 3158 return (f.Y() + "").slice(-2); 3159 }, 3160 3161 // Time 3162 a: function () { // am or pm 3163 return jsdate.getHours() > 11 ? "pm" : "am"; 3164 }, 3165 A: function () { // AM or PM 3166 return f.a().toUpperCase(); 3167 }, 3168 B: function () { // Swatch Internet time; 000..999 3169 var H = jsdate.getUTCHours() * 36e2, 3170 // Hours 3171 i = jsdate.getUTCMinutes() * 60, 3172 // Minutes 3173 s = jsdate.getUTCSeconds(); // Seconds 3174 return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3); 3175 }, 3176 g: function () { // 12-Hours; 1..12 3177 return f.G() % 12 || 12; 3178 }, 3179 G: function () { // 24-Hours; 0..23 3180 return jsdate.getHours(); 3181 }, 3182 h: function () { // 12-Hours w/leading 0; 01..12 3183 return _pad(f.g(), 2); 3184 }, 3185 H: function () { // 24-Hours w/leading 0; 00..23 3186 return _pad(f.G(), 2); 3187 }, 3188 i: function () { // Minutes w/leading 0; 00..59 3189 return _pad(jsdate.getMinutes(), 2); 3190 }, 3191 s: function () { // Seconds w/leading 0; 00..59 3192 return _pad(jsdate.getSeconds(), 2); 3193 }, 3194 u: function () { // Microseconds; 000000-999000 3195 return _pad(jsdate.getMilliseconds() * 1000, 6); 3196 }, 3197 3198 // Timezone 3199 e: function () { // Timezone identifier; e.g. Atlantic/Azores, ... 3200 // The following works, but requires inclusion of the very large 3201 // timezone_abbreviations_list() function. 3202/* return this.date_default_timezone_get();
vendor: 6,651 bytes, lines 3203-3371
3203*/ 3204 throw 'Not supported (see source code of date() for timezone on how to add support)'; 3205 }, 3206 I: function () { // DST observed?; 0 or 1 3207 // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC. 3208 // If they are not equal, then DST is observed. 3209 var a = new Date(f.Y(), 0), 3210 // Jan 1 3211 c = Date.UTC(f.Y(), 0), 3212 // Jan 1 UTC 3213 b = new Date(f.Y(), 6), 3214 // Jul 1 3215 d = Date.UTC(f.Y(), 6); // Jul 1 UTC 3216 return 0 + ((a - c) !== (b - d)); 3217 }, 3218 O: function () { // Difference to GMT in hour format; e.g. +0200 3219 var a = jsdate.getTimezoneOffset(); 3220 return (a > 0 ? "-" : "+") + _pad(Math.abs(a / 60 * 100), 4); 3221 }, 3222 P: function () { // Difference to GMT w/colon; e.g. +02:00 3223 var O = f.O(); 3224 return (O.substr(0, 3) + ":" + O.substr(3, 2)); 3225 }, 3226 T: function () { // Timezone abbreviation; e.g. EST, MDT, ... 3227 // The following works, but requires inclusion of the very 3228 // large timezone_abbreviations_list() function. 3229/* var abbr = '', i = 0, os = 0, default = 0; 3230 if (!tal.length) { 3231 tal = that.timezone_abbreviations_list(); 3232 } 3233 if (that.php_js && that.php_js.default_timezone) { 3234 default = that.php_js.default_timezone; 3235 for (abbr in tal) { 3236 for (i=0; i < tal[abbr].length; i++) { 3237 if (tal[abbr][i].timezone_id === default) { 3238 return abbr.toUpperCase(); 3239 } 3240 } 3241 } 3242 } 3243 for (abbr in tal) { 3244 for (i = 0; i < tal[abbr].length; i++) { 3245 os = -jsdate.getTimezoneOffset() * 60; 3246 if (tal[abbr][i].offset === os) { 3247 return abbr.toUpperCase(); 3248 } 3249 } 3250 } 3251*/ 3252 return 'UTC'; 3253 }, 3254 Z: function () { // Timezone offset in seconds (-43200...50400) 3255 return -jsdate.getTimezoneOffset() * 60; 3256 }, 3257 3258 // Full Date/Time 3259 c: function () { // ISO-8601 date. 3260 return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb); 3261 }, 3262 r: function () { // RFC 2822 3263 return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb); 3264 }, 3265 U: function () { // Seconds since UNIX epoch 3266 return jsdate.getTime() / 1000 | 0; 3267 } 3268 }; 3269 this.date = function (format, timestamp) { 3270 that = this; 3271 jsdate = ((typeof timestamp === 'undefined') ? new Date() : // Not provided 3272 (timestamp instanceof Date) ? new Date(timestamp) : // JS Date() 3273 new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int) 3274 ); 3275 return format.replace(formatChr, formatChrCb); 3276 }; 3277 return this.date(format, timestamp); 3278} 3279 3280function gmdate (format, timestamp) { 3281 // Format a GMT date/time 3282 // 3283 // version: 1107.2516 3284 // discuss at: http://phpjs.org/functions/gmdate 3285 // + original by: Brett Zamir (http://brett-zamir.me) 3286 // + input by: Alex 3287 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 3288 // - depends on: date 3289 // * example 1: gmdate('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400); // Return will depend on your timezone 3290 // * returns 1: '07:09:40 m is month' 3291 var dt = typeof timestamp === 'undefined' ? new Date() : // Not provided 3292 typeof timestamp === 'object' ? new Date(timestamp) : // Javascript Date() 3293 new Date(timestamp * 1000); // UNIX timestamp (auto-convert to int) 3294 timestamp = Date.parse(dt.toUTCString().slice(0, -4)) / 1000; 3295 return this.date(format, timestamp); 3296} 3297 3298function idate (format, timestamp) { 3299 // Format a local time/date as integer 3300 // 3301 // version: 1107.2516 3302 // discuss at: http://phpjs.org/functions/idate 3303 // + original by: Brett Zamir (http://brett-zamir.me) 3304 // + input by: Alex 3305 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 3306 // + improved by: Theriault 3307 // + derived from: date 3308 // + derived from: gettimeofday 3309 // * example 1: idate('y'); 3310 // * returns 1: 9 3311 if (format === undefined) { 3312 throw 'idate() expects at least 1 parameter, 0 given'; 3313 } 3314 if (!format.length || format.length > 1) { 3315 throw 'idate format is one char'; 3316 } 3317 3318 // Fix: Need to allow date_default_timezone_set() (check for this.php_js.default_timezone and use) 3319 var date = ((typeof timestamp === 'undefined') ? new Date() : // Not provided 3320 (timestamp instanceof Date) ? new Date(timestamp) : // Javascript Date() 3321 new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int) 3322 ), 3323 a; 3324 3325 switch (format) { 3326 case 'B': 3327 return Math.floor(((date.getUTCHours() * 36e2) + (date.getUTCMinutes() * 60) + date.getUTCSeconds() + 36e2) / 86.4) % 1e3; 3328 case 'd': 3329 return date.getDate(); 3330 case 'h': 3331 return date.getHours() % 12 || 12; 3332 case 'H': 3333 return date.getHours(); 3334 case 'i': 3335 return date.getMinutes(); 3336 case 'I': 3337 // capital 'i' 3338 // Logic derived from getimeofday(). 3339 // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC. 3340 // If they are not equal, then DST is observed. 3341 a = date.getFullYear(); 3342 return 0 + (((new Date(a, 0)) - Date.UTC(a, 0)) !== ((new Date(a, 6)) - Date.UTC(a, 6))); 3343 case 'L': 3344 a = date.getFullYear(); 3345 return (!(a & 3) && (a % 1e2 || !(a % 4e2))) ? 1 : 0; 3346 case 'm': 3347 return date.getMonth() + 1; 3348 case 's': 3349 return date.getSeconds(); 3350 case 't': 3351 return (new Date(date.getFullYear(), date.getMonth() + 1, 0)).getDate(); 3352 case 'U': 3353 return Math.round(date.getTime() / 1000); 3354 case 'w': 3355 return date.getDay(); 3356 case 'W': 3357 a = new Date(date.getFullYear(), date.getMonth(), date.getDate() - (date.getDay() || 7) + 3); 3358 return 1 + Math.round((a - (new Date(a.getFullYear(), 0, 4))) / 864e5 / 7); 3359 case 'y': 3360 return parseInt((date.getFullYear() + '').slice(2), 10); // This function returns an integer, unlike date() 3361 case 'Y': 3362 return date.getFullYear(); 3363 case 'z': 3364 return Math.floor((date - new Date(date.getFullYear(), 0, 1)) / 864e5); 3365 case 'Z': 3366 return -date.getTimezoneOffset() * 60; 3367 default: 3368 throw 'Unrecognized date format token'; 3369 } 3370} 3371
3372function mktime () { 3373 // Get UNIX timestamp for a date 3374 // 3375 // version: 1107.2516 3376 // discuss at: http://phpjs.org/functions/mktime 3377 // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 3378 // + improved by: baris ozdil 3379 // + input by: gabriel paderni 3380 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 3381 // + improved by: FGFEmperor 3382 // + input by: Yannoo 3383 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 3384 // + input by: jakes 3385 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 3386 // + bugfixed by: Marc Palau 3387 // + improved by: Brett Zamir (http://brett-zamir.me) 3388 // + input by: 3D-GRAF 3389 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 3390 // + input by: Chris 3391 // + revised by: Theriault 3392 // % note 1: The return values of the following examples are 3393 // % note 1: received only if your system's timezone is UTC. 3394 // * example 1: mktime(14, 10, 2, 2, 1, 2008); 3395 // * returns 1: 1201875002 3396 // * example 2: mktime(0, 0, 0, 0, 1, 2008); 3397 // * returns 2: 1196467200 3398 // * example 3: make = mktime(); 3399 // * example 3: td = new Date(); 3400 // * example 3: real = Math.floor(td.getTime() / 1000); 3401 // * example 3: diff = (real - make); 3402 // * results 3: diff < 5 3403 // * example 4: mktime(0, 0, 0, 13, 1, 1997) 3404 // * returns 4: 883612800 3405 // * example 5: mktime(0, 0, 0, 1, 1, 1998) 3406 // * returns 5: 883612800 3407 // * example 6: mktime(0, 0, 0, 1, 1, 98) 3408 // * returns 6: 883612800 3409 // * example 7: mktime(23, 59, 59, 13, 0, 2010) 3410 // * returns 7: 1293839999 3411 // * example 8: mktime(0, 0, -1, 1, 1, 1970) 3412 // * returns 8: -1 3413 var d = new Date(), 3414 r = arguments, 3415 i = 0, 3416 e = ['Hours', 'Minutes', 'Seconds', 'Month', 'Date', 'FullYear']; 3417 3418 for (i = 0; i < e.length; i++) { 3419 if (typeof r[i] === 'undefined') { 3420 r[i] = d['get' + e[i]](); 3421 r[i] += (i === 3); // +1 to fix JS months. 3422 } else { 3423 r[i] = parseInt(r[i], 10); 3424 if (isNaN(r[i])) { 3425 return false; 3426 } 3427 } 3428 } 3429 3430 // Map years 0-69 to 2000-2069 and years 70-100 to 1970-2000. 3431 r[5] += (r[5] >= 0 ? (r[5] <= 69 ? 2e3 : (r[5] <= 100 ? 1900 : 0)) : 0); 3432 3433 // Set year, month (-1 to fix JS months), and date. 3434 // !This must come before the call to setHours! 3435 d.setFullYear(r[5], r[3] - 1, r[4]); 3436 3437 // Set hours, minutes, and seconds. 3438 d.setHours(r[0], r[1], r[2]); 3439 3440 // Divide milliseconds by 1000 to return seconds and drop decimal. 3441 // Add 1 second if negative or it'll be off from PHP by 1 second. 3442 return (d.getTime() / 1e3 >> 0) - (d.getTime() < 0); 3443} 3444 3445function rand (min, max) { 3446 // http://kevin.vanzonneveld.net 3447 // + original by: Leslie Hoare 3448 // + bugfixed by: Onno Marsman 3449 // % note 1: See the commented out code below for a version which will work with our experimental (though probably unnecessary) srand() function) 3450 // * example 1: rand(1, 1); 3451 // * returns 1: 1 3452 var argc = arguments.length; 3453 if (argc === 0) { 3454 min = 0; 3455 max = 2147483647; 3456 } else if (argc === 1) { 3457 throw new Error('Warning: rand() expects exactly 2 parameters, 1 given'); 3458 } 3459 return Math.floor(Math.random() * (max - min + 1)) + min; 3460} 3461 3462function time () { 3463 // Return current UNIX timestamp 3464 // 3465 // version: 1107.2516 3466 // discuss at: http://phpjs.org/functions/time 3467 // + original by: GeekFG (http://geekfg.blogspot.com) 3468 // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 3469 // + improved by: metjay 3470 // + improved by: HKM 3471 // * example 1: timeStamp = time(); 3472 // * results 1: timeStamp > 1000000000 && timeStamp < 2000000000 3473 return Math.floor(new Date().getTime() / 1000); 3474} 3475 3476/** 3477 * Updates the repeated headings in a dynamic table. 3478 * @param {string} questionId 3479 * @param {number} rep - Repetition 3480 */ 3481function updateHeadings(questionId, rep) 3482{ 3483 var tab = $('#' + questionId).find('table.question'); 3484 tab.find('.repeat').remove(); 3485 var header = tab.find('thead>tr'); 3486 var trs = tab.find('tr:visible'); 3487 trs.each(function(i, tr) 3488 { 3489 // add heading but not for the first and the last rows 3490 if(i != 0 && i % rep == 0 && i != trs.length-1) 3491 { 3492 header.clone().addClass('repeat').addClass('headings').insertAfter(tr); 3493 } 3494 }); 3495} 3496 3497/** 3498 * Updates the colors in a dynamic table. 3499 * No use of jQuery in this function due to speed reasons. 3500 * Get all "#questionId table.question tr:visible" and reset 3501 * class array1/array2. 3502 * @param {string} questionId 3503 */ 3504function updateColors(questionId) 3505{ 3506 var tab = $('#' + questionId).find('table.question'); 3507 var trs = tab.find('tr:visible'); 3508 trs.each(function(i, tr) 3509 { 3510 // fix line colors 3511 $(tr).removeClass('array1').removeClass('array2').addClass('array' + (1 + i % 2)); 3512 }); 3513}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.