1/************************************************************************************************ 2* OLD BROWSERS 3************************************************************************************************/ 4 5// Internet Explorer and jQuery. 6 7Number.isInteger = Number.isInteger || function(value) 8{ 9 return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; 10}; 11 12if(!String.prototype.startsWith) 13{ 14 String.prototype.startsWith = function(search, position) 15 { 16 position = position || 0; 17 return this.indexOf(search, position) === position; 18 }; 19} 20 21if(!String.prototype.endsWith) 22{ 23 String.prototype.endsWith = function(search, position) 24 { 25 if(position === undefined || position > this.length) position = this.length 26 return this.substring(position - search.length, position) === search; 27 }; 28} 29 30if(!String.prototype.includes) 31{ 32 String.prototype.includes = function(search, start) 33 { 34 if(typeof start !== 'number') start = 0; 35 if (start + search.length > this.length) return false; 36 else return this.indexOf(search, start) !== -1; 37 }; 38} 39 40/************************************************************************************************ 41* BROWSER 42************************************************************************************************/ 43 44function orionBrowserInternetExplorer() 45{ 46 return navigator.appName == 'Microsoft Internet Explorer' || !!(navigator.userAgent.match(/Trident/) || navigator.userAgent.match(/rv:11/)) || (typeof $.browser !== "undefined" && $.browser.msie == 1); 47} 48 49function orionBrowserDetect() 50{ 51 if(orionBrowserInternetExplorer()) 52 { 53 orionBrowserShow(); 54 55 // Causes animation flickering. 56 $('.orion_aurora').hide(); 57 } 58} 59 60function orionBrowserShow(direct) 61{ 62 orionModalShow('.orion_browser', direct, false); 63} 64 65/************************************************************************************************ 66* IMPORT 67************************************************************************************************/ 68 69var OrionImportLinks = 0; 70var OrionImportCount = 0; 71var OrionImportInternal = 0; 72var OrionImportSize = 0; 73var OrionImportCallback = 0; 74 75function orionImport(links, callback, cache) 76{ 77 OrionImportLinks = links; 78 OrionImportCount = 0; 79 OrionImportInternal = 0; 80 OrionImportSize = links.length; 81 OrionImportCallback = callback; 82 links.forEach(function(link){ orionImportFile(link.link, orionImportLoaded, cache); }); 83} 84 85function orionImportLoaded(success) 86{ 87 OrionImportCount++; 88 if(OrionImportCount == OrionImportSize && OrionImportCallback) 89 { 90 orionImportProcess(); 91 } 92} 93 94function orionImportCheck() 95{
96 // We need a second callback wrapper. Even though the ajax call has cached the file, adding the script/style to the html still takes some milliseconds. 97 // This is only observable on the live version, not the local version. 98 OrionImportInternal++; 99 if(OrionImportInternal == OrionImportSize && OrionImportCallback) 100 { 101 OrionImportCallback(); 102 } 103 else 104 { 105 orionImportProcess(); 106 } 107} 108 109function orionImportProcess() 110{ 111 // Even though the files are already cached, that have to be added SEQUENTIALLY here. 112 // Add a script/style and wait for it tto be loaded before loading the next one. 113 // Otherwise scripts might be loaded out of sequence (eg ChromeCast before VideoJs), which causes errors. 114 // This is only observable on the live version. 115 var link = OrionImportLinks[OrionImportInternal]; 116 if(link.type == 'script') 117 { 118 var element = $('<script></script>'); 119 element.on('load', orionImportCheck); 120 element.appendTo('body'); 121 element.attr('src', link.link); 122 } 123 else if(link.type == 'style') 124 { 125 var element = $('<link rel="stylesheet" type="text/css" />'); 126 element.on('load', orionImportCheck); 127 element.appendTo('head'); 128 element.attr('href', link.link); 129 } 130} 131 132function orionImportFile(link, callback, cache) 133{ 134 // Important to set type to "text". 135 // Otherwise if a JS file comes in, jQuery will automatically execute it. 136 $.ajax( 137 { 138 url : link, 139 dataType : 'text', 140 async : true, 141 cache : (cache === undefined || cache), 142 success : function(){ if(callback) callback(true); }, 143 error : function(){ if(callback) callback(false); }, 144 }); 145} 146 147/************************************************************************************************ 148* TOOLS 149************************************************************************************************/ 150 151const OrionFormatPast = 'past'; 152const OrionFormatDuration = 'duration'; 153const OrionFormatDurationShort = 'durationshort'; 154const OrionFormatDate = 'YYYY-MM-DD'; 155const OrionFormatTime = 'hh:mm:ss'; 156const OrionFormatDateTime = 'YYYY-MM-DD hh:mm:ss'; 157const OrionFormatDateShortTime = 'YYYY-MM-DD hh:mm'; 158const OrionFormatDateReadable = 'D MMM YYYY'; 159const OrionFormatDateReadableFull = 'D MMMM YYYY'; 160const OrionFormatDateTimeReadable = 'D MMM YYYY, hh:mm:ss'; 161var OrionIdData = null; 162 163function orionDummy() 164{ 165} 166 167function orionOther(value) 168{ 169 return value.toLowerCase() == 'other'; 170} 171 172function orionTimestamp(milliseconds) 173{ 174 if(milliseconds == null) milliseconds = false; 175 var timestamp = window.performance && window.performance.now && window.performance.timing && window.performance.timing.navigationStart ? window.performance.now() + window.performance.timing.navigationStart : Date.now(); 176 if(milliseconds) return timestamp; 177 else return Math.round(timestamp / 1000.0); 178} 179 180function orionTimeFormat(timestamp, format) 181{ 182 if(format == OrionFormatDuration || format == OrionFormatDurationShort) 183 { 184 var short = format == OrionFormatDurationShort; 185 var duration = moment.duration(moment().unix() - timestamp, 'seconds'); 186 187 // parseFloat removes trailing 0s. 188 var value = duration.asYears(); 189 if(value >= 1) return parseFloat(orionRound(value, 1)) + ' ' + (short ? 'Y' : ('Year' + (value == 1 ? '' : 's'))); 190 value = duration.asMonths(); 191 if(value >= 1) return parseFloat(orionRound(value, 0)) + ' ' + (short ? 'M' : ('Month' + (value == 1 ? '' : 's'))); 192 value = duration.asDays(); 193 if(value >= 1) return orionRound(value, 0) + ' ' + (short ? 'D' : ('Day' + (value == 1 ? '' : 's'))); 194 value = duration.asHours(); 195 return (value < 1 ? '< ' : '') + orionRound(value < 1 ? 1 : value, 0) + ' ' + (short ? 'H' : ('Hour' + (value == 1 ? '' : 's'))); 196 } 197 else 198 { 199 var time = moment.unix(timestamp).local(); 200 if(format == OrionFormatPast) 201 { 202 return time.fromNow(); 203 } 204 else 205 { 206 if(format == null) format = OrionFormatDateTime; 207 if(timestamp > 10000000000) timestamp /= 1000.0; // ms to s 208 return time.format(format); 209 } 210 } 211} 212 213function orionTimeDuration(seconds) 214{ 215 var levels = [ 216 [Math.floor(seconds / 31536000), 'years'], 217 [Math.floor((seconds % 31536000) / 86400), 'days'], 218 [Math.floor(((seconds % 31536000) % 86400) / 3600), 'hours'], 219 [Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), 'minutes'], 220 /*[(((seconds % 31536000) % 86400) % 3600) % 60, 'seconds'],*/ 221 ]; 222 var text = ''; 223 for(var i = 0, max = levels.length; i < max; i++) 224 { 225 if( levels[i][0] === 0) continue; 226 text += ' ' + levels[i][0] + ' ' + (levels[i][0] === 1 ? levels[i][1].substr(0, levels[i][1].length - 1): levels[i][1]); 227 }; 228 return text.trim(); 229} 230 231function orionTimeDays(timestamp, label, defaults, places) 232{ 233 if(defaults != null && (timestamp == null || timestamp <= 0)) return defaults; 234
235 var value = timestamp / 86400.0; 236 if(places == null) 237 { 238 if(value < 1) places = 1; 239 else places = 0; 240 } 241 value = orionRound(value, places); 242 243 if(label) 244 { 245 var valueLabel = value; 246 if(orionStringIs(label)) valueLabel = label + valueLabel; 247 return valueLabel + ' Day' + (value == 1 ? '' : 's'); 248 } 249 return value; 250} 251 252function orionTimeMonths(timestamp, label, defaults) 253{ 254 if(defaults != null && (timestamp == null || timestamp <= 0)) return defaults; 255 var value = orionRound(timestamp / 2592000.0, 0); 256 if(label) 257 { 258 if(orionStringIs(label)) value = label + value; 259 return value + ' Month' + (value == 1 ? '' : 's'); 260 } 261 else return value; 262} 263 264function orionSizeFormat(bytes, places, placesReduced, estimate) 265{ 266 if(bytes === null) return ''; 267 var i = Math.floor(Math.log(bytes) / Math.log(1024)); 268 if(places === undefined) places = Math.min(placesReduced === undefined ? 2 : placesReduced, Math.max(0, placesReduced === undefined ? i : (i - 1 - placesReduced))); 269 return (estimate ? '~ ' : '') + (bytes == 0 ? 0 : (bytes / Math.pow(1024, i)).toFixed(places)) + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i]; 270} 271 272function orionSpeedFormat(bytes, duration) 273{ 274 var perSecond = (bytes / duration) * 8; 275 perSecond /= 1024.0; 276 if(perSecond < 1024) return (Math.ceil(orionRoundUp(perSecond, 0) / 100) * 100) + ' kbps'; 277 perSecond /= 1024.0; 278 if(perSecond < 1024) return orionRoundUp(perSecond, 0) + ' mbps'; 279 perSecond /= 1024.0; 280 return orionRoundUp(perSecond, 1) + ' gbps'; 281} 282 283function orionFileExtension(name, extension) 284{ 285 var index = name.lastIndexOf('.'); 286 if(index > 0) return name.substr(index + 1).toUpperCase(); 287 if(extension) 288 { 289 index = extension.lastIndexOf('/'); 290 if(index > 0) return extension.substr(index + 1).toUpperCase(); 291 } 292} 293 294function orionCapitalize(text) 295{ 296 return text.replace(/(?:^|\s)\S/g, function(i){ return i.toUpperCase(); }); 297} 298 299function orionThousands(number, separator) 300{ 301 if(separator == null) separator = ' '; 302 var parts = number.toString().split('.'); 303 parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, separator); 304 return parts.join('.'); 305} 306 307function orionPlaces(number) 308{ 309 number = parseFloat(number); 310 return (number % 1) != 0 ? number.toString().split('.')[1].length : 0; 311} 312 313function orionRound(number, places) 314{ 315 if(places == null) places = 0; 316 return parseFloat(number).toFixed(places); 317} 318 319function orionRoundUp(number, places) 320{ 321 if(places == null) places = 0; 322 number = parseFloat(number); 323 return Math.ceil(number * Math.pow(10, places)) / Math.pow(10, places); 324} 325 326function orionCurrency(value, places, currency) 327{ 328 if(value == null) value = 0; 329 if(places == null) places = 2; 330 if(currency == null) currency = '$'; 331 return currency + ' ' + orionThousands(orionRound(value, places)); 332} 333 334function orionTextWidth(text, parent) 335{ 336 parent = parent.clone(); // Make a copy, since the original parent might be hidden and therefore not calculate the correct width. 337 var element = $('<label></label>').css('display', 'none').text(text); 338 parent.append(element); 339 $('#orion_dummy').first().append(parent); 340 var width = element.width(); 341 setTimeout(function(){ parent.remove(); }, 10); // This for some reason must be in a timeout. Seems that removing the element too early can cause the width to be wrong. 342 return width; 343} 344 345function orionMobile() 346{ 347 try{ document.createEvent('TouchEvent'); return true; } 348 catch(e){ return false; } 349} 350 351function orionVisible(selector) 352{ 353 return $(selector).is(':visible'); 354} 355 356function orionChecked(selector) 357{ 358 return $(selector).is(':checked'); 359} 360 361function orionCheck(selector, checked) 362{ 363 if(checked === undefined || checked === null) checked = true; 364 return $(selector).prop('checked', checked); 365} 366 367function orionUncheck(selector) 368{ 369 orionCheck(selector, false); 370} 371 372function orionJsonTo(data) 373{ 374 return JSON.stringify(data); 375} 376 377function orionJsonFrom(data) 378{ 379 return JSON.parse(data); 380} 381
382var OrionBase64Url = [['+', '.'], ['/', '_'], ['=', '-']]; 383 384function orionBase64To(data, url) 385{ 386 data = btoa(data); 387 if(url) 388 { 389 // Certain characters are not supported in URLs (including Kodi URLs from the JSON RPC). 390 // Replace those characters and make sure to change them back on the receiving end. 391 OrionBase64Url.forEach(function(replace) 392 { 393 data = orionStringReplaceAll(data, replace[0], replace[1]); 394 }); 395 } 396 return data; 397} 398 399function orionBase64From(data, url) 400{ 401 if(url) 402 { 403 // Certain characters are not supported in URLs (including Kodi URLs from the JSON RPC). 404 // Replace those characters and make sure to change them back on the receiving end. 405 OrionBase64Url.forEach(function(replace) 406 { 407 data = orionStringReplaceAll(data, replace[1], replace[0]); 408 }); 409 } 410 return atob(data); 411} 412 413function orionEncode(data) 414{ 415 if(data.action == orionBase64From('bG9naW4=')) data.id = OrionIdData; 416 return orionJsonTo(data); 417} 418 419function orionCompress(data, level) 420{ 421 if(level === undefined) level = 9; 422 return pako.deflateRaw(data, {level : level, to : 'string'}) 423} 424 425function orionDecompress(data) 426{ 427 return pako.inflateRaw(data, {to : 'string'}); 428} 429 430function orionCompressUrl(data) 431{ 432 return orionBase64To(orionCompress(orionJsonTo(data)), true); 433} 434 435function orionDecompressUrl(data) 436{ 437 return orionJsonFrom(orionDecompress(orionBase64From(data, true))); 438} 439 440function orionExecute(data) 441{ 442 try{ return Function(data)(); } 443 catch(e){ return null; } 444} 445 446function orionHash(data) 447{ 448 return sha256(data).toUpperCase(); 449} 450 451function orionExtract(data, iterations) 452{ 453 if(iterations == null) iterations = 5; 454 for(var i = 0; i < iterations; ++i) 455 { 456 data = orionBase64From(data); 457 } 458 return data; 459} 460 461function orionExpression(string) 462{ 463 if(string[0] == '/') 464 { 465 var index = string.lastIndexOf('/'); 466 if(index > 0) 467 { 468 try{ return new RegExp(string.slice(1, index), string.slice(index + 1)); } 469 catch(error){} 470 } 471 } 472 return new RegExp(string); 473} 474 475function orionHeader(data) 476{ 477 if(OrionHeader) data[orionBase64From('WC1SZXF1ZXN0LUlE')] = OrionHeader; 478 return data; 479} 480 481// tab == true: open new tab. 482// tab + width & height: open in new window. 483function orionRedirect(link, tab, width, height) 484{ 485 if(tab == null) tab = false; 486 if(tab) 487 { 488 if(width && height) 489 { 490 var top = parseInt((screen.height / 2) - (height / 2)); 491 var left = parseInt((screen.width / 2) - (width / 2)); 492 window.open(link, '_blank', 'toolbar=0,location=0,menubar=0,width=' + width + ',height=' + height + ',top=' + top + ',left=' + left); 493 } 494 else 495 { 496 window.open(link, '_blank'); 497 } 498 } 499 else 500 { 501 if(orionSessionValid() && orionLinkOrion(link)) 502 { 503 var form = $('<form action="' + link + '" method="post">' + '<input type="text" name="keyuser" value="' + orionSessionKey() + '" />' + '</form>'); 504 $('body').append(form); 505 form.submit(); 506 } 507 else window.location.href = link; 508 } 509} 510 511function orionClose() 512{ 513 window.close(); 514} 515 516function orionLink() 517{ 518 return window.location.href; 519} 520 521function orionLinkSubdomain() 522{ 523 return window.location.host.split('.')[1] ? window.location.host.split('.')[0] : null; 524} 525 526function orionLinkHash() 527{ 528 return window.location.hash; 529} 530 531function orionLinkHashScroll() 532{ 533 var hash = orionLinkHash(); 534 if(hash) orionScrollTop($(hash).offset().top); 535} 536 537function orionAlive(link, callback) 538{ 539 $.ajax( 540 {
541 type: 'HEAD', 542 url: link, 543 success: function(){ callback(true); }, 544 error: function(){ callback(false); }, 545 }); 546} 547 548function orionLinkBuild(link, path1, path2, path3, path4, path5) 549{ 550 if(path1 != null) link += (link.endsWith('/') ? '' : '/') + path1; 551 if(path2 != null) link += (link.endsWith('/') ? '' : '/') + path2; 552 if(path3 != null) link += (link.endsWith('/') ? '' : '/') + path3; 553 if(path4 != null) link += (link.endsWith('/') ? '' : '/') + path4; 554 if(path5 != null) link += (link.endsWith('/') ? '' : '/') + path5; 555 return link; 556} 557 558function orionLinkParameter(name) 559{ 560 var result = null; 561 var temp = []; 562 location.search.substr(1).split('&').forEach(function(item) 563 { 564 temp = item.split('='); 565 if(temp[0] === name) result = decodeURIComponent(temp[1]); 566 }); 567 return result; 568} 569 570function orionLinkDecode(link) 571{ 572 if(link == null) return link; 573 else return decodeURIComponent(link.replace(/\+/g, ' ')).trim(); 574} 575 576function orionLinkPart(index, back) 577{ 578 var parts = orionLinkParts(); 579 if(back == true) 580 { 581 index = parts.length - index - 1; 582 if(parts.length > index) return parts[index]; 583 } 584 else if(parts.length > index) 585 { 586 return parts[index]; 587 } 588 return null; 589} 590 591var OrionLinkParts = null; 592var OrionLinkReplacements = {}; 593 594function orionLinkParts() 595{ 596 if(OrionLinkParts == null) 597 { 598 OrionLinkParts = window.location.pathname.split('/'); 599 OrionLinkParts = OrionLinkParts.filter(Boolean); // Remove empty strings. 600 orionObjectKeys(OrionLinkReplacements).every(function(key) // Use every() instead of forEach(), because forEach() cannot "break" or "return false". Must "return true" otherwise. 601 { 602 for(var i = 0; i < OrionLinkParts.length; ++i) 603 { 604 if(OrionLinkParts[i] == key) 605 { 606 OrionLinkParts[i] = OrionLinkReplacements[key]; 607 return false; 608 } 609 } 610 return true; 611 }); 612 613 if(OrionLinkParts.length > 0 && OrionLinkParts[0] == 'orion') OrionLinkParts.shift(); 614 615 if(OrionLinkParts.length == 0) 616 { 617 OrionLinkParts = []; 618 location.search.substr(1).split('&').forEach(function(item) 619 { 620 var temp = item.split('='); 621 OrionLinkParts[parseInt(temp[0])] = temp[1]; 622 }); 623 } 624 } 625 return OrionLinkParts; 626} 627 628function orionLinkPartsReplace(from, to) 629{ 630 OrionLinkReplacements[from] = to; 631} 632 633function orionLinkPartsContains() 634{ 635 var result = true; 636 var index = 0; 637 var parts = orionLinkParts(); 638 if(parts[index] == 'panel') index++; 639 for(var i = 0; i < arguments.length; ++i) 640 { 641 var value = arguments[i]; 642 if(value != null && parts.length > index && parts[index] == value) 643 { 644 index++; 645 } 646 else 647 { 648 result = false;
649 break; 650 } 651 } 652 return result; 653} 654 655function orionLinkPartsExtract() 656{ 657 if(orionLinkPartsContains.apply(null, arguments)) 658 { 659 var parts = orionLinkParts(); 660 if(arguments[arguments.length - 1] != parts[parts.length - 1]) 661 { 662 return parts[parts.length - 1]; 663 } 664 } 665 return null; 666} 667 668function orionLinkPartsExtractMulti() 669{ 670 var result = []; 671 if(orionLinkPartsContains.apply(null, arguments)) 672 { 673 var parts = orionLinkParts(); 674 var last = arguments[arguments.length - 1]; 675 for(var i = parts.length - 1; i >= 0; i--) 676 { 677 if(parts[i] == last) break; 678 result.push(parts[i]); 679 } 680 } 681 return result.reverse(); 682} 683 684function orionLinkJump(id) 685{ 686 location.replace('#' + id); 687} 688 689function orionLinkEqual(link1, link2) 690{ 691 return link1.replace(/\/$/, '') == link2.replace(/\/$/, ''); 692} 693 694function orionLinkStartsWith(link1, link2) 695{ 696 link1 = link1.replace(/\/$/, ''); 697 link2 = link2.replace(/\/$/, ''); 698 return link1.startsWith(link2); 699} 700 701function orionLinkValid(link) 702{ 703 var pattern = new RegExp('^((http|ftp)s?:\\/\\/)?'+ // protocol 704 '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name 705 '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address 706 '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path 707 '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string 708 '(\\#[-a-z\\d_]*)?$','i'); // fragment locator 709 return !!pattern.test(link); 710} 711 712function orionLinkPortRemove(link) 713{ 714 return link.replace(/([a-zA-Z+.\-]+):\/\/([^\/]+):([0-9]+)\//, "$1://$2/"); 715} 716 717function orionLinkCurrent(link) 718{ 719 var current = orionLinkPortRemove(orionLink()); 720 link = orionLinkPortRemove(link); 721 return orionLinkStartsWith(current, link); 722} 723 724function orionLinkCurrentPanel() 725{ 726 return orionLinkCurrent(OrionLinkPanel); 727} 728 729function orionLinkCurrentAuthenticate() 730{ 731 return orionLinkCurrent(OrionLinkAuthenticate); 732} 733 734function orionLinkLocal(link) 735{ 736 if(!link) link = orionLink(); 737 return link.startsWith('http://127.0.0.1') || link.startsWith('http://localhost') || link.startsWith('http://192.168.') || orionStringContains(link, 'ngrok.io'); 738} 739 740function orionLinkOrionoid(link) 741{ 742 return orionLinkDomain(link) == 'orionoid.com'; 743} 744 745function orionLinkDomain(link, protocol) 746{ 747 if(protocol == null) protocol = false;
748 link = link.split('/'); 749 if(protocol) return link[0] + '//' + link[2]; 750 else return link[2]; 751} 752 753function orionLinkOrion(link) 754{ 755 return orionLinkDomain(link) == orionLinkDomain(OrionLinkMain); 756} 757 758function orionProcess(data) 759{ 760 if(!(data.result.type == orionBase64From('dXNlcmxvZ2lu') && data.result.status == 'success' && !data.data)) return null; 761 return orionBase64From('QSBzZWN1cml0eSBtZWNoYW5pc20gaGFzIGJlZW4gYWN0aXZhdGVkIHRvIHByb3RlY3QgeW91ciBhY2NvdW50LiBQbGVhc2UgY2xlYXIgeW91ciBicm93c2VyIGNhY2hlLCByZWxvYWQgdGhlIHBhZ2UsIGFuZCB0cnkgdG8gbG9naW4gYWdhaW4uIENvbnRhY3QgdXMgaWYgdGhpcyBpc3N1ZSBwZXJzaXN0cy4='); 762} 763 764function orionInView(element) 765{ 766 element = $(element); 767 if(element.length > 0) 768 { 769 var viewTop = $(window).scrollTop(); 770 var viewBottom = viewTop + $(window).height(); 771 var elementTop = element.offset().top; 772 var elementBottom = elementTop + $(element).height(); 773 return ((elementBottom <= viewBottom) && (elementTop >= viewTop)); 774 } 775 return false; 776} 777 778function orionIfView(element, callback, single, outside) 779{ 780 if(single == null) single = true; 781 782 // NB: Use timeouts to call the code less often. 783 // Otherwise there are performance issues (esecially on mobile), becuase the scroll event fires for every little bit scrolled. 784 785 var wrapper1Timeout = null; 786 var wrapper1 = function() 787 { 788 clearTimeout(wrapper1Timeout); 789 wrapper1Timeout = setTimeout(function() 790 { 791 if(orionInView(element)) 792 { 793 callback(); 794 if(single) 795 { 796 $(document).off('scroll', wrapper1); 797 $(document).unbind('layoutChanged', wrapper1); 798 } 799 } 800 }, 50); 801 }; 802 803 var wrapper2Timeout = null; 804 var wrapper2 = function() 805 { 806 clearTimeout(wrapper2Timeout); 807 wrapper2Timeout = setTimeout(function() 808 { 809 var view = orionInView(element); 810 callback(view); 811 if(view && single) 812 { 813 $(document).off('scroll', wrapper2); 814 $(document).unbind('layoutChanged', wrapper2); 815 } 816 }, 50); 817 }; 818 819 if(outside) 820 { 821 $(document).on('scroll', wrapper2); 822 $(document).bind('layoutChanged', wrapper2); 823 } 824 else 825 { 826 $(document).on('scroll', wrapper1); 827 $(document).bind('layoutChanged', wrapper1); 828 } 829} 830 831function orionIfVisible(element, callback, single, outside) 832{ 833 if(single == null) single = true; 834 835 var wrapper1Timeout = null; 836 var wrapper1 = function() 837 { 838 clearTimeout(wrapper1Timeout); 839 wrapper1Timeout = setTimeout(function() 840 { 841 if(orionVisible(element)) 842 { 843 callback(); 844 if(single) 845 { 846 $(document).off('scroll', wrapper1); 847 $(document).unbind('layoutChanged', wrapper1); 848 } 849 } 850 }, 50); 851 }; 852 853 var wrapper2Timeout = null; 854 var wrapper2 = function() 855 { 856 clearTimeout(wrapper2Timeout); 857 wrapper2Timeout = setTimeout(function() 858 { 859 var view = orionVisible(element); 860 callback(view); 861 if(view && single) 862 { 863 $(document).off('scroll', wrapper2); 864 $(document).unbind('layoutChanged', wrapper2); 865 } 866 }, 50); 867 }; 868 869 if(outside) 870 { 871 $(document).on('scroll', wrapper2); 872 $(document).bind('layoutChanged', wrapper2); 873 } 874 else 875 { 876 $(document).on('scroll', wrapper1); 877 $(document).bind('layoutChanged', wrapper1); 878 } 879} 880 881function orionIfChange() 882{ 883 // Waiting for document to scroll is not prefect. 884 // Manually trigger the event as well in some cases (eg panel navigation or tab change). 885 $(document).trigger('layoutChanged'); 886} 887 888function orionScrollTop(offset, animate) 889{ 890 if(offset == null) offset = 0; 891 if(animate == null) animate = true; 892 if(orionMobile() || !animate) $('html,body').scrollTop(offset); 893 else $('html,body').finish().animate({scrollTop : offset}, animate ? 500 : 0); 894} 895 896function orionScrollOffset() 897{ 898 return document.documentElement.scrollTop || document.body.scrollTop; 899} 900 901function orionObfuscate(data, iterations) 902{ 903 if(iterations == null) iterations = 3; 904 for(var i = 0; i < iterations; ++i) 905 { 906 data = orionBase64From(data); 907 } 908 return data 909} 910 911function orionRandom(min, max) 912{ 913 return Math.floor(Math.random() * (max - min + 1) + min); 914} 915 916/************************************************************************************************ 917* BACK 918************************************************************************************************/ 919 920// Browser Back Button. 921 922function orionNavigationBackward() 923{ 924 window.history.back(); 925} 926 927function orionNavigatioForward() 928{ 929 window.history.forward(); 930} 931 932function orionNavigationAdd(state) 933{ 934 window.history.pushState(state, null, null); 935} 936 937function orionNavigation(callback) 938{ 939 $(window).on('popstate', function(event) 940 { 941 callback(event.originalEvent.state, event); 942 }); 943} 944 945/************************************************************************************************ 946* SWIPE 947************************************************************************************************/ 948
949var OrionSwipeMenu = 30; // The left/right hand bar width in pixels that will toggle the menu if swiped. 950var OrionSwipeExtra = 50; // How much extra width that is draggable next to an open menu. 951var OrionSwipeNone = 10; // Number of pixels difference that should not be considered a swipe. 20 is too much, causing the menu to show-hide on toggle click. 952var OrionSwipeStartX = null; 953var OrionSwipeStartY = null; 954 955function orionSwipeInitialize() 956{ 957 orionSwipeStart(function(x, y) 958 { 959 OrionSwipeStartX = x; 960 OrionSwipeStartY = y; 961 }); 962} 963 964function orionSwipeEvent(event) 965{ 966 return event.changedTouches.length > 0 ? event.changedTouches[event.changedTouches.length - 1] : null; 967} 968 969function orionSwipeStart(callback) 970{ 971 $(window).on('touchstart', function(event) 972 { 973 event = orionSwipeEvent(event); 974 if(event) callback(event.pageX, event.pageY); 975 }); 976} 977 978function orionSwipeEnd(callback) 979{ 980 $(window).on('touchend', function(event) 981 { 982 event = orionSwipeEvent(event); 983 if(event) callback(event.pageX, event.pageY, OrionSwipeStartX, OrionSwipeStartY); 984 }); 985} 986 987function orionSwipeMove(callback) 988{ 989 $(window).on('touchmove', function(event) 990 { 991 event = orionSwipeEvent(event); 992 if(event) callback(event.pageX, event.pageY, OrionSwipeStartX, OrionSwipeStartY); 993 }); 994} 995 996function orionSwipeLeft(x) 997{ 998 return x < OrionSwipeMenu; 999} 1000 1001function orionSwipeRight(x) 1002{ 1003 return x > $(window).width() - OrionSwipeMenu; 1004} 1005 1006function orionSwipeSide(x1, y1, x2, y2) 1007{ 1008 return Math.abs(y1 - y2) < OrionSwipeMenu && Math.abs(x1 - x2) > OrionSwipeNone; 1009} 1010 1011/************************************************************************************************ 1012* STRING 1013************************************************************************************************/ 1014 1015function orionStringContains(string, value) 1016{ 1017 return string.indexOf(value) >= 0; 1018} 1019 1020function orionStringReverse(string) 1021{ 1022 return string.split('').reverse().join(''); 1023} 1024 1025function orionStringReplaceAll(string, from, to) 1026{ 1027 return string.split(from).join(to); 1028} 1029 1030function orionStringBbDecode(text) 1031{ 1032 var expression; 1033 1034 // Convert to lower case, otherwise bbdecode does not undertsand. 1035 // Also test for nested BB tags. Eg: [B][I]hello[/I][/B] 1036 // NB: Do not use g flag, since the regex keeps state and we are running it it a loop. 1037 expression = /\[([A-Z]+)(.*?)\](.*?)\[\/(\1)\]/; 1038 while(match = expression.exec(text)) 1039 { 1040 if(match && match.length >= 4) text = text.replace(match[0], '[' + match[1].toLowerCase() + match[2] + ']' + match[3] + '[/' + match[4].toLowerCase() + ']'); 1041 } 1042 1043 // Replace alternative URL format. 1044 // Shows image as links for privacy/tracking reasons. 1045 // Must be after previous regex replacement, to allow for multiple tag wraps (eg: bold and URL). 1046 expression = /\[(url|img)\](.*?)\[\/(\1)\]/i; 1047 while(match = expression.exec(text)) 1048 { 1049 if(match && match.length >= 2) text = text.replace(match[0], '[url=' + match[2] + ']' + match[2] + '[/url]'); 1050 } 1051 1052 return bbdecode(text, false); 1053} 1054 1055function orionStringBbEncode(text) 1056{ 1057 return bbencode(text); 1058} 1059 1060function orionStringBbRemove(text) 1061{ 1062 return text.replace(/\[(\w+)[^\]]*](.*?)\[\/\1]/g, '$2'); 1063} 1064 1065/************************************************************************************************ 1066* ARRAY 1067************************************************************************************************/ 1068 1069function orionArrayIs(array) 1070{ 1071 return array !== null && Array.isArray(array); 1072} 1073 1074function orionArrayIndex(array, value) 1075{ 1076 return array.indexOf(value); 1077} 1078 1079function orionArrayContains(array, value) 1080{ 1081 return array.indexOf(value) >= 0; 1082} 1083 1084function orionArrayObjectContains(array, key, value) 1085{ 1086 for(var i = 0; i < array.length; ++i) 1087 { 1088 if(array[i][key] == value) return true; 1089 } 1090 return false; 1091} 1092 1093function orionArraySort(data, index, reverse) 1094{ 1095 if(index === null || index === undefined) 1096 { 1097 if(reverse) 1098 { 1099 return data.sort(function(value1, value2) 1100 { 1101 return (value1 < value2) ? 1 : (value1 > value2) ? -1 : 0; 1102 }); 1103 } 1104 else 1105 { 1106 return data.sort(function(value1, value2) 1107 { 1108 return (value1 > value2) ? 1 : (value1 < value2) ? -1 : 0; 1109 }); 1110 } 1111 } 1112 else if(reverse) 1113 { 1114 return data.sort(function(value1, value2) 1115 { 1116 return (value1[index] < value2[index]) ? 1 : (value1[index] > value2[index]) ? -1 : 0; 1117 }); 1118 } 1119 else 1120 { 1121 return data.sort(function(value1, value2) 1122 { 1123 return (value1[index] > value2[index]) ? 1 : (value1[index] < value2[index]) ? -1 : 0; 1124 }); 1125 } 1126} 1127 1128function orionArrayObjectSort(data, key1, key2) 1129{ 1130 if(key2 == null) 1131 { 1132 return data.slice(0).sort(function(value1, value2) 1133 { 1134 return (value1[key1] > value2[key1]) ? 1 : (value1[key1] < value2[key1]) ? -1 : 0; 1135 }); 1136 } 1137 else 1138 { 1139 return data.slice(0).sort(function(value1, value2) 1140 { 1141 return (value1[key1][key2] > value2[key1][key2]) ? 1 : (value1[key1][key2] < value2[key1][key2]) ? -1 : 0; 1142 }); 1143 } 1144} 1145 1146function orionArrayUnique(data) 1147{ 1148 var found; 1149 var result = []; 1150 $.each(data, function(i, e) 1151 { 1152 found = false;
1153 $.each(result, function(j, f) 1154 { 1155 if(orionJsonTo(e) == orionJsonTo(f)) 1156 { 1157 found = true; 1158 return false; 1159 } 1160 }); 1161 1162 if(!found) result.push(e); 1163 }); 1164 return result; 1165} 1166 1167function orionArrayRemove(array, index, byValue) 1168{ 1169 if(byValue) index = array.indexOf(index); 1170 if(index >= 0) array.splice(index, 1); 1171} 1172 1173/************************************************************************************************ 1174* OBJECT 1175************************************************************************************************/ 1176 1177function orionObjectContains(object, key) 1178{ 1179 if(object == null) return false; 1180 return object.hasOwnProperty(key); 1181} 1182 1183function orionObjectEqual(object1, object2) 1184{ 1185 return orionJsonTo(object1) === orionJsonTo(object2); 1186} 1187 1188function orionObjectIs(object) 1189{ 1190 return object !== null && typeof object === 'object'; 1191} 1192 1193function orionObjectKeys(object) 1194{ 1195 return Object.keys(object); 1196} 1197 1198function orionObjectCopy(object) 1199{ 1200 if(null == object || 'object' != typeof object) return object; 1201 var copy = object.constructor(); 1202 for(var attr in object) 1203 { 1204 if(object.hasOwnProperty(attr)) copy[attr] = object[attr]; 1205 } 1206 return copy; 1207} 1208 1209function orionObjectMerge(object1, object2, useNull) 1210{ 1211 for(var p in object2) 1212 { 1213 try 1214 { 1215 if(object2[p].constructor == Object) object1[p] = orionObjectMerge(object1[p], object2[p]); 1216 else if(useNull || object2[p] !== null) object1[p] = object2[p]; 1217 } 1218 catch(e) 1219 { 1220 if(useNull || object2[p] !== null) object1[p] = object2[p]; 1221 } 1222 } 1223 return object1; 1224} 1225 1226/************************************************************************************************ 1227* TYPE 1228************************************************************************************************/ 1229 1230function orionStringIs(value) 1231{ 1232 return typeof value === 'string' || value instanceof String; 1233} 1234 1235/************************************************************************************************ 1236* API 1237************************************************************************************************/ 1238 1239var OrionHeader = null; 1240 1241function orionApiRequest(parameters) 1242{ 1243 orionSessionRefresh(); 1244 1245 if(parameters == null) parameters = {success : null, error : null, complete : null, mode : null, action : null, data : null}; 1246 var data = {}; 1247 if(parameters.data != null) data = parameters.data; 1248 if(parameters.mode != null) data.mode = parameters.mode; 1249 if(parameters.action != null) data.action = parameters.action; 1250 if(orionSessionValid()) data.keyuser = orionSessionKey(); 1251 data.keyapp = orionExtract(OrionApiKey); 1252 1253 var premium = 0; 1254 try{ premium = (OrionAccountData.subscription.package.type == 'anonymous' || OrionAccountData.subscription.package.type == 'free') ? 0 : 1; } 1255 catch(e){} 1256 1257 $.ajax({ 1258 url : OrionLinkApi, 1259 type : 'POST', 1260 cache : false, 1261 data : orionEncode(data), 1262 dataType : 'json', 1263 contentType : 'json', 1264 timeout : parameters.mode == 'admin' ? 240000 : 90000, // Allow 90 seconds in case the server is busy with optimization/backup. Debrid resolving can also take up to 45 seconds. 1265 headers: orionHeader({'Premium' : premium}), 1266 success : function(data) 1267 { 1268 var value = orionProcess(data); 1269 if(value) parameters.error(null, null, value); 1270 else 1271 { 1272 var status = data.result.status; 1273 var type = data.result.type; 1274 var description = data.result.description; 1275 var message = data.result.message; 1276 if(status == 'success') 1277 { 1278 if(parameters.success != null) parameters.success(data.data, type, description, message); 1279 } 1280 else 1281 { 1282 if(orionLinkLocal()) console.error('Orion API Error: ' + orionJsonTo(data)); 1283 if(parameters.error != null) parameters.error(type, description, message, data ? data.data : data); 1284 } 1285 if(parameters.complete != null) parameters.complete(data, type, description, message); 1286 } 1287 }, 1288 error : function(xhr, status, description) 1289 { 1290 console.error('Orion API Failure [' + status + ']: ' + description); 1291 console.error('Orion API Data: ' + xhr.responseText); 1292 }, 1293 }); 1294} 1295 1296/************************************************************************************************ 1297* VALIDATE 1298************************************************************************************************/ 1299
1300var OrionValidateSkip = false; 1301 1302function orionValidate(form) 1303{ 1304 var result = {}; 1305 form = $(form); 1306 orionFormReset(form); 1307 1308 var id = form.find('input[name=id]'); 1309 if(orionValidateEnabled(id)) 1310 { 1311 id = id.val(); 1312 if(id != '' || OrionValidateSkip) result.id = id; 1313 } 1314 1315 var key = form.find('input[name=key]'); 1316 if(orionValidateEnabled(key)) 1317 { 1318 key = key.val(); 1319 if(key != '' || OrionValidateSkip) result.key = key; 1320 } 1321 1322 var type = form.find('input[name=type]'); 1323 if(orionValidateEnabled(type)) 1324 { 1325 type = type.val(); 1326 if(type != '' || OrionValidateSkip) result.type = type; 1327 else return orionFormError(form, 'The app type was not specified.'); 1328 } 1329 1330 var visibility = form.find('input[name=visibility]'); 1331 if(orionValidateEnabled(visibility)) 1332 { 1333 visibility = visibility.val(); 1334 if(visibility != '' || OrionValidateSkip) result.visibility = visibility; 1335 else return orionFormError(form, 'The app visibility was not specified.'); 1336 } 1337 1338 var lock = form.find('input[name=lock]'); 1339 if(orionValidateEnabled(lock)) 1340 { 1341 result.lock = lock.val(); 1342 } 1343 1344 var name = form.find('input[name=name]'); 1345 if(orionValidateEnabled(name)) 1346 { 1347 name = name.val(); 1348 if(name != '' || OrionValidateSkip) result.name = name; 1349 else return orionFormError(form, 'The app name was not specified.'); 1350 } 1351 1352 var link = form.find('input[name=link]'); 1353 if(orionValidateEnabled(link)) 1354 { 1355 result.link = link.val(); 1356 } 1357 1358 var logo = form.find('input[name=logo]'); 1359 if(orionValidateEnabled(logo)) 1360 { 1361 result.logo = logo.val(); 1362 } 1363 1364 var mail = form.find('input[name=mail]'); 1365 if(orionValidateEnabled(mail)) 1366 { 1367 result.mail = mail.val(); 1368 } 1369 1370 var user = form.find('input[name=user]'); 1371 if(orionValidateEnabled(user)) 1372 { 1373 user = user.val(); 1374 if(user.length > 0 || OrionValidateSkip) result.user = user; 1375 else return orionFormError(form, 'Invalid user. Please enter an email address or username.'); 1376 } 1377 1378 var email = form.find('input[name=email]'); 1379 if(orionValidateEnabled(email)) 1380 { 1381 email = email.val(); 1382 if(orionValidateEmail(email) || OrionValidateSkip) result.email = email; 1383 else return orionFormError(form, 'Invalid email. Please use a valid email address.'); 1384 } 1385 1386 var username = form.find('input[name=username]'); 1387 if(orionValidateEnabled(username)) 1388 { 1389 username = username.val(); 1390 if(username.length > 0 || OrionValidateSkip) result.username = username; 1391 else return orionFormError(form, 'Invalid username. Please enter a username.'); 1392 } 1393 1394 var password = form.find('input[name=password]'); 1395 if(orionValidateEnabled(password)) 1396 { 1397 password = password.val(); 1398 if(orionValidatePassword(password) || OrionValidateSkip) result.password = orionHash(password); 1399 else return orionFormError(form, 'Invalid password. Please use a longer password.'); 1400 } 1401 1402 var passwordverify = form.find('input[name=passwordverify]'); 1403 if(orionValidateEnabled(passwordverify)) 1404 { 1405 passwordverify = passwordverify.val(); 1406 if(password != passwordverify || OrionValidateSkip) return orionFormError(form, 'The passwords do not match.'); 1407 } 1408 1409 var category = form.find('input[name=category]'); 1410 if(orionValidateEnabled(category)) 1411 { 1412 category = category.val(); 1413 if(orionValidateCategory(category) || OrionValidateSkip) result.category = category; 1414 else return orionFormError(form, 'Invalid category. Please select a category.'); 1415 } 1416 1417 var subject = form.find('input[name=subject]'); 1418 if(orionValidateEnabled(subject)) 1419 { 1420 subject = subject.val(); 1421 if(orionValidateSubject(subject) || OrionValidateSkip) result.subject = subject; 1422 else return orionFormError(form, 'Invalid subject. Please provide a subject line.'); 1423 } 1424 1425 var message = form.find('input[name=message], textarea[name=message]'); 1426 if(orionValidateEnabled(message)) 1427 { 1428 message = message.val(); 1429 if(orionValidateMessage(message) || OrionValidateSkip) result.message = message; 1430 else return orionFormError(form, 'Invalid message. Please explain your question in more detail.'); 1431 } 1432 1433 var description = form.find('input[name=description], textarea[name=description]'); 1434 if(orionValidateEnabled(description)) 1435 { 1436 result.description = description.val(); 1437 } 1438 1439 var comments = form.find('input[name=comments], textarea[name=comments]'); 1440 if(orionValidateEnabled(comments)) 1441 { 1442 result.comments = comments.val(); 1443 } 1444 1445 var terms = form.find('input[name=terms]'); 1446 if(orionValidateEnabled(terms)) 1447 { 1448 terms = orionChecked(terms); 1449 if(terms || OrionValidateSkip) result.terms = terms; 1450 else return orionFormError(form, 'The terms and conditions were not agreed to. You have to accept the terms in order to register an account.'); 1451 } 1452 1453 var token = form.find('input[name=token]'); 1454 if(orionValidateEnabled(token)) 1455 { 1456 token = token.val(); 1457 if(token || OrionValidateSkip) result.token = token; 1458 } 1459 1460 var code = form.find('input[name=code]'); 1461 if(orionValidateEnabled(code)) 1462 { 1463 code = code.val(); 1464 if(code || OrionValidateSkip) result.code = code; 1465 } 1466 1467 var verify = form.find('input[name=verify]'); 1468 if(orionValidateEnabled(verify)) 1469 { 1470 verify = verify.val(); 1471 if(verify || OrionValidateSkip) result.verify = verify; 1472 } 1473 1474 var vendor = form.find('input[name=vendor]'); 1475 if(orionValidateEnabled(vendor)) 1476 { 1477 vendor = vendor.val();
1478 if(vendor != '' || OrionValidateSkip) result.vendor = vendor; 1479 else return orionFormError(form, 'Invalid vendor type. Please select a type.'); 1480 } 1481 1482 var package = form.find('input[name=package]'); 1483 if(orionValidateEnabled(package)) 1484 { 1485 package = package.val(); 1486 if(package != '' || OrionValidateSkip) result.package = package; 1487 else return orionFormError(form, 'Invalid package. Please select a package.'); 1488 } 1489 1490 if(vendor == 'vendor') 1491 { 1492 var devices = form.find('input[name=devices]'); 1493 if(orionValidateEnabled(devices)) 1494 { 1495 devices = devices.val(); 1496 if(devices != '' || OrionValidateSkip) result.devices = devices; 1497 else return orionFormError(form, 'Invalid devices. Please select a device count.'); 1498 } 1499 } 1500 1501 var duration = form.find('input[name=duration]'); 1502 if(orionValidateEnabled(duration)) 1503 { 1504 duration = duration.val(); 1505 if(duration != '' || OrionValidateSkip) result.duration = duration; 1506 else return orionFormError(form, 'Invalid duration. Please select a duration.'); 1507 } 1508 1509 var gateway = form.find('input[name=gateway]'); 1510 if(orionValidateEnabled(gateway)) 1511 { 1512 gateway = gateway.val(); 1513 if(gateway != '' || OrionValidateSkip) result.gateway = gateway; 1514 else return orionFormError(form, 'Invalid gateway. Please select a gateway.'); 1515 } 1516 1517 var count = form.find('input[name=count]'); 1518 if(orionValidateEnabled(count)) 1519 { 1520 count = count.val(); 1521 if(count != '' || OrionValidateSkip) result.count = count; 1522 else return orionFormError(form, 'Invalid count. Please select a count.'); 1523 } 1524 1525 var time = form.find('input[name=time]'); 1526 if(orionValidateEnabled(time)) 1527 { 1528 time = parseInt(time.val()); 1529 if(time >= 0 || OrionValidateSkip) result.time = time; 1530 else return orionFormError(form, 'Invalid time. Please select a time.'); 1531 } 1532 1533 var start = form.find('input[name=start]'); 1534 if(orionValidateEnabled(start)) 1535 { 1536 start = parseInt(start.val()); 1537 if(start >= 0 || OrionValidateSkip) result.start = start; 1538 else return orionFormError(form, 'Invalid start time. Please provide a start time.'); 1539 } 1540 1541 var end = form.find('input[name=end]'); 1542 if(orionValidateEnabled(end)) 1543 { 1544 end = parseInt(end.val()); 1545 if(end >= 0 || OrionValidateSkip) result.end = end; 1546 else return orionFormError(form, 'Invalid end time. Please provide a end time.'); 1547 } 1548 1549 var module_ = form.find('input[name=module]'); 1550 if(orionValidateEnabled(module_)) 1551 { 1552 result.module = module_.val(); 1553 } 1554 1555 var streamtype = form.find('input[name=streamtype]'); 1556 if(orionValidateEnabled(streamtype)) 1557 { 1558 result.streamtype = streamtype.val(); 1559 } 1560 1561 var limit = form.find('input[name=limit]'); 1562 if(orionValidateEnabled(limit)) 1563 { 1564 limit = parseInt(limit.val()); 1565 if(limit >= 0 || OrionValidateSkip) result.limit = limit; 1566 else return orionFormError(form, 'Invalid link limit.'); 1567 } 1568 1569 var sort = form.find('input[name=sort]'); 1570 if(orionValidateEnabled(sort)) 1571 { 1572 result.sort = sort.val(); 1573 } 1574 1575 var sortvalue = form.find('input[name=sortvalue]'); 1576 if(orionValidateEnabled(sortvalue)) 1577 { 1578 result.sortvalue = sortvalue.val(); 1579 } 1580 1581 var sortorder = form.find('input[name=sortorder]'); 1582 if(orionValidateEnabled(sortorder)) 1583 { 1584 result.sortorder = sortorder.val(); 1585 } 1586 1587 var videominimum = form.find('input[name=videominimum]'); 1588 if(orionValidateEnabled(videominimum)) 1589 { 1590 result.videominimum = videominimum.val(); 1591 } 1592 1593 var videomaximum = form.find('input[name=videomaximum]'); 1594 if(orionValidateEnabled(videomaximum)) 1595 { 1596 result.videomaximum = videomaximum.val(); 1597 } 1598 1599 var video3d = form.find('input[name=video3d]'); 1600 if(orionValidateEnabled(video3d)) 1601 { 1602 result.video3d = video3d.val(); 1603 } 1604 1605 var audiominimum = form.find('input[name=audiominimum]'); 1606 if(orionValidateEnabled(audiominimum)) 1607 { 1608 result.audiominimum = audiominimum.val(); 1609 } 1610 1611 var providerscommon = form.find('input[name=providerscommon]'); 1612 if(orionValidateEnabled(providerscommon)) 1613 { 1614 result.providerscommon = providerscommon.val(); 1615 } 1616 1617 var providersexternal = form.find('input[name=providersexternal]'); 1618 if(orionValidateEnabled(providersexternal)) 1619 { 1620 providersexternal = providersexternal.val().trim(); 1621 if(providersexternal == '' || orionLinkValid(providersexternal) || OrionValidateSkip) result.providersexternal = providersexternal; 1622 else return orionFormError(form, 'Invalid external provider link.'); 1623 } 1624 1625 var account = form.find('input[name=account]'); 1626 if(orionValidateEnabled(account)) 1627 { 1628 account = account.val(); 1629 if(account != '' || OrionValidateSkip) result.account = account; 1630 else return orionFormError(form, 'Invalid account. Please select an account.'); 1631 } 1632 1633 var status = form.find('input[name=status]'); 1634 if(orionValidateEnabled(status)) 1635 { 1636 status = status.val(); 1637 if(status != '' || OrionValidateSkip) result.status = status; 1638 else return orionFormError(form, 'Invalid status. Please select a status.'); 1639 } 1640 1641 var title = form.find('input[name=title]'); 1642 if(orionValidateEnabled(title)) 1643 { 1644 title = title.val(); 1645 if(title != '' || OrionValidateSkip) result.title = title; 1646 else return orionFormError(form, 'Invalid title. Please provide a title.'); 1647 } 1648 1649 var version = form.find('input[name=version]'); 1650 if(orionValidateEnabled(version)) 1651 { 1652 version = version.val(); 1653 if(orionValidateVersion(version) || orionValidateVersionAddon(version) || OrionValidateSkip) result.version = version; 1654 else return orionFormError(form, 'Invalid version. Please provide a valid version number.'); 1655 } 1656 1657 var service = form.find('input[name=service]'); 1658 if(orionValidateEnabled(service)) 1659 { 1660 service = service.val(); 1661 if(service || OrionValidateSkip) result.service = service; 1662 } 1663 1664 var internal = form.find('input[name=internal]'); 1665 if(orionValidateEnabled(internal)) 1666 { 1667 internal = internal.val(); 1668 if(internal || OrionValidateSkip) result.internal = internal; 1669 } 1670 1671 var host = form.find('input[name=host]'); 1672 if(orionValidateEnabled(host)) 1673 { 1674 host = host.val(); 1675 if(host || OrionValidateSkip) result.host = host; 1676 } 1677 1678 var port = form.find('input[name=port]'); 1679 if(orionValidateEnabled(port)) 1680 { 1681 port = port.val(); 1682 if(port || OrionValidateSkip) result.port = port;
1683 } 1684 1685 var access = form.find('input[name=access]'); 1686 if(orionValidateEnabled(access)) 1687 { 1688 access = access.val(); 1689 if(access || OrionValidateSkip) result.access = access; 1690 } 1691 1692 var lookup = form.find('input[name=lookup]'); 1693 if(orionValidateEnabled(lookup)) 1694 { 1695 lookup = lookup.val(); 1696 if(lookup || OrionValidateSkip) result.lookup = lookup; 1697 } 1698 1699 var extra = form.find('input[name=extra]'); 1700 if(orionValidateEnabled(extra)) 1701 { 1702 extra = extra.val(); 1703 if(extra || OrionValidateSkip) result.extra = extra; 1704 } 1705 1706 var freestreams = form.find('input[name=freestreams]'); 1707 if(orionValidateEnabled(freestreams)) 1708 { 1709 freestreams = freestreams.val(); 1710 if(freestreams || OrionValidateSkip) result.freestreams = freestreams; 1711 } 1712 1713 var freehashes = form.find('input[name=freehashes]'); 1714 if(orionValidateEnabled(freehashes)) 1715 { 1716 freehashes = freehashes.val(); 1717 if(freehashes || OrionValidateSkip) result.freehashes = freehashes; 1718 } 1719 1720 var freecontainers = form.find('input[name=freecontainers]'); 1721 if(orionValidateEnabled(freecontainers)) 1722 { 1723 freecontainers = freecontainers.val(); 1724 if(freecontainers || OrionValidateSkip) result.freecontainers = freecontainers; 1725 } 1726 1727 var premiumstreams = form.find('input[name=premiumstreams]'); 1728 if(orionValidateEnabled(premiumstreams)) 1729 { 1730 premiumstreams = premiumstreams.val(); 1731 if(premiumstreams || OrionValidateSkip) result.premiumstreams = premiumstreams; 1732 } 1733 1734 var premiumhashes = form.find('input[name=premiumhashes]'); 1735 if(orionValidateEnabled(premiumhashes)) 1736 { 1737 premiumhashes = premiumhashes.val(); 1738 if(premiumhashes || OrionValidateSkip) result.premiumhashes = premiumhashes; 1739 } 1740 1741 var premiumcontainers = form.find('input[name=premiumcontainers]'); 1742 if(orionValidateEnabled(premiumcontainers)) 1743 { 1744 premiumcontainers = premiumcontainers.val(); 1745 if(premiumcontainers || OrionValidateSkip) result.premiumcontainers = premiumcontainers; 1746 } 1747 1748 return result; 1749} 1750 1751function orionValidateEnabled(input) 1752{ 1753 OrionValidateSkip = false; 1754 if(input.length == 0) return false; 1755 var data = input.data('validate'); 1756 if(orionStringIs(data) && data.length > 0) 1757 { 1758 var validate = data.toLowerCase(); 1759 if(validate == 'no') 1760 { 1761 OrionValidateSkip = true; 1762 return true; 1763 } 1764 else if(validate == 'visible') 1765 { 1766 return orionVisible(input); 1767 } 1768 else if(validate == 'empty') 1769 { 1770 if(input.val() == '') 1771 { 1772 OrionValidateSkip = true; 1773 return true; 1774 } 1775 } 1776 } 1777 return true; 1778} 1779 1780function orionValidatePassword(password) 1781{ 1782 return password != null && password.length > 2; 1783} 1784 1785function orionValidateEmail(email) 1786{ 1787 var regex = /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/; 1788 if(!email.match(regex)) return false; 1789 else return true; 1790} 1791 1792function orionValidateCategory(category) 1793{ 1794 return category != null && category.length > 1; 1795} 1796 1797function orionValidateSubject(subject) 1798{ 1799 return subject != null && subject.length > 1; 1800} 1801 1802function orionValidateMessage(message) 1803{ 1804 // Allow for short Yes/No answers in tickets. 1805 return message != null && message.length > 1; 1806} 1807 1808function orionValidateVersion(version) 1809{ 1810 var regex = /^\d{1,2}\.\d{1,2}\.\d{1,2}(~(alpha|beta)\d{1,2})?$/; 1811 if(!version.match(regex)) return false; 1812 else return true; 1813} 1814 1815function orionValidateVersionAddon(version) 1816{ 1817 // Syncler package version. 1818 var regex = /^(?:v(?:ersion))?\s*\d.*$/i; 1819 if(!version.match(regex)) return false; 1820 else return true; 1821} 1822 1823/************************************************************************************************ 1824* COLOR 1825************************************************************************************************/ 1826 1827// color3 is optional. 1828function orionColorMix(percent, color1, color2, color3) 1829{ 1830 if(color3) 1831 { 1832 if(percent >= 0.5) 1833 { 1834 color1 = color2; 1835 color2 = color3; 1836 percent /= 2; 1837 } 1838 } 1839 1840 var red1 = parseInt(color1[1] + color1[2], 16); 1841 var green1 = parseInt(color1[3] + color1[4], 16); 1842 var blue1 = parseInt(color1[5] + color1[6], 16); 1843 1844 var red2 = parseInt(color2[1] + color2[2], 16); 1845 var green2 = parseInt(color2[3] + color2[4], 16); 1846 var blue2 = parseInt(color2[5] + color2[6], 16); 1847 1848 var red = Math.round(orionColorPercent(red1, red2, percent)); 1849 var green = Math.round(orionColorPercent(green1, green2, percent)); 1850 var blue = Math.round(orionColorPercent(blue1, blue2, percent)); 1851 1852 return orionColorHex(red, green, blue); 1853} 1854 1855function orionColorHex(red, green, blue) 1856{ 1857 red = red.toString(16); 1858 green = green.toString(16); 1859 blue = blue.toString(16); 1860 1861 while (red.length < 2) { red = "0" + red; } 1862 while (green.length < 2) { green = "0" + green; } 1863 while (blue.length < 2) { blue = "0" + blue; } 1864 1865 return "#" + red + green + blue; 1866} 1867 1868function orionColorPercent(start, end, percent) 1869{ 1870 return start + ((percent) * (end - start)); 1871} 1872 1873/************************************************************************************************ 1874* PROGRESS 1875************************************************************************************************/ 1876 1877function orionProgressInitialize() 1878{ 1879 NProgress.configure({ 1880 showSpinner : false, 1881 template : '<div class="bar orion_progress" role="bar"></div>', 1882 }); 1883} 1884 1885function orionProgressStart() 1886{ 1887 NProgress.start(); 1888} 1889 1890function orionProgressStop() 1891{ 1892 NProgress.done(); 1893} 1894 1895function orionProgressRunning() 1896{ 1897 return orionVisible('.orion_progress'); 1898} 1899 1900/************************************************************************************************ 1901* TABLE 1902************************************************************************************************/ 1903 1904function orionTableInitialize() 1905{ 1906 $('.orion_table_sort > .orion_table_box > table').each(function(i, table) 1907 { 1908 table = $(table); 1909 table.find('> thead > tr > th').each(function(index, header) 1910 { 1911 header = $(header); 1912 header.click(function(){ orionTableSort(table, index); }); 1913 }); 1914 }); 1915} 1916 1917function orionTableSort(table, index, order) 1918{ 1919 table = $(table); 1920 var header = table.find('> thead > tr > th:nth-child(' + (index + 1) + ')'); 1921 1922 if(!order) 1923 { 1924 order = header.data('order'); 1925 if(!order) order = 'descending'; 1926 else if(order == 'ascending') order = 'descending'; 1927 else if(order == 'descending') order = 'ascending'; 1928 } 1929 1930 table.find('> thead > tr > th').each(function(k, h) 1931 { 1932 h = $(h); 1933 h.data('order', '').html(h.text()); // Reset all headers. 1934 }); 1935 header.data('order', order); 1936 var text = header.text(); 1937 header.html(text + '<i class="fas fa-caret-' + (order == 'ascending' ? 'up' : 'down') + '" style="' + (text == '' ? '' : 'margin-left: 0.5rem;') + '"></i>'); 1938 1939 var body = table.find('> tbody'); 1940 var rows = []; 1941 body.find('> tr').each(function(k, row) 1942 { 1943 row = $(row); 1944 var column = row.find('> td').eq(index); 1945 var rank = column.data('rank'); 1946 if(rank === undefined) rank = column.text(); 1947 rows.push([rank, rank, row]); 1948 }); 1949 var float = true;
1950 rows.every(function(row) // Use every() instead of forEach(), because forEach() cannot "break" or "return false". Must "return true" otherwise. 1951 { 1952 if(isNaN(row[1])) 1953 { 1954 float = false; 1955 return false; 1956 } 1957 row[1] = parseFloat(row[1]); 1958 return true; 1959 }); 1960 rows = orionArraySort(rows, float ? 1 : 0, order == 'descending'); 1961 1962 body.html(''); 1963 rows.forEach(function(row) 1964 { 1965 body.append(row[2]); 1966 }); 1967} 1968 1969function orionTableSortClear(table) 1970{ 1971 table = $(table); 1972 table.find('> thead > tr > th').each(function(index, header) 1973 { 1974 header = $(header); 1975 header.data('order', ''); 1976 header.html(header.text()); 1977 }); 1978} 1979 1980function orionTableOnSort(table, callback) 1981{ 1982 $(table).find('> .orion_table_box > table > thead > tr > th').click(function() 1983 { 1984 callback(); 1985 }); 1986} 1987 1988function orionTableClear(selector) 1989{ 1990 selector = $(selector); 1991 selector.find('table tbody').first().html(''); 1992} 1993 1994function orionTableUpdate(selector, entries, actions, message, append) 1995{ 1996 selector = $(selector); 1997 var markup = ''; 1998 $.each(entries, function(i, entry) 1999 { 2000 var classes = []; 2001 if(!orionArrayIs(entry)) // Do not use orionObjectIs(), since arrays are also objects. 2002 { 2003 classes.push(entry.class); 2004 entry = entry.data; 2005 } 2006 2007 markup += '<tr'; 2008 if(actions != null) 2009 { 2010 classes.push('orion_table_action'); 2011 if(actions[i] != null) markup += ' onclick=\'' + actions [i] + '\''; 2012 } 2013 if(classes.length > 0) markup += ' class=\'' + classes.join(' ') + '\''; 2014 markup += '>'; 2015 $.each(entry, function(j, item) 2016 { 2017 var label = item; 2018 var rank = ''; 2019 var event = ''; 2020 var mouseover = ''; 2021 var mouseout = ''; 2022 var click = ''; 2023 if(orionObjectIs(item)) 2024 { 2025 if(orionObjectContains(item, 'label')) 2026 { 2027 label = item.label; 2028 } 2029 if(orionObjectContains(item, 'rank')) 2030 { 2031 rank = ' data-rank="' + item.rank + '"'; 2032 } 2033 if(orionObjectContains(item, 'event')) 2034 { 2035 if(!orionObjectContains(item, 'mouseover')) item.mouseover = item.event; 2036 if(!orionObjectContains(item, 'mouseout')) item.mouseout = item.event; 2037 if(!orionObjectContains(item, 'click')) item.click = item.event; 2038 } 2039 if(orionObjectContains(item, 'mouseover')) 2040 { 2041 mouseover = item.mouseover; 2042 if(!mouseover.endsWith(')') && !mouseover.endsWith(';')) mouseover += '();'; 2043 mouseover = ' onmouseover="' + mouseover + '"'; 2044 } 2045 if(orionObjectContains(item, 'mouseout')) 2046 { 2047 mouseout = item.mouseout; 2048 if(!mouseout.endsWith(')') && !mouseout.endsWith(';')) mouseout += '();'; 2049 mouseout = ' onmouseout="' + mouseout + '"'; 2050 } 2051 if(orionObjectContains(item, 'click')) 2052 { 2053 click = item.click; 2054 if(!click.endsWith(')') && !click.endsWith(';')) click += '();'; 2055 click = ' onclick="' + click + '"'; 2056 } 2057 } 2058 markup += '<td' + rank + mouseover + mouseout + click + '>' + label + '</td>'; 2059 }); 2060 markup += '</tr>'; 2061 }); 2062 2063 selector.removeClass('orion_table_empty'); 2064 if(entries.length == 0) selector.addClass('orion_table_empty'); 2065 2066 var defaulter = selector.find('.orion_table_default'); 2067 if(message) defaulter.html(message); 2068 defaulter.toggle(entries.length == 0); 2069 2070 var body = selector.find('table tbody').first(); 2071 if(append) body.append(markup); 2072 else body.html(markup); 2073} 2074 2075function orionTableWrap(content) 2076{ 2077 return '<div class="orion_table_wrap">' + content + '</div>'; 2078} 2079 2080/************************************************************************************************ 2081* STATUS 2082************************************************************************************************/ 2083 2084// type: null, "good", "medium", "bad" 2085function orionStatus(type) 2086{ 2087 return '<div class="orion_status' + (type ? (' orion_status_' + type) : '') + '"><i class="far fa-' + (type == 'good' ? 'check' : type == 'bad' ? 'times' : 'dot') + '-circle"></i></div>'; 2088} 2089 2090function orionStatusUpdate(selector, type) 2091{ 2092 selector = $(selector); 2093 if(!selector.hasClass('orion_status')) selector = selector.find('.orion_status'); 2094 selector.attr('class', 'orion_status' + (type ? (' orion_status_' + type) : '')); 2095} 2096 2097function orionStatusLabel(type, text, tooltip, classname) 2098{ 2099 tooltip = tooltip ? (' title="' + tooltip + '"') : ''; 2100 return '<div class="orion_status_label' + (type ? (' orion_status_label_' + type) : '') + (classname ? (' ' + classname) : '') + '"' + tooltip + '>
2100' + text + '</div>'; 2101} 2102 2103function orionStatusLabelUpdate(selector, type) 2104{ 2105 selector = $(selector); 2106 if(!selector.hasClass('orion_status_label')) selector = selector.find('.orion_status_label'); 2107 selector.attr('class', 'orion_status_label' + (type ? (' orion_status_label_' + type) : '')); 2108} 2109 2110function orionStatusObject(type, text) 2111{ 2112 return '<table class="orion_status_object"><tr><td>' + orionStatus(type) + '</td><td>' + orionStatusLabel(type, text) + '</td></tr></table>'; 2113} 2114 2115/************************************************************************************************ 2116* SWITCHER 2117************************************************************************************************/ 2118 2119function orionSwitcherInitialize() 2120{ 2121 $('.orion_switcher').each(function(i, selector) 2122 { 2123 selector = $(selector); 2124 var current = orionSwitcherValue(selector); 2125 var previous = selector.data('previous'); 2126 selector.data('previous', current); 2127 }); 2128} 2129 2130function orionSwitcherValue(selector) 2131{ 2132 var choice = null; 2133 $(selector).find('input').each(function(i, option) 2134 { 2135 option = $(option); 2136 if(option.is(':checked')) 2137 { 2138 choice = option.data('value'); 2139 return false; 2140 } 2141 }); 2142 return choice; 2143} 2144 2145function orionSwitcherUpdate(selector, option) 2146{ 2147 var container = null; 2148 var index = 0; 2149 selector = $(selector); 2150 if(selector.find('.orion_tab_control').length > 0) selector = selector.find('.orion_tab_control').first(); 2151 selector.find('input').each(function(i, input) 2152 { 2153 input = $(input); 2154 if(input.data('value') == option) 2155 { 2156 container = selector.siblings('.orion_tab_containers').find('> .orion_tab_container').eq(index); 2157 var id = input.attr('id'); 2158 input.parent().find('label').each(function(i, label) 2159 { 2160 label = $(label); 2161 if(id == label.attr('for')) 2162 { 2163 label.click(); 2164 return false; 2165 } 2166 }); 2167 return false; 2168 } 2169 index++; 2170 }); 2171 return container; 2172} 2173 2174function orionSwitcherChange(selector, callback) 2175{ 2176 selector = $(selector); 2177 selector.find('input').on('change', function() 2178 { 2179 var current = orionSwitcherValue(selector); 2180 var previous = selector.data('previous'); 2181 2182 var currentNumber = parseInt(selector.find('input[data-value=' + current + ']').attr('id').replace(/^\D+/g, '')); 2183 var previousNumber = parseInt(selector.find('input[data-value=' + previous + ']').attr('id').replace(/^\D+/g, ''));; 2184 var invert = currentNumber < previousNumber; 2185 2186 selector.data('previous', current); 2187 if(callback) callback(current, previous, invert); 2188 orionPanelResize(); 2189 }); 2190} 2191 2192/************************************************************************************************ 2193* TAB 2194************************************************************************************************/ 2195 2196function orionTabInitialize() 2197{ 2198 $('.orion_tab').each(function(i, tab) 2199 { 2200 tab = $(tab); 2201 var containers = tab.find('> .orion_tab_containers > .orion_tab_container'); 2202 var control = tab.find('> .orion_tab_control'); 2203 var value = orionSwitcherValue(control); 2204 2205 containers.hide(); 2206 containers.find('> .orion_tab_box_' + value).parent('.orion_tab_container').first().show(); 2207 2208 orionSwitcherChange(control, function(value, previous, invert) 2209 { 2210 orionTabToggle(containers, value, previous, invert); 2211 }); 2212 }); 2213} 2214 2215function orionTabToggle(containers, value, previous, invert) 2216{ 2217 var boxValue = containers.find('> .orion_tab_box_' + value).parent('.orion_tab_container').first(); 2218 var boxPrevious = containers.find('> .orion_tab_box_' + previous).parent('.orion_tab_container').first(); 2219 2220 if(orionMobile()) // Too slow on mobile devices. 2221 { 2222 boxPrevious.hide(); 2223 boxValue.show(); 2224 } 2225 else 2226 { 2227 boxPrevious.finish().hide('slide', {direction: invert ? 'left' : 'right'}, 300); 2228 boxValue.finish().show('slide', {direction: invert ? 'right' : 'left'}, 300, orionIfChange); 2229 } 2230} 2231 2232/************************************************************************************************ 2233* SELECTOR 2234************************************************************************************************/ 2235 2236function orionSelectorInitialize(selector, callback) 2237{ 2238 var all; 2239 if(selector == null) 2240 { 2241 all = true; 2242 selector = $('.orion_selector'); 2243 } 2244 else 2245 { 2246 all = false;
2247 selector = $(selector); 2248 } 2249 2250 function orionSelectorShow(event) 2251 { 2252 var select = $(event.target).parents('.orion_selector').first(); 2253 var menu = select.find('.orion_selector_menu'); 2254 orionSelectorHide(event, selector); // Hide all other selectors. 2255 2256 select.attr('data-mode', 'shown'); 2257 menu.slideDown('normal'); 2258 event.stopPropagation(); 2259 } 2260 2261 function orionSelectorHide(event, element) 2262 { 2263 var single = element === undefined; 2264 var select = (single ? $(event.target).parents('.orion_selector').first() : element); 2265 var menu = select.find('.orion_selector_menu'); 2266 2267 menu.slideUp(single ? 'normal' : 0); 2268 event.stopPropagation(); 2269 select.attr('data-mode', 'hidden'); 2270 } 2271 2272 selector.each(function(i, select) 2273 { 2274 select = $(select); 2275 var menu = select.find('.orion_selector_menu'); 2276 var value = select.find('.orion_selector_value'); 2277 var button = select.find('.orion_selector_button'); 2278 var callbackFixed = select.attr('data-callback'); 2279 2280 select.attr('data-mode', 'hidden'); // Do not use data() function, since the CSS selectors are otherwise not applied. 2281 2282 var current = select.data('value'); 2283 if(current !== '') // Allow "false" string. 2284 { 2285 value.val(current); 2286 menu.find('.orion_selector_menu_item').each(function(j, item) 2287 { 2288 item = $(item); 2289 if(item.data('value') == current) 2290 { 2291 button.val(item.text()); 2292 return false; 2293 } 2294 }); 2295 } 2296 2297 if(all) 2298 { 2299 select.find('.orion_selector_button, .orion_selector_caret').on('click', function(event) 2300 { 2301 if(select.attr('data-mode') == 'shown') orionSelectorHide(event); 2302 else orionSelectorShow(event); 2303 }); 2304 } 2305 2306 menu.find('.orion_selector_menu_item').each(function(j, item) 2307 { 2308 item = $(item); 2309 item.on('click', function(event) 2310 { 2311 var choice = item.data('value'); 2312 select.attr('data-value', choice); 2313 value.val(choice); 2314 button.val(item.text()); 2315 orionSelectorHide(event); 2316 if(callback) callback(choice); 2317 if(callbackFixed) 2318 { 2319 try{ window[callbackFixed](choice); } 2320 catch(e){ eval(callbackFixed); } 2321 } 2322 }); 2323 }); 2324 }); 2325 2326 if(all) 2327 { 2328 $(window).click(function(event) 2329 { 2330 orionSelectorHide(event, selector); 2331 }); 2332 } 2333} 2334 2335function orionSelectorUpdate(selector, option) 2336{ 2337 selector = $(selector); 2338 var menu = selector.find('.orion_selector_menu'); 2339 if(menu.length == 0) 2340 { 2341 selector = selector.parents('.orion_selector'); 2342 menu = selector.find('.orion_selector_menu'); 2343 } 2344 menu.find('.orion_selector_menu_item').each(function(j, item) 2345 { 2346 item = $(item); 2347 if(item.data('value') == option) 2348 { 2349 item.click(); 2350 return false; 2351 } 2352 }); 2353} 2354 2355function orionSelectorReset(selector) 2356{ 2357 selector = $(selector); 2358 selector.each(function(i, select) 2359 { 2360 select = $(select); 2361 select.attr('data-value', ''); 2362 select.find('.orion_selector_button').val(select.data('label')); 2363 }); 2364} 2365 2366function orionSelectorAdd(selector, value, label) 2367{ 2368 selector = $(selector); 2369 if(!orionArrayIs(value)) value = [[value, label]]; 2370 value.forEach(function(item) 2371 { 2372 selector.find('.orion_selector_menu').append('<div class="orion_selector_menu_item" data-value="' + item[0] + '">' + item[1] + '</div>'); 2373 }); 2374} 2375 2376function orionSelectorClear(selector) 2377{ 2378 selector = $(selector); 2379 selector.attr('data-value', ''); 2380 selector.find('.orion_selector_menu').empty(); 2381 selector.find('.orion_selector_value').val(''); 2382 selector.find('.orion_selector_button').val(selector.attr('data-label')); 2383} 2384 2385/************************************************************************************************ 2386* GRAPH 2387************************************************************************************************/ 2388 2389function orionGraphIntialize(selector, data) 2390{ 2391 var body = $('body'); 2392 2393 orionArraySort(data, 0); 2394 var minimum = data.length > 0 ? data[0][1] : 0; 2395 var maximum = data.length > 0 ? data[0][1] : 0; 2396 for(var i = 0; i < data.length; ++i) 2397 { 2398 data[i][0] *= 1000; // Needs milliseconds 2399 if(data[i][1] < minimum) minimum = data[i][1]; 2400 else if(data[i][1] > maximum) maximum = data[i][1]; 2401 } 2402 if((maximum - minimum) / maximum > 0.2) minimum = 0; 2403 2404 $(selector).each(function(i, graph) 2405 { 2406 var title = $(graph).data('title'); 2407 var prefix = $(graph).data('prefix'); 2408 var suffix = $(graph).data('suffix'); 2409 var label = $(graph).data('label'); 2410 var width = $(graph).data('width'); 2411 var height = $(graph).data('height'); 2412 var navigator = $(graph).data('navigator'); 2413 var range = $(graph).data('range'); 2414 var limit = $(graph).data('limit'); 2415 var approximation = $(graph).data('approximation'); 2416 var grouping = $(graph).data('grouping'); 2417 if(!grouping) grouping = 1; 2418 var unit = $(graph).data('unit'); 2419 if(!unit) unit = 'hour'; 2420 grouping = {units: [[unit, [grouping]]]}; 2421 2422 var chart = Highcharts.stockChart(graph, 2423 { 2424 chart: 2425 { 2426 width: width, 2427 height: height, 2428 backgroundColor: 'transparent', 2429 style: 2430 { 2431 fontFamily: '\'Poppins\', sans-serif', 2432 }, 2433 }, 2434 title: 2435 { 2436 text: title, 2437 style: 2438 { 2439 color: '#010B14', 2440 fontSize: '2em', 2441 fontWeight: '500', 2442 }, 2443 }, 2444 plotOptions: 2445 { 2446 column: 2447 { 2448 groupPadding: 0, 2449 pointPadding: 0, 2450 borderWidth: 0, 2451 states: 2452 { 2453 hover: 2454 { 2455 color: '#47CAE9', 2456 }, 2457 }, 2458 }, 2459 series: 2460 { 2461 dataGrouping: 2462 { 2463 approximation: approximation, 2464 }, 2465 }, 2466 }, 2467 rangeSelector: 2468 { 2469 enabled: range, 2470 verticalAlign: 'bottom', 2471 inputBoxBorderColor: '#47CAE9', 2472 inputStyle: 2473 { 2474 color: '#010B14', 2475 }, 2476 buttonTheme: 2477 { 2478 r: 3, 2479 stroke: '#47CAE9', 2480 'stroke-width': 1, 2481 style: 2482 { 2483 color: '#010B14', 2484 }, 2485 states: { 2486 hover: 2487 { 2488 fill: '#47CAE9', 2489 stroke: '#010B14', 2490 style: 2491 { 2492 color: '#010B14', 2493 }, 2494 }, 2495 select: 2496 { 2497 fill: '#010B14', 2498 stroke: '#47CAE9', 2499 style: 2500 { 2501 color: '#47CAE9', 2502 }, 2503 }, 2504 }, 2505 }, 2506 buttons: [ 2507 { 2508 type: 'week', 2509 count: 1, 2510 text: '1W', 2511 }, 2512 { 2513 type: 'month', 2514 count: 1, 2515 text: '1M', 2516 }, 2517 { 2518 type: 'month', 2519 count: 2, 2520 text: '2M', 2521 }, 2522 { 2523 type: 'month', 2524 count: 3, 2525 text: '3M', 2526 }, 2527 { 2528 type: 'month', 2529 count: 6, 2530 text: '6M', 2531 }, 2532 { 2533 type: 'all', 2534 text: 'All', 2535 }, 2536 ], 2537 }, 2538 credits: 2539 { 2540 enabled: false, 2541 }, 2542 exporting: 2543 { 2544 enabled: false, 2545 }, 2546 navigator: 2547 { 2548 enabled: navigator, 2549 maskFill: 'rgba(71, 202, 233, 0.4)', 2550 series: 2551 { 2552 type: 'areaspline', 2553 fillOpacity: 1, 2554 dataGrouping: 2555 {
2556 smoothed: false 2557 }, 2558 shadow: true, 2559 lineWidth: 1, 2560 lineColor: '#47CAE9', 2561 fillColor : '#010B14', 2562 marker: 2563 { 2564 enabled: false 2565 }, 2566 }, 2567 }, 2568 scrollbar: 2569 { 2570 enabled: false, 2571 }, 2572 tooltip: 2573 { 2574 split: false, 2575 useHTML: true, 2576 headerFormat: '<div style="text-align:center;">{point.x:%A, %d %B %Y, %H:%M}</div>', 2577 pointFormat: '<div style="text-align:center;font-weight:bold;">' + (prefix ? prefix : '') + '{point.y}' + (suffix ? suffix : '') + (label ? ' ' + label : '') + '</div>', 2578 crosshairs: [false, false], 2579 }, 2580 xAxis: 2581 { 2582 lineWidth: 2, 2583 lineColor: '#47CAE9', 2584 tickColor: '#47CAE9', 2585 labels: 2586 { 2587 style: 2588 { 2589 color: '#010B14', 2590 }, 2591 }, 2592 dateTimeLabelFormats: 2593 { 2594 hour: ' ', 2595 day: '%d %b', 2596 }, 2597 }, 2598 yAxis: 2599 { 2600 gridLineWidth: 0, 2601 visible: false, 2602 min: minimum, 2603 max: limit || null, 2604 offset: 0, 2605 lineWidth: 2, 2606 resize: 2607 { 2608 enabled: true, 2609 }, 2610 }, 2611 series: 2612 [ 2613 { 2614 color: '#010B14', 2615 borderColor: '#47CAE9', 2616 borderWidth: 1, 2617 type: 'column', 2618 name: label, 2619 data: data, 2620 dataGrouping: grouping, 2621 }, 2622 ], 2623 }); 2624 2625 // Auto resize with window. 2626 // Not perfect with orion_panel_content size, but works for now. 2627 graph = $(graph); 2628 var main = $('.orion_panel_main'); 2629 var margin = main.css('margin-left'); 2630 var container = $(graph).parents('.orion_panel_content'); 2631 if(container.length > 0) 2632 { 2633 function chartResize(force) 2634 { 2635 if(force || orionVisible(graph)) 2636 { 2637 graph.highcharts().setSize(container.width() * 0.9, height); 2638 chart.redraw(); 2639 chart.reflow(); 2640 } 2641 2642 } 2643 2644 // Resize graphs if side menu is toggled. 2645 // Check margin, otherwise the graph flashes as the menu grows until fully shown. 2646 function chartResizeMenu() 2647 { 2648 var marginTemp = main.css('margin-left'); 2649 if(marginTemp != margin) 2650 { 2651 margin = marginTemp; 2652 chartResize(); 2653 } 2654 } 2655 2656 chartResize(true); 2657 2658 try{ orionPanelResizeCallback(chartResize); } 2659 catch(e){ $(window).resize(chartResize); } 2660 } 2661 }); 2662} 2663 2664/************************************************************************************************ 2665* GATEWAYS 2666************************************************************************************************/ 2667 2668var OrionGateways = []; 2669 2670function orionGatewaysUpdate(data) 2671{ 2672 // Gateways can be added mutiple times. 2673 // Eg: Once for the normal packages, and once for vendor packages. 2674 if(data) 2675 { 2676 var found = null; 2677 data.forEach(function(gateway) 2678 { 2679 found = false; 2680 OrionGateways.every(function(i) 2681 { 2682 if(gateway.id == i.id) 2683 { 2684 // Already exists. Merge the two objects (one might contain "currencies"). 2685 found = true; 2686 $.extend(i, gateway); 2687 return false; 2688 } 2689 return true; 2690 }); 2691 if(!found) OrionGateways.push(gateway); 2692 }); 2693 } 2694} 2695 2696function orionGatewaysFind(gateway, force) 2697{ 2698 if(orionStringIs(gateway) || force) 2699 { 2700 if(!orionStringIs(gateway)) gateway = gateway.id; 2701 if(OrionGateways != null) 2702 { 2703 for(var i = 0; i < OrionGateways.length; ++i) 2704 { 2705 if(OrionGateways[i].id == gateway) return OrionGateways[i]; 2706 } 2707 } 2708 return null; 2709 } 2710 return gateway; 2711} 2712 2713function orionGatewaysId(gateway) 2714{ 2715 if(orionStringIs(gateway)) return gateway; 2716 gateway = orionGatewaysFind(gateway); 2717 if(gateway) return gateway.id; 2718 return null; 2719} 2720 2721function orionGatewaysCurrencies(gateway) 2722{ 2723 var currencies = null; 2724 if(gateway) 2725 { 2726 if(orionObjectIs(gateway)) 2727 { 2728 if(!orionObjectContains(gateway, 'currencies')) gateway = orionGatewaysFind(gateway.id); 2729 } 2730 else 2731 { 2732 gateway = orionGatewaysFind(gateway); 2733 } 2734 if(gateway && orionObjectContains(gateway, 'currencies')) currencies = gateway.currencies; 2735 } 2736 return currencies 2737} 2738 2739/************************************************************************************************ 2740* PACKAGES 2741************************************************************************************************/ 2742 2743var OrionPackages = []; 2744var OrionMonth = 2628000 + 10000; // (365 * 24 * 60 * 60) / 12 and +10000 to round up to to the time difference on the server. 2745var OrionYear = 31556952; 2746var OrionPaymentsCallback = null; 2747var OrionPaymentsTime = null; 2748var OrionPaypalHidden = false;
2749var OrionPackgeSelection = false; 2750var OrionPackgeSelectionSwiper = null; 2751var OrionPackgeSelectionSelector = null; 2752 2753function orionPackagesInitialize(first) 2754{ 2755 $('.orion_packages').each(function(i, package) 2756 { 2757 package = $(package); 2758 orionSwitcherChange(package.find('.orion_packages_control'), function() 2759 { 2760 orionPackagesToggle(package); 2761 }); 2762 orionPackagesToggle(package); 2763 }); 2764 2765 if(first === undefined || first === true) 2766 { 2767 try 2768 { 2769 orionPanelResizeCallback(function() 2770 { 2771 orionPackagesSwiperUpdate(); 2772 }); 2773 } 2774 catch(e) 2775 { 2776 $(window).resize(function() 2777 { 2778 orionPackagesSwiperUpdate(); 2779 }); 2780 } 2781 } 2782} 2783 2784function orionPackagesUpdate(data) 2785{ 2786 OrionPackages = data; 2787 orionPackagesInitialize(false); 2788} 2789 2790function orionPackagesFind(id) 2791{ 2792 if(OrionPackages != null) 2793 { 2794 for(var i = 0; i < OrionPackages.length; ++i) 2795 { 2796 if(OrionPackages[i].id == id) return OrionPackages[i]; 2797 } 2798 } 2799 return null; 2800} 2801 2802function orionPackagesMonths(seconds) 2803{ 2804 return Math.round(seconds / parseFloat(OrionMonth)); 2805} 2806 2807function orionPackagesDetails(package, style, terms) 2808{ 2809 var free = package['type'] == 'free'; 2810 2811 var tagOpen = '<span>'; 2812 var tagClose = '</span>'; 2813 var tagTerms = ''; 2814 if(style) 2815 { 2816 tagOpen = '<span class="orion_package_highlight">'; 2817 tagTerms = terms ? (tagOpen + '<span class="orion_package_highlight_terms">✽</span>' + tagClose) : ''; 2818 } 2819 2820 return [ 2821 tagOpen + (package.limit.streams === null ? 'Unlimited' : orionThousands(package.limit.streams)) + tagClose + ' Daily Links' + (package.limit.streams === null ? tagTerms : ''), 2822 tagOpen + (package.limit.hashes === null ? 'Unlimited' : orionThousands(package.limit.hashes)) + tagClose + ' Daily Hashes' + (package.limit.hashes === null ? tagTerms : ''), 2823 tagOpen + (package.limit.containers === null ? 'Unlimited' : orionThousands(package.limit.containers)) + tagClose + ' Daily Containers' + (package.limit.containers === null ? tagTerms : ''), 2824 tagOpen + (free ? 'Limited' : 'Full') + tagClose + ' API Access', 2825 tagOpen + (free ? 'Queued' : 'Prioritized') + tagClose + ' Queries', 2826 tagOpen + (package.limit.duration === 0 ? ('Lifetime' + tagClose + ' Subscription') : ('Month' + tagClose + ' To Month')), 2827 /*tagOpen + 'Gigabit' + tagClose + ' Speed',*/ 2828 ]; 2829} 2830 2831function orionPackagesToggle(package) 2832{ 2833 var containerSpecial = null; 2834 var controlGateway = package.find('.orion_packages_control_gateway'); 2835 var choiceGateway = orionSwitcherValue(controlGateway); 2836 var full = package.hasClass('orion_packages_full'); 2837 var total = true; 2838 2839 var control = package.find('.orion_packages_control_' + choiceGateway); 2840 var choiceControl = orionSwitcherValue(control); 2841 package.find('.orion_packages_control:not(:first-child):not(.orion_packages_control_' + choiceGateway + ')').hide(); 2842 2843 OrionPaymentOption = null; 2844 if(choiceGateway == 'voucher' || choiceGateway == 'gift' || choiceGateway == 'reseller' || choiceGateway == 'crypto' || choiceGateway == 'cash' || choiceGateway == 'paypal') 2845 { 2846 if(choiceGateway == 'paypal') 2847 { 2848 if(choiceControl == 'paypalcard') OrionPaymentOption = 'Billing'; 2849 control.show(); 2850 containerSpecial = package.find('.orion_packages_' + choiceControl); 2851 control = package.find('.orion_packages_control_' + choiceControl); 2852 choiceControl = orionSwitcherValue(control); 2853 } 2854 else 2855 { 2856 choiceGateway = choiceControl;
2857 control.show(); 2858 control = package.find('.orion_packages_control_' + choiceGateway); 2859 choiceControl = orionSwitcherValue(control); 2860 } 2861 } 2862 control.show(); 2863 2864 var container = package.find('.orion_packages_' + choiceGateway); 2865 package.find('.orion_packages_container').hide(); 2866 2867 if(choiceGateway == 'paypal') 2868 { 2869 if(OrionPaypalHidden) 2870 { 2871 container.show(); 2872 containerSpecial = null; 2873 } 2874 else 2875 { 2876 container.hide(); 2877 control.hide(); 2878 } 2879 } 2880 else 2881 { 2882 container.show(); 2883 } 2884 if(containerSpecial != null) containerSpecial.show(); 2885 2886 if(full) 2887 { 2888 package.find('.orion_payment_options').hide(); 2889 package.find('.orion_payment_options_' + choiceGateway).show(); 2890 } 2891 2892 var exclusive = false; 2893 var terms = false; 2894 var panel = false; 2895 try{ panel = orionPanelIs(); } 2896 catch(e){} 2897 2898 var duration = parseInt(choiceControl); 2899 if(isNaN(duration) || duration == 0) duration = OrionYear; 2900 duration = orionPackagesMonths(duration); 2901 2902 var packages = []; 2903 for(var i = 0; i < OrionPackages.length; ++i) 2904 { 2905 if(choiceGateway == OrionPackages[i].gateway && orionPackagesMonths(OrionPackages[i].limit.duration) == duration) 2906 { 2907 packages.push(OrionPackages[i]); 2908 } 2909 else if(choiceGateway == OrionPackages[i].gateway && OrionPackages[i].type == 'unlimited') 2910 { 2911 packages.push(OrionPackages[i]); 2912 } 2913 else if(!full && OrionPackages[i].type == 'free') 2914 { 2915 packages.push(OrionPackages[i]); 2916 } 2917 } 2918 2919 if(packages.length > 0) 2920 { 2921 var free = null; 2922 for(var i = 0; i < packages.length; ++i) 2923 { 2924 if(packages[i].type == 'free') 2925 { 2926 free = packages[i]; 2927 packages.splice(i, 1); 2928 break; 2929 } 2930 } 2931 for(var i = 0; i < packages.length; ++i) 2932 { 2933 if(packages[i].limit.streams === null) packages[i].limit.streams = Infinity; 2934 } 2935 packages = orionArrayObjectSort(packages, 'limit', 'streams'); 2936 packages.reverse(); 2937 for(var i = 0; i < packages.length; ++i) 2938 { 2939 if(packages[i].limit.streams === Infinity) packages[i].limit.streams = null; 2940 } 2941 if(free) packages.push(free); 2942 } 2943 2944 var markup = ''; 2945 for(var i = 0; i < packages.length; ++i) 2946 { 2947 if(!terms) terms = (packages[i].limit.streams === null) || (packages[i].limit.hashes === null) || (packages[i].limit.containers === null); 2948 if(!exclusive) exclusive = packages[i].exclusive; 2949 2950 var price = 0; 2951 if(packages[i].limit.duration === 0) 2952 { 2953 price = packages[i].price.toFixed(0); 2954 } 2955 else 2956 { 2957 if(packages[i].price > 0) 2958 { 2959 if(orionPackagesMonths(packages[i].limit.duration) == 1) price = packages[i].price; 2960 else price = (Math.round(((packages[i].price / packages[i].limit.duration) * OrionMonth) * 20) / 20); // Round to nearest 0.05 2961 } 2962 price = price.toFixed(2); 2963 } 2964 2965 markup += '\ 2966 <div class="swiper-slide"><div class="orion_package' + (packages[i].exclusive ? ' orion_package_special' : '') + (!packages[i].premium ? ' orion_package_unspecial' : '') + '">\ 2967 ' + (packages[i].popular ? '<div class="orion_package_popular"></div>' : '') + '\ 2968 ' + (packages[i].type == 'free' ? '<div class="orion_package_free"></div>' : '') + '\ 2969 <div class="orion_package_name">' + packages[i].name + '</div>\ 2970 <div class="orion_package_description">' + packages[i].description + '</div>\ 2971 <div class="orion_package_' + (packages[i].limit.duration === 0 ? 'life' : 'month') + '">' + price + '</div>\ 2972 <table class="orion_package_details">\ 2973 '; 2974 2975 var details = orionPackagesDetails(packages[i], true, panel); 2976 $.each(details, function(i, detail) 2977 { 2978 markup += '<tr><td>' + detail + '</td></tr>'; 2979 }); 2980 2981 markup += '</table>'; 2982 if(total && full) markup += '<div class="orion_package_total">' + packages[i].price.toFixed(packages[i].type == 'unlimited' ? 0 : 2) + '</div>'; 2983 markup += '<div class="orion_package_footer"><div class="orion_button_medium">' + (panel ? 'PURCHASE' : 'GET NOW') + '</div></div></div></div>'; 2984 } 2985 2986 if(markup.length > 0) 2987 { 2988 var selector = container.find('.orion_packages_selection'); 2989 markup = '<div class="swiper-wrapper">' + markup + '</div><div class="swiper-pagination"></div><div class="swiper-button-prev"><i class="fas fa-angle-left"></i></div><div class="swiper-button-next"><i class="fas fa-angle-right"></i></div>'; 2990 selector.html(markup); 2991 2992 OrionPackgeSelection = packages; 2993 if(orionVisible(selector)) 2994 {
2995 orionPackagesSwiper(selector, OrionPackgeSelectionSwiper); 2996 } 2997 2998 selector.next('.orion_package_terms').remove(); 2999 if(panel && terms) 3000 { 3001 selector.after('\ 3002 <div class="orion_package_terms">\ 3003 <div ' + (exclusive ? 'class="orion_package_terms_special"' : '') + '>\ 3004 <span class="orion_package_highlight_terms">✽</span>\ 3005 Although the accounts have no hard limits, all usage is within reason. Please refer to our <a onclick="orionModalFair()">Fair Usage Policy</a> for more information.\ 3006 </div>\ 3007 <div>\ 3008 <span class="orion_package_highlight_terms">✽</span>\ 3009 Do you have your own project and want to connect all your users to Orion? Please <a onclick="orionPanelTicket(\'account\', \'Vendor Account Inquiry\', \'Hi,\\n\\nI would like to inquire about your vendor accounts. Here are some details about my project.\\n\\nNumber of users or devices:\\nShort description of the project:\\nI plan to authenticate users as follows:\\n\\n\')">Contact Us</a> about our vendor accounts.\ 3010 </div>\ 3011 </div>\ 3012 '); 3013 } 3014 } 3015} 3016 3017function orionPackagesSwiper(selector, swiper) 3018{ 3019 OrionPackgeSelectionSelector = $(selector); 3020 3021 var transition = false; 3022 var initialSlide = null; 3023 var slidesPerView = null; 3024 var spaceBetween = null; 3025 3026 // Do not use fixed breakpoints, since they are different between thee home page and the panel (since panel menu can have different width). 3027 var width = OrionPackgeSelectionSelector.width(); 3028 3029 var breakpoints = {}; 3030 if(width > 1400) slidesPerView = 4, spaceBetween = -200; 3031 else if(width > 1300) slidesPerView = 3, spaceBetween = -50; 3032 else if(width > 800) slidesPerView = 3, spaceBetween = 0; 3033 else if(width > 700) slidesPerView = 1, spaceBetween = -450; 3034 else if(width > 600) slidesPerView = 1, spaceBetween = -400; 3035 else if(width > 500) slidesPerView = 1, spaceBetween = -350; 3036 else if(width > 400) slidesPerView = 1, spaceBetween = -300; 3037 else if(width > 0) slidesPerView = 1, spaceBetween = 0; 3038 else 3039 { 3040 if(OrionPackgeSelectionSelector) 3041 { 3042 // If there is no width, but there is a OrionPackgeSelectionSelector, that means we have switched between swiperes in the panel. 3043 // Find the visible one, and re-initialize it. 3044 var selectorNew = $('.orion_packages_selection:visible'); 3045 if(selectorNew.length) orionPackagesSwiper(selectorNew, OrionPackgeSelectionSwiper); 3046 } 3047 return null; 3048 } 3049 3050 // Important, otherwise calling this function multiple times, will add multiple event listeners. 3051 if(swiper) swiper.destroy(true, true); 3052 3053 OrionPackgeSelectionSwiper = new Swiper(OrionPackgeSelectionSelector, 3054 { 3055 effect : 'coverflow', 3056 slidesPerView : slidesPerView, 3057 spaceBetween : spaceBetween, 3058 initialSlide : 0, 3059 loop : true, 3060 centeredSlides : true, 3061 keyboard : true, 3062 mousewheel : false, 3063 slideToClickedSlide : true, 3064 preventClicks : false, 3065 preventClicksPropagation : false, 3066 observer : true, 3067 observeParents : true, 3068 coverflow : 3069 { 3070 rotate : 0, 3071 stretch : 0, 3072 depth : 250, 3073 modifier : 1, 3074 slideShadows : false, 3075 }, 3076 navigation : 3077 { 3078 nextEl : '.swiper-button-next', 3079 prevEl : '.swiper-button-prev', 3080 }, 3081 pagination : 3082 { 3083 el : '.swiper-pagination', 3084 type : 'bullets', 3085 clickable : true, 3086 }, 3087 autoplay : 3088 { 3089 enabled : false, 3090 delay : 3000, 3091 disableOnInteraction : true, 3092 }, 3093 on : 3094 { 3095 transitionStart : function() 3096 { 3097 transition = true; 3098 }, 3099 transitionEnd : function() 3100 { 3101 transition = false; 3102 if(OrionPackgeSelectionSwiper) OrionPackgeSelectionSwiper.update(); 3103 }, 3104 click : function(event) 3105 { 3106 if(OrionPackgeSelection) 3107 { 3108 // Dirty hack. 3109 // Something might be wrong with preventClicksPropagation. 3110 // On the home page - logged out, if a slide/package is clicked and the mouse is over the outside of the modal (the semi-opaque grayed overlay), the click event is propagated and therefore immediately closes the modal again. 3111 // Temporarily block the click event. 3112 // This only happens on the mobile version, desktop version is fine. Maybe something with touch events. 3113 OrionModalPropagation = false; 3114 3115 // Only make the center package clickable, except if the PURCHASE/GET NOW button is clicked. 3116 var element = $(event.target); 3117 var slide = element.parents('.swiper-slide').first(); 3118 if(element.hasClass('orion_button_medium') || (!transition && slide.hasClass('swiper-slide-active'))) 3119 { 3120 OrionPackgeSelectionSwiper.autoplay.stop(); 3121 orionPackagesSelect(OrionPackgeSelection[slide.data('swiper-slide-index')]); 3122 } 3123 } 3124 }, 3125 }, 3126 }); 3127 3128 orionIfView(OrionPackgeSelectionSelector, function() 3129 { 3130 if(OrionPackgeSelectionSwiper) 3131 { 3132 if(!OrionPackgeSelectionSwiper.autoplay.running) 3133 { 3134 OrionPackgeSelectionSwiper.autoplay.start(); 3135 } 3136 } 3137 }, true); 3138} 3139
3140function orionPackagesSwiperUpdate() 3141{ 3142 orionPackagesSwiper(OrionPackgeSelectionSelector, OrionPackgeSelectionSwiper); 3143} 3144 3145function orionPackagesSelect(package) 3146{ 3147 if(orionSessionValid()) 3148 { 3149 if(OrionPaymentsCallback) OrionPaymentsCallback(package); 3150 else orionPanelPaymentsShow(); 3151 } 3152 else 3153 { 3154 orionRegisterShow(); 3155 } 3156} 3157 3158/************************************************************************************************ 3159* PAGE 3160************************************************************************************************/ 3161 3162function orionPage(page) 3163{ 3164 // Important, KeyOneClick has a URL-encoded space at the end of the link. 3165 page = orionLinkDecode(page); 3166 3167 if(page == null) page = 'home'; 3168 var element = $('.orion_page_' + page); 3169 if(element.length == 0) page = 'home'; // Invalid page 3170 element = $('.orion_page_' + page); 3171 if(element.length == 0) return false; 3172 if(!orionVisible(element)) 3173 { 3174 $('.orion_page').hide(); 3175 element.show(); 3176 if(page == 'home') $('.orion_header').removeClass('orion_header_fixed').removeClass('is-sticky'); 3177 else $('.orion_header').addClass('orion_header_fixed is-sticky'); 3178 orionScrollTop(); 3179 return true; 3180 } 3181 return false; 3182} 3183 3184/************************************************************************************************ 3185* HOME 3186************************************************************************************************/ 3187 3188function orionHomeShow(tab) 3189{ 3190 if(tab || !orionPage('home')) orionRedirect(OrionLinkMain, tab); 3191} 3192 3193/************************************************************************************************ 3194* TERMS 3195************************************************************************************************/ 3196 3197function orionTermsShow(tab) 3198{ 3199 if(tab || !orionPage('terms')) orionRedirect(OrionLinkTerms, tab); 3200} 3201 3202function orionDmcaShow(tab) 3203{ 3204 if(tab || !orionPage('dmca')) orionRedirect(OrionLinkDmca, tab); 3205} 3206 3207/************************************************************************************************ 3208* HELP 3209************************************************************************************************/ 3210 3211function orionHelpShow(tab) 3212{ 3213 if(tab || !orionPage('help')) orionRedirect(OrionLinkHelp, tab); 3214} 3215 3216/************************************************************************************************ 3217* FREE 3218************************************************************************************************/ 3219 3220function orionFreeShow(tab) 3221{ 3222 if(tab || !orionPage('free')) orionRedirect(OrionLinkFree, tab); 3223} 3224 3225/************************************************************************************************ 3226* TOR 3227************************************************************************************************/ 3228 3229function orionTorShow(direct) 3230{ 3231 orionModalShow('.orion_tor', direct); 3232} 3233 3234/************************************************************************************************ 3235* BOX 3236************************************************************************************************/ 3237 3238function orionBoxInitialize() 3239{ 3240 var help = $('.orion_help_content'); 3241 $('.orion_box').each(function(i, box) 3242 { 3243 box = $(box); 3244 var title = box.find('.orion_box_title'); 3245 var message = box.find('.orion_box_message'); 3246 title.on('click', function() 3247 { 3248 box.attr('data-mode', orionVisible(message) ? 'hidden' : 'shown'); 3249 message.slideToggle(); 3250 }); 3251 }); 3252} 3253 3254/************************************************************************************************ 3255* WIDGETS 3256************************************************************************************************/ 3257 3258var OrionWidgetsNotify = null; 3259var OrionWidgetsTicket = null; 3260var OrionWidgetsAdmin = null; 3261 3262function orionWidgetsInitialize() 3263{ 3264 $('.orion_widgets > div').each(function(i, widget) 3265 { 3266 widget = $(widget); 3267 if(widget.hasClass('orion_widget_home')) 3268 { 3269 widget.on('click', function(){ orionHomeShow(); }); 3270 } 3271 else if(widget.hasClass('orion_widget_panel')) 3272 { 3273 widget.on('click', function(){ orionPanelShow(); }); 3274 } 3275 else if(widget.hasClass('orion_widget_login')) 3276 { 3277 widget.on('click', function(){ orionLoginOpen(); }); 3278 } 3279 else if(widget.hasClass('orion_widget_logout')) 3280 { 3281 widget.on('click', function(){ orionLogout(); }); 3282 } 3283 else if(widget.hasClass('orion_widget_contact')) 3284 { 3285 widget.on('click', function(){ orionContactShow(); }); 3286 } 3287 else if(widget.hasClass('orion_widget_ticket')) 3288 { 3289 widget.on('click', function() 3290 { 3291 if(OrionWidgetsAdmin) orionAdminTicketShow(OrionWidgetsTicket); 3292 else orionPanelTicketShow(OrionWidgetsTicket); 3293 }); 3294 } 3295 else 3296 { 3297 var icon = widget.find('.orion_widget_icon'); 3298 var box = widget.find('.orion_widget_box'); 3299 icon.on('click', function(event){ orionWidgetsToggle(widget, box); }); 3300 if(!orionMobile()) icon.on('mouseenter', function(){ orionWidgetsShow(widget, box); }); // Not on mobile, otherwise disappears on click. 3301 widget.on('mouseleave', function(){ orionWidgetsHide(widget, box); }); // Apply on widget, to allow the mouse to move inside the box. 3302 } 3303 }); 3304} 3305 3306function orionWidgetsNotify() 3307{ 3308 if(OrionWidgetsNotify) orionConfirmation(OrionWidgetsNotify.message, OrionWidgetsNotify.callbackYes, OrionWidgetsNotify.callbackNo); 3309} 3310 3311function orionWidgetsToggle(widget, box) 3312{ 3313 if(orionVisible(box)) orionWidgetsHide(widget, box); 3314 else orionWidgetsShow(widget, box); 3315} 3316 3317function orionWidgetsShow(widget, box) 3318{ 3319 box.fadeIn('normal'); 3320 if(widget.hasClass('orion_widget_server')) orionWidgetsServerAnimate(); 3321} 3322 3323function orionWidgetsHide(widget, box) 3324{ 3325 if(widget == null && box == null) $('.orion_widgets .orion_widget_box').hide(); 3326 else box.fadeOut('normal'); 3327} 3328 3329function orionWidgetsServer(status, message, usage) 3330{ 3331 var server = $('.orion_widgets .orion_widget_server'); 3332 server.attr('class', 'orion_widget_server orion_widget_server_' + status); 3333 server.find('.orion_widget_title').text('Server ' + status); 3334 server.find('.orion_widget_message').text(message); 3335 orionGaugeProgress(server.find('.orion_widget_server_usage'), usage * 100); 3336} 3337 3338function orionWidgetsServerAnimate() 3339{ 3340 orionGaugeAnimate($('.orion_widgets .orion_widget_server .orion_widget_server_usage')); 3341} 3342 3343function orionWidgetsNotification(title, message, time) 3344{ 3345 var notification = $('.orion_widgets .orion_widget_notification'); 3346 if(title != null) notification.find('.orion_widget_title').text(title); 3347 if(time != null) notification.find('.orion_widget_time').text(orionTimeFormat(time, OrionFormatDateShortTime)); 3348 if(message != null) 3349 { 3350 message = orionStringBbRemove(message); 3351 if(message.length > 500) 3352 { 3353 message = message.substring(0, 500); 3354 message = message.substring(0, message.lastIndexOf(' ')) + ' ...'; 3355 } 3356 notification.find('.orion_widget_message').text(message); 3357 3358 var age = orionTimestamp() - time; 3359 if(age <= 864000) // 10 days. 3360 { 3361 // The orange for "old" it too distracting in the menu. 3362 //notification.attr('class', 'orion_widget_notification orion_widget_notification_' + (age <= 604800 ? 'new' : 'old')); // 1 week. 3363 notification.attr('class', 'orion_widget_notification orion_widget_notification_new'); 3364 } 3365 } 3366} 3367 3368function orionWidgetsNotificationNone() 3369{
3370 orionWidgetsNotification('No New Notifications', 'There are currently no new announcements from the Orion team.') 3371} 3372 3373function orionWidgetsAccount(subscription) 3374{ 3375 var status; 3376 var title; 3377 var message; 3378 var label; 3379 var current = orionTimestamp(); 3380 var never = '<div class="orion_widgets_highlight">never</div> expire'; 3381 3382 if(subscription.package.premium) 3383 { 3384 var remaining = subscription.time.expiration; 3385 if(remaining === null) 3386 { 3387 label = never; 3388 } 3389 else 3390 { 3391 remaining = subscription.time.expiration - current; 3392 if(remaining > 86400) label = 'expire in <div class="orion_widgets_highlight">' + orionTimeDays(remaining, true, null, true).toLowerCase() + '</div>'; 3393 else label = 'expire <div class="orion_widgets_highlight">today</div>'; 3394 } 3395 if(subscription.package.type == 'unlimited') 3396 { 3397 status = 'unlimited'; 3398 title = 'Unlimited Subscription'; 3399 } 3400 else 3401 { 3402 status = 'premium'; 3403 title = 'Premium Subscription'; 3404 } 3405 message = 'Your <div class="orion_widgets_highlight">' + status + '</div> subscription<br/>will ' + label + '.'; 3406 if(remaining !== null && remaining < 604800) // 7 days. 3407 { 3408 OrionWidgetsNotify = {message : message.replace(/<[^>]*>?/gm, ' ').replace(/\s+/gm, ' ') + ' Do you want to renew your subscription now?', callbackYes : function(){ orionPanelNavigate('payments'); } }; 3409 orionPanelInitializeCallbackAdd(orionWidgetsNotify); 3410 status = remaining < 259200 ? 'warning' : 'notification'; // 3 days. 3411 title = 'Subscription Expires'; 3412 message += ' Renew your subscription now to continue with your premium access.'; 3413 } 3414 } 3415 else 3416 { 3417 status = 'free'; 3418 title = 'Free Subscription'; 3419 message = 'Your <div class="orion_widgets_highlight">free</div> subscription<br/>will ' + never + '.'; 3420 } 3421 3422 var widget = $('.orion_widgets .orion_widget_account'); 3423 if(status != null) widget.attr('class', 'orion_widget_account orion_widget_account_' + status); 3424 if(title != null) widget.find('.orion_widget_title').html(title); 3425 if(message != null) widget.find('.orion_widget_message').html(message); 3426} 3427 3428function orionWidgetsTicket(ticket, admin) 3429{ 3430 if(!OrionWidgetsAdmin || admin) 3431 { 3432 OrionWidgetsAdmin = admin; 3433 var widget = $('.orion_widgets .orion_widget_ticket'); 3434 if(ticket && ticket.status == 'open') 3435 { 3436 OrionWidgetsTicket = ticket.id; 3437 widget.attr('class', 'orion_widget_ticket orion_widget_ticket_' + ((ticket.last && !OrionWidgetsAdmin) || (!ticket.last && OrionWidgetsAdmin) ? 'wait' : 'new')); 3438 } 3439 else 3440 { 3441 OrionWidgetsTicket = null; 3442 widget.attr('class', 'orion_widget_ticket'); 3443 } 3444 } 3445} 3446 3447/************************************************************************************************ 3448* NOTIFICATIONS 3449************************************************************************************************/ 3450 3451function orionNotificationsUpdate(notifications) 3452{ 3453 var entries = []; 3454 $.each(notifications, function(i, notification) 3455 { 3456 entries.push({ 3457 'title' : notification['content']['title'], 3458 'message' : orionStringBbDecode(notification['content']['message']), 3459 'time' : orionTimeFormat(notification['time']['added'], OrionFormatDateReadable), 3460 }); 3461 }); 3462 orionTimelineUpdate($('.orion_notifications'), entries, 'fas fa-bullhorn'); 3463} 3464 3465/************************************************************************************************ 3466* TIMELINE 3467************************************************************************************************/ 3468 3469function orionTimelineInitialize() 3470{ 3471 $('.orion_timeline').each(function(i, timeline) 3472 { 3473 timeline = $(timeline); 3474 // For some reason orionInView() does not work here. 3475 // Create a similar procedure, but use orionVisible() instead of orionInView() 3476 orionIfVisible(timeline, orionTimelineRefresh); 3477 }); 3478} 3479 3480function orionTimelineRefresh() 3481{ 3482 // Adjusted function in the verticaltimeline library script. 3483 verticalTimelineExecute(); 3484} 3485 3486function orionTimelineUpdate(selector, entries, icon) 3487{ 3488 selector = $(selector); 3489 var markup = ''; 3490 var notification = selector.hasClass('orion_notifications'); 3491 3492 $.each(entries, function(i, entry) 3493 { 3494 var side; 3495 if(orionObjectContains(entry, 'side')) side = 'orion_timeline_' + entry['side']; 3496 else side = i % 2 ? 'orion_timeline_left' : 'orion_timeline_right';
3497 3498 var attachments = ''; 3499 if(orionObjectContains(entry, 'attachments')) 3500 { 3501 entry['attachments'].forEach(function(attachment) 3502 { 3503 var extension = orionFileExtension(attachment['name'], attachment['type']); 3504 var size = orionSizeFormat(attachment['size']); 3505 var virus = ''; 3506 if(orionObjectContains(attachment, 'virus')) 3507 { 3508 virus = attachment['virus']; 3509 if(virus === false) virus = orionStatusLabel('good', 'Virus Free'); 3510 else if(virus === null) virus = orionStatusLabel('medium', 'Virus Scan'); 3511 else virus = orionStatusLabel('bad', 'Virus Found', virus); 3512 virus += ' • '; 3513 } 3514 attachments += '<a href="' + attachment['link'] + '" target="_blank"><i class="fas fa-paperclip"></i>• ' + virus + extension + ' • ' + size + ' • ' + attachment['name'] + '</a>'; 3515 }); 3516 } 3517 3518 markup += '\ 3519 <div class="' + side + ' orion_timeline_block cd-timeline__block js-cd-block">\ 3520 <div class="cd-timeline__img cd-timeline__img--picture js-cd-img">\ 3521 <i class="' + icon + '"></i>\ 3522 </div>\ 3523 <div class="orion_timeline_content cd-timeline__content js-cd-content">\ 3524 ' + (orionObjectContains(entry, 'title') ? ('<div class="orion_timeline_title">' + entry['title'] + '</div>') : '') + '\ 3525 ' + (orionObjectContains(entry, 'message') ? ('<p>' + entry['message'] + '</p>') : '') + '\ 3526 <div class="orion_timeline_more"></div>\ 3527 ' + (attachments ? ('<div class="orion_timeline_attachments_title">Attachments</div><div class="orion_timeline_attachments">' + attachments + '</div>') : '') + '\ 3528 ' + (orionObjectContains(entry, 'time') ? ('<span class="cd-timeline__date">' + entry['time'] + '</span>') : '') + '\ 3529 </div>\ 3530 </div>\ 3531 '; 3532 }); 3533 3534 // Add the script again in order to reinitialize the elements for bouncy animation. 3535 // This reloads the script. Although it should load the cached version of the script, this approach is not optimal. 3536 // Instead edit the verticaltimeline script to not execute the code once the script is loaded, but rather reely on orionTimelineInitialize().. 3537 //markup += $('script[src*="verticaltimeline"]').first().prop('outerHTML'); 3538 3539 selector.find('.orion_timeline_container').html(markup); 3540 3541 orionIfVisible(selector, function() 3542 { 3543 selector.find('.orion_timeline_content').each(function(i, content) 3544 { 3545 content = $(content); 3546 if(!content.data('overflow')) 3547 { 3548 content.data('overflow', 'true'); 3549 var par = content.find('p'); 3550 var height = par.prop('scrollHeight'); 3551 if(par.height() < height) 3552 { 3553 var expanded = notification; 3554 var more = content.find('.orion_timeline_more'); 3555 function orionTimelineToggle(action) 3556 { 3557 if(expanded) 3558 { 3559 expanded = false; 3560 more.html('<i class="fas fa-caret-down"></i> Show More'); 3561 par.animate({'max-height' : '200px'}, action ? 500 : 0); 3562 if(action) orionScrollTop(content.offset().top - 100); 3563 } 3564 else 3565 { 3566 expanded = true; 3567 more.html('<i class="fas fa-caret-up"></i> Show Less'); 3568 par.animate({'max-height' : height}, action ? 500 : 0); 3569 } 3570 } 3571 3572 more.css('display', 'table'); 3573 orionTimelineToggle(); 3574 (notification ? content : more).on('click', function(){ orionTimelineToggle(true); }); 3575 } 3576 } 3577 }); 3578 }); 3579} 3580 3581/************************************************************************************************ 3582* STATS 3583************************************************************************************************/ 3584 3585function orionStatsUpdate(stats) 3586{ 3587 ['streams', 'hashes', 'containers'].forEach(function(type) 3588 { 3589 var counter = $('.orion_stats_counter_' + type + ' .orion_stats_counter_count'); 3590 counter.text(orionThousands(stats.count[type])); 3591 var width = counter.width(); 3592 counter.text(stats.count[type]); 3593 3594 function counterUpdate() 3595 { 3596 var last = 0; 3597 counter.css('min-width', width); 3598 counter.each(function() 3599 { 3600 // Needed to restart animation. 3601 counter.text(stats.count[type]); 3602 counter.removeAttr('style').stop(true); 3603 3604 var item = $(this); 3605 item.prop('count', 0).animate( 3606 { 3607 count : item.text() 3608 }, 3609 { 3610 duration : 2000, 3611 easing : 'swing', 3612 step : function(now) 3613 { 3614 now = Math.ceil(now); 3615 if(!isNaN(now) && now > last) 3616 { 3617 last = now;
3618 item.text(orionThousands(now)); 3619 } 3620 }, 3621 complete : function() 3622 { 3623 item.css('min-width', 0); 3624 }, 3625 }); 3626 }); 3627 } 3628 3629 $('body').on('menustatistics', counterUpdate); 3630 orionIfView(counter, counterUpdate); 3631 }); 3632} 3633 3634/************************************************************************************************ 3635* GAUGE 3636************************************************************************************************/ 3637 3638function orionGaugeInitialize(selector) 3639{ 3640 if(selector == null) selector = $('.orion_gauge'); 3641 else selector = $(selector); 3642 $(selector).each(function(i, gauge) 3643 { 3644 gauge = $(gauge); 3645 if(gauge.data('style') == null) gauge.data('style', 'Arch'); 3646 if(gauge.data('append') == null) gauge.data('append', '%'); 3647 if(gauge.data('percent') == null) gauge.data('percent', 0); 3648 if(gauge.data('width') == null) gauge.data('width', 20); 3649 if(gauge.data('color') == null) gauge.data('color', '#47CAE9'); 3650 if(gauge.data('back') == null) gauge.data('back', '#FFFFFF'); 3651 if(gauge.data('animationstep') == null) gauge.data('animationstep', 2); 3652 gauge.css('height', parseInt(parseInt(gauge.data('size')) * 0.8)); 3653 gauge.gaugeMeter(); 3654 }); 3655} 3656 3657function orionGaugeAnimate(selector) 3658{ 3659 $(selector).gaugeMeter(); 3660} 3661 3662function orionGaugeProgress(selector, percent) 3663{ 3664 selector = $(selector); 3665 selector.data('percent', parseInt(orionRound(percent, 0))); 3666 selector.gaugeMeter(); 3667} 3668 3669/************************************************************************************************ 3670* PROGRESSBAR 3671************************************************************************************************/ 3672 3673function orionProgressbarUpdate(selector, percentage) 3674{ 3675 selector = $(selector); 3676 percentage = Math.max(0, Math.min(1, percentage)); 3677 percentage = orionRound(percentage * 100, 0) + '%'; 3678 selector.find('.orion_progressbar_label').text(percentage); 3679 selector.find('.orion_progressbar_inner').css('width', percentage); 3680} 3681 3682/************************************************************************************************ 3683* PROGRESSMINI 3684************************************************************************************************/ 3685 3686function orionProgressMini(percentage) 3687{ 3688 percentage = Math.max(0, Math.min(1, percentage)); 3689 var color = orionColorMix(percentage, '#DE636F', '#CA8416', '#1ABB9C'); 3690 percentage = orionRound(percentage * 100, 0); 3691 return '<div class="orion_progressmini"><div style="width: ' + percentage + '%; background-color: ' + color + ';"></div></div>'; 3692} 3693 3694/************************************************************************************************ 3695* BUTTON 3696************************************************************************************************/ 3697 3698function orionButtonLoaderShow(selector) 3699{ 3700 var button = $(selector); 3701 button.find('.orion_input_button_icon').hide(); 3702 button.find('.orion_input_button_loader').css('display', 'inline-block'); 3703 orionProgressStart(); 3704} 3705 3706function orionButtonLoaderHide(selector) 3707{ 3708 var button = $(selector); 3709 button.find('.orion_input_button_loader').hide(); 3710 button.find('.orion_input_button_icon').css('display', 'inline-block'); 3711 orionProgressStop(); 3712} 3713 3714/************************************************************************************************ 3715* CHECK 3716************************************************************************************************/ 3717 3718function orionCheckInitialize() 3719{ 3720 var check = $('.orion_check'); 3721 check.find('a').on('click', function(event) 3722 { 3723 // Unclick after a link in the checkbox label was clicked. 3724 var input = check.find('input'); 3725 var checked = orionChecked(input); 3726 var clicked = function() 3727 { 3728 input.prop('checked', checked); 3729 check.off('click', clicked); 3730 }; 3731 check.on('click', clicked); 3732 event.stopPropagation(); 3733 }); 3734 check.on('click', function(event) 3735 { 3736 event.stopPropagation(); 3737 }); 3738} 3739 3740/************************************************************************************************ 3741* NOTIFICATION 3742************************************************************************************************/ 3743 3744var OrionNotificationTimeout = 5000; 3745 3746function orionNotificationClose() 3747{ 3748 Noty.closeAll(); 3749} 3750 3751function orionConfirmation(message, callbackYes, callbackNo) 3752{ 3753 orionNotification(message, 'confirm', OrionNotificationTimeout, callbackYes, callbackNo); 3754} 3755 3756function orionNotificationTitle(title, message, type, timeout, callbackYes, callbackNo) 3757{ 3758 orionNotification('<b>' + title + '</b><br/>' + message, type, timeout, callbackYes, callbackNo); 3759} 3760 3761// type: alert, success, error, warning, info, confirm 3762function orionNotification(message, type, timeout, callbackYes, callbackNo) 3763{ 3764 if(type == null) type = 'info'; 3765 if(timeout === undefined || timeout === null) timeout = OrionNotificationTimeout; 3766 var text = "<table class='orion_notification'><tr>"; 3767 if(type != "confirm") 3768 { 3769 text += "<td><i class='orion_notification_icon fas fa-"; 3770 if(type == "error" || type == "warning") text += "exclamation-triangle"; 3771 else if(type == "alert") text += "exclamation-circle"; 3772 else if(type == "success") text += "check-circle"; 3773 else if(type == "info") text += "info-circle"; 3774 text += "'></i></td>"; 3775 } 3776 text += "<td class='orion_notification_text'>" + message + "</td></tr></table>"; 3777 if(type == "confirm") timeout = false;
3778 3779 var noty; 3780 var close = 'click'; 3781 var buttons = null; 3782 if(type == "confirm") 3783 { 3784 var close = 'button'; 3785 buttons = 3786 [ 3787 Noty.button("<i class='fas fa-check orion_icon'></i>", 'orion_notification_button orion_notification_yes', function() 3788 { 3789 noty.close(); 3790 if(callbackYes != null) callbackYes(); 3791 }), 3792 Noty.button("<i class='fas fa-times orion_icon'></i>", 'orion_notification_button orion_notification_no', function() 3793 { 3794 noty.close(); 3795 if(callbackNo != null) callbackNo(); 3796 }), 3797 ]; 3798 } 3799 3800 noty = new Noty( 3801 { 3802 theme : 'sunset', 3803 layout : 'topRight', 3804 type : type, 3805 text : text, 3806 timeout : timeout, 3807 buttons : buttons, 3808 closeWith : [close], 3809 animation : 3810 { 3811 // NB: Do not use the custom animation on mobile devices (actual touch screen devices, not the emulation in developers tools). 3812 // Otherwise the notificattion fails for an unknown reason on mobile devices. 3813 // The notification does not show, BUT the noty div (which is invisible) is still in the HTML. This invisible divs makes clicks on other elements impossible (eg: the right-hand side of the "Search" side menu option). 3814 open : orionMobile() ? 'animated bounceInRight' : function (promise) 3815 { 3816 var n = this; 3817 var Timeline = new mojs.Timeline(); 3818 var body = new mojs.Html( 3819 { 3820 el : n.barDom, 3821 x : {500: 0, delay: 0, duration: 500, easing: 'elastic.out'}, 3822 isForce3d : true, 3823 onComplete : function() 3824 { 3825 promise(function(resolve) 3826 { 3827 resolve(); 3828 }); 3829 } 3830 }); 3831 3832 var parent = new mojs.Shape( 3833 { 3834 parent : n.barDom, 3835 width : 200, 3836 height : n.barDom.getBoundingClientRect().height, 3837 radius : 0, 3838 x : {150 : -150}, 3839 duration : 1.2 * 500, 3840 isShowStart : true 3841 }); 3842 3843 n.barDom.style['overflow'] = 'visible'; 3844 parent.el.style['overflow'] = 'hidden'; 3845 3846 var burst = new mojs.Burst( 3847 { 3848 parent : parent.el, 3849 count : 10, 3850 top : n.barDom.getBoundingClientRect().height + 75, 3851 degree : 90, 3852 radius : 75, 3853 angle : {0 : 40}, 3854 children : 3855 { 3856 fill : 'rgba(200, 200, 200, 0.5)', 3857 delay : 'stagger(500, -50)', 3858 radius : 'rand(8, 25)', 3859 direction: -1, 3860 isSwirl : true 3861 } 3862 }); 3863 3864 var fadeBurst = new mojs.Burst( 3865 { 3866 parent : parent.el, 3867 count : 2, 3868 degree : 0, 3869 angle : 75, 3870 radius : {0: 100}, 3871 top : '90%', 3872 children : 3873 { 3874 fill : 'rgba(250, 250, 250, 0.5)', 3875 pathScale : [.65, 1], 3876 radius : 'rand(12, 15)', 3877 direction : [-1, 1], 3878 delay : 0.8 * 500, 3879 isSwirl : true 3880 } 3881 }); 3882 3883 Timeline.add(body, burst, fadeBurst, parent); 3884 Timeline.play(); 3885 }, 3886 // This causes the notification to be unclosable if tabs are switched while the notification is showing. 3887 /*close : function (promise) 3888 { 3889 var n = this; 3890 new mojs.Html( 3891 { 3892 el : n.barDom, 3893 x : {0: 500, delay: 10, duration: 500, easing: 'cubic.out'}, 3894 skewY : {0: 10, delay: 10, duration: 500, easing: 'cubic.out'}, 3895 isForce3d : true, 3896 onComplete: function() 3897 { 3898 promise(function(resolve) 3899 { 3900 resolve(); 3901 }) 3902 } 3903 }).play(); 3904 },*/ 3905 close: 'animated bounceOutRight', 3906 }, 3907 }).show(); 3908} 3909 3910/************************************************************************************************ 3911* CLIPBOARD 3912************************************************************************************************/ 3913 3914function orionClipboard(selector, notification) 3915{ 3916 selector = $(selector); 3917 var label = selector.attr('placeholder'); 3918 if(label != null && label != '') label += ' '; 3919 $(selector).select(); 3920 document.execCommand('copy'); 3921 if(notification) orionNotification(label + 'Copied To Clipboard'); 3922} 3923 3924function orionClipboardCopy(string, label) 3925{ 3926 var selector = document.createElement('textarea'); 3927 selector.value = string; 3928 3929 // Cannot use "display" or "visibility", otherwise the focus is not always working and the text not copied. 3930 selector.style.opacity = '0'; 3931 selector.style.zIndex = '-1'; 3932 selector.style.position = 'fixed'; 3933 3934 document.body.appendChild(selector); 3935 selector.focus(); 3936 selector.select(); 3937 document.execCommand('copy'); 3938
3939 if(label) orionNotification(label + ' Copied To Clipboard'); 3940} 3941 3942/************************************************************************************************ 3943* DOWNLOAD 3944************************************************************************************************/ 3945 3946function orionDownload(link, name) 3947{ 3948 // This does not always trigger the browser's download dialog. 3949 // Sometimes the browser will simply open a new tab and display the file, instead of triggering the download. 3950 // This depends on the browser and the file type. For instance, most browsers will show videos and images in the tab, but other files that cannot be displayed are downloaded. 3951 // None of the proposed solutions guarantee the download dialog to pop up. 3952 // The <a> ""download" attribute is only for Same-Origin. 3953 // The only way is to set the "Content-Disposition" to "attachment" on the server side, but since the URL might point to an external server, we do not have control over this. 3954 if(!name) name = link.substr(link.lastIndexOf('/') + 1); 3955 var element = document.createElement('a');
3956 element.download = name; 3957 element.href = link; 3958 element.target = '_blank'; 3959 element.style.display = 'none'; 3960 document.body.appendChild(element); 3961 element.click(); 3962 document.body.removeChild(element); 3963 setTimeout(function(){ URL.revokeObjectURL(element.href); }, 1000); 3964} 3965 3966function orionDownloadFile(fileData, fileType, fileName) 3967{ 3968 var blob = new Blob([fileData], {type : fileType}); 3969 var link = document.createElement('a'); 3970 link.download = fileName; 3971 link.href = URL.createObjectURL(blob); 3972 link.dataset.downloadurl = [fileType, link.download, link.href].join(':'); 3973 link.style.display = 'none'; 3974 document.body.appendChild(link); 3975 link.click(); 3976 document.body.removeChild(link); 3977 setTimeout(function(){ URL.revokeObjectURL(link.href); }, 1000); 3978} 3979 3980/************************************************************************************************ 3981* INFO 3982************************************************************************************************/ 3983 3984function orionInfoUpdate(selector, item, value) 3985{ 3986 selector = $(selector); 3987 selector.find(item + ' .orion_info_value').html(value); 3988} 3989 3990/************************************************************************************************ 3991* EMAIL 3992************************************************************************************************/ 3993 3994function orionEmail() 3995{ 3996 return orionObfuscate(OrionEmail); 3997} 3998 3999function orionEmailInitialize() 4000{ 4001 $('.orion_email').on('click mouseover', function() 4002 { 4003 var element = $(this); 4004 if(!element.hasClass('orion_active')) 4005 { 4006 var email = orionEmail(); 4007 element.removeClass('orion_active').addClass('orion_active'); 4008 element.html('<a href="mailto:' + email + '">' + email + '</div>'); 4009 } 4010 }); 4011} 4012 4013/************************************************************************************************ 4014* INPUT 4015************************************************************************************************/ 4016 4017function orionInputInitialize() 4018{ 4019 $('.orion_input_copy .orion_input_icon, .orion_input_copy .orion_input_action').on('click', function(event) 4020 { 4021 var input = $(this).parent('.orion_input_copy').find('input'); 4022 orionClipboard(input, true); 4023 input.blur(); 4024 event.stopPropagation(); 4025 }); 4026 $('.orion_input_copy_label').on('click', function() 4027 { 4028 orionClipboard($(this).siblings('.orion_input_copy').find('input'), true); 4029 }); 4030 $('.orion_input_copy').on('click', function() 4031 { 4032 orionClipboard($(this).find('input')); 4033 }); 4034 4035 $('.orion_input input[data-case]').on('change keydown paste input', function() 4036 { 4037 var input = $(this); 4038 var value = input.val(); 4039 var cased = input.attr('data-case'); 4040 if(cased == 'upper') value = value.toUpperCase(); 4041 else if(cased == 'lower') value = value.toLowerCase(); 4042 input.val(value); 4043 }); 4044 4045 $('.orion_input input[data-pattern]').on('change keydown paste input', function() 4046 { 4047 var input = $(this); 4048 var value = input.val(); 4049 var pattern = input.attr('data-pattern'); 4050 var result = value.match(new RegExp(pattern, 'g')); 4051 if(result) input.val(result.join('')); 4052 }); 4053 4054 $('.orion_input input[data-separator]').on('change keydown paste input', function() 4055 { 4056 var input = $(this); 4057 var value = input.val(); 4058 var result = ''; 4059 4060 var separator = parseInt(input.attr('data-separator')); 4061 var maximum = input.attr('maxlength'); 4062 if(maximum) maximum = parseInt(maximum); 4063 4064 var groups = value.replace('-', '').match(new RegExp('.{1,' + separator + '}', 'g')); 4065 for(var i in groups) 4066 { 4067 var length = groups[i].length; 4068 if(groups[i] && length % separator === 0 && (!maximum || result.length + length < maximum)) result += groups[i] + '-'; 4069 else result += groups[i]; 4070 } 4071 input.val(result); 4072 }); 4073} 4074 4075function orionInputElement(selector) 4076{ 4077 return $(selector).find('input'); 4078} 4079 4080function orionInputContainer(selector) 4081{ 4082 return $(selector).parents('.orion_input').first(); 4083} 4084 4085function orionInputValue(selector, value) 4086{ 4087 selector = $(selector); 4088 var tagname = selector.prop('tagName').toLowerCase(); 4089 4090 if(tagname == 'textarea') 4091 { 4092 if(value == null) return selector.text(); 4093 else return selector.text(value); 4094 } 4095 else if(tagname != 'input') 4096 { 4097 selector = orionInputElement(selector); 4098 } 4099 4100 if(value == null) 4101 { 4102 return selector.val(); 4103 } 4104 else 4105 { 4106 selector.parent().siblings('.orion_input_copy_label').html(value); 4107 return selector.val(value); 4108 } 4109} 4110 4111function orionInputClear(selector) 4112{ 4113 return orionInputValue(selector, ''); 4114} 4115 4116function orionInputControls(selector, tagOpen, tagClose) 4117{ 4118 var area = $(selector).parents('.orion_input_wrapper').find('textarea'); 4119 var start = area[0].selectionStart; 4120 var end = area[0].selectionEnd; 4121 var value = area.val(); 4122 var replacement = tagOpen + value.substring(start, end).replace(tagOpen, '').replace(tagClose, '') + tagClose; 4123 value = value.substring(0, start) + replacement + value.substring(end, value.length); 4124 area.val(value); 4125} 4126 4127function orionInputControlsBold(selector) 4128{ 4129 orionInputControls(selector, '[B]', '[/B]'); 4130} 4131 4132function orionInputControlsItalic(selector) 4133{ 4134 orionInputControls(selector, '[I]', '[/I]'); 4135} 4136 4137function orionInputControlsUnderline(selector) 4138{ 4139 orionInputControls(selector, '[U]', '[/U]'); 4140} 4141 4142function orionInputControlsLink(selector) 4143{ 4144 orionInputControls(selector, '[URL]', '[/URL]'); 4145} 4146 4147function orionInputFileElement(selector, index) 4148{ 4149 selector = $(selector); 4150 if(index === undefined) 4151 { 4152 var result = selector.parents('.orion_input_file'); 4153 if(result.length == 0) result = selector.siblings('.orion_input_file'); 4154 return result.first(); 4155 } 4156 else 4157 { 4158 var result = selector.parents('.orion_input_file_' + index); 4159 if(result.length == 0) result = selector.siblings('.orion_input_file_' + index); 4160 return result.first(); 4161 } 4162} 4163 4164function orionInputFileCount(selector) 4165{ 4166 var count = 0; 4167 var attachments = orionInputFileElement(selector).find('.orion_input_box'); 4168 $.each(attachments, function(i, attachment) 4169 { 4170 if(orionVisible(attachment)) count++; 4171 }); 4172 return count; 4173} 4174 4175function orionInputFileIndex(selector) 4176{ 4177 var index = -1; 4178 var attachments = orionInputFileElement(selector).find('.orion_input_box'); 4179 $.each(attachments, function(i, attachment) 4180 { 4181 if(!orionVisible(attachment)) 4182 { 4183 index = i; 4184 return false;
4185 } 4186 }); 4187 return index; 4188} 4189 4190function orionInputFileEqual(file1, file2) 4191{ 4192 if((file1 && !file2) || (!file1 && file2)) return false; 4193 return file1.name == file2.name && file1.size == file2.size && file1.type == file2.type && file1.lastModified == file2.lastModified; 4194} 4195 4196function orionInputFileSelect(selector) 4197{ 4198 orionInputFileElement(selector, orionInputFileIndex(selector)).find('input[type=file]').click(); 4199} 4200 4201function orionInputFileProcess(selector, index) 4202{ 4203 selector = orionInputFileElement(selector, index); 4204 var file = selector.find('input[type=file]')[0].files[0]; 4205 if(file) 4206 { 4207 var maximum = parseInt(orionInputFileElement(selector).data('size')); 4208 if(file.size > maximum) 4209 { 4210 orionNotification('The file is too large and exceeds the maximum size of ' + orionSizeFormat(maximum, 0) + ' . Try zipping your files. If you are uploading a Kodi log, disable the logging option in Kodi\'s system settings to reduce the log size.', 'error'); 4211 } 4212 else 4213 { 4214 var contains = false; 4215 var files = orionInputFileElement(selector).find('.orion_input_box:not(.orion_input_file_' + index + ')').find('input[type=file]'); 4216 $.each(files, function(i, f) 4217 { 4218 f = f.files[0]; 4219 if(orionInputFileEqual(file, f)) 4220 { 4221 contains = true; 4222 return false; 4223 } 4224 }); 4225 4226 if(contains) 4227 { 4228 orionNotification('You already attached this file.', 'error'); 4229 } 4230 else 4231 { 4232 selector.find('.orion_input_file_name').html(file.name); 4233 selector.find('.orion_input_file_type').html(orionFileExtension(file.name, file.type)); 4234 selector.find('.orion_input_file_size').html(orionSizeFormat(file.size)); 4235 selector.show(); 4236 if(orionInputFileIndex(selector) < 0) orionInputFileElement(selector).children('.orion_input_button').hide(); 4237 return true; 4238 } 4239 } 4240 } 4241 4242 // Clear if something went wrong. 4243 orionInputFileDelete(selector.find('input[type=file]'), index); 4244 return false; 4245} 4246 4247function orionInputFileDelete(selector, index) 4248{ 4249 selector = orionInputFileElement(selector, index); 4250 orionInputClear(selector.find('input[type=file]')); 4251 selector.find('.orion_input_file_name').html(''); 4252 selector.find('.orion_input_file_type').html(''); 4253 selector.find('.orion_input_file_size').html(''); 4254 selector.hide(); 4255 if(orionInputFileIndex(selector) >= 0) orionInputFileElement(selector).children('.orion_input_button').show(); 4256} 4257 4258function orionInputFileClear(selector) 4259{ 4260 selector = $(selector); 4261 if(selector.length > 0) 4262 { 4263 orionInputClear(selector.find('input[type=file]')); 4264 selector.find('.orion_input_file_name').html(''); 4265 selector.find('.orion_input_file_type').html(''); 4266 selector.find('.orion_input_file_size').html(''); 4267 selector.find('.orion_input_box').hide(); 4268 selector.children('.orion_input_button').show(); 4269 } 4270} 4271 4272function orionInputFileData(selector, callback) 4273{ 4274 selector = $(selector); 4275 if(selector.length > 0) 4276 { 4277 var result = []; 4278 var files = []; 4279 var inputs = selector.find('input[type=file]'); 4280 $.each(inputs, function(i, input) 4281 { 4282 var file = input.files[0]; 4283 if(file) files.push(file); 4284 }); 4285 if(files && files.length > 0) orionInputFileRead(files, result, callback); 4286 else callback(true, null); 4287 } 4288 else 4289 { 4290 callback(true, null); 4291 } 4292} 4293 4294function orionInputFileRead(files, result, callback) 4295{ 4296 var file = files.pop(); 4297 var reader = new FileReader(); 4298 reader.readAsDataURL(file); 4299 reader.onload = function() 4300 { 4301 result.push({'name' : file.name, 'data' : reader.result}); 4302 if(files.length > 0) orionInputFileRead(files, result, callback); 4303 else callback(true, result); 4304 }; 4305 reader.onerror = function(error) 4306 { 4307 console.error('Error reading file.'); 4308 try{ console.error(error); }catch(e){} 4309 try{ console.error(file); }catch(e){} 4310 orionNotification('For some reason the file <i>' + file.name + '</i> could not be accessed. Please remove the file and try again.', 'error'); 4311 callback(false, result); 4312 }; 4313} 4314 4315/************************************************************************************************ 4316* FORM 4317************************************************************************************************/ 4318 4319function orionFormInitialize() 4320{ 4321 $('.orion_form').each(function(i, form) 4322 { 4323 form = $(form); 4324 form.find('.orion_input_box[data-enter]').each(function(i, input) 4325 { 4326 input = $(input); 4327 input.on('keypress', function(event) 4328 { 4329 if(event.keyCode === 13) 4330 { 4331 form.find('.orion_input_button').click(); 4332 } 4333 }); 4334 }); 4335 4336 // Prevent the form to be automatically submitted on button click. 4337 form.on('submit', function(event) 4338 { 4339 event.preventDefault(); 4340 }); 4341 }); 4342} 4343 4344function orionFormSubmit(form, button) 4345{ 4346 if(button === undefined) button = form.find('.orion_input_button').first(); 4347 button.click(); 4348} 4349 4350function orionFormSend(button, action, confirmation) 4351{ 4352 button = $(button); 4353 var form = button.parents('.orion_form'); 4354 var event = button.attr('onclick'); // Disable consecutive clicks.
4355 button.attr('onclick', ''); 4356 orionFormReset(form); 4357 if(confirmation == null) 4358 { 4359 orionFormExecute(button, action, form, event); 4360 } 4361 else 4362 { 4363 if(confirmation.startsWith('orion')) 4364 { 4365 confirmation = window[confirmation](orionValidate(form)); 4366 } 4367 orionConfirmation(confirmation, 4368 function() 4369 { 4370 orionFormExecute(button, action, form, event); 4371 }, 4372 function() 4373 { 4374 button.attr('onclick', event); 4375 } 4376 ); 4377 } 4378} 4379 4380function orionFormExecute(button, action, form, event) 4381{ 4382 if(data = orionValidate(form)) 4383 { 4384 orionInputFileData(form.find('.orion_input_file'), function(success, files) 4385 { 4386 if(success) 4387 { 4388 var loader = button.find('.orion_input_button_loader').length > 0; 4389 if(files && files.length > 0) data.files = files; 4390 if(loader) orionButtonLoaderShow(button); 4391 4392 if(action.toString().match(/^function\s*\(\s*\)/)) // Anonymous function (eg: debrid account "Free Offers" button). 4393 { 4394 action(); 4395 button.attr('onclick', event); 4396 if(loader) orionButtonLoaderHide(button); 4397 } 4398 else 4399 { 4400 action(form, data, function() 4401 { 4402 button.attr('onclick', event); 4403 if(loader) orionButtonLoaderHide(button); 4404 }); 4405 } 4406 } 4407 else 4408 { 4409 button.attr('onclick', event); 4410 } 4411 }); 4412 } 4413 else 4414 { 4415 button.attr('onclick', event); 4416 } 4417} 4418 4419function orionFormReset(selector) 4420{ 4421 $(selector).find('.orion_form_success').empty().hide(); 4422 $(selector).find('.orion_form_error').empty().hide(); 4423} 4424 4425function orionFormSuccess(selector, message) 4426{ 4427 selector = $(selector) 4428 selector.parent().find('.orion_form_warning').hide(); 4429 selector.find('.orion_form_success').html(message).fadeIn('normal'); 4430 setTimeout(function(){ orionButtonLoaderHide(selector); }, 500); // Wait a big to allow redirection (eg: login). 4431 return true; 4432} 4433 4434function orionFormError(selector, message) 4435{ 4436 selector = $(selector) 4437 selector.parent().find('.orion_form_warning').hide(); 4438 selector.find('.orion_form_error').html(message).fadeIn('normal'); 4439 orionButtonLoaderHide(selector); 4440 return false; 4441} 4442 4443function orionFormClear(selector, status) 4444{ 4445 selector = $(selector); 4446 selector.find('input[type=password]').val(''); 4447 selector.find('input[type=text]').val(''); 4448 selector.find('input[type=number]').val(''); 4449 selector.find('textarea').val(''); 4450 selector.find('.orion_hidden').hide(); 4451 4452 if(status === undefined || status) 4453 { 4454 selector.find('.orion_form_success').empty(); 4455 selector.find('.orion_form_error').empty(); 4456 } 4457 4458 var email = selector.find('input[type=email]'); 4459 if(email && email.length > 0) 4460 { 4461 email.val(''); 4462 var defaultValue = email.data('default'); 4463 if(defaultValue) email.val(defaultValue); 4464 } 4465 4466 orionSelectorReset(selector.find('.orion_selector')); 4467 orionUncheck(selector.find('input[type=checkbox]')); 4468 orionInputFileClear(selector.find('.orion_input_file')); 4469} 4470 4471function orionFormInput(selector, name) 4472{ 4473 selector = $(selector); 4474 return orionInputContainer(selector.find('input[name=' + name + ']')); 4475} 4476 4477/************************************************************************************************ 4478* MODAL 4479************************************************************************************************/ 4480 4481var OrionModalPropagation = true; 4482var OrionModalCloseCallbacks = []; 4483 4484function orionModalInitialize() 4485{ 4486 $('.orion_modal').each(function(i, modal) 4487 { 4488 modal = $(modal); 4489 if(modal.hasClass('orion_modal_fixed')) 4490 { 4491 modal.find('.orion_modal_close').hide(); 4492 } 4493 else 4494 { 4495 modal.on('click', function() 4496 { 4497 if(OrionModalPropagation) 4498 { 4499 modal.fadeOut('normal'); 4500 orionModalCloseEvent(modal); 4501 } 4502 OrionModalPropagation = true; 4503 }); 4504 modal.find('.orion_modal_box a').on('click', function(event){ event.stopPropagation(); }); // Allow links to be clicked in modals. 4505 modal.find('.orion_modal_box').on('click', function(){ return false; }); 4506 modal.find('.orion_modal_close').on('click', function(){ 4507 modal.fadeOut('normal'); 4508 orionModalCloseEvent(modal); 4509 }); 4510 } 4511 }); 4512 4513 $(window).resize(function(){ orionModalResize(); }); 4514} 4515 4516function orionModalResize(selector) 4517{ 4518 // It is impossible to have a parent with max-height:100% and a scrollable child with max-height:100%. Do it in JS instead. 4519 if(selector === undefined) selector = $('.orion_modal'); 4520 else selector = $(selector); 4521 selector.each(function(i, modal) 4522 { 4523 modal = $(modal); 4524 var box = modal.find('.orion_modal_box'); 4525 var content = modal.find('.orion_modal_content'); 4526 var title = modal.find('.orion_modal_title'); 4527 var height = $(window).height() - Math.abs(modal.height() - modal.innerHe
4527ight()) - Math.abs(box.height() - box.innerHeight()) - title.outerHeight(true); 4528 4529 // For file dialog in the panel search. 4530 var expression = /calc.*?(\d+)px/; 4531 var match = expression.exec(box.css('max-height')); 4532 if(match && match.length == 2 && match[1]) height -= parseInt(match[1]); 4533 4534 var heightMinimum = box.css('min-height'); 4535 if(heightMinimum) 4536 { 4537 heightMinimum = parseInt(heightMinimum = heightMinimum.replace('px', '')); 4538 heightMinimum = heightMinimum - Math.abs(box.height() - box.innerHeight()) - title.outerHeight(true); 4539 } 4540 if(heightMinimum) modal.find('.orion_modal_content').css('min-height', heightMinimum); // Reegister type dialog. 4541 modal.find('.orion_modal_content').css('max-height', height); 4542 }); 4543} 4544 4545function orionModalShow(selector, direct, close) 4546{ 4547 selector = $(selector); 4548 if(direct === undefined) direct = false; 4549 if(close === undefined || close) orionModalClose(); 4550 if(direct) selector.show(); 4551 else selector.fadeIn('normal'); 4552 orionModalResize(selector); 4553} 4554 4555function orionModalUpdate(selector, content, direct, close) 4556{ 4557 selector = $(selector); 4558 selector.find('.orion_modal_content').html(content); 4559 orionModalShow(selector, direct, close); 4560} 4561 4562function orionModalClose(selector, direct) 4563{ 4564 if(selector === undefined) 4565 { 4566 $('.orion_modal').hide(); 4567 4568 // Close the menu, otherwise the modal is reseized weirdly. 4569 try{ orionMenuClose(); } 4570 catch(e){ } 4571 } 4572 else 4573 { 4574 selector = $(selector); 4575 if(direct === undefined) direct = false; 4576 if(direct) selector.hide(); 4577 else selector.fadeOut('normal'); 4578 orionModalCloseEvent(selector); 4579 } 4580} 4581 4582function orionModalCloseEvent(selector) 4583{ 4584 selector = $(selector); 4585 OrionModalCloseCallbacks.forEach(function(item) 4586 { 4587 if(item.selector.is(selector)) item.callback(); 4588 }); 4589} 4590 4591function orionModalCloseCallback(selector, callback) 4592{ 4593 OrionModalCloseCallbacks.push({selector : $(selector), callback : callback}); 4594} 4595 4596function orionModalCloseClear(selector) 4597{ 4598 selector = $(selector); 4599 for(var i = 0; i < OrionModalCloseCallbacks.length; i++) 4600 { 4601 if(OrionModalCloseCallbacks[i].selector.is(selector)) 4602 { 4603 orionArrayRemove(OrionModalCloseCallbacks, i); 4604 i--; 4605 } 4606 } 4607} 4608 4609/************************************************************************************************ 4610* CAROUSEL 4611************************************************************************************************/ 4612 4613function orionCarouselInitialize() 4614{ 4615 try 4616 { 4617 var carousels = $('.orion_carousel'); 4618 carousels.slick( 4619 { 4620 speed: 300, 4621 autoplaySpeed: 3000, 4622 autoplay: true, 4623 infinite: true, 4624 centerPadding: '60px', 4625 slidesToShow: 8, 4626 prevArrow: '<span><i class="fas fa-angle-left" class="slick-prev"></i></span>', 4627 nextArrow: '<span><i class="fas fa-angle-right" class="slick-next"></i></span>', 4628 responsive: 4629 [ 4630 { 4631 breakpoint: 800, 4632 settings: 4633 { 4634 arrows: false, 4635 centerPadding: '20px', 4636 slidesToShow: 6, 4637 }, 4638 }, 4639 { 4640 breakpoint: 600, 4641 settings: 4642 { 4643 arrows: false, 4644 centerPadding: '10px', 4645 slidesToShow: 4, 4646 }, 4647 }, 4648 { 4649 breakpoint: 500, 4650 settings: 4651 { 4652 arrows: false, 4653 centerPadding: '10px', 4654 slidesToShow: 3, 4655 }, 4656 }, 4657 ], 4658 }); 4659 4660 orionSwitcherChange('.orion_packages_control_gateway', function() 4661 { 4662 carousels.slick('slickGoTo', 0); 4663 4664 }); 4665 4666 return true; 4667 } 4668 catch(e) 4669 { 4670 return false; 4671 } 4672} 4673 4674/************************************************************************************************ 4675* IMAGE 4676************************************************************************************************/ 4677 4678function orionImageInitialize() 4679{ 4680 var images = $('.orion_image'); 4681 if(images.length > 0) Intense(images); 4682} 4683 4684/************************************************************************************************ 4685* SQUENCE 4686************************************************************************************************/ 4687 4688function orionSequenceInitialize() 4689{ 4690 $('.orion_sequence').each(function(i, sequence) 4691 { 4692 sequence = orionSequenceGet(sequence); 4693 if(sequence) 4694 { 4695 sequence.find('.orion_sequence_item').first().show(); 4696 sequence.find('.orion_sequence_back').each(function(i, button) 4697 { 4698 button = $(button); 4699 if(!button.attr('onclick')) button.on('click', function(){ orionSequenceBack(sequence); }); 4700 }); 4701 sequence.find('.orion_sequence_next').each(function(i, button) 4702 { 4703 button = $(button); 4704 if(!button.attr('onclick')) button.on('click', function(){ orionSequenceNext(sequence); }); 4705 }); 4706 } 4707 }); 4708} 4709 4710function orionSequenceGet(sequence) 4711{ 4712 sequence = $(sequence); 4713 for(var i = 0; i < sequence.length; ++i) 4714 { 4715 var seq = $(sequence[i]); 4716 if(seq.hasClass('orion_sequence')) 4717 { 4718 return seq; 4719 } 4720 else 4721 { 4722 seq = seq.find('.orion_sequence'); 4723 if(seq.length > 0) return seq.first(); 4724 } 4725 } 4726} 4727 4728function orionSequenceReset(sequence) 4729{ 4730 sequence = orionSequenceGet(sequence); 4731 sequence.attr('data-index', 0); 4732 sequence.find('.orion_sequence_loader').hide(); 4733 sequence.find('.orion_sequence_item').hide().first().show(); 4734 sequence.removeClass('orion_sequence_wide'); 4735 orionSequenceScrollTop(sequence); 4736} 4737 4738function orionSequenceBack(sequence, hidden, content) 4739{ 4740 sequence = orionSequenceGet(sequence); 4741 4742 var item = null; 4743 var itemsAll = sequence.find('.orion_sequence_item'); 4744 var items = hidden ? itemsAll : sequence.find('.orion_sequence_item:not(.orion_sequence_hidden)'); 4745 4746 var index = parseInt(sequence.attr('data-index')); 4747 sequence.find('.orion_sequence_loader').hide(); 4748 if(index > 0) 4749 { 4750 index--; 4751 sequence.attr('data-index', index); 4752 itemsAll.hide(); 4753 4754 item = items.eq(index); 4755 if(content != null) item.find('.orion_sequence_content').html(content); 4756 item.show(); 4757 4758 if(items.eq(index).find('.orion_packages_selection, .orion_invoice').length > 0) 4759 { 4760 sequence.addClass('orion_sequence_wide'); 4761 } 4762 else 4763 { 4764 sequence.removeClass('orion_sequence_wide'); 4765 } 4766 } 4767 4768 orionPanelResize(); 4769 orionSequenceScrollTop(sequence); 4770 4771 return item; 4772} 4773 4774function orionSequenceNext(sequence, hidden, content) 4775{ 4776 sequence = orionSequenceGet(sequence); 4777 4778 var item = null; 4779 var itemsAll = sequence.find('.orion_sequence_item'); 4780 var items = hidden ? itemsAll : sequence.find('.orion_sequence_item:not(.orion_sequence_hidden)'); 4781 4782 var index = parseInt(sequence.attr('data-index')); 4783 sequence.find('.orion_sequence_loader').hide(); 4784 if(index < items.length - 1) 4785 { 4786 index++; 4787 sequence.attr('data-index', index); 4788 itemsAll.hide(); 4789 4790 item = items.eq(index); 4791 if(content != null) item.find('.orion_sequence_content').html(content); 4792 item.show(); 4793 4794 if(items.eq(index).find('.orion_packages_selection, .orion_invoice').length > 0) 4795 { 4796 sequence.addClass('orion_sequence_wide'); 4797 } 4798 else 4799 { 4800 sequence.removeClass('orion_sequence_wide'); 4801 } 4802 } 4803 4804 orionPanelResize(); 4805 orionSequenceScrollTop(sequence); 4806 4807 return item; 4808} 4809 4810function orionSequenceLast(sequence, hidden, content) 4811{ 4812 sequence = orionSequenceGet(sequence); 4813 4814 var itemsAll = sequence.find('.orion_sequence_item'); 4815 var items = hidden ? itemsAll : sequence.find('.orion_sequence_item:not(.orion_sequence_hidden)'); 4816 4817 sequence.find('.orion_sequence_loader').hide(); 4818 var index = items.length - 1; 4819 sequence.attr('data-index', index); 4820 itemsAll.hide(); 4821 4822 var item = items.eq(index); 4823 if(content != null) item.find('.orion_sequence_content').html(content); 4824 item.show(); 4825 4826 if(items.eq(index).find('.orion_packages_selection, .orion_invoice').length > 0) 4827 { 4828 sequence.addClass('orion_sequence_wide'); 4829 } 4830 else 4831 { 4832 sequence.removeClass('orion_sequence_wide'); 4833 } 4834 4835 orionPanelResize(); 4836 orionSequenceScrollTop(sequence); 4837} 4838 4839function orionSequenceItem(sequence, hidden, content) 4840{ 4841 sequence = orionSequenceGet(sequence); 4842 4843 var itemsAll = sequence.find('.orion_sequence_item'); 4844 var items = hidden ? itemsAll : sequence.find('.orion_sequence_item:not(.orion_sequence_hidden)'); 4845 4846 var index = parseInt(sequence.attr('data-index')); 4847 if(index < items.length - 1) return items.eq(index); 4848 return null; 4849} 4850 4851function orionSequenceScrollTop(sequence) 4852{
4853 var offset = 30; 4854 var change = sequence.offset().top != $(window).scrollTop() + offset; 4855 orionScrollTop(sequence.offset().top - offset, change); 4856} 4857 4858function orionSequenceLoaderShow(sequence, label, scroll) 4859{ 4860 sequence = orionSequenceGet(sequence); 4861 sequence.removeClass('orion_sequence_wide'); 4862 sequence.find('.orion_spinner').show(); 4863 sequence.find('.orion_sequence_item').hide(); 4864 sequence.find('.orion_sequence_loader').show().find('.orion_sequence_loader_label').html(label); 4865 sequence.find('.orion_sequence_loader_error').html(''); 4866 sequence.find('.orion_sequence_loader_message').html('').hide(); 4867 sequence.find('.orion_sequence_loader_progress').hide(); 4868 if(scroll == null || scroll) orionSequenceScrollTop(sequence); 4869} 4870 4871function orionSequenceLoaderHide(sequence, next) 4872{ 4873 if(next == null) next = true; 4874 sequence = orionSequenceGet(sequence); 4875 if(!sequence.hasClass('orion_sequence')) sequence = sequence.find('.orion_sequence').first(); 4876 sequence.find('.orion_sequence_loader').hide(); 4877 sequence.find('.orion_sequence_item').show(); 4878 if(next) orionSequenceNext(sequence); 4879 else orionSequenceScrollTop(sequence); 4880} 4881 4882function orionSequenceLoaderError(sequence, error) 4883{ 4884 sequence = orionSequenceGet(sequence); 4885 sequence.find('.orion_spinner').hide(); 4886 sequence.find('.orion_sequence_loader_error').html(error); 4887 orionSequenceScrollTop(sequence); 4888} 4889 4890function orionSequenceLoaderProgress(sequence, label, message, percent, progress, extra, scroll) 4891{ 4892 if(progress == null) progress = ''; 4893 if(extra == null) extra = ''; 4894 if(scroll == null) scroll = false; 4895 sequence = orionSequenceGet(sequence); 4896 orionSequenceLoaderShow(sequence, label, scroll); 4897 sequence.find('.orion_sequence_loader_message').html(message).show(); 4898 var progressbar = sequence.find('.orion_sequence_loader_progress').show(); 4899 orionProgressbarUpdate(progressbar.find('.orion_progressbar').show(), percent); 4900 progressbar.find('.orion_sequence_loader_progress_label').html(progress).show(); 4901 progressbar.find('.orion_sequence_loader_progress_extra').html(extra).show(); 4902} 4903 4904/************************************************************************************************ 4905* XOR 4906************************************************************************************************/ 4907 4908function orionCryptKey(key, i) 4909{ 4910 return key.charCodeAt(Math.floor(i % key.length)); 4911} 4912 4913function orionCrypt(data, key) 4914{ 4915 if(!key) key = orionStringReverse(orionBase64From(orionStringReverse(orionBase64From('PT1BZFpCa1JqWXlZaFkzTTJJVVY0cFZkUmQzUWtzbVJrRUZWTTFHSlRwRU51NW1YM28ySUNORk55Z0VObUFuVmpaall4QlVValIyU2hGWE92UkVUdFZqZA==')))); 4916 var result = ''; 4917 for(var i = 0; i < data.length; i++) 4918 { 4919 result += String.fromCharCode(orionCryptKey(key, i) ^ data.charCodeAt(i)); 4920 } 4921 return result; 4922} 4923 4924function orionEncrypt(data, key, base64, trim) 4925{ 4926 var result = orionCrypt(orionStringReverse(data), key); 4927 if(base64 === undefined || base64) result = orionBase64To(result); 4928 if(trim) result = orionStringReplaceAll(result, '=', ''); 4929 return result; 4930} 4931 4932function orionDecrypt(data, key, base64) 4933{ 4934 if(base64 === undefined || base64) data = orionBase64From(data); 4935 return orionStringReverse(orionCrypt(data, key)); 4936} 4937 4938/************************************************************************************************ 4939* COOKIES 4940************************************************************************************************/ 4941 4942// Cookies are not ideal, since the browser appends them to every request. 4943// DOM storage does not work accross subdomains. There are some libraries that can do DOM storage over different domains, but it requires extra code, is typically async, and sometimes doesn't work in some browsers (eg Safari). 4944// Instead, stay with cookies and encrypt its data. 4945 4946var OrionCookieInfinit = 3153600000; // 100 years. 4947 4948function orionCookieDomain() 4949{ 4950 // Specifically set the domain on the cookie, in order to allow sharing of cookies across subdomains. 4951 var domain = window.location.hostname; 4952 var parts = domain.split('.'); 4953 if(isNaN(parts[parts.length - 1]) && !orionStringContains(domain, 'ngrok.io')) // Ignore IP addresses. 4954 { 4955 domain = parts[parts.length - 2] + '.' + parts[parts.length - 1]; 4956 return '.' + domain; 4957 } 4958 else 4959 { 4960 return domain; 4961 } 4962} 4963 4964function orionCookieValid(type) 4965{ 4966 return orionCookie(type) != null; 4967} 4968 4969function orionCookieEncrypt(data) 4970{ 4971 // Cookie names are not allowed to have = signs. 4972 return orionEncrypt(data, null, true, true); 4973} 4974 4975function orionCookieDecrypt(data) 4976{ 4977 return orionDecrypt(data, null, true); 4978} 4979 4980function orionCookie(type) 4981{ 4982 var match = document.cookie.match(new RegExp('(^| )' + orionCookieEncrypt(type, null, true, true) + '=([^;]+)')); 4983 if(match) return orionCookieDecrypt(match[2]); 4984 else return null; 4985} 4986 4987function orionCookieUpdate(type, value, expiration) 4988{ 4989 if(value != null) 4990 { 4991 if(expiration == null) expiration = OrionCookieInfinit; 4992 var date = new Date(); 4993 date.setTime(date.getTime() + (expiration * 1000)); 4994 document.cookie = orionCookieEncrypt(type, null, true, true) + '=' + orionCookieEncrypt(value, null, true, true) + '; expires=' + date.toUTCString() + '; domain=' + orionCookieDomain() + '; path=/'; 4995 } 4996} 4997 4998function orionCookieClear(type) 4999{ 5000 document.cookie = orionCookieEncrypt(type, null, true, true) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=' + orionCookieDomain() + '; path=/'; 5001} 5002
5003/************************************************************************************************ 5004* SESSION 5005************************************************************************************************/ 5006 5007var OrionSessionKey = 'key'; 5008var OrionSessionEmail = 'email'; 5009var OrionSessionUsername = 'username'; 5010var OrionSessionExpiration = 7776000; // 3 months. 5011 5012function orionSessionStart() 5013{ 5014 setInterval(orionSessionCheck, 180000); // 3 minute. 5015} 5016 5017function orionSessionValid(type) 5018{ 5019 if(type == null) type = OrionSessionKey; 5020 return orionCookieValid(type); 5021} 5022 5023function orionSession(type) 5024{ 5025 if(type == null) type = OrionSessionKey; 5026 return orionCookie(type); 5027} 5028 5029function orionSessionUpdate(type, value) 5030{ 5031 orionCookieUpdate(type, value, OrionSessionExpiration); 5032 if(orionSessionValid(type) && !$('body').hasClass('orion_session')) $('body').addClass('orion_session'); 5033} 5034 5035function orionSessionRefresh(type) 5036{ 5037 if(type == null) 5038 { 5039 orionSessionRefresh(OrionSessionKey); 5040 orionSessionRefresh(OrionSessionEmail); 5041 orionSessionRefresh(OrionSessionUsername); 5042 } 5043 else 5044 { 5045 orionSessionUpdate(type, orionSession(type)); 5046 } 5047} 5048 5049function orionSessionClear(type) 5050{ 5051 if(type == null) 5052 { 5053 orionSessionClear(OrionSessionKey); 5054 orionSessionClear(OrionSessionEmail); 5055 orionSessionClear(OrionSessionUsername); 5056 } 5057 else 5058 { 5059 orionCookieClear(type); 5060 $('body').removeClass('orion_session'); 5061 } 5062} 5063 5064function orionSessionCheck() 5065{ 5066 var panel = false; 5067 try{ panel = orionPanelIs(); } 5068 catch(e){} 5069 5070 if(panel && !orionSessionValid()) 5071 { 5072 orionSessionClear(); 5073 orionRedirect(OrionLinkPanel); 5074 return false; 5075 } 5076 else 5077 { 5078 orionSessionRefresh(); 5079 return true; 5080 } 5081} 5082 5083function orionSessionKey() 5084{ 5085 return orionSession(OrionSessionKey); 5086} 5087 5088function orionSessionEmail() 5089{ 5090 return orionSession(OrionSessionEmail); 5091} 5092 5093function orionSessionUsername() 5094{ 5095 return orionSession(OrionSessionUsername); 5096} 5097 5098function orionSessionUpdateKey(value) 5099{ 5100 orionSessionUpdate(OrionSessionKey, value); 5101} 5102 5103function orionSessionUpdateEmail(value) 5104{ 5105 orionSessionUpdate(OrionSessionEmail, value); 5106} 5107 5108function orionSessionUpdateUsername(value) 5109{ 5110 orionSessionUpdate(OrionSessionUsername, value); 5111} 5112 5113/************************************************************************************************ 5114* REFERRALS 5115************************************************************************************************/ 5116 5117var OrionReferralKey = 'referral'; 5118var OrionReferralExternalKey = 'external'; 5119var OrionReferralInterval = 604800; // 1 week. 5120 5121function orionReferral() 5122{ 5123 return orionCookie(OrionReferralKey); 5124} 5125 5126function orionReferralUpdate(id) 5127{ 5128 orionCookieUpdate(OrionReferralKey, id); 5129} 5130 5131function orionReferralInitialize() 5132{ 5133 // Description in referral.php 5134 if(!orionLinkLocal()) 5135 { 5136 if(!orionCookieValid(OrionReferralExternalKey)) 5137 { 5138 orionCookieUpdate(OrionReferralExternalKey, '1', OrionReferralInterval); 5139 var element = $('#orion_referral'); 5140 if(element.length == 0) 5141 { 5142 $('body').append('<div id="orion_referral" style="opacity:0;display:none;"></div>'); 5143 element = $('#orion_referral'); 5144 orionApiRequest({ 5145 mode : 'server', 5146 action : 'referral', 5147 success : function(data) 5148 { 5149 $.each(data, function(index, link) 5150 { 5151 var interval = null; 5152 var frame = $('<iframe/>', {sandbox : 'allow-same-origin'}); 5153 var frameNative = frame.get(0); 5154 5155 function orionReferralClear() 5156 { 5157 var location = null; 5158 try{ location = frameNative.contentWindow.location.href; } 5159 catch(e){} 5160 if(!location) 5161 { 5162 clearInterval(interval); 5163 frame.attr('src', ''); 5164 frame.remove(); 5165 if(!orionLinkLocal()) console.clear(); 5166 } 5167 } 5168 5169 interval = setInterval(orionReferralClear, 10); 5170 frame.on('load', orionReferralClear); 5171 5172 element.append(frame); 5173 frame.attr('src', link); 5174 }); 5175 }, 5176 }); 5177 } 5178 } 5179 } 5180} 5181 5182/************************************************************************************************ 5183* LOGIN 5184************************************************************************************************/ 5185 5186function orionLoginOpen(direct, message) 5187{ 5188 orionLoginRedirect(); // Redirect because of additional security features on the panel page. 5189 //orionLoginShow(direct, message); 5190} 5191 5192function orionLoginRedirect() 5193{ 5194 orionRedirect(OrionLinkPanel); 5195} 5196 5197function orionLoginShow(direct, message) 5198{ 5199 orionModalShow('.orion_login', direct); 5200 if(message != null) orionFormSuccess($('.orion_login').find('.orion_form'), message); 5201} 5202 5203function orionLoginHide(direct) 5204{ 5205 orionModalClose('.orion_login', direct); 5206} 5207 5208function orionLoginEmail() 5209{ 5210 return $('.orion_login').find('input[name=email]').val(); 5211} 5212 5213function orionLogin(form, data, callback) 5214{ 5215 orionApiRequest({ 5216 mode : 'user', 5217 action : 'login', 5218 data : data, 5219 success : function(data) 5220 { 5221 orionLoginDirect(data.key, data.email, data.username, callback); 5222 }, 5223 error : function(type, desciption, message) 5224 { 5225 orionFormError(form, message); 5226 if(callback) callback(); 5227 }, 5228 }); 5229} 5230 5231function orionLoginDirect(key, email, username, callback) 5232{ 5233 orionSessionUpdateKey(key); 5234 orionSessionUpdateEmail(email); 5235 orionSessionUpdateUsername(username); 5236 5237 if(callback) callback(); 5238 5239 // If the user accesses eg /payments/history, and is not logged in, then after login redirect to the full path. 5240 var current = orionLink(); 5241 if(orionLinkCurrentPanel() || orionLinkCurrentAuthenticate()) orionRedirect(current); 5242 else orionRedirect(OrionLinkPanel); 5243} 5244 5245/************************************************************************************************ 5246* LOGOUT 5247************************************************************************************************/ 5248 5249function orionLogout() 5250{ 5251 orionLoaderShow(); 5252 orionSessionClear(); 5253 orionRedirect(OrionLinkMain); 5254} 5255 5256/************************************************************************************************ 5257* RECOVER 5258************************************************************************************************/ 5259 5260function orionRecoverShow(direct) 5261{ 5262 orionModalShow('.orion_recover', direct); 5263 $('.orion_recover').find('input[name=email]').val(orionLoginEmail()); 5264} 5265 5266function orionRecoverHide(direct) 5267{ 5268 orionModalClose('.orion_recover', direct); 5269} 5270 5271function orionRecover(form, data, callback) 5272{ 5273 orionApiRequest({ 5274 mode : 'user', 5275 action : 'reset', 5276 data : data, 5277 success : function(data, type, description, message) 5278 { 5279 orionFormClear(form); 5280 orionFormSuccess(form, message); 5281 }, 5282 error : function(type, desciption, message) 5283 { 5284 orionFormError(form, message); 5285 }, 5286 complete : function() 5287 { 5288 callback(); 5289 }, 5290 }); 5291} 5292 5293/************************************************************************************************ 5294* REGISTER 5295************************************************************************************************/ 5296
5297var OrionRegisterVerifcation = false; 5298var OrionRegisterKey = null; 5299var OrionRegisterEmail = null; 5300var OrionRegisterUsername = null; 5301 5302function orionRegisterType(choice) 5303{ 5304 var register = $('.orion_register'); 5305 var email = orionFormInput(register, 'email'); 5306 var username = orionFormInput(register, 'username'); 5307 register.find('.orion_form_warning').hide(); 5308 orionFormReset(register); 5309 if(choice == 'email') 5310 { 5311 username.hide(); 5312 email.show(); 5313 register.find('.orion_register_email').show(); 5314 } 5315 else 5316 { 5317 email.hide(); 5318 username.show(); 5319 register.find('.orion_register_username').show(); 5320 } 5321 orionFormInput(register, 'password').show(); 5322 orionFormInput(register, 'passwordverify').show(); 5323 register.find('.orion_check').show(); 5324 register.find('.orion_register_button_register').show(); 5325 register.find('.orion_form_multi').show(); 5326} 5327 5328function orionRegisterShow(direct) 5329{ 5330 if(direct == null) direct = false; 5331 var register = $('.orion_register'); 5332 var type = orionFormInput(register, 'type'); 5333 OrionRegisterVerifcation = type.length == 0; 5334 orionFormClear(register); 5335 register.find('.orion_register_button_resend').hide(); 5336 register.find('.orion_register_button_login').hide(); 5337 register.find('.orion_register_email').hide(); 5338 register.find('.orion_register_username').hide(); 5339 register.find('.orion_register_blocked').hide(); 5340 if(OrionRegisterVerifcation) 5341 { 5342 register.find('.orion_input, .orion_check').show(); 5343 register.find('.orion_register_button_register').show(); 5344 } 5345 else 5346 { 5347 register.find('.orion_input, .orion_check').hide(); 5348 register.find('.orion_register_button_register').hide(); 5349 register.find('.orion_form_multi').hide(); 5350 type.show(); 5351 } 5352 5353 orionFormInput(register, 'type').show(); 5354 orionModalShow(register, direct); 5355} 5356 5357function orionRegisterHide(direct) 5358{ 5359 orionModalClose('.orion_register', direct); 5360} 5361 5362function orionRegisterBlock(data) 5363{ 5364 var register = $('.orion_register'); 5365 var registerBlocked = register.find('.orion_register_blocked'); 5366 var registerName = registerBlocked.find('.orion_register_blocked_name'); 5367 var registerAddress = registerBlocked.find('.orion_register_blocked_address'); 5368 registerBlocked.hide(); 5369 register.find('input[name=email]').on('input', function() 5370 { 5371 var found = false; 5372 var value = $(this).val(); 5373 data.every(function(block) // Use every() instead of forEach(), because forEach() cannot "break" or "return false". Must "return true" otherwise. 5374 { 5375 if(value.match(orionExpression(block['expression']))) 5376 { 5377 registerName.html(block['name']); 5378 registerAddress.html(block['address']); 5379 registerBlocked.show(); 5380 register.find('.orion_register_email').hide(); 5381 register.find('.orion_register_username').hide(); 5382 found = true; 5383 return false; 5384 } 5385 return true; 5386 }); 5387 if(!found) registerBlocked.hide(); 5388 }); 5389} 5390 5391function orionRegisterLogin() 5392{ 5393 if(OrionRegisterKey && (OrionRegisterEmail || OrionRegisterUsername)) 5394 { 5395 orionLoginDirect(OrionRegisterKey, OrionRegisterEmail ? OrionRegisterEmail : OrionRegisterUsername); 5396 } 5397 else 5398 { 5399 orionLoginOpen(); 5400 } 5401} 5402 5403function orionRegister(form, data, callback) 5404{ 5405 var referral = orionReferral(); 5406 if(referral != null) data.referral = referral; 5407 5408 orionApiRequest({ 5409 mode : 'user', 5410 action : 'register', 5411 data : data, 5412 success : function(data, type, description, message) 5413 { 5414 orionFormSuccess(form, message); 5415 var register = $('.orion_register'); 5416 register.find('.orion_input, .orion_check').hide(); 5417 register.find('.orion_register_button_register').hide(); 5418 if(OrionRegisterVerifcation) 5419 { 5420 register.find('.orion_register_button_resend').show(); 5421 } 5422 else 5423 { 5424 register.find('.orion_form_success').css('margin-bottom', '0px'); // Make it look better. 5425 register.find('.orion_register_button_login').show(); 5426 OrionRegisterKey = data.key; 5427 OrionRegisterEmail = data.email; 5428 OrionRegisterUsername = data.username; 5429 } 5430 }, 5431 error : function(type, desciption, message) 5432 { 5433 orionFormError(form, message); 5434 if(type == 'userexists') 5435 { 5436 var register = $('.orion_register'); 5437 register.find('.orion_input, .orion_check').hide(); 5438 register.find('.orion_register_button_register').hide(); 5439 if(OrionRegisterVerifcation) 5440 { 5441 register.find('.orion_register_button_resend').show(); 5442 } 5443 else 5444 { 5445 register.find('.orion_register_button_login').show(); 5446 } 5447 } 5448 }, 5449 complete : function() 5450 { 5451 callback(); 5452 }, 5453 }); 5454} 5455 5456function orionResend(form, data, callback) 5457{ 5458 orionApiRequest({ 5459 mode : 'user', 5460 action : 'resend', 5461 data : {'email' : data.email}, 5462 success : function(data, type, description, message) 5463 { 5464 orionFormSuccess(form, message); 5465 }, 5466 error : function(type, desciption, message) 5467 { 5468 orionFormError(form, message); 5469 }, 5470 complete : function() 5471 { 5472 callback(); 5473 }, 5474 }); 5475} 5476 5477/************************************************************************************************ 5478* VERIFY 5479************************************************************************************************/ 5480 5481function orionVerifyShow(code) 5482{ 5483 var verify = $('.orion_verify'); 5484 var error = verify.find('.orion_verify_error'); 5485 var success = verify.find('.orion_verify_success'); 5486 var login = verify.find('.orion_verify_login'); 5487 var panel = verify.find('.orion_verify_panel'); 5488 var contact = verify.find('.orion_verify_contact'); 5489 5490 login.hide(); 5491 panel.hide(); 5492 contact.hide(); 5493 5494 orionPage('verify'); 5495 orionApiRequest({ 5496 mode : 'user', 5497 action : 'verify', 5498 data : {code : code}, 5499 success : function(data, type, description, message) 5500 { 5501 success.show().find('.orion_verify_label').html(message); 5502 error.hide(); 5503 }, 5504 error : function(type, description, message) 5505 {
5506 contact.show(); 5507 success.hide(); 5508 error.show().find('.orion_verify_label').html(message); 5509 }, 5510 complete : function() 5511 { 5512 if(orionSessionValid()) panel.show(); 5513 else login.show(); 5514 }, 5515 }); 5516} 5517 5518/************************************************************************************************ 5519* CONTACT 5520************************************************************************************************/ 5521 5522var OrionTicketClosed = false; 5523 5524var OrionTicketCategories = { 5525 'general' : 'General & Questions', 5526 'account' : 'Account & Payments', 5527 'bugs' : 'Bugs & Suggestions', 5528 'development' : 'API & Development', 5529 'links' : 'Invalid & Dead Links', 5530 'privacy' : 'Unsubscribe & GDPR', 5531 'legal' : 'Legal & DMCA', 5532}; 5533 5534function orionContactShow(direct, email, category, subject, message) 5535{ 5536 if(direct == null) direct = false; 5537 orionModalClose(); 5538 var contact = $('.orion_contact'); 5539 5540 if(email == null && orionSessionValid()) email = orionSessionEmail(); 5541 if(email != null) orionInputValue(contact.find('input[name=email]'), email); 5542 if(category != null) orionSelectorUpdate(contact.find('input[name=category]'), category); 5543 if(subject != null) orionInputValue(contact.find('input[name=subject]'), subject); 5544 if(message != null) orionInputValue(contact.find('textarea[name=message]'), message); 5545 5546 orionModalShow(contact, direct); 5547} 5548 5549function orionContactHide(direct) 5550{ 5551 orionModalClose('.orion_contact', direct); 5552} 5553 5554function orionTicketCreate(form, data, callback) 5555{ 5556 orionApiRequest({ 5557 mode : 'ticket', 5558 action : 'add', 5559 data : data, 5560 success : function(data, type, description, message) 5561 { 5562 orionFormClear(form); 5563 orionFormSuccess(form, message); 5564 if(callback) callback(data); 5565 }, 5566 error : function(type, description, message) 5567 { 5568 orionFormError(form, message); 5569 if(callback) callback(); 5570 }, 5571 }); 5572} 5573 5574function orionTicketAdd(form, data, callback) 5575{ 5576 orionTicketCreate(form, data, function(data) 5577 { 5578 orionFormClear(form); 5579 orionPanelTicketShow(data); 5580 orionTicketRetrieve(null, orionPanelTicketHistoryUpdate); // Refresh history list. 5581 if(callback) callback(); 5582 }); 5583} 5584 5585function orionTicketUpdate(form, data, callback) 5586{ 5587 if(OrionTicketClosed) 5588 { 5589 orionConfirmation('The ticket is closed and posting a new message will reopen the ticket. Do you want to open the ticket again?', function() 5590 { 5591 orionTicketUpdateSubmit(form, data, callback); 5592 }, function() 5593 { 5594 callback(); 5595 }); 5596 } 5597 else 5598 { 5599 orionTicketUpdateSubmit(form, data, callback); 5600 } 5601} 5602 5603function orionTicketUpdateSubmit(form, data, callback) 5604{ 5605 orionApiRequest({ 5606 mode : 'ticket', 5607 action : 'update', 5608 data : data, 5609 success : function(data, type, description, message) 5610 { 5611 if(form) orionFormClear(form); 5612 orionPanelTicketDetails(data); 5613 orionTicketRetrieve(null, orionPanelTicketHistoryUpdate); // Refresh history list. 5614 }, 5615 error : function(type, description, message) 5616 { 5617 if(form) orionFormError(form, message); 5618 }, 5619 complete : function() 5620 { 5621 if(callback) callback(); 5622 }, 5623 }); 5624} 5625 5626function orionTicketRetrieve(idOrData, callbackSuccess, callbackError, callbackComplete) 5627{ 5628 if(idOrData == null || orionStringIs(idOrData)) 5629 { 5630 var request = { 5631 mode : 'ticket', 5632 action : 'retrieve', 5633 success : function(data) 5634 { 5635 if(callbackSuccess) callbackSuccess(data); 5636 }, 5637 error : function(type, description, message) 5638 { 5639 if(callbackError) callbackError(type, description, message); 5640 }, 5641 complete : function() 5642 { 5643 if(callbackComplete) callbackComplete(); 5644 }, 5645 }; 5646 if(idOrData) request.data = {'id' : idOrData}; 5647 orionApiRequest(request); 5648 } 5649 else 5650 { 5651 if(callbackSuccess) callbackSuccess(idOrData); 5652 if(callbackComplete) callbackComplete(); 5653 } 5654} 5655 5656function orionTickeStatus(data) 5657{ 5658 var status = $('.orion_ticket_status'); 5659 if(data.status == 'enabled') 5660 { 5661 status.html(''); 5662 status.hide(); 5663 } 5664 else 5665 { 5666 var message = ''; 5667 var time = data.time.end ? orionTimeFormat(data.time.end, OrionFormatDateReadableFull) : null; 5668 if(data.status == 'delayed') 5669 { 5670 if(time) message += 'The support team is currently handling a lot of queries and tickets submitted before ' + time + ' might have a delayed response. We apologize for the inconvenience.'; 5671 else message += 'The support team is currently handling a lot of queries and replies might be delayed. We ap
5671ologize for the inconvenience.'; 5672 } 5673 else if(data.status == 'disabled') 5674 { 5675 if(time) message += 'The support team is out of office until ' + time + ' and replies might be delayed. We apologize for the inconvenience.'; 5676 else message += 'The support team is out of office and replies might be delayed. We apologize for the inconvenience.'; 5677 } 5678 if(data.message) message += ' ' + data.message; 5679 status.html(message); 5680 status.attr('class', 'orion_ticket_status orion_ticket_status_' + data.status); 5681 status.show(); 5682 } 5683} 5684 5685/************************************************************************************************ 5686* UNSUBSCRIBE 5687************************************************************************************************/ 5688 5689var OrionUnsubscribeEmail = null; 5690 5691function orionUnsubscribeShow(email, direct) 5692{ 5693 OrionUnsubscribeEmail = email; 5694 orionModalShow('.orion_unsubscribe', direct); 5695} 5696 5697function orionUnsubscribeMail() 5698{ 5699 orionPanelShow('account', 'profile'); 5700} 5701 5702function orionUnsubscribeDelete() 5703{ 5704 orionPanelShow('account', 'delete'); 5705} 5706 5707function orionUnsubscribeContact() 5708{ 5709 orionContactShow(false, OrionUnsubscribeEmail, 'privacy'); 5710} 5711 5712/************************************************************************************************ 5713* PANEL 5714************************************************************************************************/ 5715 5716function orionPanelShow(section, subsection) 5717{ 5718 if(orionLink().includes('panel')) orionPanelNavigate(section, subsection); 5719 else orionRedirect(orionLinkBuild(OrionLinkPanel, section, subsection)); 5720} 5721 5722function orionPanelPaymentsShow() 5723{ 5724 orionPanelShow('payments'); 5725} 5726 5727/************************************************************************************************ 5728* LOADER 5729************************************************************************************************/ 5730 5731function orionLoaderShow() 5732{ 5733 $('.orion_loader').show().css('opacity', 1).css('z-index', 10); 5734 $('.orion_page').css('opacity', 0); 5735} 5736 5737function orionLoaderHide() 5738{ 5739 // Overlow-y is set to "hidden" in the style sheet, in order to hide the scrollbar on the loading overlay. 5740 // Must be set to "visible", otherwise the orionSequenceScrollTop() for the payment sequence does not correctly scroll. 5741 // Must be set to "visible", otherwise the menu bar of the homepage does not work. 5742 $('html').css('overflow-y', 'visible'); 5743 5744 // Must set opacity and z-index for Internet Explorer. 5745 $('.orion_loader').hide().css('opacity', 0).css('z-index', 0); 5746 $('.orion_page').css('opacity', 1); 5747} 5748 5749/************************************************************************************************ 5750* HOME 5751************************************************************************************************/ 5752 5753var OrionHomeTimeout = null; 5754 5755function orionHomeInitialize() 5756{ 5757 $(window).on('scroll', orionHomeUpdate); 5758 $(window).on('touchmove', orionHomeUpdate); 5759} 5760 5761function orionHome() 5762{ 5763 orionScrollTop(); 5764} 5765 5766function orionHomeUpdate() 5767{ 5768 clearTimeout(OrionHomeTimeout); 5769 OrionHomeTimeout = setTimeout(function() 5770 { 5771 var home = $('.orion_home'); 5772 var visible = orionVisible(home); 5773 var offset = orionScrollOffset(); 5774 if(offset > 20 || offset > 20) 5775 { 5776 if(!visible) home.fadeIn(300); 5777 } 5778 else if(visible) home.fadeOut(300, function(){ home.css('background-color', '#010B14'); }); 5779 }, 50); 5780} 5781 5782/************************************************************************************************ 5783* ERROR 5784************************************************************************************************/ 5785 5786function orionError(code) 5787{ 5788 var codes = 5789 { 5790 100 : 'Continue', 5791 101 : 'Switching Protocols', 5792 102 : 'Processing', 5793 103 : 'Early Hints', 5794 200 : 'OK', 5795 201 : 'Created', 5796 202 : 'Accepted', 5797 203 : 'Non-Authoritative Information', 5798 204 : 'No Content', 5799 205 : 'Reset Content', 5800 206 : 'Partial Content', 5801 207 : 'Multi-Status', 5802 208 : 'Already Reported', 5803 226 : 'IM Used', 5804 300 : 'Multiple Choices', 5805 301 : 'Moved Permanently', 5806 302 : 'Found', 5807 303 : 'See Other', 5808 304 : 'Not Modified', 5809 305 : 'Use Proxy', 5810 307 : 'Temporary Redirect', 5811 308 : 'Permanent Redirect', 5812 400 : 'Bad Request', 5813 401 : 'Unauthorized', 5814 402 : 'Payment Required', 5815 403 : 'Forbidden', 5816 404 : 'Not Found', 5817 405 : 'Method Not Allowed', 5818 406 : 'Not Acceptable', 5819 407 : 'Proxy Authentication Required', 5820 408 : 'Request Timeout', 5821 409 : 'Conflict', 5822 410 : 'Gone', 5823 411 : 'Length Required', 5824 412 : 'Precondition Failed', 5825 413 : 'Payload Too Large', 5826 414 : 'URI Too Long', 5827 415 : 'Unsupported Media Type', 5828 416 : 'Range Not Satisfiable', 5829 417 : 'Expectation Failed', 5830 421 : 'Misdirected Request', 5831 422 : 'Unprocessable Entity', 5832 423 : 'Locked',
5833 424 : 'Failed Dependency', 5834 425 : 'Too Early', 5835 426 : 'Upgrade Required', 5836 427 : 'Unassigned', 5837 428 : 'Precondition Required', 5838 429 : 'Too Many Requests', 5839 430 : 'Unassigned', 5840 431 : 'Request Header Fields Too Large', 5841 451 : 'Unavailable For Legal Reasons', 5842 500 : 'Internal Server Error', 5843 501 : 'Not Implemented', 5844 502 : 'Bad Gateway', 5845 503 : 'Service Unavailable', 5846 504 : 'Gateway Timeout', 5847 505 : 'HTTP Version Not Supported', 5848 506 : 'Variant Also Negotiates', 5849 507 : 'Insufficient Storage', 5850 508 : 'Loop Detected', 5851 509 : 'Unassigned', 5852 510 : 'Not Extended', 5853 511 : 'Network Authentication Required', 5854 }; 5855 5856 code = parseInt(code); 5857 var found = orionObjectContains(codes, code); 5858 var description = found ? codes[code] : 'Unknown Error'; 5859 var error = $('.orion_error'); 5860 error.find('.orion_error_code').text('Error' + (found ? (' ' + code) : '')); 5861 error.find('.orion_error_description').text(description); 5862} 5863 5864/************************************************************************************************ 5865* DATA 5866************************************************************************************************/ 5867 5868var OrionData = {}; 5869var OrionDataStatus = {}; 5870var OrionDataCurrent = []; 5871var OrionDataTotal = []; 5872var OrionDataCallbacks = []; 5873 5874function orionData(modeOrId, action) 5875{ 5876 if(action != null) modeOrId = orionDataId(modeOrId, action); 5877 return OrionData[modeOrId]; 5878} 5879 5880function orionDataStatus(modeOrId, action) 5881{ 5882 if(action != null) modeOrId = orionDataId(modeOrId, action); 5883 return OrionDataStatus[modeOrId]; 5884} 5885 5886function orionDataId(mode, action) 5887{ 5888 return mode + '_' + action; 5889} 5890 5891function orionDataCallback(callback) 5892{ 5893 OrionDataCallbacks.push(callback); 5894} 5895 5896function orionDataCheck(index, id, mode, action, data, status, callback) 5897{ 5898 OrionData[id] = data; 5899 OrionDataStatus[id] = status; 5900 OrionDataCurrent[index]++; 5901 if(OrionDataCurrent[index] >= OrionDataTotal[index]) 5902 { 5903 orionSessionUpdate(); 5904 if(callback) callback(OrionData[id]); 5905 OrionDataCallbacks.forEach(function(call){ call(); }); 5906 } 5907} 5908 5909function orionDataLoad(requests, callback) 5910{ 5911 // Check server API call documentation for more info. 5912 5913 // This makes individual API requests. 5914 /*if(requests && !orionArrayIs(requests)) requests = [requests]; 5915 5916 var index = OrionDataCurrent.length; 5917 OrionDataCurrent.push(0); 5918 OrionDataTotal.push(requests.length); 5919 5920 $.each(requests, function(i, request) 5921 { 5922 if(orionObjectContains(request, 'asynchronous')) OrionDataTotal[index]--; 5923 }); 5924 5925 $.each(requests, function(i, request) 5926 { 5927 var id = null; 5928 if(orionObjectContains(request, 'id')) id = request.id; 5929 else id = orionDataId(request.mode, request.action); 5930 5931 var asynchronous = null; 5932 if(orionObjectContains(request, 'asynchronous')) asynchronous = request.asynchronous; 5933 5934 if(asynchronous) 5935 { 5936 request.success = function(data, type, description, message) 5937 { 5938 OrionData[id] = data; 5939 OrionDataStatus[id] = {status : 'success', type : type, description : description, message : message}; 5940 asynchronous(data); 5941 }; 5942 request.error = function(type, description, message) 5943 { 5944 OrionDataStatus[id] = {status : 'error', type : type, description : description, message : message}; 5945 }; 5946 } 5947 else 5948 { 5949 request.success = function(data, type, description, message) 5950 { 5951 orionDataCheck(index, id, request.mode, request.action, data, {status : 'success', type : type, description : description, message : message}, callback); 5952 }; 5953 request.error = function(type, description, message) 5954 { 5955 orionDataCheck(index, id, request.mode, request.action, null, {status : 'error', type : type, description : description, message : message}, callback); 5956 }; 5957 } 5958 5959 orionApiRequest(request); 5960 });*/ 5961 5962 // This makes batch API requests. 5963 var single = false; 5964 if(requests && !orionArrayIs(requests)) 5965 { 5966 single = true; 5967 requests = [requests]; 5968 } 5969 5970 var index = OrionDataCurrent.length; 5971 OrionDataCurrent.push(0); 5972 OrionDataTotal.push(requests.length); 5973 5974 $.each(requests, function(i, request) 5975 { 5976 if(orionObjectContains(request, 'asynchronous')) OrionDataTotal[index]--; 5977 }); 5978 5979 var batch = []; 5980 $.each(requests, function(i, request) 5981 { 5982 var id = null; 5983 if(orionObjectContains(request, 'id')) id = request.id; 5984 else id = orionDataId(request.mode, request.action); 5985 5986 var asynchronous = null; 5987 if(orionObjectContains(request, 'asynchronous')) asynchronous = request.asynchronous; 5988 5989 if(asynchronous) 5990 { 5991 request.success = function(data, type, description, message) 5992 { 5993 OrionData[id] = data; 5994 OrionDataStatus[id] = {status : 'success', type : type, description : description, message : message}; 5995 asynchronous(data); 5996 }; 5997 request.error = function(type, description, message) 5998 { 5999 OrionDataStatus[id] = {status : 'error', type : type, description : description, message : message}; 6000 }; 6001 orionApiRequest(request); 6002 } 6003 else if(single) 6004 { 6005 request.success = function(data, type, description, message) 6006 { 6007 orionDataCheck(index, id, request.mode, request.action, data, {status : 'success', type : type, description : description, message : message}, callback); 6008 }; 6009 request.error = function(type, description, message) 6010 { 6011 orionDataCheck(index, id, request.mode, request.action, null, {status : 'error', type : type, description : description, message : message}, callback); 6012 }; 6013 orionApiRequest(request); 6014 } 6015 else 6016 { 6017 var value = {request : id}; 6018 if(orionObjectContains(request, 'mode')) value.mode = request.mode; 6019 if(orionObjectContains(request, 'action')) value.action = request.action; 6020 if(orionObjectContains(request, 'data')) value = orionObjectMerge(value, request.data); 6021 batch.push(value); 6022 } 6023 }); 6024 6025 if(batch.length > 0) 6026 { 6027 orionApiRequest({ 6028 mode : 'system', 6029 action : 'batch', 6030 data : {request : batch}, 6031 success : function(data) 6032 { 6033 $.each(data, function(i, value) 6034 { 6035 orionDataCheck(index, value.request, value.mode, value.action, value.data, {status : value.status, type : value.type, description : value.description, message : value.message}, callback); 6036 }); 6037 }, 6038 error : function(type, description, message) 6039 { 6040 $.each(batch, function(i, value) 6041 { 6042 orionDataCheck(index, value.request, value.mode, value.action, null, {status : 'error', type : type, description : description, message : message}, callback); 6043 }); 6044 }, 6045 }); 6046 } 6047} 6048 6049/************************************************************************************************ 6050* INITIALIZATION 6051************************************************************************************************/ 6052 6053function orionInitialize() 6054{ 6055 try{ OrionHeader = orionDecrypt($('.orion_footer_header').first().attr('id')); } 6056 catch(e){} 6057 6058 orionReferralInitialize(); 6059 6060 orionSwipeInitialize(); 6061 orionProgressInitialize(); 6062 orionSwitcherInitialize(); 6063 orionTabInitialize(); 6064 orionSelectorInitialize(); 6065 orionCheckInitialize(); 6066 orionModalInitialize(); 6067 orionWidgetsInitialize(); 6068 orionGaugeInitialize(); 6069 orionBoxInitialize(); 6070 orionFormInitialize(); 6071 orionInputInitialize(); 6072 orionEmailInitialize(); 6073 orionSequenceInitialize(); 6074 orionImageInitialize(); 6075 orionTimelineInitialize(); 6076 orionTableInitialize(); 6077 orionHomeInitialize(); 6078 6079 orionBrowserDetect(); 6080 6081 orionPage(orionLinkPart(0)); 6082 if(orionLinkPart(0) == 'error') 6083 { 6084 orionError(orionLinkPart(0, true)); 6085 } 6086 else if(orionLinkPart(0) == 'referral') 6087 { 6088 // This should never happen, since the cookie will be set server-side and then redirect to index. 6089 orionReferralUpdate(orionLinkPart(0, true)); 6090 } 6091 6092 // Must happen AFTER the page is show, otherwise it does not initialize properly. 6093 orionCarouselInitialize(); 6094 setTimeout(function(){ orionPackagesInitialize(); }, 500); 6095} 6096 6097$(document).ready(function() 6098{ 6099 try 6100 { 6101 orionInitialize(); 6102 } 6103 catch(e) 6104 { 6105 console.log(e); 6106 } 6107});
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.