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