1function Alea(seed) { 2 3 if(seed === undefined) {seed = +new Date() + Math.random();} 4 5 function Mash() { 6 7 var n = 4022871197; 8 9 return function(r) { 10 11 for(var t, s, u = 0, e = 0.02519603282416938; u < r.length; u++) 12 13 s = r.charCodeAt(u), f = (e * (n += s) - (n*e|0)), 14 15 n = 4294967296 * ((t = f * (e*n|0)) - (t|0)) + (t|0); 16 17 return (n|0) * 2.3283064365386963e-10; 18 19 } 20 21 } 22 23 return function() { 24 25 var m = Mash(), a = m(" "), b = m(" "), c = m(" "), x = 1, y; 26 27 seed = seed.toString(), a -= m(seed), b -= m(seed), c -= m(seed); 28 29 a < 0 && a++, b < 0 && b++, c < 0 && c++; 30 31 return function() { 32 33 var y = x * 2.3283064365386963e-10 + a * 2091639; a = b, b = c; 34 35 return c = y - (x = y|0); 36 37 }; 38 39 }(); 40 41} 42 43 44 45function isMobileView() { return window.innerWidth <= 800 } 46 47 48 49var Spoiler = function (options){ 50 51 this.data = options.data; 52 53 this.mainElement = options.element; 54 55 this.enableControl = options.enableControl != null ? options.enableControl : true; 56 57 this.enableLinks = options.enableLinks != null ? options.enableLinks : true; 58 59 this.showVersion = options.showVersion != null ? options.showVersion : false; 60 61 62 63 this.resetSeed(); 64 65 this.initializeStructure(); 66 67 this.initializeCardElements(); 68 69 this.initializeSorting(); 70 71 this.redraw(); 72 73 74 75 var spoiler = this; 76 77 //$(window).resize(function() { 78 79 // spoiler.redraw(); 80 81 //}); 82 83}; 84 85 86 87Spoiler.prototype.resetSeed = function() { 88 89 var seed = parseInt(this.getUrlVars().seed) || new Date().getTime(); 90 91 console.log("seed", seed) 92 93 this.alea = Alea(seed); 94 95} 96 97 98 99Spoiler.prototype.getUrlVars = function () { 100 101 var vars = []; 102 103 var locationWithoutHash = window.location.href.split('#')[0]; 104 105 var hashes = locationWithoutHash.slice(locationWithoutHash.indexOf('?') + 1).split('&'); 106 107 for (let i = 0; i < hashes.length; i++) { 108 109 let hash = hashes[i].split('='); 110 111 vars.push(decodeURIComponent(hash[0])); 112 113 vars[hash[0]] = decodeURIComponent(hash[1]); 114 115 } 116 117 return vars; 118 119} 120 121 122 123Spoiler.prototype.initializeStructure = function () { 124 125 if(this.enableControl) 126 127 { 128 129 this.mainElement.html( 130 131 //"<div class='spoler-cards-no'>Number of cards: " + this.data.length + "</div>" + 132 133 "<div class='spoiler-filters-and-sorts'>" + 134 135 (!isMobileView() ? "<div class='spoiler-mode'>" + 136 137 " Display: <a href='javascript:void(0)' onclick='spoiler.setMode(\"spoiler\")' mode='spoiler' class='activeSort' title='Display all card information'>Spoiler</a>" + 138 139 " <a href='javascript:void(0)' onclick='spoiler.setMode(\"images\")' mode='images' title='Display card images only'>Images</a>" + 140 141 " </div>" : "" ) + 142 143 " <div class='spoiler-sort'>" + 144 145 " Sort by: <a href='javascript:void(0)' onclick='spoiler.sort(\"color\")' sort='color' title='Sort by color, then name'>Color</a>" + 146 147 " <a href='javascript:void(0)' onclick='spoiler.sort(\"rarity\")' sort='rarity' title='Sort by rarity, then color and name'>Rarity</a>" + 148 149 " <a href='javascript:void(0)' onclick='spoiler.sort(\"cmc\")' sort='cmc' title='Sort by converted mana cost, then color and name'>CMC</a>" + 150 151 " <a href='javascript:void(0)' onclick='spoiler.sort(\"name\")' class='activeSort' sort='name' title='Sort by name'>Name</a>" + 152 153 " <a href='javascript:void(0)' onclick='spoiler.sort(\"random\")' sort='random' title='Sort randomly'>Randomly</a>" + 154 155 " </div>" + 156 157 " <div class='spoiler-filters spoiler-filters-rarity'>" + 158 159 " Rarity filter: <a href='javascript:void(0)' onclick='spoiler.filterByRarity(\"M\")' filter='M' title='Mythic rares only'>M</a>" + 160 161 " <a href='javascript:void(0)' onclick='spoiler.filterByRarity(\"R\")' filter='R' title='Rares only'>R</a>" + 162 163 " <a href='javascript:void(0)' onclick='spoiler.filterByRarity(\"U\")' filter='U' title='Uncommons only'>U</a>" + 164 165 " <a href='javascript:void(0)' onclick='spoiler.filterByRarity(\"C\")' filter='C' title='Commons only'>C</a>" + 166 167 " <a href='javascript:void(0)' onclick='spoiler.filterByRarity(\"S\")' filter='S' title='Special only'>S</a>" + 168 169 " </div>" + 170 171 " <div class='spoiler-filters spoiler-filters-color'>" + 172 173 " Color filter: <a href='javascript:void(0)' onclick='spoiler.filterByColor(\"W\")' filter='W' title='White cards only'><span class='icon-wrapper'><i class='mtg white'></i></span></a>" + 174 175 " <a href='javascript:void(0)' onclick='spoiler.filterByColor(\"U\")' filter='U' title='Blue cards only'><span class='icon-wrapper'><i class='mtg blue'></i></span></a>" + 176 177 " <a href='javascript:void(0)' onclick='spoiler.filterByColor(\"B\")' filter='B' title='Black cards only'><span class='icon-wrapper'><i class='mtg black'></i></span></a>" + 178 179 " <a href='javascript:void(0)' onclick='spoiler.filterByColor(\"R\")' filter='R' title='Red cards only'><span class='icon-wrapper'><i class='mtg red'></i></span></a>" + 180 181 " <a href='javascript:void(0)' onclick='spoiler.filterByColor(\"G\")' filter='G' title='Green cards only'><span class='icon-wrapper'><i class='mtg green'></i></span></a>" + 182 183 " <a href='javascript:void(0)' onclick='spoiler.filterByColor(\"M\")' filter='M' title='Multicolor cards only'><span class='icon-wrapper'><i class='mtg hybrid-wu'></i></span></a>" + 184 185 " <a href='javascript:void(0)' onclick='spoiler.filterByColor(\"1\")' filter='1' title='Colorless cards only'><span class='icon-wrapper'><i class='mtg mana-1'></i></span></a>" + 186 187 " </div>" + 188 189 " <div class='spoiler-filters spoiler-filters-type'>" + 190 191 " Type filter: <a href='javascript:void(0)' onclick='spoiler.filterByType(\"Artifact\")' filter='Artifact' title='Artifacts only'>Artifact</a>" + 192 193 " <a href='javascript:void(0)' onclick='spoiler.filterByType(\"Creature\")' filter='Creature' title='Creatures only'>Creature</a>" + 194 195 " <a href='javascript:void(0)' onclick='spoiler.filterByType(\"Enchantment\")' filter='Enchantment' title='Enchantments only'>Enchantment</a>" + 196 197 " <a href='javascript:void(0)' onclick='spoiler.filterByType(\"Instant\")' filter='Instant' title='Instants only'>Instant</a>" + 198 199 " <a href='javascript:void(0)' onclick='spoiler.filterByType(\"Land\")' filter='Land' title='Lands only'>Land</a>" + 200 201 " <a href='javascript:void(0)' onclick='spoiler.filterByType(\"Planeswalker\")' filter='Planeswalker' title='Planeswalkers only'>Planeswalker</a>" + 202 203 " <a href='javascript:void(0)' onclick='spoiler.filterByType(\"Sorcery\")' filter='Sorcery' title='Sorceries only'>Sorcery</a>" + 204 205 " <a href='javascript:void(0)' onclick='spoiler.filterByType(\"Token\")' filter='Token' title='Tokens only'>Token</a>" + 206 207 " </div>" + 208 209 "</div>" + 210 211 "<br />" + 212 213 "<hr class='card-separator' />" + 214 215 "<div class='spoiler-cards'></div>"); 216 217 } 218 219 else { 220 221 this.mainElement.html("<div class='spoiler-cards'></div>"); 222 223 } 224 225 226 227 this.cardsElement = $(".spoiler-cards", this.mainElement); 228 229} 230 231 232 233Spoiler.prototype.initializeCardElements = function () { 234 235 this.imageCardElements = new Array(); 236 237 this.spoilerCardElements = new Array(); 238 239 240 241 this.mode = "spoiler"; 242 243 244 245 for (var i = 0; i < this.data.length; i++) { 246 247 var card = this.data[i]; 248 249 250 251 this.imageCardElements[card.cardId] = $("" + 252 253 "<a href='" + card.url + "'><img src='" + card.artUrl + "' alt='" + card.name + "' class='card-image card-image-" + card.shape + "' /></a>"); 254 255 256 257 this.spoilerCardElements[card.cardId] = $("" + 258 259 "<table class='card-detail shape-" + card.shape + "'>" + 260 261 " <tr>" + 262 263 " <td class='card-image-day card-front' rowspan='15'><div class='lazyload' data-original='" + card.artUrl + "'></td>" + 264 265 (card.shape == "flip" || card.shape == "double" ? "<td class='card-image-night card-back' rowspan='15'><div class='lazyload' data-original='" + card.artUrl + "'></td>" : "") + 266 267 " <td class='card-main-row card-front'><div class='card-name'><a href='" + card.url + "'>" + card.name + "</a> " + (this.showVersion ? "<span class='card-set-version'>(" + card.setVersionLink + ")</span>" : "") +"</div>" + (card.manaCost != null ?"<div class='card-cost'>" + card.manaCost + "</div></td>" : "</td>")+ 268 269 " </tr>" + 270 271 " <tr>" + 272 273 " <td class='card-type-row card-front'><div class='card-types'>" + card.types + "</div><div class='card-rarity card-rarity-" + card.rarity.toLowerCase() +"'>" + card.rarityName + "</div></td>" + 274 275 " </tr>" + 276 277 " <tr>" + 278 279 " <td class='card-rules-row card-front'><div class='card-rules'>" + card.rulesText + "</div></td>" + 280 281 " </tr>" + 282 283 (card.flavorText != null ? " <tr>" + 284 285 " <td class='card-flavor-row card-front'><div class='card-flavor'>" + card.flavorText + "</div></td>" + 286 287 " </tr>" : "") + 288 289 (card.ptString != null ? " <tr>" + 290 291 " <td class='card-pt-row card-front'><div class='card-pt'>" + card.ptString + "</div></td>" + 292 293 " </tr>" : "") + 294 295 (card.name2 != "" ? 296 297 " <tr>" + 298 299 " <td class='card-separator-row'><hr /></td>" + 300 301 " </tr>" + 302 303 " <tr>" + 304 305 " <td class='card-main-row card-back'><div class='card-name'><a href='" + card.url + "'>" + card.name2 + "</a></div>" + (card.manaCost2 != null ?"<div class='card-cost'>" + card.manaCost2 + "</div></td>" : "</td>")+ 306 307 " </tr>" + 308 309 " <tr>" + 310 311 " <td class='card-type-row card-back'><div class='card-types'>" + card.types2 + "</div><div class='card-rarity card-rarity-" + card.rarity.toLowerCase() +"'>" + card.rarityName + "</div></td>" + 312 313 " </tr>" + 314 315 " <tr>" + 316 317 " <td class='card-rules-row card-back'><div class='card-rules'>" + card.rulesText2 + "</div></td>" + 318 319 " </tr>" + 320 321 (card.flavorText2 != null ? " <tr>" + 322 323 " <td class='card-flavor-row card-back'><div class='card-flavor'>" + card.flavorText2 + "</div></td>" + 324 325 " </tr>" : "") + 326 327 (card.ptString2 != null ? " <tr>" + 328 329 " <td class='card-pt-row card-back'><div class='card-pt'>" + card.ptString2 + "</div></td>" + 330 331 " </tr>" : "") 332 333 : "") + 334 335 (this.enableLinks ? 336 337 " <tr>" + 338 339 " <td class='card-filler-row'>" + 340 341 " <a href='javascript:void(0)' onclick='spoiler.copyAsBBCode(\"" + card.name + "\")'>Copy as forum code</a>" + 342 343 " <a href='javascript:void(0)' onclick='spoiler.copyUrl(\"" + card.name + "\")'>Copy permalink</a>" + 344 345 " <a href='javascript:void(0)' onclick='spoiler.copyArtUrl(\"" + card.name + "\")'>Copy image URL</a>" + 346 347 " </td>" + 348 349 " </tr>" 350 351 : "") + 352 353 "</table><hr class='card-separator' />" 354 355 356 357 ); 358 359 360 361 if(!this.enableLinks){ 362 363 $('a', this.spoilerCardElements[card.cardId]).each(function(){ 364 365 $(this).replaceWith( this.childNodes ); 366 367 }); 368 369 } 370 371 } 372 373} 374 375 376 377Spoiler.prototype.initializeSorting = function () { 378
379 if(this.enableControl){ 380 381 this.order = "color"; 382 383 } 384 385 else { 386 387 this.order = "sequence"; 388 389 } 390 391 392 393 var modifierFunction = function(x) { 394 395 var modifier = 0; 396 397 if(x.types.indexOf("Basic") !== -1 && x.types.indexOf("Land") !== -1) modifier = 50; 398 399 if(x.types.indexOf("Token") !== -1 || x.types.indexOf("Emblem") !== -1) modifier = 100; 400 401 return modifier; 402 403 } 404 405 406 407 this.sortFunctions = { 408 409 "color": function(spoiler, a, b) { 410 411 var rate = function(x) { 412 413 var modifier = modifierFunction(x); 414 415 if (x.colors.length == 0 && x.rarity == 'B') return 8 + modifier; 416 417 else if (x.colors.length == 0 && x.types.indexOf("Artifact") == -1) return 7 + modifier; 418 419 else if (x.colors.length == 0 && x.types.indexOf("Artifact") != -1) return 6 + modifier; 420 421 else if (x.colors.length > 1) return 5 + modifier; 422 423 else if (x.colors[0] == 'G') return 4 + modifier; 424 425 else if (x.colors[0] == 'R') return 3 + modifier; 426 427 else if (x.colors[0] == 'B') return 2 + modifier; 428 429 else if (x.colors[0] == 'U') return 1 + modifier; 430 431 else if (x.colors[0] == 'W') return 0 + modifier; 432 433 else throw "Not reached " + x.colors[0]; 434 435 } 436 437 438 439 var ratingA = rate(a); 440 441 var ratingB = rate(b); 442 443 444 445 if (ratingA == ratingB) return a.name.localeCompare(b.name); 446 447 else return ratingA - ratingB; 448 449 }, 450 451 "rarity": function (spoiler, a, b) { 452 453 var rate = function (x) { 454 455 var modifier = modifierFunction(x); 456 457 if (x.rarity == 'T') return 7 + modifier; 458 459 else if (x.rarity == 'B') return 6 + modifier; 460 461 else if (x.rarity == 'S') return 5 + modifier; 462 463 else if (x.rarity == 'C') return 4 + modifier; 464 465 else if (x.rarity == 'U') return 3 + modifier; 466 467 else if (x.rarity == 'R') return 2 + modifier; 468 469 else if (x.rarity == 'M') return 1 + modifier; 470 471 else throw "Not reached \"" + x.rarity + "\""; 472 473 } 474 475 476 477 var ratingA = rate(a); 478 479 var ratingB = rate(b); 480 481 482 483 484 485 if (ratingA == ratingB) return spoiler.sortFunctions["color"](spoiler, a, b); 486 487 else return ratingA - ratingB; 488 489 }, 490 491 "cmc": function (spoiler, a, b) { 492 493 var ratingA = a.cmc != null ? (a.rarity != 'B' ? a.cmc : -2) : -1; 494 495 var ratingB = b.cmc != null ? (b.rarity != 'B' ? b.cmc : -2) : -1; 496 497 498 499 if (ratingA == ratingB) return spoiler.sortFunctions["color"](spoiler, a, b); 500 501 else return ratingA - ratingB; 502 503 }, 504 505 "name": function (spoiler, a, b) { 506 507 return a.name.localeCompare(b.name); 508 509 }, 510 511 "sequence": function (spoiler, a, b) { 512 513 return a.id - b.id; 514 515 }, 516 517 "random": function (spoiler, a, b) { 518 519 return spoiler.alea() - spoiler.alea(); 520 521 }, 522 523 }; 524 525 526 527} 528 529 530 531Spoiler.prototype.initializeFilters = function() { 532 533 this.rarityFilter = null; 534 535 this.typeFilter = null; 536 537 this.colorFilter = null; 538 539} 540 541 542 543Spoiler.prototype.sort = function (sortFunction) { 544 545 this.order = sortFunction; 546 547 this.redraw(); 548 549 $('.activeSort', $(".spoiler-sort", this.mainElement)).removeClass('activeSort'); 550 551 $("[sort='" + this.order + "']", $(".spoiler-sort", this.mainElement)).addClass('activeSort'); 552 553} 554 555 556 557Spoiler.prototype.filterByRarity = function (filterValue) { 558 559 if (filterValue == this.rarityFilter) { 560 561 this.rarityFilter = null; 562 563 } else { 564 565 this.rarityFilter = filterValue; 566 567 } 568 569 570 571 this.redraw(); 572 573 574 575 $('.activeSort', $(".spoiler-filters-rarity", this.mainElement)).removeClass('activeSort'); 576 577 $("[filter='" + this.rarityFilter + "']", $(".spoiler-filters-rarity", this.mainElement)).addClass('activeSort'); 578 579} 580 581 582 583Spoiler.prototype.filterByType = function (filterValue) { 584 585 if (filterValue == this.typeFilter) { 586 587 this.typeFilter = null; 588 589 } else { 590
591 this.typeFilter = filterValue; 592 593 } 594 595 596 597 this.redraw(); 598 599 600 601 $('.activeSort', $(".spoiler-filters-type", this.mainElement)).removeClass('activeSort'); 602 603 $("[filter='" + this.typeFilter + "']", $(".spoiler-filters-type", this.mainElement)).addClass('activeSort'); 604 605} 606 607 608 609Spoiler.prototype.filterByColor = function (filterValue) { 610 611 if (filterValue == this.colorFilter) { 612 613 this.colorFilter = null; 614 615 } else { 616 617 this.colorFilter = filterValue; 618 619 } 620 621 622 623 this.redraw(); 624 625 626 627 $('.activeSort', $(".spoiler-filters-color", this.mainElement)).removeClass('activeSort'); 628 629 $("[filter='" + this.colorFilter + "']", $(".spoiler-filters-color", this.mainElement)).addClass('activeSort'); 630 631} 632 633 634 635Spoiler.prototype.setMode = function (mode) { 636 637 this.mode = mode; 638 639 640 641 this.redraw(); 642 643 644 645 $('.activeSort', $(".spoiler-mode", this.mainElement)).removeClass('activeSort'); 646 647 $("[mode='" + this.mode + "']", $(".spoiler-mode", this.mainElement)).addClass('activeSort'); 648 649} 650 651 652 653Spoiler.prototype.getCardByName = function (cardName) { 654 655 var card; 656 657 for (var i = 0; i < this.data.length; i++) { 658 659 if (this.data[i].name == cardName) return this.data[i]; 660 661 } 662 663 664 665 return null; 666 667} 668 669 670 671Spoiler.prototype.copyArtUrl = function(cardName) { 672 673 var card = this.getCardByName(cardName); 674 675 showCopyable(card.artUrl); 676 677 return false; 678 679}; 680 681 682 683 684 685Spoiler.prototype.copyUrl = function(cardName) { 686 687 var card = this.getCardByName(cardName); 688 689 showCopyable(card.url); 690 691 return false; 692 693}; 694 695 696 697//In-built replace is dumb and replaces only one occurence 698 699Spoiler.prototype.smartReplace = function (haystack, needle, replace) { 700 701 return haystack.replace(new RegExp(needle, 'g'), replace); 702 703} 704 705 706 707Spoiler.prototype.copyAsBBCode = function (cardName) { 708 709 var card = this.getCardByName(cardName); 710 711 712 713 showCopyable(card.bbCode); 714 715} 716 717 718 719Spoiler.prototype.copyAsBBLink = function (cardName) { 720 721 var bbCode = (this.localUrl != null ? "[url=" + this.localUrl + "#" + cardName + "]" + cardName + "[/url]" : cardName); 722 723 showCopyable(bbCode); 724 725} 726 727 728 729Spoiler.prototype.redraw = function () { 730 731 console.log("redraw mobile: ", isMobileView()); 732 733 734 735 this.cardsElement.empty(); 736 737 738 739 var spoiler = this; 740 741 742 743 this.resetSeed(); 744 745 746 747 // Presort the data so that random sort has predicatable initial state 748 749 this.data.sort(function(a, b) { return a.name.localeCompare(b.name); }); 750 751 752 753 this.data.sort(function (a, b) { 754 755 return spoiler.sortFunctions[spoiler.order](spoiler, a, b); 756 757 }); 758 759 760 761 for (var i = 0; i < this.data.length; i++) { 762 763 var card = this.data[i]; 764 765 766 767 var include = true; 768 769 770 771 if (this.rarityFilter != null) { 772 773 if (this.rarityFilter != card.rarity) { 774 775 include = false; 776 777 } 778 779 } 780 781 782 783 if (this.typeFilter != null) { 784 785 if (card.types.indexOf(this.typeFilter) == -1 && card.types2.indexOf(this.typeFilter) == -1) { 786 787 include = false; 788 789 } 790 791 } 792 793 794 795 if (this.colorFilter != null) { 796 797 if (this.colorFilter == "1") { 798 799 if (card.colors.length > 0) include = false; 800 801 } 802 803 else if (this.colorFilter == "M") { 804 805 if (card.colors.length < 2) include = false; 806 807 } else { 808 809 if (card.colors.indexOf(this.colorFilter) == -1) { 810 811 include = false; 812 813 } 814 815 } 816 817 } 818 819 820 821 if (include) { 822 823 if(this.mode == "spoiler" && !isMobileView()){ 824 825 this.cardsElement.append(this.spoilerCardElements[card.cardId]); 826 827 } 828 829 else { 830 831 this.cardsElement.append(this.imageCardElements[card.cardId]); 832 833 } 834 835 } 836 837 } 838 839 840 841 this.lazyload = $(".lazyload", this.mainElement).lazyload({ 842 843 effect : "fadeIn", 844 845 skip_invisible : true 846 847 }); 848 849 850 851 $(window).scroll(); 852 853 854 855 //if(this.lazyload) this.lazyload.update(); 856 857 //$(window).trigger('resize'); 858 859}
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.