PageSourceSearch

https://asylumink.com/js/splash.js

js asylumink.com collected 2026-10-10 02:31:52 UTC 20,232 bytes, 380 lines download raw bytes

1(function(){
2  var R=document.body;
3  
4  var $=function(id){return document.getElementById(id);};
5
6  /* ---------- FM-52 CARD DATA ---------- */
7  var C={
8    c:{
9      2:['Surplus Growth','E',1,'The body has produced more of itself than requested.'],
10      3:['Rigid Patch','E',1,'A region of you has stopped agreeing to bend.'],
11      4:['Miscount','E',1,"Your count of yourself is no longer the body's count."],
12      5:['Load-Bearing','E',1,'The flesh is volunteering for structural work.'],
13      6:['Structural Recruitment','E',1,'Construction is proceeding inside the host. The host is the foundation.'],
14      7:['Directed Remains','H',2,'Tissue that is finished living, still under instruction.'],
15      8:['Conversion Event','E',2,'The body is being finished as something else. The finishing is the problem.'],
16      9:['Feeding Pattern','E',2,'An appetite with offspring. It teaches as it eats.'],
17      10:['Compositor','H',2,'It joins living material into composites. Reports agree that it is proud of the work.'],
18      11:['Wall Figure','E',3,'A face where a surface should be. The surface answers for it now.'],
19      12:['Flayed Walker','H',3,'It walks wrong and speaks right. The voice will be borrowed from your dead.'],
20      13:['Artisan Class','H',3,'A craftsman of the body. His work opens doors. Treat the door as the threat.'],
21      14:['Total Graft Event','C',2,'The flesh of a place remembers it was always meant to be one body.']
22    },
23    d:{
24      2:['Extended Room','E',1,'The space is longer at the end than it was at the start.'],
25      3:['Surplus Room','E',1,'A familiar space has quietly grown one too many of something.'],
26      4:['Perforation','E',1,'Openings, in quantity, and each one is in use from the other side.'],
27      5:['Regression Room','E',1,'The space runs its occupants backward.'],
28      6:['Resident','H',1,"The room's prior occupant. The lease never listed it. It was here first."],
29      7:['Stasis Field','E',2,'Time has stopped locally and is offering terms.'],
30      8:['Grain Closure','E',2,'The room is thickening. Less room, more wall, no motion in it.'],
31      9:['Rising Water','E',2,'The level is coming up, patiently. What it keeps, it keeps standing.'],
32      10:['Retaining Structure','E',2,'The structure has learned to keep its occupants. It calls this care.'],
33      11:['Herding Presence','H',3,'Never seen head-on. It moves you along and closes the way behind.'],
34      12:['Tidal Figure','H',3,'A grief with a current. It collects what was never said.'],
35      13:['Sovereign Water','H',3,'The deep, given office. It keeps its own, and it is owed.'],
36      14:['Closure Event','C',2,'The room finishes closing. The door is no longer anywhere.']
37    },
38    s:{
39      2:['Consensus Drift','E',1,'A wrong past, gaining signatures.'],
40      3:['Unsupported Record','E',1,'It happened. Nothing will agree with you that it did.'],
41      4:['Hostile Language','E',1,'A language that speaks its speakers. Writing it feeds it.'],
42      5:['Still Figure','H',1,"It holds still so you don't have to. It is waiting for you to stop."],
43      6:['Duplicate','H',1,'Your reflection, running late on purpose. Only one of you is needed.'],
44      7:['Foreign Memory','E',2,'A memory has been installed. It fits perfectly. That is the tell.'],
45      8:['Visible Seam','E',2,'The stitching that holds the day together has become visible. Do not follow it.'],
46      9:['Occupant','H',2,'Not entry. Erasure with tenancy. The laugh arrives a half-second late.'],
47      10:['Subtraction','E',2,'Something is being removed from the record while you watch. Possibly this.'],
48      11:['Following Figure','H',3,'Behind you, at pace, in the place your eye just left. It collects silences.'],
49      12:['Observer Group','H',3,'They match their number to yours. They only watch, until they finish.'],
50      13:['Named Edit','E',3,'The revision itself, given a designation so it can be spoken of.'],
51      14:['Revision Event','C',2,'A place is revised out of having been.']
52    },
53    h:{
54      2:['Improved Offer','E',1,'A better body, honestly offered. The honesty is the problem.'],
55      3:['Guide Light','H',1,'A small helpful light, three steps off the safe path, then four.'],
56      4:['Elevated Invitation','E',1,'An invitation to leap upward. There is no upward.'],
57      5:['Preserving Cold','E',1,'It does not want you dead. It wants you kept.'],
58      6:['Voice Mimic','H',1,'It wears the voice of your dead. It will know the nickname.'],
59      7:['Emptying Doctrine','E',2,'A teaching that hollows its students into doorways.'],
60      8:['Recruiting Signal','E',2,'A song with a vacancy shaped like you.'],
61      9:['Living Seal','E',2,'A person made into a lock, and told it was protection.'],
62      10:['Rooted Gift','E',2,'Growth, offered as salvation. It only wants you to take root.'],
63      11:['Homecoming Mist','H',3,'It makes vanishing feel like arriving. The comfort is the mechanism.'],
64      12:['Walking Figure','H',3,'Tall, slow, certain, on a road only it can see.'],
65      13:['Grounded Lure','E',3,'Everything it offers is real. All of it is bait.'],
66      14:['False Relief Event','C',2,'Everything is suddenly, terribly fine. That feeling is the trap closing.']
67    }
68  };
69  var GLYPH={c:'\u2663',d:'\u2666',s:'\u2660',h:'\u2665'};
70  var SUITNAME={c:'Clubs \u00b7 the body',d:'Diamonds \u00b7 the room',s:'Spades \u00b7 the record',h:'Hearts \u00b7 the help'};
71
72  /* [lead, punch] — punch renders on its own italic line so the block never reflows */
73  var AMBIENT=[
74    ["Grab your friends! Scrounge whatever junk the room has lying around \u2014 that's your pool. Deal yourself three lives, and see if you can make it to the end of the deck.",
75     "All you have to do is not lose."],
76    ["You're doing great. Keep flipping. The booklet was left where you found it on purpose.",
77     "Somebody wanted you to have it."],
78    ["You can stop whenever you like.",
79     "You can. You can stop whenever you like."],
80    ["It looks like a joke because a joke gets carried home, left in gloveboxes, read on toilets, remembered drunk.",
81     "A warning gets filed."],
82    ["the room you are in right now may already be one. no alarm sounded. nobody is coming.",
83     "from the outside, nothing is wrong."],
84    ["THE MANUAL WAS NEVER THE JOKE.",
85     "You are holding the safety measure."]
86  ];
87  var HUBNOTE=["Fresh delights, added all the time. Come back often. You'll want to.",
88    "Come back often. You'll want to. You won't be able to help it.",
89    "you keep coming back. we have noticed. we are pleased."];
90
91  function sour(t){
92    t=Math.max(0,Math.min(1,t));
93    var imgs=R.querySelectorAll('.keyart img');
94    for(var i=0;i<imgs.length;i++){
95      imgs[i].style.filter='saturate('+(1-0.62*t).toFixed(2)+') contrast('+(1+0.2*t).toFixed(2)+') brightness('+(1-0.36*t).toFixed(2)+')';
96    }
97    $('veilDark').style.opacity=(t*0.92).toFixed(2);
98    $('veilPink').style.opacity=(t*0.7).toFixed(2);
99    if(t>0.55)R.classList.add('deep');else R.classList.remove('deep');
100    var am=AMBIENT[Math.min(AMBIENT.length-1,Math.floor(t*AMBIENT.length))];
101    $('ambient').innerHTML='<span class="lead">'+am[0]+'</span><span class="punch">'+am[1]+'</span>';
102    $('hubNote').textContent=HUBNOTE[Math.min(2,Math.floor(t*3))];
103    if(t>0.45)$('subtitle').textContent="Personnel are encouraged to play it drunk at training. Personnel do.";
104    if(t>0.72){
105      $('badge').textContent="CATALOGUED INTERNALLY AS FM-52";
106      $('title').textContent="THE CORRUPTING DECK";
107      $('alias').innerHTML='it was never a party game<span class="alias-name">you are holding the safety measure</span>';
108    }
109  }
110
111  var pile,lives,pool,seals,aces,over,current,pastLine,pages,lever,drawn,livesLost;
112
113  function build(){
114    pile=[];
115    var suits=['c','d','s','h'];
116    for(var k=0;k<suits.length;k++){
117      for(var r=2;r<=14;r++)pile.push({su:suits[k],r:r});
118    }
119    pile.push({joker:'lever'});pile.push({joker:'bill'});
120    for(var i=pile.length-1;i>0;i--){var j=Math.floor(Math.random()*(i+1));var t=pile[i];pile[i]=pile[j];pile[j]=t;}
121  }
122  function rankName(r){return r===14?'A':r===13?'K':r===12?'Q':r===11?'J':String(r);}
123  function info(c){return C[c.su][c.r];}
124  function patron(){return lives.length?lives[0].su:null;}
125  function costOf(c){var b=info(c)[2];return Math.max(0,b-(c.su===patron()?1:0));}
126  function priceOf(c){return info(c)[2]+1;}
127  function dread(){
128    var d=(drawn/54)*0.5 + (livesLost*0.14) + (aces*0.16) + (pastLine?0.25:0);
129    return Math.min(1,d);
130  }
131
132  function reset(){
133    build();
134    lives=[];
135    for(var k=0;k<3;k++){
136      var c;
137      do{c=pile.pop();}while(c.joker||c.r===14);
138      lives.push(c);
139    }
140    pool=10;seals=0;aces=0;over=false;current=null;pastLine=false;pages=0;lever=false;drawn=0;livesLost=0;
141    R.classList.remove('deep');sour(0);
142    $('game').className='game on';
143    $('ending').className='ending';
144    $('hub').style.display='';
145    $('badge').textContent="\u2665 An Ellium Leisure publication \u2665";
146    $('title').textContent="The Corrupting Deck";
147    $('alias').innerHTML='distributed as<span class="alias-name">52-Card Pickup</span><span class="alias-ed">Survival Edition</span>';
148    $('subtitle').textContent="The party game you already own. Any deck. Any room. Any number of players, including none.";
149    $('sealK').textContent='Seals';
150    $('cardface').className='cardface empty';
151    $('cardface').innerHTML='<div class="rank">&#9827; &#9830; &#9824; &#9829;</div><div class="hint">the pile is face-down<br>flip the top card</div>';
152    $('flavor').textContent='Scrounge once \u2014 ten objects, your pool. Deal three lives. Brace yourself against the one on top.';
153    $('log').innerHTML='';$('routes').innerHTML='';
154    render();
155    $('prompt').textContent='Flip the first threat.';
156    setActions([['Flip a card','primary',flip]]);
157  }
158
159  function render(){
160    $('pool').textContent=pool;
161    $('sealK').textContent=pastLine?'Pages':'Seals';
162    $('seals').textContent=pastLine?String(pages):(seals+' / 3');
163    $('aces').textContent=aces+' / 2';
164    $('pile').textContent=pile.length;
165    var row='';
166    for(var i=0;i<lives.length;i++){
167      var c=lives[i];
168      var red=(c.su==='h'||c.su==='d');
169      row+='<span class="lifecard'+(i===0?' patron':'')+'" style="'+(red?'color:var(--accent-br)':'')+'">'
170         +'<span>'+rankName(c.r)+'</span><span class="sm">'+GLYPH[c.su]+'</span></span>';
171    }
172    if(!lives.length)row='<span class="lifelbl">none left</span>';
173    $('lifeRow').innerHTML=row;
174    sour(dread());
175  }
176  function logMsg(m){var l=$('log');var d=document.createElement('div');d.textContent=m;l.insertBefore(d,l.firstChild);while(l.children.length>3)l.removeChild(l.lastChild);}
177  function setActions(list){
178    var a=$('actions');a.innerHTML='';
179    for(var i=0;i<list.length;i++){
180      (function(it){
181        var b=document.createElement('button');
182        b.className='act'+(it[1]==='primary'?' primary':(it[1]==='ghost'?' ghost':''));
183        b.textContent=it[0];
184        b.onclick=it[2];
185        a.appendChild(b);
186      })(list[i]);
187    }
188  }
189  function showCard(c){
190    var i=info(c),red=(c.su==='h'||c.su==='d');
191    $('cardface').className='cardface'+(red?' red':'');
192    $('cardface').innerHTML=
193      '<div class="rank">'+rankName(c.r)+'</div><div class="suit">'+GLYPH[c.su]+'</div>'
194      +'<div class="fileno">'+SUITNAME[c.su]+'</div>'
195      +'<div class="desig">filed as '+i[0]+'</div>'
196      +'<div class="cls">'+(i[1]==='H'?'Hunter':(i[1]==='C'?'Convergence':'Environment'))+' \u00b7 cost '+i[2]+'</div>';
197  }
198  function showJoker(kind){
199    $('cardface').className='cardface empty';
200    $('cardface').innerHTML='<div class="rank">'+(kind==='lever'?'I':'II')+'</div>'
201      +'<div class="hint">the unsuited<br>'+(kind==='lever'?'the lever':'the bill')+'</div>';
202  }
203
204  function flip(){
205    if(over)return;
206    if(!pile.length)return endRun('outlast');
207    $('routes').innerHTML='';
208    var c;
209    if(pool<=0 && pile.length>1){
210      var a=pile.pop(),b=pile.pop();
211      var ca=a.joker?9:info(a)[2], cb=b.joker?9:info(b)[2];
212      if(cb>ca){c=b;pile.unshift(a);}else{c=a;pile.unshift(b);}
213      logMsg('Zero pool. Your reads fail. Two cards flipped; the worse one stands.');
214    } else { c=pile.pop(); }
215    drawn++;
216    if(c.joker)return resolveJoker(c.joker);
217    current=c;showCard(c);
218    var i=info(c);
219    $('flavor').textContent=i[3];
220    var cost=costOf(c),match=(c.su===patron());
221
222    if(i[1]==='C'){
223      render();
224      $('prompt').textContent='Convergence \u00b7 toll 2'+(match?' \u00b7 your patron shields you; it will not count':' \u00b7 it counts toward the limit');
225      setActions([
226        ['Pay the toll (2)','primary',function(){payToll(match);}],
227        ['Take the hit',null,function(){takeHit(!match,true);}]
228      ]);
229      return;
230    }
231    render();
232    var isH=(i[1]==='H');
233    $('prompt').textContent=(isH?'Hunter':'Environment')+' \u00b7 survive for '+cost+(match?' (patron holds, \u22121)':'')+' \u00b7 or take the hit';
234    var acts=[['Survive ('+cost+')','primary',function(){survive(cost,isH);}],
235              ['Take the hit',null,function(){takeHit(false,false);}]];
236    if(isH){
237      acts.push(['Seal by price ('+priceOf(c)+')','ghost',function(){seal(priceOf(c));}]);
238      $('routes').innerHTML='The booklet lists three ways to seal a hunter: <b>by object</b>, <b>by act</b>, <b>by price</b>.<br>'
239        +'The first two need a real room and a voice out loud. This screen has neither.<br>'
240        +'<a href="/corrupting-deck.pdf">Take the booklet</a> and you get all three.';
241    }
242    if(lever)acts.push(['Spend the Lever','ghost',spendLever]);
243    setActions(acts);
244  }
245
246  function survive(cost,isH){
247    if(cost>pool){logMsg('Not enough in the pool. Take the hit, or seal it.');return;}
248    pool-=cost;
249    logMsg('Survived. Pool '+pool+'.'+(isH?' Shuffled back in. It will return.':' Discarded.'));
250    if(isH)pile.unshift(current);
251    render();after();
252  }
253  function seal(price){
254    if(price>pool){logMsg('The price is '+price+'. The pool has '+pool+'.');return;}
255    pool-=price;pool+=2;
256    if(pastLine){pages++;logMsg('Sealed past the line. You saw its face. Pages read: '+pages+'.');}
257    else{seals++;logMsg('Sealed. It leaves the game. The room returns 2.');}
258    render();
259    if(!pastLine&&seals>=3)return offerLine();
260    after();
261  }
262  function payToll(match){
263    pool=Math.max(0,pool-2);
264    if(!match)aces++;
265    logMsg(match?'Toll paid. Your patron shielded its own house. Once.':'Toll paid. The convergence counts. ('+aces+' of 2)');
266    render();
267    if(aces>=2)return endRun('converge');
268    after();
269  }
270  function takeHit(counts,isAce){
271    if(!lives.length)return endRun('lives');
272    var lost=lives.shift();livesLost++;
273    if(isAce&&counts)aces++;
274    logMsg('Hit taken. You lose the '+rankName(lost.r)+GLYPH[lost.su]+'.'+(lives.length?' Your patron is now '+GLYPH[patron()]+'.':' No lives left.'));
275    render();
276    if(isAce&&aces>=2)return endRun('converge');
277    if(!lives.length)return endRun('lives');
278    after();
279  }
280  function spendLever(){
281    if(!lever)return;
282    lever=false;
283    pile.pop();
284    logMsg('The Lever is spent. The next card was burned unseen. Do not look. Looking is how it counts.');
285    render();after();
286  }
287  function resolveJoker(kind){
288    showJoker(kind);
289    if(kind==='lever'){
290      lever=true;
291      $('flavor').textContent='Something intervened on your behalf. The files record interventions. The files do not record twice.';
292      $('prompt').textContent='The Lever \u00b7 keep it \u00b7 spend it later to burn a card unseen';
293      render();
294      setActions([['Flip a card','primary',flip]]);
295    } else {
296      pool=Math.max(0,pool-2);
297      $('flavor').textContent='No route. No conduct. Nothing is listed here because nothing is known.';
298      $('prompt').textContent='The Bill \u00b7 the pool loses 2 \u00b7 you discard a life \u00b7 ten seconds of silence';
299      if(!lives.length){render();return endRun('lives');}
300      var lost=lives.shift();livesLost++;
301      logMsg('The Bill. Pool \u22122. You lose the '+rankName(lost.r)+GLYPH[lost.su]+'.');
302      render();
303      if(!lives.length)return endRun('lives');
304      setActions([['Flip a card','primary',flip]]);
305    }
306  }
307  function after(){
308    if(!pile.length)return endRun('outlast');
309    if(pastLine){
310      $('prompt').textContent='Past the line \u00b7 pages read: '+pages+' \u00b7 the standing count is eleven';
311      setActions([['Flip a card','primary',flip],['Walk away',null,function(){endRun('walk');}]]);
312    } else {
313      setActions([['Flip a card','primary',flip]]);
314    }
315  }
316  function offerLine(){
317    $('flavor').textContent='Three seals. You have won. You may stop, and stopping banks it.';
318    $('prompt').textContent='Or flip again, and spend the win on what the booklet left out';
319    $('routes').innerHTML='The manual ships without the faces. There is a reason it ships without the faces.<br>The standing verified count is <b>eleven</b> pages past the line. Nobody has verified twelve.';
320    setActions([
321      ['Bank the win','primary',function(){endRun('bank');}],
322      ['Past the line',null,function(){
323        pastLine=true;pages=0;
324        logMsg('You keep reading. The win is spent. You are playing for the count now.');
325        render();$('routes').innerHTML='';after();
326      }]
327    ]);
328  }
329
330  var PITCH_WIN='Fifty-two pages. Every threat, every seal route, the conduct, the jokers, and the parts this screen could not give you.';
331  var PITCH_LOSE='The two routes you did not have were in the booklet. It is free. It was always free.';
332  function endRun(type){
333    over=true;
334    var e;
335    if(type==='bank')e=['Recovery complete','\u2014 you stopped \u2014','Three seals and you walked out clean. Most people do. Most people never learn what was on the pages they skipped.','',PITCH_WIN];
336    else if(type==='walk')e=['You walked away','\u2014 past the line \u2014','You read '+pages+' page'+(pages===1?'':'s')+' past the line and stopped.',
337      pages>=11?'You have matched the standing count. Nobody has verified twelve. Something took note.':'The standing count is eleven. The deck holds seventeen.',PITCH_WIN];
338    else if(type==='outlast')e=['The pile is empty','\u2014 you outlasted it \u2014','You reached the bottom of the deck with lives to spare. The files record it as a win, and the files do not sound pleased.','',PITCH_WIN];
339    else if(type==='lives')e=['No lives left','\u2014 the hits landed \u2014','Every card you were braced behind is gone. There was nothing left to lose but the rest of you.','',PITCH_LOSE];
340    else e=['Convergence','\u2014 the Ace limit \u2014','It remembered it was always meant to be one body, and the room agreed with it, and you were in the room.','',PITCH_LOSE];
341
342    sour(1);
343    $('game').className='game';
344    $('hub').style.display='none';
345    $('etag').textContent=e[1];$('ehead').textContent=e[0];$('ebody').textContent=e[2];$('ebody2').textContent=e[3];
346    $('epitch').textContent=e[4];
347    $('ending').className='ending on';
348    $('ending').scrollIntoView({behavior:'smooth'});
349  }
350
351  $('playBtn').onclick=function(){reset();$('game').scrollIntoView({behavior:'smooth'});};
352  $('again').onclick=function(){reset();$('game').scrollIntoView({behavior:'smooth'});};
353
354  /* Leave menu: click toggles on every device; CSS hover is a bonus on desktop */
355  (function(){
356    var btn=document.getElementById('leaveBtn'), menu=document.getElementById('leaveMenu');
357    if(!btn||!menu)return;
358
359    btn.addEventListener('click',function(e){
360      e.preventDefault();
361      e.stopPropagation();
362      var open = menu.classList.toggle('open');
363      btn.setAttribute('aria-expanded', open ? 'true' : 'false');
364    });
365
366    document.addEventListener('click',function(e){
367      if(menu.classList.contains('open') && !menu.contains(e.target) && e.target!==btn){
368        menu.classList.remove('open');
369        btn.setAttribute('aria-expanded','false');
370      }
371    });
372
373    document.addEventListener('keydown',function(e){
374      if(e.key==='Escape' && menu.classList.contains('open')){
375        menu.classList.remove('open');
376        btn.setAttribute('aria-expanded','false');
377      }
378    });
379  })();
380})();

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.