1function QuickieBar() { 2 3 //local reference to wp jQuery 4 var $ = jQuery; 5 6 var self = this; 7 8 self.previewingOnAdminPage = false; 9 self.preventHidingWithCloseButton = false;//prevents hiding the bar using the close button 10 11 /*Default Options*/ 12 self.options = { 13 14 bar_uuid: 0, //the bar's id 15 16 bar_height: 'thin', // regular || thin || tall || skinny 17 new_tab: 'enabled', // enabled || disabled 18 placement: 'top', // top || bottom 19 devices: 'all', // all || desktoponly || mobileonly 20 attribution: 'hidden', // visible || hidden 21 alignment: 'leftright', // centered || leftright 22 sticky: 'enabled', // enabled || disabled 23 animation: 'slidein', // slidein || none 24 button_style: 'rounded', // rounded || pill || square || outline 25 close_button_visibility: 'onhover', // onhover || always || hidden 26 27 color_bar_background: '#56C4C3', 28 color_bar_text: '#FFFFFF', 29 color_button_background: '#062332', 30 color_button_text: '#FFFFFF', 31 32 bar_text: 'Get the most powerful conversion dropdown for Wordpress {{arrow-right}}', 33 button_text: 'FREE DOWNLOAD {{download}}', 34 35 destination: 'https://quickiebar.com', 36 37 fixed_compatibility: 'off', 38 bar_zindex: '100' 39 }; 40 41 self.init = function(options){ 42 43 if(options){ 44 45 //for each option, update self.options 46 $.each(options, function(index, option){ 47 48 //unescape strings that might contain special characters 49 if(index == 'bar_text' || 50 index == 'button_text' || 51 index == 'subscribe_text' || 52 index == 'bar_html' 53 ){ 54 option = unescape(option); 55 } 56 self.options[index] = option; 57 }); 58 59 } 60 } 61 62 self.initAndCreateBar = function(options){ 63 self.init(options); 64 65 self.createBar(); 66 67 self.bindEventsToBar(); 68 } 69 70 self.initAndShowBar = function(options, isAdminPage){ 71 72 //we have to set up the bar slightly differently for admin page preview 73 if(isAdminPage){ 74 self.previewingOnAdminPage = true; 75 self.preventHidingWithCloseButton = true; 76 } 77 78 self.init(options); 79 80 self.createBar(); 81 82 self.bindEventsToBar(); 83 84 self.show(); 85 } 86 87 self.prepareBarOrButtonText = function(text, removeRightArrows){ 88 if(!text || text == ''){ 89 return ''; 90 } 91 92 //only remove right arrows when page width < 900px 93 if(removeRightArrows && $('body').width() < 900){ 94 text = text.replace(/ {{(.*?)(-right)(.*?)}}/g, ''); 95 } 96 97 //remove {{}} if text includes "-right" so as to not show right arrows on mobile devices 98 99 //find each inserted icon and replace with <i> html 100 return text.replace(/{{(.*?)}}/g, ' <i class="fa fa-$1"></i> '); 101 } 102 103 self.getQuickieBarTopLevelClasses = function(){ 104 var qbClasses = ''; 105 106 //add the associated classes based on bar options to quickiebar div 107 qbClasses += 'qb-bar_height-' + self.options.bar_height + ' '; 108 qbClasses += 'qb-sticky-' + (self.options.fixed_compatibility == 'on' ? 'enabled' : self.options.sticky) + ' ';//overwrite default sticky option if fixed_compatibility mode is on 109 qbClasses += 'qb-placement-' + self.options.placement + ' '; 110 qbClasses += 'qb-attribution-' + self.options.attribution + ' '; 111 qbClasses += 'qb-alignment-' + self.options.alignment + ' '; 112 qbClasses += 'qb-button_style-' + self.options.button_style + ' '; 113 qbClasses += 'qb-close_button_visibility-' + self.options.close_button_visibility + ' '; 114 115 if(self.previewingOnAdminPage){ 116 qbClasses += 'qb-admin-preview '; 117 } 118 119 return qbClasses; 120 } 121 122 //create html block to be placed before #page div that contains all the html for the quickiebar 123 self.craftHtml = function(){ 124 125 var barText = self.options.bar_text ? self.prepareBarOrButtonText(self.options.bar_text, true) : self.prepareBarOrButtonText('Bar Text goes here', true); 126 var buttonText = self.options.button_text ? self.prepareBarOrButtonText(self.options.button_text) : ''; 127 128 $qbHtml = ''; 129 130 $qbHtml = '<div id="quickiebar-show-button" class="show-button-sticky-' + (self.options.fixed_compatibility == 'on' ? 'enabled' : self.options.sticky) + ' show-button-placement-' + self.options.placement + '" style="color:' + self.options.color_bar_text + ';background:' + self.options.color_bar_background + ';z-index:' + self.options.bar_zindex + ';"><div class="show-button" style="color:' + self.options.color_bar_text + ';background:' + self.options.color_bar_background + ';"><i class="fa fa-chevron-down"></i><i class="fa fa-chevron-up"></i></div></div>'; 131
132 $qbHtml += '<div id="quickiebar" class="qb-' + self.options.bar_uuid + ' qb-' + self.options.id + ' qb ' + self.getQuickieBarTopLevelClasses() + '" style="background:' + self.options.color_bar_background + ';z-index:' + self.options.bar_zindex + ';">'; 133 134 $qbHtml += '<div class="hover-background-overlay"></div>'; 135 136 if(self.options.attribution == 'visible'){ 137 $qbHtml += '<a href="https://quickiebar.com/" target="_blank"><div class="qb-attribution ' + (GetLuminance(self.options.color_bar_background) > 200 ? 'qb-attribution-dark' : '') + '"></div></a>'; 138 } 139 140 $qbHtml += '<div class="wrap">'; 141 $qbHtml += '<div class="qb-wrap">'; 142 $qbHtml += '<span class="bar-text" style="color:' + self.options.color_bar_text + ';">' + barText + '</span>'; 143 $qbHtml += '<span class="bar-button" style="' + (buttonText == '' ? 'display:none;' : '') + 'color:' + self.options.color_button_text + ';background:' + self.options.color_button_background + ';border-color:' + self.options.color_button_text + ';">' + buttonText + '</span>'; 144 $qbHtml += '</div>';//end .qb-wrap 145 $qbHtml += '</div>';//end .wrap 146 147 $qbHtml += '<div class="qb-close-button ' + (GetLuminance(self.options.color_bar_background) > 200 ? 'qb-close-button-dark' : '') + '"><i class="fa fa-times-circle-o"></i></div>'; 148 149 $qbHtml += '<a href="' + self.options.destination + '" ' + (self.options.new_tab == 'enabled' && (self.options.destination.indexOf('#') != 0) ? 'target="_blank"' : '') + ' class="link-overlay" style="' + (self.options.destination == '' ? 'display:none;' : '') + '"></a>' 150 151 $qbHtml += '<div class="qb-close-bar"><i class="fa fa-chevron-up"></i></div>'; 152 153 $qbHtml += '</div>';//end #quickiebar 154 155 return $qbHtml; 156 } 157 158 self.createBar = function(){ 159 160 $page = self.getPage(); 161 162 //self.getPage().before(self.craftCSS()); 163 $page.before(self.craftHtml()); 164 165 //TODO implement this / put this in function 166 //$qbReviveHtml = '<div id="quickiebar-revive"><i class="fa fa-bolt"></i></div>'; 167 } 168 169 self.hideAndDestroyBar = function(){ 170 171 self.hide(0, function(){ 172 $('#quickiebar.qb').remove(); 173 }); 174 175 } 176 177 self.bindEventsToBar = function(){ 178 179 //Bind hover functions to show close button & attribution (if applicable) 180 $('#quickiebar.qb').on('mouseover', function(){ 181 $(".qb-attribution").stop().addClass('visible'); 182 $(".qb-close-button").stop().addClass('visible'); 183 }).on('mouseout', function(){ 184 $(".qb-attribution").stop().removeClass('visible'); 185 $(".qb-close-button").stop().removeClass('visible'); 186 }); 187 188 //Bind close functions 189 $('.qb-close-bar,.qb-close-button').click(function(){ 190 if(self.preventHidingWithCloseButton || self.previewingOnAdminPage){ 191 return; 192 } 193 194 self.hide(); 195 }); 196 197 //Bind conversion tracking on bar click 198 $("#quickiebar.qb .link-overlay").click(function(){ 199 self.trackConversion(); 200 //console.log("TRACK CONVERSION"); 201 }); 202 203 //Bind show function on show-button 204 $("#quickiebar-show-button").click(function(){ 205 qb.show(); 206 207 //if we're showing the bar again, we should clear the dismissal tracking 208 qb.resetCurrentBarDismissalTracking(); 209 }); 210 } 211 212 self.getPage = function(){ 213 if(self.previewingOnAdminPage){ 214 return $('html > body'); 215 } 216 else{ 217 return $('html > body'); 218 } 219 } 220 221 self.getFixedHeader = function(){ 222 223 if($('.qb-fixed-header') && $('.qb-fixed-header').length > 0){ 224 return $('.qb-fixed-header'); 225 } 226 227 if($('.qbp-fixed-header') && $('.qbp-fixed-header').length > 0){ 228 return $('.qbp-fixed-header'); 229 } 230 231 if($('header') && $('header').length > 0){ 232 return $('header'); 233 } 234 235 if($('#header') && $('#header').length > 0){ 236 return $('#header'); 237 } 238 239 if($('#masthead') && $('#masthead').length > 0){ 240 return $('#masthead'); 241 } 242 243 if($('.site-header') && $('.site-header').length > 0){ 244 return $('.site-header').first(); 245 } 246 247 //if we can't find it with selectors, the loop through every element in <body> - stopping once we find a position:fixed element and return that. 248 //TODO 249 return false; 250 } 251 252 //Just show the toggle for the bar, not the bar itself (show bar in "minimized" display) 253 self.showBarToggle = function(){ 254 255 if(self.options.placement == 'top'){ 256 $("#quickiebar-show-button").css('margin-top', -24); 257 } 258 else if(self.options.placement == 'bottom'){ 259 $("#quickiebar-show-button").css('margin-bottom', -24); 260 } 261 262 $('#quickiebar-show-button').show(); 263 $("#quickiebar-show-button").stop().animate({'margin-top': 0,'margin-bottom': 0}, 250); 264 } 265 266 self.show = function(){ 267 268 $page = self.getPage(); 269 270 $qbHeight = $('#quickiebar').height(); 271 272 $slideIn = self.options.animation === 'slidein'; 273 274 //if we need to make page adjustments 275 if((self.options.fixed_compatibility == 'on' || self.options.sticky == 'enabled' || self.options.placement == 'bottom' || self.previewingOnAdminPage) && $('body').width() > 900){ 276 277 if(self.options.placement == 'top'){ 278 279 if($slideIn){ 280 $page.addClass('qb-disable-animation').animate({'padding-top': $qbHeight}, 300, 'swing', function(){ 281 $page.removeClass('qb-disable-animation'); 282 }); 283 } 284 else{ 285 $page.addClass('qb-disable-animation'); 286 $page.css('padding-top', $qbHeight); 287 288 //not sure why...but I have to do this after a slight delay 289 setTimeout(function(){ 290 $page.removeClass('qb-disable-animation'); 291 }, 20); 292 } 293 294 //adjust fixed header if required 295 if(self.options.fixed_compatibility == 'on'){ 296 $fixedHeader = self.getFixedHeader(); 297 298 if($fixedHeader){ 299 300 if($slideIn){ 301 $fixedHeader.animate({'margin-top': $qbHeight}, 300, 'swing'); 302 } 303 else{ 304 $fixedHeader.css('margin-top', $qbHeight); 305 } 306 307 } 308 } 309 310 //adjust for WordPress admin top bar if required AND not previewing on Bars page (since we remove the admin bar in this situation) 311 if($('#wpadminbar') && !self.previewingOnAdminPage){ 312 $page.css('padding-top', $qbHeight + $('#wpadminbar').height()); 313 314 $('#quickiebar').css('marginTop', $('#wpadminbar').height()); 315 } 316 317 } 318 else if(self.options.placement === 'bottom'){ 319 $page.css('margin-bottom', $qbHeight); 320 } 321 } 322 323 //Animate the bar itself 324 if($slideIn){ 325 326 $('#quickiebar').stop().slideDown(300); 327 } 328 else{ 329 $('#quickiebar').stop().show(); 330 } 331 332 //Hide the show button if visible 333 $('#quickiebar-show-button').hide(); 334 335 } 336 337 self.hide = function(animationDuration, callback){ 338 339 //track the dismissal first before any other code, just in case errors are thrown 340 //we want to make sure to not show this bar to the user again 341 self.trackDismissal(); 342 343 if(typeof animationDuration == 'undefined'){ 344 animationDuration = 200; 345 } 346 347 $page = self.getPage(); 348 349 $page.addClass('qb-disable-animation').animate({'padding-top': 0, 'margin-bottom': 0}, animationDuration, 'swing', function(){ 350 $page.removeClass('qb-disable-animation'); 351 }); 352 353 $('#quickiebar').stop().slideUp(animationDuration, function(){ 354 //execute callback when bar hidden from page 355 if(typeof callback == 'function'){ 356 callback(); 357 } 358 }); 359 360 //adjust fixed header if required 361 if(self.options.fixed_compatibility == 'on' && self.options.placement == 'top'){ 362 $fixedHeader = self.getFixedHeader(); 363 364 if($fixedHeader){ 365 366 if($slideIn){ 367 $fixedHeader.animate({'margin-top': 0}, 300, 'swing'); 368 } 369 else{ 370 $fixedHeader.css('margin-top', 0); 371 } 372 373 } 374 } 375 376 //Show the show button 377 self.showBarToggle(); 378 379 if(typeof callback === 'function'){ 380 callback(); 381 } 382 383 } 384 385 self.fetchBar = function(callback){ 386 $.ajax({ 387 type: "POST", 388 url: ajaxurl, 389 data: { 390 action: 'qb_public_ajax', 391 endpoint: 'get_bar', 392 qb_public_nonce: QB_PUBLIC_GLOBALS.QB_PUBLIC_NONCE 393 }, 394 success: function(bar){ 395 callback(bar); 396 }, 397 dataType: 'json' 398 }); 399 } 400 401 self.getUserUuid = function(){ 402 var user_uuid = QBGetCookie('qb_user_uuid'); 403 404 if(!user_uuid){ 405 //if no user_uuid created, create it now 406 user_uuid = QBGenerateUuid(); 407 408 //persist uuid to local storage 409 QBSetCookie('qb_user_uuid', user_uuid, 7);//TODO allow user to set the expiration days 410 } 411 412 return user_uuid; 413 } 414 415 self.getBarViews = function(){ 416 417 var bar_views_cookie = QBGetCookie('qb_bar_views'); 418 var bar_views; 419 420 if(!bar_views_cookie){ 421 422 //initialize empty array as bar_views property 423 bar_views = []; 424 425 QBSetCookie('qb_bar_views', JSON.stringify(bar_views), 7); 426 } 427 else{ 428 429 //load bars_viewed from cookie 430 bar_views = JSON.parse(QBGetCookie('qb_bar_views')); 431 } 432 433 return bar_views; 434 435 } 436 437 self.getBarConversions = function(){ 438
439 var bar_conversions_cookie = QBGetCookie('qb_bar_conversions'); 440 var bar_conversions; 441 442 if(!bar_conversions_cookie){ 443 444 //initialize empty array as bar_conversions property 445 bar_conversions = []; 446 447 QBSetCookie('qb_bar_conversions', JSON.stringify(bar_conversions), 7); 448 } 449 else{ 450 451 //load bars_viewed from cookie 452 bar_conversions = JSON.parse(QBGetCookie('qb_bar_conversions')); 453 } 454 455 return bar_conversions; 456 457 } 458 459 self.getBarDismissals = function(){ 460 461 var bar_dismissals_cookie = QBGetCookie('qb_bar_dismissals'); 462 var bar_dismissals; 463 464 if(!bar_dismissals_cookie){ 465 466 //initialize empty array as bar_conversions property 467 bar_dismissals = []; 468 469 QBSetCookie('qb_bar_dismissals', JSON.stringify(bar_dismissals), 7); 470 } 471 else{ 472 473 //load bars_viewed from cookie 474 bar_dismissals = JSON.parse(QBGetCookie('qb_bar_dismissals')); 475 } 476 477 return bar_dismissals; 478 479 } 480 481 self.resetAllTracking = function(){ 482 QBDeleteCookie('qb_user_uuid'); 483 QBDeleteCookie('qb_bar_views'); 484 QBDeleteCookie('qb_bar_conversions'); 485 QBDeleteCookie('qb_bar_dismissals'); 486 } 487 488 self.resetCurrentBarDismissalTracking = function(){ 489 var bar_dismissals = self.getBarDismissals(); 490 491 for(var i = bar_dismissals.length; i >= 0; i--){ 492 if(bar_dismissals[i] == qb.options.bar_uuid){ 493 bar_dismissals.splice(i, 1); 494 } 495 } 496 497 QBSetCookie('qb_bar_dismissals', JSON.stringify(bar_dismissals), 7); 498 } 499 500 self.trackView = function(){ 501 502 var bar_uuid = self.options.bar_uuid; 503 var bar_views = self.getBarViews(); 504 505 //if bar_uuid == 0, don't track the view 506 if(bar_uuid == 0){ 507 return; 508 } 509 510 511 if(bar_views.indexOf(bar_uuid) < 0){ 512 513 //if user hasn't viewed bar yet, track the view to the db then update locally 514 $.ajax({ 515 type: "POST", 516 url: ajaxurl, 517 data: { 518 action: 'qb_public_ajax', 519 endpoint: 'save_view', 520 user_uuid: self.getUserUuid(), 521 bar_uuid: bar_uuid, 522 qb_public_nonce: QB_PUBLIC_GLOBALS.QB_PUBLIC_NONCE 523 }, 524 success: function(){ 525 526 //push the current bar onto the list of viewed bars 527 bar_views.push(bar_uuid); 528 529 //persist viewed bars as cookie 530 QBSetCookie('qb_bar_views', JSON.stringify(bar_views), 7); 531 532 }, 533 dataType: 'json' 534 }); 535 } 536 537 } 538 539 self.trackConversion = function(){ 540 541 var bar_uuid = self.options.bar_uuid; 542 var bar_conversions = self.getBarConversions(); 543 544 //if bar_uuid == 0, don't track the view 545 if(bar_uuid == 0){ 546 return; 547 } 548 549 550 if(bar_conversions.indexOf(bar_uuid) < 0){ 551 552 //if user hasn't converted on the bar yet, track the conversion to the db then update locally 553 $.ajax({ 554 type: "POST", 555 url: ajaxurl, 556 data: { 557 action: 'qb_public_ajax', 558 endpoint: 'save_conversion', 559 user_uuid: self.getUserUuid(), 560 bar_uuid: bar_uuid, 561 qb_public_nonce: QB_PUBLIC_GLOBALS.QB_PUBLIC_NONCE 562 }, 563 success: function(){ 564 565 //push the current bar onto the list of viewed bars 566 bar_conversions.push(bar_uuid); 567 568 //persist viewed bars as cookie 569 QBSetCookie('qb_bar_conversions', JSON.stringify(bar_conversions), 7); 570 571 }, 572 dataType: 'json' 573 }); 574 } 575 576 } 577 578 self.trackDismissal = function(){ 579 var bar_uuid = self.options.bar_uuid; 580 var bar_dismissals = self.getBarDismissals(); 581 582 //if bar_uuid == 0, don't track the view 583 if(bar_uuid == 0){ 584 return; 585 } 586 587 //we don't persist this information to the server... 588 //instead, just updated user's cookie so they are not shown the bar again 589 590 //push the current bar onto the list of viewed bars 591 bar_dismissals.push(bar_uuid); 592 593 //persist viewed bars as cookie 594 QBSetCookie('qb_bar_dismissals', JSON.stringify(bar_dismissals), 7); 595 } 596 597} 598 599jQuery(document).ready(function($){ 600 601 //if qbhide is toggled in URL, don't create & show the quickiebar 602 //this is used on quickiebar.com for previewing the bar on third-party sites 603 if(location.hash.indexOf('qbhide') > -1 || location.href.indexOf('wp-admin/admin.php') > -1 || location.href.indexOf('wp-login.php') > -1){ 604 return; 605 } 606 607 //globally instantiate a new QuickieBar object 608 qb = new QuickieBar(); 609 610 qb.fetchBar(function(bar){ 611 612 //if on admin page 613 614 615 if(!bar || !bar.bar_uuid){//need to check bar_uuid also just in case default qb options come back (depending on php version & debuggin settings, this might happen) 616 //if no bar is live, nothing more to do 617 return; 618 } 619 //immedialy show bar if debug_mode and hash 620 else if(bar.debug_mode == 'on' && location.hash.toLowerCase().indexOf('qbshow') > -1){ 621 qb.initAndShowBar(bar); 622 qb.trackView(); 623 } 624 //if bar that is returned has already been dismissed, show toggle instead of bar 625 else if(qb.getBarDismissals().indexOf(bar.bar_uuid) > -1 && (QB_PUBLIC_GLOBALS.USER_TYPE != 'admin')){ 626 qb.initAndCreateBar(bar);//create the bar but don't show it 627 qb.showBarToggle(); 628 } 629 //more logic to determine whether or not to show bar 630 else{ 631 //if fixed header compatibility mode is on, don't show if on mobile devices (< 900 px) 632 if(bar.fixed_compatibility == 'on' && $('body').width() < 900){ 633 return; 634 } 635 636 if(bar.device_visibility != 'all'){ 637 if(bar.device_visibility == 'desktoponly' && isMobileDevice()
637){ 638 return; 639 } 640 else if(bar.device_visibility == 'mobileonly' && !isMobileDevice()){ 641 return; 642 } 643 } 644 645 qb.initAndShowBar(bar); 646 qb.trackView(); 647 } 648 649 }); 650 651}); 652 653 654/* 655Sample Init Code: 656 657qb.init({ 658 bar_height: 'thin', // regular || thin || tall || skinny 659 new_tab: 'enabled', // true || false 660 placement: 'top', // top || bottom 661 devices: 'all', // all || desktoponly || mobileonly 662 attribution: 'visible', // visible || hidden 663 alignment: 'leftright', // centered || leftright 664 sticky: 'enabled', // true || false 665 animation: 'slidein', // slidein || none 666 button_style: 'rounded', // rounded || pill || square || outline 667 close_button_visibility: 'onhover', // onhover || alwaysshow || alwayshide 668 669 color_bar_background: '#56C4C3', 670 color_bar_text: '#FFFFFF', 671 color_button_background: '#062332', 672 color_button_text: '#FFFFFF', 673 674 bar_text: 'Get the most powerful conversion dropdown for Wordpress {{arrow-right}}', 675 button_text: 'FREE DOWNLOAD {{download}}' 676});*/ 677 678function isMobileDevice(){ 679 var check = false; 680 (function(a,b){if(/(android|bb\d+|meego).+mobile|android|ipad|playbook|silk|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera); 681 return check; 682} 683 684function QBSetCookie(name, value, days) { 685 var d = new Date(); 686 d.setTime(d.getTime() + (days*24*60*60*1000)); 687 var expires = "expires="+d.toUTCString(); 688 document.cookie = name + "=" + value + "; " + expires + '; path=/'; 689} 690 691function QBGetCookie(name) { 692 name += "="; 693 var ca = document.cookie.split(';'); 694 for(var i=0; i<ca.length; i++) { 695 var c = ca[i]; 696 while (c.charAt(0)==' ') c = c.substring(1); 697 if (c.indexOf(name) == 0) return c.substring(name.length, c.length); 698 } 699 return false; 700} 701 702function QBDeleteCookie(name) { 703 if(QBGetCookie(name)){ 704 QBSetCookie(name, '', -1); 705 } 706} 707 708//creates 13 hexidecimal random number as hash / practical "uuid" 709function QBGenerateUuid(){ 710 //return Math.random().toString(36).slice(2); 711 712 var id = []; 713 var hexDigits = "0123456789abcdef"; 714 for(var i = 0;i<13;i++){ 715 id[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); 716 } 717 718 return id.join(""); 719} 720 721 722function ColorLuminance(hex, lum) { 723 724 // validate hex string 725 hex = String(hex).replace(/[^0-9a-f]/gi, ''); 726 if (hex.length < 6) { 727 hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]; 728 } 729 lum = lum || 0; 730 731 // convert to decimal and change luminosity 732 var rgb = "#", c, i; 733 for (i = 0; i < 3; i++) { 734 c = parseInt(hex.substr(i*2,2), 16); 735 c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16); 736 rgb += ("00"+c).substr(c.length); 737 } 738 739 return rgb; 740} 741 742/*http://stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black*/ 743function GetLuminance(hex){ 744 var c = hex.substring(1); // strip # 745 var rgb = parseInt(c, 16); // convert rrggbb to decimal 746 var r = (rgb >> 16) & 0xff; // extract red 747 var g = (rgb >> 8) & 0xff; // extract green 748 var b = (rgb >> 0) & 0xff; // extract blue 749 750 var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709 751 752 return luma 753}
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.