I think it's this one... Looks like you run !deck to get help. (function(){
"use strict";
const numberStyle=`position:absolute;top:3px;right:3px;z-index:100;font-weight:bold;color:white;font-size:2em;text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;`,
cardStyle=`max-width: 5em;max-height:7em;position:relative;display:inline-block;`,
// nameStyle=`position:absolute;bottom:3px;left:3px;z-index:100;font-weight:bold;color:white;font-size:1em;text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;`,
esRE = function (s) {
var escapeForRegexp = /(\\|\/|\[|\]|\(|\)|\{|\}|\?|\+|\*|\||\.|\^|\$)/g;
return s.replace(escapeForRegexp,"\\$1");
},
HE = (function(){
var entities={
//' ' : '&'+'nbsp'+';',
'<' : '&'+'lt'+';',
'>' : '&'+'gt'+';',
"'" : '&'+'#39'+';',
'@' : '&'+'#64'+';',
'{' : '&'+'#123'+';',
'|' : '&'+'#124'+';',
'}' : '&'+'#125'+';',
'[' : '&'+'#91'+';',
']' : '&'+'#93'+';',
'"' : '&'+'quot'+';'
},
re=new RegExp('('+_.map(_.keys(entities),esRE).join('|')+')','g');
return function(s){
return s.replace(re, function(c){ return entities[c] || c; });
};
}()),
ch = function (c) {
var entities = {
'<' : 'lt',
'>' : 'gt',
"'" : '#39',
'@' : '#64',
'{' : '#123',
'|' : '#124',
'}' : '#125',
'[' : '#91',
']' : '#93',
'"' : 'quot',
'-' : 'mdash',
' ' : 'nbsp'
};
if(_.has(entities,c) ){
return ('&'+entities[c]+';');
}
return '';
},
keyFormat = (s)=>s.toLowerCase().replace(/[^a-z0-9]/g,''),
showHelp = function(who){
sendChat('',`/w "${who}" `+
`<div>`+
`<div>`+
`<code>!deck `+
`--${ch('<')}Deck name${ch('>')} ${ch('[')}--${ch('<')}Operation${ch('>')} ${ch('[')}--${ch('<')}Option${ch('>')} ...${ch(']')} ${ch(']')}`+
`</code>`+
`</div>`+
`<div>`+
`<h4>Operations</h4>`+
`<ul>`+
`<li><code>list</code> -- The default operation, shows the current stack of cards for the deck.</li>`+
`<li><code>stack</code> -- Stack the deck with cards. Each subsequent option is the name of a card in the deck and will be placed on the top of the deck in the order specified. Cards that are replaced will be moved to where each new card was.</li>`+
`</ul>`+
`<h4>Names</h4>`+
`<p>Wherever you specify a card or deck name, you can use the minimal matching part of the name. Case is ignored, as are spaces and any punctuation. ${ch('"')}Bob - the - builder!${ch('"')} would be matched by ${ch('"')}bob${ch('"')} or ${ch('"')}thebui${ch('"')} or a similar substring.</p>`+
`</div>`
);
},
getDecks = function(name){
let deckKey=keyFormat(name||'');
return deckKey ?
_.filter(findObjs({ type: 'deck' }), (d)=> -1 !== keyFormat(d.get('name')).indexOf(deckKey)) :
[];
},
getCards = function(deck, cardNames){
let cards = findObjs({
type: 'card',
deckid: deck.id
});
return _.chain(cardNames)
.map(keyFormat)
.reduce((m,cardKey)=>{
let match = _.reduce(cards,(m,c) => {
let cKey = keyFormat(c.get('name'));
if(-1 !== cKey.indexOf(cardKey)){
if(cKey===cardKey){
return {
card: c,
exact: true
};
} else if(!m.card){
return {
card: c,
exact: false
};
}
}
return m;
},{card:false, exact:false});
m.push(match.card);
return m;
},[])
.value();
},
showDeckOptions = function(who,msg,decks,deckName){
let notFound = (decks.length ? '' : `<div style="color:red;font-weight:bold;">No deck found for <code>${deckName}</code></div>`),
deckOpt = (decks.length ? decks : findObjs({type:'deck'}));
sendChat('',`/w "${who}" `+
`<div>`+
notFound+
`<div><div>Possible options:</div><ul>`+
_.map(deckOpt,(d)=>{
return `<li><a href="${HE(msg.replace(`--${deckName}`,`--${keyFormat(d.get('name'))}`))}">${d.get('name')}</a></li>`;
}).join('')+
`</ul></div>`+
`</div>`
);
},
showCardOptions = function(who,deck, cardNames){
sendChat('',`/w "${who}" `+
`<div>`+
`<div style="color:red;font-weight:bold;">No card found in <code>${deck.get('name')}</code> for <code>${cardNames.join('</code>, <code>')}</code></div>`+
`<div>Possible options:</div>`+
`<div>${getDeckCardList(deck)}</div>`+
`</div>`
);
},
getDeckCardList = function(deck){
let cards=_.chain(deck.get('currentDeck').split(/\s*,\s*/))
.map((id)=>getObj('card',id))
.reject(_.isUndefined)
.value();
let disp = _.map(cards,(o,idx)=>{
return `<div style="${cardStyle}">`+
`<span `+
`style="${numberStyle}min-width:.1em;" `+
`class="tipsy showtip" `+
`title="${HE(HE(o.get('name')))}">`+
(idx+1)+
`</span>`+
`<img src="${o.get('avatar')}">`+
`</div>`;
}).join('');
return disp;
},
moveCardToPosition = function(deck,cardData,idx){
let card = findObjs({
type: 'card',
deckid: deck.id,
name: cardData.name,
avatar: cardData.avatar
})[0];
if(card){
let cardPos=deck.get('currentDeck').split(/\s*,\s*/),
currentIdx=cardPos[idx];
if(currentIdx){
let cardCur=getObj('card',currentIdx);
card.set({
name: cardCur.get('name'),
avatar: cardCur.get('avatar')
});
cardCur.set(cardData);
}
}
}
;
on('ready',function(){
on('chat:message',function(msg){
if(msg.type !== 'api' || !playerIsGM(msg.playerid)){
return;
}
if(msg.content.match(/^!deck/)){
let args = msg.content
.replace(/<br\/>\n/g, ' ')
.replace(/(\{\{(.*?)\}\})/g," $2 ")
.trim()
.split(/\s+--/),
who=(getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname'),
operation = (args[2] || 'list').toLowerCase(),
decks = getDecks(args[1]);
if(1 === args.length){
showHelp(who);
return;
}
if(1 !== decks.length){
showDeckOptions(who,msg.content,decks,args[1]);
return;
}
switch(operation){
case 'list':
// show
_.each(decks, (d)=>{
sendChat('',`/w "${who}" `+
`<div><h3>Current ordering of cards</h3>`+
`<div>${getDeckCardList(d)}</div>`+
`</div>`
);
});
break;
case 'stack': {
let deck = _.first(decks),
cardNames = _.rest(args, 3),
stack=getCards(deck, cardNames),
unmatched=[];
_.each(stack,(c,i)=>{
if(c===false){
unmatched.push(cardNames[i]);
}
});
if(unmatched.length){
showCardOptions(who,deck, unmatched);
return;
}
let stackData=_.map(stack,(o)=>({name: o.get('name'),avatar: o.get('avatar')}));
_.each(stackData,(o,idx)=>{
moveCardToPosition(deck,o,idx);
});
sendChat('',`/w "${who}" `+
`<div><h3>New ordering of cards</h3>`+
`<div>${getDeckCardList(deck)}</div>`+
`</div>`
);
}
break;
}
}
});
});
})();