@flesh-and-blood/search 5.2.8 → 5.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/metaFilters.js +23 -38
- package/dist/queryParse.js +8 -23
- package/dist/search.d.ts +14 -4
- package/dist/search.js +70 -31
- package/dist/searchIndex.d.ts +7 -0
- package/dist/searchIndex.js +57 -1
- package/dist/shorthands.d.ts +2 -2
- package/package.json +14 -16
- package/dist/abbreviations.d.ts +0 -9
- package/dist/abbreviations.js +0 -385
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ const searcher = new Searcher(cards);
|
|
|
20
20
|
const { searchResults } = searcher.search("rhinar go again");
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
- `new Searcher(cards, additionalHeroes?, additionalSets
|
|
23
|
+
- `new Searcher(cards, additionalHeroes?, additionalSets?)`
|
|
24
24
|
- `.search(text)` → `SearchResults`: `{ searchResults: SearchCard[], appliedFilters, keywords, attributes }`
|
|
25
25
|
|
|
26
26
|
Data-only modules are available as subpath imports (handy for lazy-loaded UI like a search-bar dropdown):
|
|
@@ -40,8 +40,8 @@ import { shorthands } from "@flesh-and-blood/search/shorthands";
|
|
|
40
40
|
## Working with this project
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
npm run build # build:esm (per-file ESM) + build:cjs (bundled) + tsc declarations
|
|
44
|
-
npm test #
|
|
43
|
+
npm run build # build:esm (per-file ESM) + build:cjs (bundled) + tsc declarations
|
|
44
|
+
npm test # vitest
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
Uses `@flesh-and-blood/cards` (`file:../cards`) as a dev dependency for tests.
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var Ht=Object.create;var ie=Object.defineProperty;var Qt=Object.getOwnPropertyDescriptor;var jt=Object.getOwnPropertyNames;var Kt=Object.getPrototypeOf,Ut=Object.prototype.hasOwnProperty;var Gt=(e,t)=>{for(var r in t)ie(e,r,{get:t[r],enumerable:!0})},$e=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of jt(t))!Ut.call(e,i)&&i!==r&&ie(e,i,{get:()=>t[i],enumerable:!(a=Qt(t,i))||a.enumerable});return e};var Wt=(e,t,r)=>(r=e!=null?Ht(Kt(e)):{},$e(t||!e||!e.__esModule?ie(r,"default",{value:e,enumerable:!0}):r,e)),_t=e=>$e(ie({},"__esModule",{value:!0}),e);var Ea={};Gt(Ea,{FilterCategory:()=>l,FilterKind:()=>b,FilterProperty:()=>j,MARKUP:()=>Ce,NO_CARD_PROPERTY:()=>D,PUNCTUATION:()=>P,RARITY_VALUES_MAPPING:()=>Le,abbreviations:()=>Re,aliasesByFilterCategory:()=>z,availableExclusions:()=>H,availableModifiers:()=>Ae,default:()=>Nt,filterCard:()=>Lt,filtersToCardPropertyMappings:()=>$,getAbbreviation:()=>ce,getAbbreviationByCard:()=>ir,getCardsByName:()=>ue,getCardsReferencedBy:()=>fe,getCardsReferencing:()=>ge,getCatalogueIndex:()=>we,getCleanText:()=>G,getEscapedForRegExp:()=>_,getExcludedMetaFilters:()=>ke,getFilterCategory:()=>J,getFilterMapping:()=>de,getFilterTokenSpansForKey:()=>na,getFilterValue:()=>He,getIncompleteFilterToken:()=>De,getIsExcludedToken:()=>oa,getIsValueInFilterVocabulary:()=>Pe,getKeywordsAndAppliedFiltersFromText:()=>wa,getMetaFilterResolution:()=>Z,getMetaFilters:()=>pr,getNormalizedFilterValue:()=>w,getNormalizedText:()=>q,getParsedQuery:()=>te,getQueryFilterToken:()=>he,getQueryTokenSpans:()=>ye,getQuotedValue:()=>da,getResolvedFilterKey:()=>Oe,getSuggestedFilterKey:()=>Se,getTextWithoutMarkup:()=>W,getTokensReferencedByCards:()=>Va,getUnquotedValue:()=>me,getValuePartsFromFilterValue:()=>Vt,getValuesFromFilterValue:()=>Qe,multiWordShorthands:()=>Ke,shorthands:()=>je,singleWordShorthands:()=>Ue});module.exports=_t(Ea);var be=require("@flesh-and-blood/types"),_e=Wt(require("fuse.js"),1);var P=/[!"#$%&'’(),./:;<=>?@[\]^_`|~]/g,Ce=/\*/g;var C=require("@flesh-and-blood/types");var G=e=>q(e.toLowerCase().trim().replace(P,"")),q=e=>e.normalize("NFD").replace(/\p{Diacritic}/gu,""),w=e=>e.toLowerCase().replace(P,""),W=e=>e.replace(Ce,""),_=e=>e.replace(/[.*+?^${}()|[\]\\-]/g,"\\$&");var l={Arcane:"arcane",Artist:"artist",Banned:"banned",Bond:"bond",Chain:"chain",Class:"class",Cost:"cost",Defense:"defense",Flow:"flow",Foiling:"foiling",Fusion:"fusion",Intellect:"intellect",Is:"is",Keyword:"keyword",Legal:"legal",Life:"life",Name:"name",Pitch:"pitch",Power:"power",Print:"print",Rarity:"rarity",ReferencedBy:"referencedby",References:"references",Set:"set",Shorthand:"shorthand",Specialization:"specialization",Subtype:"subtype",Talent:"talent",Text:"text",Trait:"trait",Treatment:"treatment",Type:"type",TypeText:"typetext",Year:"year"},b={Comparator:"comparator",ExactMatch:"exactMatch",PartialMatch:"partialMatch"},Ae=[">=",">","<=","<"],H=["!","-"],D="n/a",pt=[...Object.values(C.Format),...Object.values(C.Hero)],$t={category:l.Arcane,canonicalAlias:"arcane",kind:b.Comparator,property:"arcane",specialProperty:"specialArcane",isNumber:!0,partialMatch:!0},Fe={category:l.Artist,canonicalAlias:"art",kind:b.PartialMatch,property:"artists",isArray:!0,partialMatch:!0},ze={category:l.Banned,canonicalAlias:"banned",kind:b.ExactMatch,vocabulary:pt,property:D,isMeta:!0},Ye={category:l.Bond,canonicalAlias:"bond",kind:b.ExactMatch,vocabulary:Object.values(C.Bond),property:"bonds",isArray:!0},zt={category:l.Chain,canonicalAlias:"chain",kind:b.PartialMatch,property:D},qe={category:l.Class,canonicalAlias:"c",kind:b.PartialMatch,vocabulary:Object.values(C.Class),property:"classes",isArray:!0,partialMatch:!0},Xe={category:l.Cost,canonicalAlias:"co",kind:b.Comparator,property:"cost",specialProperty:"specialCost",isNumber:!0,partialMatch:!0},X={category:l.Defense,canonicalAlias:"d",kind:b.Comparator,property:"defense",specialProperty:"specialDefense",isNumber:!0},Je={category:l.Flow,canonicalAlias:"flow",kind:b.ExactMatch,vocabulary:Object.values(C.Flow),property:"flows",isArray:!0},Ze={category:l.Foiling,canonicalAlias:"foil",kind:b.ExactMatch,vocabulary:Object.values(C.Foiling),nestedProperty:"foiling",property:"printings",isArray:!0},et={category:l.Fusion,canonicalAlias:"f",kind:b.ExactMatch,vocabulary:Object.values(C.Fusion),property:"fusions",isArray:!0},tt={category:l.Intellect,canonicalAlias:"i",kind:b.Comparator,property:"intellect",isNumber:!0},rt={category:l.Keyword,canonicalAlias:"k",kind:b.ExactMatch,vocabulary:Object.values(C.Keyword),property:"keywords",isArray:!0},ve={category:l.Legal,canonicalAlias:"l",kind:b.ExactMatch,vocabulary:pt,property:D,isMeta:!0},at={category:l.Life,canonicalAlias:"li",kind:b.Comparator,property:"life",specialProperty:"specialLife",isNumber:!0},it={category:l.Is,canonicalAlias:"is",kind:b.ExactMatch,vocabulary:Object.values(C.Meta),property:"meta",isArray:!0},st={category:l.Name,canonicalAlias:"name",kind:b.PartialMatch,property:"name",isString:!0,partialMatch:!0},Te={category:l.Pitch,canonicalAlias:"p",kind:b.Comparator,property:"pitch",isNumber:!0},se={category:l.Power,canonicalAlias:"pwr",kind:b.Comparator,property:"power",specialProperty:"specialPower",isNumber:!0},oe={category:l.Print,canonicalAlias:"print",kind:b.PartialMatch,property:"setIdentifiers",isArray:!0,partialMatch:!0},ot={category:l.Rarity,canonicalAlias:"r",kind:b.ExactMatch,vocabulary:Object.values(C.Rarity),property:D,isMeta:!0},Yt={category:l.ReferencedBy,canonicalAlias:"referencedby",kind:b.PartialMatch,property:D},qt={category:l.References,canonicalAlias:"references",kind:b.PartialMatch,property:D},nt={category:l.Set,canonicalAlias:"s",kind:b.PartialMatch,vocabulary:Object.values(C.Release),property:"sets",isArray:!0,partialMatch:!0},Me={category:l.Shorthand,canonicalAlias:"short",kind:b.PartialMatch,vocabulary:Object.values(C.Shorthand),property:"shorthands",isArray:!0,partialMatch:!0},ne={category:l.Specialization,canonicalAlias:"sp",kind:b.PartialMatch,vocabulary:Object.values(C.Hero),property:"specializations",isArray:!0,partialMatch:!0},lt={category:l.Subtype,canonicalAlias:"st",kind:b.ExactMatch,vocabulary:Object.values(C.Subtype),property:"subtypes",isArray:!0},dt={category:l.Type,canonicalAlias:"t",kind:b.ExactMatch,vocabulary:Object.values(C.Type),property:"types",isArray:!0},xe={category:l.Talent,canonicalAlias:"tal",kind:b.ExactMatch,vocabulary:Object.values(C.Talent),property:"talents",isArray:!0},Xt={category:l.Text,canonicalAlias:"text",kind:b.PartialMatch,property:"functionalText",hasMarkup:!0,isString:!0,partialMatch:!0},Jt={category:l.Trait,canonicalAlias:"trait",kind:b.PartialMatch,vocabulary:Object.values(C.Trait),property:"traits",isArray:!0,partialMatch:!0},ct={category:l.TypeText,canonicalAlias:"x",kind:b.PartialMatch,property:"typeText",isString:!0,partialMatch:!0},le={category:l.Treatment,canonicalAlias:"treatment",kind:b.ExactMatch,vocabulary:Object.values(C.Treatment),nestedProperty:"treatments",property:"printings",isArray:!0,isNestedPropertyArray:!0},Zt={category:l.Year,canonicalAlias:"year",kind:b.PartialMatch,property:"firstReleaseDate",isString:!0,partialMatch:!0},$={arcane:$t,a:Fe,artist:Fe,art:Fe,attack:se,b:X,block:X,banned:ze,bond:Ye,bonds:Ye,c:qe,class:qe,chain:zt,co:Xe,cost:Xe,color:Te,d:X,def:X,defense:X,flow:Je,flows:Je,f:et,fusion:et,foil:Ze,foiling:Ze,i:tt,intellect:tt,is:it,k:rt,keyword:rt,l:ve,legal:ve,hero:ve,li:at,life:at,meta:it,n:st,name:st,p:Te,pitch:Te,pwr:se,pow:se,power:se,print:oe,printing:oe,printings:oe,prints:oe,r:ot,rarity:ot,referencedby:Yt,references:qt,rf:ze,s:nt,set:nt,short:Me,shorthand:Me,shorthands:Me,sp:ne,spec:ne,specialization:ne,specializations:ne,st:lt,subtype:lt,t:dt,type:dt,tal:xe,talent:xe,talents:xe,text:Xt,trait:Jt,treat:le,treatment:le,var:le,variation:le,x:ct,typetext:ct,year:Zt},er=new Map(Object.entries($)),de=e=>er.get(e.toLowerCase()),J=e=>de(e)?.category,tr=()=>{let e=Object.create(null);for(let[t,{category:r}]of Object.entries($)){let a=e[r];a?a.push(t):e[r]=[t]}return e},z=tr(),rr=()=>{let e=new Map,t=new Set,r=Object.values($);for(let a of r){let{vocabulary:i}=a;if(i&&!t.has(a)){t.add(a);for(let s of i){let o=w(s),n=e.get(o);n?n.push(a):e.set(o,[a])}}}return e},ut=rr(),Pe=(e,t)=>!!ut.get(w(t))?.some(r=>r.category===e),ar=(e,t)=>{let r=[],a=!0;for(let i of t){let s=(ut.get(w(i))||[]).filter(o=>o.category!==e);r=a?s:r.filter(o=>s.includes(o)),a=!1}return r},Se=(e,t)=>{let r=ar(e,t),[a]=r;return r.length===1?a.canonicalAlias:void 0};var ee=require("@flesh-and-blood/types");var ce=e=>Re.find(({abbreviations:t})=>t.find(r=>r.toLowerCase()===e)),ir=e=>Re.find(({card:t})=>t.toLowerCase()===e.name.toLowerCase()),Re=[{abbreviations:["10k"],card:"10,000 Year Reunion"},{abbreviations:["Pajamas","PJs"],card:"Alluvion Constellas"},{abbreviations:["Slippy","Arakni Slipped Through the Cracks","Arakni, Slipped Through the Cracks"],card:"Arakni, 5L!p3d 7hRu 7h3 cR4X"},{abbreviations:["Dullcap"],card:"Arcanite Skullcap"},{abbreviations:["ALS"],card:"Arc Light Sentinel"},{abbreviations:["AoW"],card:"Art of War"},{abbreviations:["BBD"],card:"Barraging Beatdown"},{abbreviations:["BBS"],card:"Big Blue Sky"},{abbreviations:["Starvo"],card:"Bravo, Star of the Show"},{abbreviations:["BEB"],card:"Bull's Eye Bracers"},{abbreviations:["BLW"],card:"Be Like Water"},{abbreviations:["BoJ"],card:"Balance of Justice"},{abbreviations:["BOHH"],card:"Blood on Her Hands"},{abbreviations:["BRB"],card:"Bloodrush Bellow"},{abbreviations:["Breezies"],card:"Breeze Rider Boots"},{abbreviations:["BTA"],card:"Burn Them All"},{abbreviations:["CStrike","C-Strike","C Strike"],card:"Celestial Cataclysm"},{abbreviations:["CBelly"],card:"Cerebellum Processor"},{abbreviations:["CLF"],card:"Channel Lake Frigid"},{abbreviations:["CLV"],card:"Channel Lightning Valley"},{abbreviations:["CMH"],card:"Channel Mount Heroic"},{abbreviations:["CMI"],card:"Channel Mount Isen"},{abbreviations:["CMT"],card:"Channel the Millennium Tree"},{abbreviations:["CnC","C&C"],card:"Command and Conquer"},{abbreviations:["Sea and Sea"],card:"Conqueror of the High Seas"},{abbreviations:["CYB"],card:"Count Your Blessings"},{abbreviations:["Cat","Kitty"],card:"Crouching Tiger"},{abbreviations:["CoD"],card:"Crown of Dominion"},{abbreviations:["CoP"],card:"Crown of Providence"},{abbreviations:["CtW"],card:"Crush the Weak"},{abbreviations:["DD"],card:"Death Dealer"},{abbreviations:["DnD"],card:"Devotion Never Dies"},{abbreviations:["DIO"],card:"Dash I/O"},{abbreviations:["EBTT"],card:"Even Bigger Than That!"},{abbreviations:["NewNigma"],card:"Enigma, New Moon"},{abbreviations:["EPot","E Pot"],card:"Energy Potion"},{abbreviations:["EStrike","E-Strike","E Strike"],card:"Enlightened Strike"},{abbreviations:["FFS"],card:"Fyendal's Fighting Spirit"},{abbreviations:["FoN"],card:"Force of Nature"},{abbreviations:["Frosty","\u{1F976}","\u{1F9CA}","\u2744\uFE0F"],card:"Frostbite"},{abbreviations:["Yum yum"],card:"Fruits of the Forest"},{abbreviations:["GnT"],card:"Give and Take"},{abbreviations:["Habibi"],card:"Hanabi Blaster"},{abbreviations:["HMH"],card:"Hope Merchant's Hood"},{abbreviations:["HoI"],card:"Heart of Ice"},{abbreviations:["Pumpkin"],card:"Jack-o'-lantern"},{abbreviations:["RKO","Cheato"],card:"Kayo, Underhanded Cheat"},{abbreviations:["KKBB"],card:"Knick Knack Bric-a-brac"},{abbreviations:["BStrike"],card:"Levels of Enlightenment"},{abbreviations:["LAG","Twominaris"],card:"Luminaris, Angel's Glow"},{abbreviations:["LCF","Newminaris"],card:"Luminaris, Celestial Fury"},{abbreviations:["LDE"],card:"Last Ditch Effort"},{abbreviations:["LtC"],card:"Lead the Charge"},{abbreviations:["LNW"],card:"Leave No Witnesses"},{abbreviations:["LFaL","L4aL"],card:"Life for a Life"},{abbreviations:["LiT"],card:"Lost in Thought"},{abbreviations:["MMB"],card:"Mage Master Boots"},{abbreviations:["MaxV"],card:"Maximum Velocity"},{abbreviations:["MoM"],card:"Mask of Momentum"},{abbreviations:["MoPL"],card:"Mask of the Pouncing Lynx"},{abbreviations:["MnG"],card:"Meat and Greet"},{abbreviations:["Cake","\u{1F382}"],card:"Ninth Blade of the Blood Oath"},{abbreviations:["PoM"],card:"Peace of Mind"},{abbreviations:["P-Bone"],card:"Performance Bonus"},{abbreviations:["PF","\u{1F525}"],card:"Phoenix Flame"},{abbreviations:["PtW"],card:"Poison the Well"},{abbreviations:["Thanos","Infinity Gauntlet"],card:"Polarity Reversal Script"},{abbreviations:["DPot","D Pot"],card:"Potion of D\xE9j\xE0 Vu"},{abbreviations:["Ponder Run"],card:"Premeditate"},{abbreviations:["Qi Unbound"],card:"Qi Unleashed"},{abbreviations:["RitL"],card:"Red in the Ledger"},{abbreviations:["Cats","Ghost cat","Ghost cats"],card:"Restless Coalescence"},{abbreviations:["Eugene"],card:"Rhinar, Reckless Rampage",isHidden:!0},{abbreviations:["SSGB"],card:"Sandscour Greatbow"},{abbreviations:["SSP"],card:"Sand Sketched Plan"},{abbreviations:["SFaS","S4aS"],card:"Scar for a Scar"},{abbreviations:["Tyler"],card:"Scurv, Stowaway",isHidden:!0},{abbreviations:["SWOMB"],card:"Shifting Winds of the Mystic Beast"},{abbreviations:["Snaps"],card:"Snapdragon Scalers"},{abbreviations:["SWK"],card:"Spinning Wheel Kick"},{abbreviations:["SFTL"],card:"Swing Fist, Think Later"},{abbreviations:["TTT"],card:"Take the Tempo"},{abbreviations:["Ultron"],card:"Teklovossen, the Mechropotent"},{abbreviations:["ToS"],card:"Test of Strength"},{abbreviations:["TAYG"],card:"That All You Got?"},{abbreviations:["TROM"],card:"This Round's on Me"},{abbreviations:["3oak"],card:"Three of a Kind"},{abbreviations:["Pox Malone","Post Malone"],card:"Virulent Touch"},{abbreviations:["Cast Homes"],card:"Visit Goldmane Estate"},{abbreviations:["Frosty Hammer"],card:"Winter's Wail"},{abbreviations:["Wreckless Wing"],card:"War Cry of Bellona"},{abbreviations:["ZTS"],card:"Zero to Sixty"}];var c=require("@flesh-and-blood/types");var S=require("@flesh-and-blood/types");var j={BannedFormats:"bannedFormats",LegalFormats:"legalFormats",LegalHeroes:"legalHeroes"},pe=Array.from(Array(50).keys()).map(e=>`${e}`),sr=[{format:S.Format.ClassicConstructed,nicknames:["cc","classic"]},{format:S.Format.LivingLegend,nicknames:["cc ll","classic constructed ll","ll cc","ll","living legend"]},{format:S.Format.SilverAge,nicknames:["sage"]},{format:S.Format.GoldenAge,nicknames:["gage"]},{format:S.Format.UltimatePitFight,nicknames:["upf"]}],or=Object.values(S.Format).map(e=>{let t=sr.find(({format:a})=>a===e),r=e.toLowerCase().replaceAll(P,"");return t?{...t,format:r}:{format:r}}),nr=[{hero:S.Hero.DataDoll,nicknames:["data","datadoll"]},{hero:S.Hero.Dorinthea,nicknames:["dori"]},{hero:S.Hero.Genis,nicknames:["genis"]},{hero:S.Hero.GravyBones,nicknames:["gravy"]},{hero:S.Hero.Iyslander,nicknames:["islander"]}],lr=Object.values(S.Hero).map(e=>{let t=nr.find(({hero:a})=>a===e),r=e.toLowerCase().replaceAll(P,"");return t?{...t,hero:r}:{hero:r}}),gt=["common","rare","super rare","majestic","legendary","fabled"],dr=({modifier:e,value:t})=>{let r=[],a=e==="<"||e==="<=",i=e===">="||e==="<=",s=a?[...gt].reverse():gt,o=!1;for(let n of s)o?r.push(n):n===t&&(o=!0,i&&r.push(n));return r},cr=(e,t)=>{let r=[];for(let a of e)a.modifier?r.push(...dr(a)):r.push(a.value);return{filterToPropertyMapping:{nestedProperty:"rarity",property:"printings",isArray:!0},isExcluded:t,isOr:!0,values:r}},ft=(e,t,r,a)=>{let i=r.map(d=>({hero:d.toLowerCase().replaceAll(P,"")})),s=[],o=[],n=[],p=[];for(let{value:d}of e){let u=or.find(({format:y,nicknames:h})=>y===d||!!h&&h.includes(d));if(u)o.push(u.format);else{let y=lr.find(({hero:h,nicknames:v})=>h===d||!!v&&v.includes(d))||i.find(({hero:h})=>h===d);y?n.push(y.hero):p.push(d)}}return o.length>0&&s.push({filterToPropertyMapping:{property:a,isArray:!0},values:o,isOr:!0,isExcluded:t}),n.length>0&&s.push({filterToPropertyMapping:{property:j.LegalHeroes,isArray:!0},values:n,isOr:!0,isExcluded:t}),{appliedFilters:s,unresolvedValues:p}},Z=(e,t,{additionalHeroes:r=[],isExcluded:a=!1}={})=>{let i=J(e),s={appliedFilters:[],unresolvedValues:[]};return i===l.Legal?s=ft(t,a,r,j.LegalFormats):i===l.Banned?s=ft(t,a,r,j.BannedFormats):i===l.Rarity&&(s={appliedFilters:[cr(t,a)],unresolvedValues:[]}),s},pr=(e,t,r,a,i,s)=>Z(r,a.map(o=>({modifier:i,value:o})),{additionalHeroes:s,isExcluded:e}).appliedFilters,ur=[{filterToPropertyMapping:{property:"cost",isNumber:!0},isExcluded:!0,values:pe},{filterToPropertyMapping:{property:"specialCost",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token","weapon"]}],gr=[{filterToPropertyMapping:{property:"defense",isNumber:!0},isExcluded:!0,values:pe},{filterToPropertyMapping:{property:"specialDefense",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["hero","placeholder","token","weapon"]}],fr=[{filterToPropertyMapping:{property:"pitch",isNumber:!0},isExcluded:!0,values:pe},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token","weapon"]},{filterToPropertyMapping:{property:"isCardBack",isBoolean:!0},isExcluded:!0,values:["true"]}],yr=[{filterToPropertyMapping:{property:"power",isNumber:!0},isExcluded:!0,values:pe},{filterToPropertyMapping:{property:"specialPower",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token"]}],hr=[{filterToPropertyMapping:{property:"talents",isArray:!0},isExcluded:!0,values:Object.values(S.Talent).map(e=>e.toLowerCase())}],mr=[{filterToPropertyMapping:{property:"classes",isArray:!0},isExcluded:!0,values:Object.values(S.Class).map(e=>e.toLowerCase())}],br=[{category:l.Class,filters:mr},{category:l.Cost,filters:ur},{category:l.Defense,filters:gr},{category:l.Pitch,filters:fr},{category:l.Power,filters:yr},{category:l.Talent,filters:hr}],Cr=()=>{let e=new Map;for(let{category:t,filters:r}of br)for(let a of z[t])for(let i of H)e.set(`${i}${a}`,r);return e},Fr=Cr(),ke=e=>{let t=[],r=Fr.get(e);return r&&t.push(...r),t};var K=require("@flesh-and-blood/types");var yt=new WeakMap,Q=Object.freeze([]),vr=Number.MAX_SAFE_INTEGER,ht=(e,t)=>{let r=new Map;for(let a of e)for(let i of t(a)||[]){let s=r.get(i);s?s.push(a):r.set(i,[a])}return r},Tr=e=>{let t=new Map;for(let r of e){let a=r.types.includes(K.Type.Hero)&&!r.isCardBack,i=a?K.CardRole.Hero:(0,K.getCardRole)(r);if(a||i!==K.CardRole.Hero){let o=t.get(i);o?o.push(r):t.set(i,[r])}}return t},Mr=e=>{let t,r,a,i,s,o=()=>{if(!t){let g=new Map,f=new Map,m=[],T=new Map,M=0;for(let R of e){g.set(R.cardIdentifier,R),f.set(R.cardIdentifier,M),M++;let k=G(R.name),U=T.get(k);U?U.push(R):(T.set(k,[R]),m.push(k))}t={cardByCardIdentifier:g,corpusPositionByCardIdentifier:f,cleanedNames:m,pitchCycleByCleanedName:T}}return t},n=g=>{let{corpusPositionByCardIdentifier:f}=o(),m=({cardIdentifier:T})=>f.get(T)??vr;return[...g].sort((T,M)=>m(T)-m(M))},p=g=>o().cardByCardIdentifier.get(g),d=g=>{let{cardByCardIdentifier:f}=o(),m=[];for(let T of g||[]){let M=f.get(T);M&&m.push(M)}return n(m)},u=g=>{let f=new Map;return m=>{let T=f.get(m);if(!T){let M=p(m),R=d(M&&g(M)),k=R.length>0;T=k?R:Q,k&&f.set(m,T)}return T}},y=g=>{let{pitchCycleByCleanedName:f}=o(),m=p(g);return m?f.get(G(m.name))??Q:Q},h=g=>{let{cleanedNames:f,pitchCycleByCleanedName:m}=o(),T=G(g),M=m.get(T);if(!M&&T.length>0){let k=f.find(U=>U.includes(T));k&&(M=m.get(k))}return M??Q},v=g=>{let{pitchCycleByCleanedName:f}=o();return f.get(G(g))??Q},I=()=>{if(!s){let g=new Set;for(let f of e)for(let m of f.artists)g.add(m);s=[...g].sort((f,m)=>f.localeCompare(m,"en",{sensitivity:"base"}))}return s},V=u(({oppositeSideCardIdentifiers:g})=>g),A=u(({referencedCards:g})=>g),E=g=>(r||(r=ht(e,({referencedCards:f})=>f)),r.get(g)??Q),L=u(({createdExtras:g})=>g);return{cards:e,getCard:p,getPitchCycle:y,getCardsByName:h,getCardsByExactName:v,getArtists:I,getOppositeSide:V,getReferences:A,getReferencedBy:E,getCreates:L,getCreatedBy:g=>(a||(a=ht(e,({createdExtras:f})=>f)),a.get(g)??Q),getCreatedClosure:g=>{let f=new Map,m=new Set,T=[...g];for(let M of T)if(!m.has(M)){m.add(M);for(let k of L(M))f.set(k.cardIdentifier,k),T.push(k.cardIdentifier)}return n([...f.values()])},getByRole:g=>(i||(i=Tr(e)),i.get(g)??Q),getCardsInCorpusOrder:n}},we=e=>{let t=yt.get(e);return t||(t=Mr(e),yt.set(e,t)),t},Ve=(e,t)=>e.getPitchCycle(t.cardIdentifier),ue=(e,t)=>e.getCardsByName(t),mt=(e,t)=>{let r=new Map;for(let a of t)for(let i of Ve(e,a))r.set(i.cardIdentifier,i);return e.getCardsInCorpusOrder([...r.values()])},ge=(e,t)=>{let r=[];for(let a of Ve(e,t))r.push(...e.getReferencedBy(a.cardIdentifier));return mt(e,r)},fe=(e,t)=>{let r=[];for(let a of Ve(e,t))r.push(...e.getReferences(a.cardIdentifier));return mt(e,r)};var xr=e=>{let[t]=e,r=t?.modifier;return e.every(({modifier:i})=>i===r)?r:void 0},Ie=({filterValues:e,isAnd:t,isExcluded:r,mapping:a})=>{let i=[];for(let{value:s}of e)i.push(a.hasMarkup?W(s):s);return{filterToPropertyMapping:a,filterValues:e,isAnd:t,isExcluded:r,isOr:!t&&i.length>1,modifier:xr(e),values:i}},vt=({isAnd:e,isExcluded:t,mapping:r},a)=>({filterToPropertyMapping:r,isAnd:e,isExcluded:t,isOr:!e&&a.length>1,values:a}),Ar=({category:e,filterValues:t,mapping:r})=>{let a=[];if(r.kind===b.ExactMatch&&!!r.vocabulary)for(let{value:s}of t)Pe(e,s)||a.push(s);return a},Pr=e=>({appliedFilters:[Ie(e)],unresolvedValues:Ar(e)}),Be=({isExcluded:e},t,r)=>e?void 0:{[t]:r},Tt=(e,t)=>({appliedFilters:[Ie(e)],attributes:Be(e,t,e.filterValues.map(({value:r})=>r)),unresolvedValues:[]}),Sr=e=>Tt(e,"artists"),Rr=e=>Tt(e,"prints"),Ne=(e,t,r)=>{let a=[],i=[],s=[];for(let{value:o}of e.filterValues){let n=r(o);if(n.length>0)for(let p of n)a.push(p),i.push(w(p));else s.push(o)}return{appliedFilters:[vt(e,i)],attributes:Be(e,t,a),canonicalValues:i,unresolvedValues:s}},kr=new Map(Object.entries({purple:4,blue:3,yellow:2,red:1,white:0})),wr=e=>{let t=[],r=[];for(let{modifier:a,value:i}of e.filterValues){let s=kr.get(i),o=s===void 0?i:`${s}`;t.push({modifier:a,value:o}),r.push(o)}return{appliedFilters:[Ie({...e,filterValues:t})],canonicalValues:r,unresolvedValues:[]}},Ee=new Map;for(let e of Object.values(c.Release)){let t=w(e),r=Ee.get(t);if(r===void 0)Ee.set(t,e);else throw new Error(`${r} and ${e} are one name as a filter reads it, so a set filter naming it could reach either`)}var bt=(e,t)=>{let r=e.get(t);return r?[r]:[]},Vr=(e,t)=>{let r=[()=>bt(Ee,e),()=>bt(c.setIdentifierToSetMappings,e),()=>Object.values(c.Release).filter(i=>i.toLowerCase().includes(e)),()=>{let i=t.find(s=>w(s)===e);return i?[i]:[]}],a=[];for(let i of r)a.length===0&&a.push(...i());return a},Er=(e,{additionalSets:t})=>Ne(e,"releases",r=>Vr(r,t)),Ir=new Map(Object.entries({r:c.Foiling.Rainbow,rf:c.Foiling.Rainbow,rainbow:c.Foiling.Rainbow,c:c.Foiling.Cold,cf:c.Foiling.Cold,cold:c.Foiling.Cold,g:c.Foiling.Gold,gf:c.Foiling.Gold,gold:c.Foiling.Gold})),Br=e=>{let t=Ir.get(e);return t?[t]:[]},Nr=e=>Ne(e,"foilings",Br),Mt=new Map(Object.entries({aa:c.Treatment.AA,alt:c.Treatment.AA,"alt art":c.Treatment.AA,ab:c.Treatment.AB,"alt border":c.Treatment.AB,at:c.Treatment.AT,"alt text":c.Treatment.AT,ea:c.Treatment.EA,extended:c.Treatment.EA,"extended art":c.Treatment.EA,fa:c.Treatment.FA,full:c.Treatment.FA,"full art":c.Treatment.FA}));for(let e of Object.values(c.Treatment))Mt.set(e.toLowerCase(),e);var Lr=new Map(Object.entries(c.Treatment)),Or=e=>{let t=Mt.get(e)||Lr.get(e.toUpperCase());return t?[t]:[]},Dr=e=>Ne(e,"treatments",Or),Le=new Map(Object.entries({b:c.Rarity.Basic,c:c.Rarity.Common,f:c.Rarity.Fabled,l:c.Rarity.Legendary,m:c.Rarity.Majestic,p:c.Rarity.Promo,r:c.Rarity.Rare,s:c.Rarity.SuperRare,t:c.Rarity.Token,v:c.Rarity.Marvel})),Hr=e=>Le.get(e)||Object.values(c.Rarity).find(t=>t.toLowerCase()===e),Qr=(e,{additionalHeroes:t})=>{let r=[],a=[],i=[],s=[];for(let{modifier:n,value:p}of e.filterValues){let d=Hr(p);d?(r.push(d),a.push(d.toLowerCase()),i.push({modifier:n,value:d.toLowerCase()})):(s.push(p),i.push({modifier:n,value:p}))}let{appliedFilters:o}=Z(e.key,i,{additionalHeroes:t,isExcluded:e.isExcluded});return{appliedFilters:o,attributes:Be(e,"rarities",r),canonicalValues:a,unresolvedValues:s}},Ct=({filterValues:e,isExcluded:t,key:r},{additionalHeroes:a})=>{let{appliedFilters:i,unresolvedValues:s}=Z(r,e,{additionalHeroes:a,isExcluded:t}),o=[];for(let{values:n}of i)o.push(...n);return{appliedFilters:i,canonicalValues:o,unresolvedValues:s}},jr=["unique"],Kr=["preview","spoiler","unreleased"],Ur=["released"],Ft={property:"firstReleaseDate",isDate:!0},Gr=new Map(Object.entries({dual:c.Meta.DualClass,exp:c.Meta.Expansion,expansion:c.Meta.Expansion,rainbow:c.Meta.Rainbow,reprint:c.Meta.Reprint,reprints:c.Meta.Reprint})),Wr=e=>{let t=[],r=[];for(let i of e){let s=Gr.get(i);s?t.push(s):r.push(i)}let a=[];if(t.length===0){let i=new Set;for(let s of Object.values(c.Meta)){let o=!1;for(let n of r)s.toLowerCase().includes(n)&&(o=!0,i.add(n));o&&t.push(s)}for(let s of r)i.has(s)||a.push(s)}else a.push(...r);return{unresolvedValues:a,values:t}},_r=(e,{today:t})=>{let{filterValues:r,isAnd:a,isExcluded:i}=e,s=[],o=[],n=[],p=[],d=[];for(let{value:A}of r)jr.includes(A)?o.push(A):Kr.includes(A)?n.push(A):Ur.includes(A)?p.push(A):d.push(A);let u=!a&&r.length>1;o.length>0&&s.push({filterToPropertyMapping:$.is,values:[w(c.Meta.Reprint)],isAnd:a,isOr:u,isExcluded:!i}),n.length>0&&s.push({filterToPropertyMapping:Ft,values:[t],isAnd:a,isOr:u,isExcluded:i}),p.length>0&&s.push({filterToPropertyMapping:Ft,values:[t],isAnd:a,isOr:u,isExcluded:!i});let{unresolvedValues:y,values:h}=Wr(d),v=[...o,...n,...p,...h.map(w)];(d.length>0||s.length===0)&&s.push(vt(e,h.map(w)));let V=h.includes(c.Meta.Expansion)&&!i;return{appliedFilters:s,attributes:V?{isExpansionSlot:V}:void 0,canonicalValues:v,unresolvedValues:y}},$r={property:"cardIdentifier",isString:!0,isNormalized:!0},zr=20,Yr=(e,t)=>{let r=new Set,a=[],i=new Set,s=[],o=d=>{r.add(d.cardIdentifier),i.has(d.name)||(i.add(d.name),a.push(d))},n=d=>{d.types.includes(c.Type.Hero)||o(d)};for(let d of t){let u=ue(e,d);for(let y of u)o(y);u.length===0&&s.push(d)}let p=0;for(;p<a.length&&p<=zr;){let d=a[p];for(let y of fe(e,d))n(y);if(p===0)for(let y of ge(e,d))n(y);p++}return{cardIdentifiers:r,unresolvedValues:s}},xt=(e,t,r)=>{let a=new Set;for(let i of ue(e,t)){let s=r?fe(e,i):ge(e,i);for(let o of s)a.add(o.cardIdentifier)}return a},qr=(e,t)=>{let r=new Set,[a=new Set,...i]=e;if(t)for(let s of a)i.every(n=>n.has(s))&&r.add(s);else for(let s of e)for(let o of s)r.add(o);return r},At=(e,t)=>({filterToPropertyMapping:$r,values:[...e],valuesSet:e,isExcluded:t,isOr:!0}),Pt=({filterValues:e,isAnd:t,isExcluded:r},a)=>{let i=[],s=[];for(let{value:o}of e){let n=a(o);i.push(n),n.size===0&&s.push(o)}return{appliedFilters:[At(qr(i,t),r)],unresolvedValues:s}},Xr=(e,{index:t})=>{let{cardIdentifiers:r,unresolvedValues:a}=Yr(t,e.filterValues.map(({value:i})=>i));return{appliedFilters:[At(r,e.isExcluded)],unresolvedValues:a}},Jr=(e,{index:t})=>Pt(e,r=>xt(t,r,!0)),Zr=(e,{index:t})=>Pt(e,r=>xt(t,r,!1)),ea=new Map([[l.Artist,Sr],[l.Banned,Ct],[l.Chain,Xr],[l.Foiling,Nr],[l.Is,_r],[l.Legal,Ct],[l.Pitch,wr],[l.Print,Rr],[l.Rarity,Qr],[l.ReferencedBy,Jr],[l.References,Zr],[l.Set,Er],[l.Treatment,Dr]]),St=(e,t)=>(ea.get(e.category)||Pr)(e,t);var kt=H.map(_).join(""),ta=/(?:[^\s"]+|"[^"]*(?:"|$))+/g,ra=new RegExp(`^([${kt}])?([A-Za-z]+):(.+)$`),aa=new RegExp(`^([${kt}])?([A-Za-z]+):$`),ia=",",Rt="+",sa='"',wt=e=>{let t=[],r=!1,a="",i=!1;for(let s of e)s===sa?(i=!i,a+=s):!i&&(s===ia||s===Rt)?(r=r||s===Rt,a&&t.push(a),a=""):a+=s;return a&&t.push(a),{isAndList:r,parts:t}},ye=e=>{let t=[];for(let r of e.matchAll(ta))t.push({end:r.index+r[0].length,start:r.index,token:r[0]});return t},oa=e=>H.some(t=>e.startsWith(t)),he=e=>{let t=e.match(ra),r;if(t){let[,a,i,s]=t;r={isAndList:wt(s).isAndList,isExcluded:!!a,key:i,valueText:s}}return r},De=e=>{let t=e.match(aa),r;return t&&(r={isAndList:!1,isExcluded:!!t[1],key:t[2],valueText:""}),r},He=e=>{let t=e.trim(),r=Ae.find(a=>t.startsWith(a));return{modifier:r,value:r?t.slice(r.length).trim():t}},Oe=e=>J(e)??e.toLowerCase(),na=(e,t)=>{let r=Oe(t),a=[];for(let{end:i,start:s,token:o}of ye(e)){let n=he(o);n&&Oe(n.key)===r&&a.push({...n,end:i,start:s,token:o})}return a},Vt=e=>wt(e).parts,me=e=>e.replace(/^"|"$/g,""),Qe=e=>{let t=[];for(let r of Vt(e)){let a=me(r);a&&t.push(a)}return t},la=/[\s,:+"]/,da=e=>{let t=e.replaceAll('"',"");return la.test(e)?`"${t}"`:t};var N=require("@flesh-and-blood/types"),je=[{description:"Attack actions",expanded:["st:attack"],filters:{subtypes:[N.Subtype.Attack]},isCardProperty:!1,shorthands:["AA"]},{description:"Arcane barrier",expanded:['k:"arcane barrier"'],filters:{keywords:[N.Keyword.ArcaneBarrier]},isCardProperty:!1,shorthands:["AB"]},{description:"Attack reactions",expanded:['t:"attack reaction"'],filters:{types:[N.Type.AttackReaction]},isCardProperty:!1,shorthands:["AR"]},{description:"Defense reactions",expanded:['t:"defense reaction"'],filters:{types:[N.Type.DefenseReaction]},isCardProperty:!1,shorthands:["DR"]},{description:"Gain life",expanded:["gain {h}"],filters:{functionalText:"gain {h}"},isCardProperty:!1,shorthands:["Gain life","Gains life"]},{description:"Go again",expanded:['k:"go again"'],filters:{keywords:[N.Keyword.GoAgain]},isCardProperty:!1,shorthands:["GA"]},{description:"Non-attack actions",expanded:["t:action","st:non-attack"],filters:{subtypes:[N.Subtype.NonAttack],types:[N.Type.Action]},isCardProperty:!1,shorthands:["NAA"]},{description:"Plus defense",expanded:["+ {d}"],filters:{functionalText:"+ {d}"},isCardProperty:!1,shorthands:["Pump defense","Pumps defense","Buff defense","Buffs defense"]},{description:"Spellvoid",expanded:['k:"spellvoid"'],filters:{keywords:[N.Keyword.Spellvoid]},isCardProperty:!1,shorthands:["SV"]}],Ke=je.filter(({shorthands:e})=>e.some(t=>t.includes(" "))).map(e=>({...e,shorthands:e.shorthands.filter(t=>t.includes(" ")).map(t=>t.toLowerCase()).sort((t,r)=>r.length-t.length)})),Ue=je.filter(({shorthands:e})=>e.some(t=>!t.includes(" "))).map(e=>({...e,shorthands:e.shorthands.filter(t=>!t.includes(" ")).map(t=>t.toLowerCase()).sort((t,r)=>r.length-t.length)}));var ca=["\u201C","\u201D"],pa=[{text:ee.Release.ClassicBattlesRhinarDorinthea.toLowerCase(),override:ee.Release.ClassicBattlesRhinarDorinthea.toLowerCase().replaceAll(P,"")}],Ge=new Map([...ee.setToSetIdentifierMappings].map(([e,t])=>[e.toLowerCase(),t])),ua=[...z[l.Set],...z[l.Print]],ga=H.map(_).join(""),fa=[...Ge.keys()].sort((e,t)=>t.length-e.length).map(_).join("|"),ya=new RegExp(`(?<=^|\\s)([${ga}]?(?:${ua.join("|")}):(?:[^\\s]*[,+])?"?)(${fa})(?="?(?:[,+]|\\s|$))`,"g"),ha=(e,t)=>{let r=e.trim().toLowerCase();for(let s of ca)r=r.replaceAll(s,'"');for(let{expanded:s,shorthands:o}of Ke)for(let n of o)if(r.includes(n)){r=r.replace(n,s.join(" "));break}r=r.replace(ya,(s,o,n)=>{let p=Ge.get(n);return p?`${o}${p[0]}`:s});let a=Ge.get(r),i=t.getCardsByExactName(r).length>0;a&&!i&&(r=`set:${a[0]}`);for(let{override:s,text:o}of pa)r.includes(o)&&(r=r.replace(o,s));return{isWholeQueryAbbreviation:!!ce(r)?.card,text:r}},ma=e=>{let t=Ue.find(({shorthands:a})=>a.includes(e)),r=!!t&&!t.isCardProperty;return{isExpanded:r,tokens:r?t.expanded:[e]}},ba=({isWholeQueryAbbreviation:e,text:t})=>{let r=[],a=e?[{end:t.length,start:0,token:t}]:ye(t);for(let{end:i,start:s,token:o}of a){let{isExpanded:n,tokens:p}=ma(o);for(let d of p)r.push({end:i,isExpanded:n,start:s,token:d})}return r},Ca=e=>{let t=[];for(let r of e){let{modifier:a,value:i}=He(r),s=w(i);s&&t.push({modifier:a,value:s})}return t},Fa=(e,t,r)=>{let a={key:e,reason:"value",values:r},i=Se(t,r);return i&&(a.suggestedKey=i),a},va=()=>{let e=new Date,t=`${e.getMonth()+1}`.padStart(2,"0"),r=`${e.getDate()}`.padStart(2,"0");return`${e.getFullYear()}-${t}-${r}`},te=(e,t,{additionalHeroes:r=[],additionalSets:a=[],today:i=va()}={})=>{let s=ha(e,t),o={additionalHeroes:r,additionalSets:a,index:t,today:i},n=[],p={artists:[],foilings:[],isExpansionSlot:!1,prints:[],rarities:[],releases:[],treatments:[]},d=[],u=[],y=[];for(let h of ba(s)){let v=he(h.token)||De(h.token);if(v){let{isAndList:I,isExcluded:V,key:A,valueText:E}=v,L=de(A),O=L?.category,F=Qe(E),B=Ca(F),g={...h,canonicalValues:B.map(({value:f})=>f),category:O,filterValues:B,isAnd:I,isExcluded:V,isFilter:!0,isResolved:!0,key:A};if(F.length>0)if(L&&O){let f=F;if(B.length>0){let m=St({category:O,filterValues:B,isAnd:g.isAnd,isExcluded:V,key:A,mapping:L},o);n.push(...m.appliedFilters),m.canonicalValues&&(g.canonicalValues=m.canonicalValues),m.attributes&&Object.assign(p,m.attributes),f=m.unresolvedValues}f.length>0&&(g.isResolved=!1,y.push(Fa(A,O,f)))}else g.isResolved=!1,y.push({key:A,reason:"key",values:[]});u.push(g)}else{let{end:I,start:V,token:A}=h;u.push({end:I,isFilter:!1,start:V,token:A});let E=me(h.token),L=ce(E)?.card,O=ke(E);L?d.push(`"${L.toLowerCase().replace(P,"")}"`):O.length>0?n.push(...O):E&&d.push(E.replace(P,""))}}return{appliedFilters:n,attributes:p,keywords:d,nodes:u,text:s.text,unresolvedFilters:y}};var x=require("@flesh-and-blood/types"),Et={artists:["Hoodwill"],cardIdentifier:"fangs-a-lot-blue",classes:[x.Class.Generic],defaultImage:"FNG000",firstReleaseDate:"2022-06-02",functionalText:"If Fangs A Lot is put into your banished zone from your graveyard, instead put it into your hand.",legalFormats:[],legalHeroes:[x.Hero.Kayo,x.Hero.Levia,x.Hero.Rhinar],printings:[{artists:["Hoodwill"],identifier:"FNG000",image:"FNG000",print:"FNG000",rarity:x.Rarity.Rare,set:x.Release.Promos},{artists:["Hoodwill"],identifier:"FNG000",image:"FNG000_Marvel",print:`FNG000-${x.Treatment.FA}`,rarity:x.Rarity.Marvel,set:x.Release.Promos,treatments:[x.Treatment.FA]}],name:"Fangs A Lot",rarities:[x.Rarity.Rare,x.Rarity.Marvel],rarity:x.Rarity.Rare,sets:[x.Release.Promos],setIdentifiers:["FNG000"],specialImage:"FNG000_Marvel",subtypes:[x.Subtype.Attack],types:[x.Type.Action],typeText:"Generic Action - Attack"},It=[{keyword:Et.name.toLowerCase(),card:Et}];var Ta={getFn:(e,t)=>{let r=_e.default.config.getFn(e,t),a=r;if(Array.isArray(r))a=r.map(i=>q(i.replace(P,"")));else if(r){let i=q(r).replace(P,"");a=t.includes("functionalText")?W(i):i}return a},ignoreLocation:!0,includeScore:!0,keys:[{name:"name",weight:10},{name:"functionalText",weight:6},{name:"shorthands",weight:4},{name:"setIdentifiers",weight:2},{name:"traits",weight:4},{name:"typeText",weight:6}],threshold:.15,useExtendedSearch:!0},We=class{constructor(t,r=[],a=[],i=!1){this.getFuse=()=>(this.fuse||(this.fuse=new _e.default(this.cards,Ta)),this.fuse);this.log=(t,...r)=>{this.debug&&console.log(t,...r)};this.search=(t,r)=>{let a,{appliedFilters:i,attributes:s,keywords:o,unresolvedFilters:n}=te(t,this.index,{additionalHeroes:this.additionalHeroes,additionalSets:this.additionalSets}),p=o.join(" "),d=r?It.filter(F=>F.keyword===p):[];if(d.length>0?a=d.map(({card:F})=>F):o.length?a=this.getFuse().search(p).map(F=>F.item):a=[...this.cards],i.length&&(a=a.filter(F=>F&&Lt(F,i))),o.length===0){let F="";if(s.releases.length===1){let f=be.setToSetIdentifierMappings.get(s.releases[0]);f?.length&&(F=f[0].toUpperCase())}if(!F&&s.prints.length===1){let f=s.prints[0];be.setIdentifierToSetMappings.has(f)&&(F=f.toUpperCase())}F?a.sort((f,m)=>{let T=f.setIdentifiers.find(R=>R.includes(F))?.replace(F,""),M=m.setIdentifiers.find(R=>R.includes(F))?.replace(F,"");return T&&M?T.localeCompare(M):-1}):a.sort((f,m)=>f.name===m.name?`${f.pitch}`.localeCompare(`${m.pitch}`):f.name.localeCompare(m.name))}else{let F=[],B=[],g=o.map(f=>f.toLowerCase().replace(P,"")).join(" ");for(let f of a)f.name.toLowerCase().replace(P,"")===g?F.push(f):B.push(f);a=[...F,...B]}let u=[],{artists:y,isExpansionSlot:h,foilings:v,prints:I,rarities:V,releases:A,treatments:E}=s;(y.length>0||h||v.length>0||I.length>0||V.length>0||A.length>0||E.length>0)&&(u=a.map(F=>{let B=F.printings.filter(g=>{let f=!!g.image,m=y.length===0||y.some(Y=>g.artists.find(Dt=>Dt.replace(P,"").toLowerCase().includes(Y))),T=!h||h===g.isExpansionSlot,M=v.length===0||!!g.foiling&&v.includes(g.foiling),R=I.length===0||I.some(Y=>g.identifier.includes(Y.toUpperCase())),k=V.length===0||V.includes(g.rarity),U=A.length===0||A.includes(g.set),Ot=E.length===0||g.treatments?.some(Y=>E.includes(Y));return f&&m&&T&&M&&R&&k&&U&&Ot});return{...F,matchingPrintings:B}}));let O=u.length>0?u:a;return{appliedFilters:i,attributes:s,keywords:o,searchResults:O,unresolvedFilters:n}};let s=Array.isArray(r)?{additionalHeroes:r,additionalSets:a,debug:i}:r;this.additionalHeroes=s.additionalHeroes||[],this.additionalSets=s.additionalSets||[],this.cards=[...t],this.debug=s.debug||!1,this.index=s.index||we(t)}},Nt=We,Lt=(e,t)=>{let r=!0;for(let a of t){let{isNumber:i,isString:s,isArray:o,isBoolean:n,isDate:p}=a.filterToPropertyMapping;a.isOptional||(i?r=r&&Ma(e,a):s?r=r&&xa(e,a):o?r=r&&Aa(e,a,t):n?r=r&&Pa(e,a):p&&(r=r&&Sa(e,a)))}return r},Bt=(e,t,r)=>{let a=parseInt(t),i;switch(r){case">=":i=e>=a;break;case">":i=e>a;break;case"<=":i=e<=a;break;case"<":i=e<a;break;default:i=e===a}return i},Ma=(e,t)=>{let{filterValues:r,values:a,modifier:i,isExcluded:s,filterToPropertyMapping:{partialMatch:o}}=t,n=!0;if(ae(t,e)){let p=re(e,t),d;if(p!=null&&!isNaN(p)){let u=parseInt(p);d=r?r.some(({modifier:y,value:h})=>Bt(u,h,y)):a.some(y=>Bt(u,y,i))}else{let u=ka(e,t)?.toLowerCase();d=o?a.some(y=>!!u?.includes(y)):a.some(y=>u===y)}n=s?!d:d}return n},xa=(e,t)=>{if(ae(t,e)){let{values:r,valuesSet:a,isAnd:i,isExcluded:s,filterToPropertyMapping:{hasMarkup:o,isNormalized:n,partialMatch:p}}=t,d=re(e,t),u=n?d:d?.replaceAll(P,"").toLowerCase(),y=o&&u?W(u):u;if(p){let h=i?r?.every(v=>y?.includes(v)):r?.some(v=>y?.includes(v));return s?!h:h}else{let h;return i?h=r?.every(v=>y===v):a?h=a.has(y):h=r?.some(v=>y===v),s?!h:h}}else return!0},Aa=(e,t,r)=>{if(ae(t,e)){let{values:a,isAnd:i,isExcluded:s,filterToPropertyMapping:{partialMatch:o}}=t,n=Ra(e,t,r).map(p=>p?.replaceAll(P,""));if(o){let p=i?a.every(u=>n?.some(y=>y?.toLowerCase().includes(u))):a.some(u=>n?.some(y=>y?.toLowerCase().includes(u))),d=n.length===0;return s?!p||d:p}else{let p=i?a.every(d=>n?.some(u=>u?.toLowerCase()===d)):a.some(d=>n?.some(u=>u?.toLowerCase()===d));return s?!p:p}}else return!0},Pa=(e,t)=>{if(ae(t,e)){let{isExcluded:r}=t,a=re(e,t);return r?!a:a}else return!0},Sa=(e,t)=>{if(ae(t,e)){let{values:r,isExcluded:a}=t,i=re(e,t),s=r?.some(o=>i>o);return a?!s:s}else return!0},re=(e,t)=>{let{filterToPropertyMapping:{property:r}}=t,a;return r!==D&&(a=e[r]),a},Ra=(e,t,r)=>{let{filterToPropertyMapping:{isNestedPropertyArray:a,nestedProperty:i}}=t,s=[],o=Object.keys(e.legalOverrides||{}).length>0,n=t.filterToPropertyMapping.property===j.LegalHeroes,p=r.find(({filterToPropertyMapping:u})=>u.property===j.LegalFormats);if(o&&n&&!!p){let u=new Set;for(let{format:y,heroes:h}of e.legalOverrides||[])if(p.values.includes(y.toLowerCase()))for(let v of h)u.add(v);s=Array.from(u)}if(s.length===0)if(i){let u=new Set;for(let y of e.printings){let h=y[i];if(a){if(Array.isArray(h))for(let v of h)u.add(v)}else h&&typeof h=="string"&&u.add(h)}s=Array.from(u)}else{let u=re(e,t);if(Array.isArray(u))for(let y of u)typeof y=="string"&&s.push(y)}return s},ka=(e,t)=>{let{filterToPropertyMapping:{specialProperty:r}}=t,a;return r&&(a=e[r]),a},ae=({cardTypes:e},{types:t,subtypes:r})=>!e||e?.some(a=>t.map(i=>i.toLowerCase()).includes(a.toLowerCase())||r.map(i=>i.toLowerCase()).includes(a.toLowerCase()));var wa=(e,t,r=[],a=[],i)=>{let{appliedFilters:s,attributes:o,keywords:n}=te(e,t,{additionalHeroes:r,additionalSets:a,today:i});return{appliedFilters:s,attributes:o,keywords:n}};var Va=(e,t)=>{let r=new Set;for(let i of e)for(let s of i.createdExtras||[])r.add(s);let a=[];for(let i of t)r.has(i.cardIdentifier)&&a.push(i);return a};0&&(module.exports={FilterCategory,FilterKind,FilterProperty,MARKUP,NO_CARD_PROPERTY,PUNCTUATION,RARITY_VALUES_MAPPING,abbreviations,aliasesByFilterCategory,availableExclusions,availableModifiers,filterCard,filtersToCardPropertyMappings,getAbbreviation,getAbbreviationByCard,getCardsByName,getCardsReferencedBy,getCardsReferencing,getCatalogueIndex,getCleanText,getEscapedForRegExp,getExcludedMetaFilters,getFilterCategory,getFilterMapping,getFilterTokenSpansForKey,getFilterValue,getIncompleteFilterToken,getIsExcludedToken,getIsValueInFilterVocabulary,getKeywordsAndAppliedFiltersFromText,getMetaFilterResolution,getMetaFilters,getNormalizedFilterValue,getNormalizedText,getParsedQuery,getQueryFilterToken,getQueryTokenSpans,getQuotedValue,getResolvedFilterKey,getSuggestedFilterKey,getTextWithoutMarkup,getTokensReferencedByCards,getUnquotedValue,getValuePartsFromFilterValue,getValuesFromFilterValue,multiWordShorthands,shorthands,singleWordShorthands});
|
|
1
|
+
"use strict";var Kt=Object.create;var le=Object.defineProperty;var _t=Object.getOwnPropertyDescriptor;var $t=Object.getOwnPropertyNames;var zt=Object.getPrototypeOf,Gt=Object.prototype.hasOwnProperty;var Wt=(e,t)=>{for(var r in t)le(e,r,{get:t[r],enumerable:!0})},Ye=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of $t(t))!Gt.call(e,a)&&a!==r&&le(e,a,{get:()=>t[a],enumerable:!(s=_t(t,a))||s.enumerable});return e};var Yt=(e,t,r)=>(r=e!=null?Kt(zt(e)):{},Ye(t||!e||!e.__esModule?le(r,"default",{value:e,enumerable:!0}):r,e)),qt=e=>Ye(le({},"__esModule",{value:!0}),e);var Ls={};Wt(Ls,{FilterCategory:()=>l,FilterKind:()=>m,FilterProperty:()=>G,MARKUP:()=>Me,NO_CARD_PROPERTY:()=>K,PUNCTUATION:()=>k,RARITY_VALUES_MAPPING:()=>De,aliasesByFilterCategory:()=>J,availableExclusions:()=>_,availableModifiers:()=>Se,default:()=>Ht,filterCard:()=>jt,filtersToCardPropertyMappings:()=>Z,getCardsByName:()=>ye,getCardsReferencedBy:()=>Ce,getCardsReferencing:()=>me,getCatalogueIndex:()=>we,getCleanText:()=>B,getEscapedForRegExp:()=>X,getExcludedMetaFilters:()=>Ie,getFilterCategory:()=>re,getFilterMapping:()=>ge,getFilterTokenSpansForKey:()=>us,getFilterValue:()=>je,getIncompleteFilterToken:()=>He,getIsExcludedToken:()=>ps,getIsValueInFilterVocabulary:()=>ke,getKeywordsAndAppliedFiltersFromText:()=>Bs,getMetaFilterResolution:()=>se,getMetaFilters:()=>fr,getNormalizedFilterValue:()=>V,getNormalizedText:()=>z,getParsedQuery:()=>ie,getQueryFilterToken:()=>Fe,getQueryTokenSpans:()=>he,getQuotedValue:()=>fs,getResolvedFilterKey:()=>Qe,getSuggestedFilterKey:()=>Ve,getTextWithoutMarkup:()=>q,getTokensReferencedByCards:()=>Os,getUnquotedValue:()=>Te,getValuePartsFromFilterValue:()=>Ot,getValuesFromFilterValue:()=>Ue,multiWordShorthands:()=>_e,shorthands:()=>Ke,singleWordShorthands:()=>$e});module.exports=qt(Ls);var xe=require("@flesh-and-blood/types"),We=Yt(require("fuse.js"),1);var k=/[!"#$%&'’(),./:;<=>?@[\]^_`|~]/g,Me=/\*/g;var T=require("@flesh-and-blood/types");var B=e=>z(e.toLowerCase().trim().replace(k,"")),z=e=>e.normalize("NFD").replace(/\p{Diacritic}/gu,""),V=e=>e.toLowerCase().replace(k,""),q=e=>e.replace(Me,""),X=e=>e.replace(/[.*+?^${}()|[\]\\-]/g,"\\$&");var l={Arcane:"arcane",Artist:"artist",Banned:"banned",Bond:"bond",Chain:"chain",Class:"class",Cost:"cost",Defense:"defense",Flow:"flow",Foiling:"foiling",Fusion:"fusion",Intellect:"intellect",Is:"is",Keyword:"keyword",Legal:"legal",Life:"life",Name:"name",Pitch:"pitch",Power:"power",Print:"print",Rarity:"rarity",ReferencedBy:"referencedby",References:"references",Set:"set",Shorthand:"shorthand",Specialization:"specialization",Subtype:"subtype",Talent:"talent",Text:"text",Trait:"trait",Treatment:"treatment",Type:"type",TypeText:"typetext",Year:"year"},m={Comparator:"comparator",ExactMatch:"exactMatch",PartialMatch:"partialMatch"},Se=[">=",">","<=","<"],_=["!","-"],K="n/a",gt=[...Object.values(T.Format),...Object.values(T.Hero)],Xt={category:l.Arcane,canonicalAlias:"arcane",kind:m.Comparator,property:"arcane",specialProperty:"specialArcane",isNumber:!0,partialMatch:!0},be={category:l.Artist,canonicalAlias:"art",kind:m.PartialMatch,property:"artists",isArray:!0,partialMatch:!0},qe={category:l.Banned,canonicalAlias:"banned",kind:m.ExactMatch,vocabulary:gt,property:K,isMeta:!0},Xe={category:l.Bond,canonicalAlias:"bond",kind:m.ExactMatch,vocabulary:Object.values(T.Bond),property:"bonds",isArray:!0},Zt={category:l.Chain,canonicalAlias:"chain",kind:m.PartialMatch,property:K},Ze={category:l.Class,canonicalAlias:"c",kind:m.PartialMatch,vocabulary:Object.values(T.Class),property:"classes",isArray:!0,partialMatch:!0},Je={category:l.Cost,canonicalAlias:"co",kind:m.Comparator,property:"cost",specialProperty:"specialCost",isNumber:!0,partialMatch:!0},te={category:l.Defense,canonicalAlias:"d",kind:m.Comparator,property:"defense",specialProperty:"specialDefense",isNumber:!0},et={category:l.Flow,canonicalAlias:"flow",kind:m.ExactMatch,vocabulary:Object.values(T.Flow),property:"flows",isArray:!0},tt={category:l.Foiling,canonicalAlias:"foil",kind:m.ExactMatch,vocabulary:Object.values(T.Foiling),nestedProperty:"foiling",property:"printings",isArray:!0},rt={category:l.Fusion,canonicalAlias:"f",kind:m.ExactMatch,vocabulary:Object.values(T.Fusion),property:"fusions",isArray:!0},st={category:l.Intellect,canonicalAlias:"i",kind:m.Comparator,property:"intellect",isNumber:!0},at={category:l.Keyword,canonicalAlias:"k",kind:m.ExactMatch,vocabulary:Object.values(T.Keyword),property:"keywords",isArray:!0},Ae={category:l.Legal,canonicalAlias:"l",kind:m.ExactMatch,vocabulary:gt,property:K,isMeta:!0},it={category:l.Life,canonicalAlias:"li",kind:m.Comparator,property:"life",specialProperty:"specialLife",isNumber:!0},nt={category:l.Is,canonicalAlias:"is",kind:m.ExactMatch,vocabulary:Object.values(T.Meta),property:"meta",isArray:!0},ot={category:l.Name,canonicalAlias:"name",kind:m.PartialMatch,property:"name",isString:!0,partialMatch:!0},Pe={category:l.Pitch,canonicalAlias:"p",kind:m.Comparator,property:"pitch",isNumber:!0},de={category:l.Power,canonicalAlias:"pwr",kind:m.Comparator,property:"power",specialProperty:"specialPower",isNumber:!0},ce={category:l.Print,canonicalAlias:"print",kind:m.PartialMatch,property:"setIdentifiers",isArray:!0,partialMatch:!0},lt={category:l.Rarity,canonicalAlias:"r",kind:m.ExactMatch,vocabulary:Object.values(T.Rarity),property:K,isMeta:!0},Jt={category:l.ReferencedBy,canonicalAlias:"referencedby",kind:m.PartialMatch,property:K},er={category:l.References,canonicalAlias:"references",kind:m.PartialMatch,property:K},dt={category:l.Set,canonicalAlias:"s",kind:m.PartialMatch,vocabulary:Object.values(T.Release),property:"sets",isArray:!0,partialMatch:!0},ve={category:l.Shorthand,canonicalAlias:"short",kind:m.PartialMatch,vocabulary:Object.values(T.Shorthand),property:"shorthands",isArray:!0,partialMatch:!0},pe={category:l.Specialization,canonicalAlias:"sp",kind:m.PartialMatch,vocabulary:Object.values(T.Hero),property:"specializations",isArray:!0,partialMatch:!0},ct={category:l.Subtype,canonicalAlias:"st",kind:m.ExactMatch,vocabulary:Object.values(T.Subtype),property:"subtypes",isArray:!0},pt={category:l.Type,canonicalAlias:"t",kind:m.ExactMatch,vocabulary:Object.values(T.Type),property:"types",isArray:!0},Re={category:l.Talent,canonicalAlias:"tal",kind:m.ExactMatch,vocabulary:Object.values(T.Talent),property:"talents",isArray:!0},tr={category:l.Text,canonicalAlias:"text",kind:m.PartialMatch,property:"functionalText",hasMarkup:!0,isString:!0,partialMatch:!0},rr={category:l.Trait,canonicalAlias:"trait",kind:m.PartialMatch,vocabulary:Object.values(T.Trait),property:"traits",isArray:!0,partialMatch:!0},ut={category:l.TypeText,canonicalAlias:"x",kind:m.PartialMatch,property:"typeText",isString:!0,partialMatch:!0},ue={category:l.Treatment,canonicalAlias:"treatment",kind:m.ExactMatch,vocabulary:Object.values(T.Treatment),nestedProperty:"treatments",property:"printings",isArray:!0,isNestedPropertyArray:!0},sr={category:l.Year,canonicalAlias:"year",kind:m.PartialMatch,property:"firstReleaseDate",isString:!0,partialMatch:!0},Z={arcane:Xt,a:be,artist:be,art:be,attack:de,b:te,block:te,banned:qe,bond:Xe,bonds:Xe,c:Ze,class:Ze,chain:Zt,co:Je,cost:Je,color:Pe,d:te,def:te,defense:te,flow:et,flows:et,f:rt,fusion:rt,foil:tt,foiling:tt,i:st,intellect:st,is:nt,k:at,keyword:at,l:Ae,legal:Ae,hero:Ae,li:it,life:it,meta:nt,n:ot,name:ot,p:Pe,pitch:Pe,pwr:de,pow:de,power:de,print:ce,printing:ce,printings:ce,prints:ce,r:lt,rarity:lt,referencedby:Jt,references:er,rf:qe,s:dt,set:dt,short:ve,shorthand:ve,shorthands:ve,sp:pe,spec:pe,specialization:pe,specializations:pe,st:ct,subtype:ct,t:pt,type:pt,tal:Re,talent:Re,talents:Re,text:tr,trait:rr,treat:ue,treatment:ue,var:ue,variation:ue,x:ut,typetext:ut,year:sr},ar=new Map(Object.entries(Z)),ge=e=>ar.get(e.toLowerCase()),re=e=>ge(e)?.category,ir=()=>{let e=Object.create(null);for(let[t,{category:r}]of Object.entries(Z)){let s=e[r];s?s.push(t):e[r]=[t]}return e},J=ir(),nr=()=>{let e=new Map,t=new Set,r=Object.values(Z);for(let s of r){let{vocabulary:a}=s;if(a&&!t.has(s)){t.add(s);for(let i of a){let n=V(i),o=e.get(n);o?o.push(s):e.set(n,[s])}}}return e},ft=nr(),ke=(e,t)=>!!ft.get(V(t))?.some(r=>r.category===e),or=(e,t)=>{let r=[],s=!0;for(let a of t){let i=(ft.get(V(a))||[]).filter(n=>n.category!==e);r=s?i:r.filter(n=>i.includes(n)),s=!1}return r},Ve=(e,t)=>{let r=or(e,t),[s]=r;return r.length===1?s.canonicalAlias:void 0};var ae=require("@flesh-and-blood/types");var d=require("@flesh-and-blood/types");var E=require("@flesh-and-blood/types");var G={BannedFormats:"bannedFormats",LegalFormats:"legalFormats",LegalHeroes:"legalHeroes"},fe=Array.from(Array(50).keys()).map(e=>`${e}`),lr=[{format:E.Format.ClassicConstructed,nicknames:["cc","classic"]},{format:E.Format.LivingLegend,nicknames:["cc ll","classic constructed ll","ll cc","ll","living legend"]},{format:E.Format.SilverAge,nicknames:["sage"]},{format:E.Format.GoldenAge,nicknames:["gage"]},{format:E.Format.UltimatePitFight,nicknames:["upf"]}],dr=Object.values(E.Format).map(e=>{let t=lr.find(({format:s})=>s===e),r=e.toLowerCase().replaceAll(k,"");return t?{...t,format:r}:{format:r}}),cr=Object.values(E.Hero).map(B),yt=e=>e.replaceAll(" ",""),pr=(e,t)=>{let r=yt(e),s,a=[];for(let n of t){let o=yt(n);o===r?s=n:o.startsWith(r)&&a.push(n)}let i=a.length===1;return s??(i?a[0]:void 0)},mt=["common","rare","super rare","majestic","legendary","fabled"],ur=({modifier:e,value:t})=>{let r=[],s=e==="<"||e==="<=",a=e===">="||e==="<=",i=s?[...mt].reverse():mt,n=!1;for(let o of i)n?r.push(o):o===t&&(n=!0,a&&r.push(o));return r},gr=(e,t)=>{let r=[];for(let s of e)s.modifier?r.push(...ur(s)):r.push(s.value);return{filterToPropertyMapping:{nestedProperty:"rarity",property:"printings",isArray:!0},isExcluded:t,isOr:!0,values:r}},Ct=(e,t,r,s)=>{let a=new Set([...cr,...r.map(B)]),i=[],n=[],o=[],c=[];for(let{value:p}of e){let g=dr.find(({format:f,nicknames:C})=>f===p||!!C&&C.includes(p));if(g)n.push(g.format);else{let f=pr(p,a);f?o.push(f):c.push(p)}}return n.length>0&&i.push({filterToPropertyMapping:{property:s,isArray:!0},values:n,isOr:!0,isExcluded:t}),o.length>0&&i.push({filterToPropertyMapping:{property:G.LegalHeroes,isArray:!0},values:o,isOr:!0,isExcluded:t}),{appliedFilters:i,unresolvedValues:c}},se=(e,t,{additionalHeroes:r=[],isExcluded:s=!1}={})=>{let a=re(e),i={appliedFilters:[],unresolvedValues:[]};return a===l.Legal?i=Ct(t,s,r,G.LegalFormats):a===l.Banned?i=Ct(t,s,r,G.BannedFormats):a===l.Rarity&&(i={appliedFilters:[gr(t,s)],unresolvedValues:[]}),i},fr=(e,t,r,s,a,i)=>se(r,s.map(n=>({modifier:a,value:n})),{additionalHeroes:i,isExcluded:e}).appliedFilters,yr=[{filterToPropertyMapping:{property:"cost",isNumber:!0},isExcluded:!0,values:fe},{filterToPropertyMapping:{property:"specialCost",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token","weapon"]}],mr=[{filterToPropertyMapping:{property:"defense",isNumber:!0},isExcluded:!0,values:fe},{filterToPropertyMapping:{property:"specialDefense",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["hero","placeholder","token","weapon"]}],Cr=[{filterToPropertyMapping:{property:"pitch",isNumber:!0},isExcluded:!0,values:fe},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token","weapon"]},{filterToPropertyMapping:{property:"isCardBack",isBoolean:!0},isExcluded:!0,values:["true"]}],hr=[{filterToPropertyMapping:{property:"power",isNumber:!0},isExcluded:!0,values:fe},{filterToPropertyMapping:{property:"specialPower",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token"]}],Fr=[{filterToPropertyMapping:{property:"talents",isArray:!0},isExcluded:!0,values:Object.values(E.Talent).map(e=>e.toLowerCase())}],Tr=[{filterToPropertyMapping:{property:"classes",isArray:!0},isExcluded:!0,values:Object.values(E.Class).map(e=>e.toLowerCase())}],xr=[{category:l.Class,filters:Tr},{category:l.Cost,filters:yr},{category:l.Defense,filters:mr},{category:l.Pitch,filters:Cr},{category:l.Power,filters:hr},{category:l.Talent,filters:Fr}],Mr=()=>{let e=new Map;for(let{category:t,filters:r}of xr)for(let s of J[t])for(let a of _)e.set(`${a}${s}`,r);return e},br=Mr(),Ie=e=>{let t=[],r=br.get(e);return r&&t.push(...r),t};var W=require("@flesh-and-blood/types");var Ar=3,Pr=e=>{let t=z(e.toLowerCase()).replace(/[^a-z\s-]/g,""),r=new Set;for(let s of[/[\s-]+/,/\s+/]){let a="";for(let i of t.split(s)){let n=i.replaceAll("-","");n&&(a+=n[0])}a.length>=Ar&&r.add(a)}return[...r]},ht=e=>B(e).replaceAll("-",""),Ft=(e,t,r)=>{let s=e.get(t);s?s.push(r):e.set(t,[r])},Tt=new WeakMap,j=Object.freeze([]),vr=Number.MAX_SAFE_INTEGER,xt=(e,t)=>{let r=new Map;for(let s of e)for(let a of t(s)||[]){let i=r.get(a);i?i.push(s):r.set(a,[s])}return r},Rr=e=>{let t=new Map;for(let r of e){let s=r.types.includes(W.Type.Hero)&&!r.isCardBack,a=s?W.CardRole.Hero:(0,W.getCardRole)(r);if(s||a!==W.CardRole.Hero){let n=t.get(a);n?n.push(r):t.set(a,[r])}}return t},Sr=e=>{let t,r,s,a,i,n,o,c=()=>{if(!t){let u=new Map,y=new Map,h=[],F=new Map,M=0;for(let w of e){u.set(w.cardIdentifier,w),y.set(w.cardIdentifier,M),M++;let S=B(w.name),Y=F.get(S);Y?Y.push(w):(F.set(S,[w]),h.push(S))}t={cardByCardIdentifier:u,corpusPositionByCardIdentifier:y,cleanedNames:h,pitchCycleByCleanedName:F}}return t},p=u=>{let{corpusPositionByCardIdentifier:y}=c(),h=({cardIdentifier:F})=>y.get(F)??vr;return[...u].sort((F,M)=>h(F)-h(M))},g=u=>c().cardByCardIdentifier.get(u),f=u=>{let{cardByCardIdentifier:y}=c(),h=[];for(let F of u||[]){let M=y.get(F);M&&h.push(M)}return p(h)},C=u=>{let y=new Map;return h=>{let F=y.get(h);if(!F){let M=g(h),w=f(M&&u(M)),S=w.length>0;F=S?w:j,S&&y.set(h,F)}return F}},b=u=>{let{pitchCycleByCleanedName:y}=c(),h=g(u);return h?y.get(B(h.name))??j:j},D=u=>{let{cleanedNames:y,pitchCycleByCleanedName:h}=c(),F=B(u),M=h.get(F);if(!M&&F.length>0){let S=y.find(Y=>Y.includes(F));S&&(M=h.get(S))}return M??j},I=u=>{let{pitchCycleByCleanedName:y}=c();return y.get(B(u))??j},P=u=>{if(!n){n=new Map;for(let y of e)for(let h of y.nicknames??[])Ft(n,ht(h),y)}return n.get(ht(u))??j},O=u=>{if(!o){o=new Map;for(let y of e)for(let h of Pr(y.name))Ft(o,h,y)}return o.get(u)??j},N=()=>{if(!i){let u=new Set;for(let y of e)for(let h of y.artists)u.add(h);i=[...u].sort((y,h)=>y.localeCompare(h,"en",{sensitivity:"base"}))}return i},Q=C(({oppositeSideCardIdentifiers:u})=>u),U=C(({referencedCards:u})=>u),$=u=>(r||(r=xt(e,({referencedCards:y})=>y)),r.get(u)??j),H=C(({createdExtras:u})=>u);return{cards:e,getCard:g,getPitchCycle:b,getCardsByName:D,getCardsByExactName:I,getCardsByNickname:P,getCardsByInitials:O,getArtists:N,getOppositeSide:Q,getReferences:U,getReferencedBy:$,getCreates:H,getCreatedBy:u=>(s||(s=xt(e,({createdExtras:y})=>y)),s.get(u)??j),getCreatedClosure:u=>{let y=new Map,h=new Set,F=[...u];for(let M of F)if(!h.has(M)){h.add(M);for(let S of H(M))y.set(S.cardIdentifier,S),F.push(S.cardIdentifier)}return p([...y.values()])},getByRole:u=>(a||(a=Rr(e)),a.get(u)??j),getCardsInCorpusOrder:p}},we=e=>{let t=Tt.get(e);return t||(t=Sr(e),Tt.set(e,t)),t},Ee=(e,t)=>e.getPitchCycle(t.cardIdentifier),ye=(e,t)=>e.getCardsByName(t),Mt=(e,t)=>{let r=new Map;for(let s of t)for(let a of Ee(e,s))r.set(a.cardIdentifier,a);return e.getCardsInCorpusOrder([...r.values()])},me=(e,t)=>{let r=[];for(let s of Ee(e,t))r.push(...e.getReferencedBy(s.cardIdentifier));return Mt(e,r)},Ce=(e,t)=>{let r=[];for(let s of Ee(e,t))r.push(...e.getReferences(s.cardIdentifier));return Mt(e,r)};var kr=e=>{let[t]=e,r=t?.modifier;return e.every(({modifier:a})=>a===r)?r:void 0},Be=({filterValues:e,isAnd:t,isExcluded:r,mapping:s})=>{let a=[];for(let{value:i}of e)a.push(s.hasMarkup?q(i):i);return{filterToPropertyMapping:s,filterValues:e,isAnd:t,isExcluded:r,isOr:!t&&a.length>1,modifier:kr(e),values:a}},vt=({isAnd:e,isExcluded:t,mapping:r},s)=>({filterToPropertyMapping:r,isAnd:e,isExcluded:t,isOr:!e&&s.length>1,values:s}),Vr=({category:e,filterValues:t,mapping:r})=>{let s=[];if(r.kind===m.ExactMatch&&!!r.vocabulary)for(let{value:i}of t)ke(e,i)||s.push(i);return s},Ir=e=>({appliedFilters:[Be(e)],unresolvedValues:Vr(e)}),Oe=({isExcluded:e},t,r)=>e?void 0:{[t]:r},Rt=(e,t)=>({appliedFilters:[Be(e)],attributes:Oe(e,t,e.filterValues.map(({value:r})=>r)),unresolvedValues:[]}),wr=e=>Rt(e,"artists"),Er=e=>Rt(e,"prints"),Le=(e,t,r)=>{let s=[],a=[],i=[];for(let{value:n}of e.filterValues){let o=r(n);if(o.length>0)for(let c of o)s.push(c),a.push(V(c));else i.push(n)}return{appliedFilters:[vt(e,a)],attributes:Oe(e,t,s),canonicalValues:a,unresolvedValues:i}},Nr=new Map(Object.entries({purple:4,blue:3,yellow:2,red:1,white:0})),Br=e=>{let t=[],r=[];for(let{modifier:s,value:a}of e.filterValues){let i=Nr.get(a),n=i===void 0?a:`${i}`;t.push({modifier:s,value:n}),r.push(n)}return{appliedFilters:[Be({...e,filterValues:t})],canonicalValues:r,unresolvedValues:[]}},Ne=new Map;for(let e of Object.values(d.Release)){let t=V(e),r=Ne.get(t);if(r===void 0)Ne.set(t,e);else throw new Error(`${r} and ${e} are one name as a filter reads it, so a set filter naming it could reach either`)}var bt=(e,t)=>{let r=e.get(t);return r?[r]:[]},Or=(e,t)=>{let r=[()=>bt(Ne,e),()=>bt(d.setIdentifierToSetMappings,e),()=>Object.values(d.Release).filter(a=>a.toLowerCase().includes(e)),()=>{let a=t.find(i=>V(i)===e);return a?[a]:[]}],s=[];for(let a of r)s.length===0&&s.push(...a());return s},Lr=(e,{additionalSets:t})=>Le(e,"releases",r=>Or(r,t)),Dr=new Map(Object.entries({r:d.Foiling.Rainbow,rf:d.Foiling.Rainbow,rainbow:d.Foiling.Rainbow,c:d.Foiling.Cold,cf:d.Foiling.Cold,cold:d.Foiling.Cold,g:d.Foiling.Gold,gf:d.Foiling.Gold,gold:d.Foiling.Gold})),Qr=e=>{let t=Dr.get(e);return t?[t]:[]},Hr=e=>Le(e,"foilings",Qr),St=new Map(Object.entries({aa:d.Treatment.AA,alt:d.Treatment.AA,"alt art":d.Treatment.AA,ab:d.Treatment.AB,"alt border":d.Treatment.AB,at:d.Treatment.AT,"alt text":d.Treatment.AT,ea:d.Treatment.EA,extended:d.Treatment.EA,"extended art":d.Treatment.EA,fa:d.Treatment.FA,full:d.Treatment.FA,"full art":d.Treatment.FA}));for(let e of Object.values(d.Treatment))St.set(e.toLowerCase(),e);var jr=new Map(Object.entries(d.Treatment)),Ur=e=>{let t=St.get(e)||jr.get(e.toUpperCase());return t?[t]:[]},Kr=e=>Le(e,"treatments",Ur),De=new Map(Object.entries({b:d.Rarity.Basic,c:d.Rarity.Common,f:d.Rarity.Fabled,l:d.Rarity.Legendary,m:d.Rarity.Majestic,p:d.Rarity.Promo,r:d.Rarity.Rare,s:d.Rarity.SuperRare,t:d.Rarity.Token,v:d.Rarity.Marvel})),_r=e=>De.get(e)||Object.values(d.Rarity).find(t=>t.toLowerCase()===e),$r=(e,{additionalHeroes:t})=>{let r=[],s=[],a=[],i=[];for(let{modifier:o,value:c}of e.filterValues){let p=_r(c);p?(r.push(p),s.push(p.toLowerCase()),a.push({modifier:o,value:p.toLowerCase()})):(i.push(c),a.push({modifier:o,value:c}))}let{appliedFilters:n}=se(e.key,a,{additionalHeroes:t,isExcluded:e.isExcluded});return{appliedFilters:n,attributes:Oe(e,"rarities",r),canonicalValues:s,unresolvedValues:i}},At=({filterValues:e,isExcluded:t,key:r},{additionalHeroes:s})=>{let{appliedFilters:a,unresolvedValues:i}=se(r,e,{additionalHeroes:s,isExcluded:t}),n=[];for(let{values:o}of a)n.push(...o);return{appliedFilters:a,canonicalValues:n,unresolvedValues:i}},zr=["unique"],Gr=["preview","spoiler","unreleased"],Wr=["released"],Pt={property:"firstReleaseDate",isDate:!0},Yr=new Map(Object.entries({dual:d.Meta.DualClass,exp:d.Meta.Expansion,expansion:d.Meta.Expansion,rainbow:d.Meta.Rainbow,reprint:d.Meta.Reprint,reprints:d.Meta.Reprint})),qr=e=>{let t=[],r=[];for(let a of e){let i=Yr.get(a);i?t.push(i):r.push(a)}let s=[];if(t.length===0){let a=new Set;for(let i of Object.values(d.Meta)){let n=!1;for(let o of r)i.toLowerCase().includes(o)&&(n=!0,a.add(o));n&&t.push(i)}for(let i of r)a.has(i)||s.push(i)}else s.push(...r);return{unresolvedValues:s,values:t}},Xr=(e,{today:t})=>{let{filterValues:r,isAnd:s,isExcluded:a}=e,i=[],n=[],o=[],c=[],p=[];for(let{value:P}of r)zr.includes(P)?n.push(P):Gr.includes(P)?o.push(P):Wr.includes(P)?c.push(P):p.push(P);let g=!s&&r.length>1;n.length>0&&i.push({filterToPropertyMapping:Z.is,values:[V(d.Meta.Reprint)],isAnd:s,isOr:g,isExcluded:!a}),o.length>0&&i.push({filterToPropertyMapping:Pt,values:[t],isAnd:s,isOr:g,isExcluded:a}),c.length>0&&i.push({filterToPropertyMapping:Pt,values:[t],isAnd:s,isOr:g,isExcluded:!a});let{unresolvedValues:f,values:C}=qr(p),b=[...n,...o,...c,...C.map(V)];(p.length>0||i.length===0)&&i.push(vt(e,C.map(V)));let I=C.includes(d.Meta.Expansion)&&!a;return{appliedFilters:i,attributes:I?{isExpansionSlot:I}:void 0,canonicalValues:b,unresolvedValues:f}},Zr={property:"cardIdentifier",isString:!0,isNormalized:!0},Jr=20,es=(e,t)=>{let r=new Set,s=[],a=new Set,i=[],n=p=>{r.add(p.cardIdentifier),a.has(p.name)||(a.add(p.name),s.push(p))},o=p=>{p.types.includes(d.Type.Hero)||n(p)};for(let p of t){let g=ye(e,p);for(let f of g)n(f);g.length===0&&i.push(p)}let c=0;for(;c<s.length&&c<=Jr;){let p=s[c];for(let f of Ce(e,p))o(f);if(c===0)for(let f of me(e,p))o(f);c++}return{cardIdentifiers:r,unresolvedValues:i}},kt=(e,t,r)=>{let s=new Set;for(let a of ye(e,t)){let i=r?Ce(e,a):me(e,a);for(let n of i)s.add(n.cardIdentifier)}return s},ts=(e,t)=>{let r=new Set,[s=new Set,...a]=e;if(t)for(let i of s)a.every(o=>o.has(i))&&r.add(i);else for(let i of e)for(let n of i)r.add(n);return r},Vt=(e,t)=>({filterToPropertyMapping:Zr,values:[...e],valuesSet:e,isExcluded:t,isOr:!0}),It=({filterValues:e,isAnd:t,isExcluded:r},s)=>{let a=[],i=[];for(let{value:n}of e){let o=s(n);a.push(o),o.size===0&&i.push(n)}return{appliedFilters:[Vt(ts(a,t),r)],unresolvedValues:i}},rs=(e,{index:t})=>{let{cardIdentifiers:r,unresolvedValues:s}=es(t,e.filterValues.map(({value:a})=>a));return{appliedFilters:[Vt(r,e.isExcluded)],unresolvedValues:s}},ss=(e,{index:t})=>It(e,r=>kt(t,r,!0)),as=(e,{index:t})=>It(e,r=>kt(t,r,!1)),is=new Map([[l.Artist,wr],[l.Banned,At],[l.Chain,rs],[l.Foiling,Hr],[l.Is,Xr],[l.Legal,At],[l.Pitch,Br],[l.Print,Er],[l.Rarity,$r],[l.ReferencedBy,ss],[l.References,as],[l.Set,Lr],[l.Treatment,Kr]]),wt=(e,t)=>(is.get(e.category)||Ir)(e,t);var Nt=_.map(X).join(""),ns=/(?:[^\s"]+|"[^"]*(?:"|$))+/g,os=new RegExp(`^([${Nt}])?([A-Za-z]+):(.+)$`),ls=new RegExp(`^([${Nt}])?([A-Za-z]+):$`),ds=",",Et="+",cs='"',Bt=e=>{let t=[],r=!1,s="",a=!1;for(let i of e)i===cs?(a=!a,s+=i):!a&&(i===ds||i===Et)?(r=r||i===Et,s&&t.push(s),s=""):s+=i;return s&&t.push(s),{isAndList:r,parts:t}},he=e=>{let t=[];for(let r of e.matchAll(ns))t.push({end:r.index+r[0].length,start:r.index,token:r[0]});return t},ps=e=>_.some(t=>e.startsWith(t)),Fe=e=>{let t=e.match(os),r;if(t){let[,s,a,i]=t;r={isAndList:Bt(i).isAndList,isExcluded:!!s,key:a,valueText:i}}return r},He=e=>{let t=e.match(ls),r;return t&&(r={isAndList:!1,isExcluded:!!t[1],key:t[2],valueText:""}),r},je=e=>{let t=e.trim(),r=Se.find(s=>t.startsWith(s));return{modifier:r,value:r?t.slice(r.length).trim():t}},Qe=e=>re(e)??e.toLowerCase(),us=(e,t)=>{let r=Qe(t),s=[];for(let{end:a,start:i,token:n}of he(e)){let o=Fe(n);o&&Qe(o.key)===r&&s.push({...o,end:a,start:i,token:n})}return s},Ot=e=>Bt(e).parts,Te=e=>e.replace(/^"|"$/g,""),Ue=e=>{let t=[];for(let r of Ot(e)){let s=Te(r);s&&t.push(s)}return t},gs=/[\s,:+"]/,fs=e=>{let t=e.replaceAll('"',"");return gs.test(e)?`"${t}"`:t};var L=require("@flesh-and-blood/types"),Ke=[{description:"Attack actions",expanded:["st:attack"],filters:{subtypes:[L.Subtype.Attack]},isCardProperty:!1,shorthands:["AA"]},{description:"Arcane barrier",expanded:['k:"arcane barrier"'],filters:{keywords:[L.Keyword.ArcaneBarrier]},isCardProperty:!1,shorthands:["AB"]},{description:"Attack reactions",expanded:['t:"attack reaction"'],filters:{types:[L.Type.AttackReaction]},isCardProperty:!1,shorthands:["AR"]},{description:"Defense reactions",expanded:['t:"defense reaction"'],filters:{types:[L.Type.DefenseReaction]},isCardProperty:!1,shorthands:["DR"]},{description:"Gain life",expanded:["gain {h}"],filters:{functionalText:"gain {h}"},isCardProperty:!1,shorthands:["Gain life","Gains life"]},{description:"Go again",expanded:['k:"go again"'],filters:{keywords:[L.Keyword.GoAgain]},isCardProperty:!1,shorthands:["GA"]},{description:"Non-attack actions",expanded:["t:action","st:non-attack"],filters:{subtypes:[L.Subtype.NonAttack],types:[L.Type.Action]},isCardProperty:!1,shorthands:["NAA"]},{description:"Plus defense",expanded:["+ {d}"],filters:{functionalText:"+ {d}"},isCardProperty:!1,shorthands:["Pump defense","Pumps defense","Buff defense","Buffs defense"]},{description:"Spellvoid",expanded:['k:"spellvoid"'],filters:{keywords:[L.Keyword.Spellvoid]},isCardProperty:!1,shorthands:["SV"]}],_e=Ke.filter(({shorthands:e})=>e.some(t=>t.includes(" "))).map(e=>({...e,shorthands:e.shorthands.filter(t=>t.includes(" ")).map(t=>t.toLowerCase()).sort((t,r)=>r.length-t.length)})),$e=Ke.filter(({shorthands:e})=>e.some(t=>!t.includes(" "))).map(e=>({...e,shorthands:e.shorthands.filter(t=>!t.includes(" ")).map(t=>t.toLowerCase()).sort((t,r)=>r.length-t.length)}));var ys=["\u201C","\u201D"],ms=[{text:ae.Release.ClassicBattlesRhinarDorinthea.toLowerCase(),override:ae.Release.ClassicBattlesRhinarDorinthea.toLowerCase().replaceAll(k,"")}],ze=new Map([...ae.setToSetIdentifierMappings].map(([e,t])=>[e.toLowerCase(),t])),Cs=[...J[l.Set],...J[l.Print]],hs=_.map(X).join(""),Fs=[...ze.keys()].sort((e,t)=>t.length-e.length).map(X).join("|"),Ts=new RegExp(`(?<=^|\\s)([${hs}]?(?:${Cs.join("|")}):(?:[^\\s]*[,+])?"?)(${Fs})(?="?(?:[,+]|\\s|$))`,"g"),xs=(e,t)=>{let r=e.trim().toLowerCase();for(let i of ys)r=r.replaceAll(i,'"');for(let{expanded:i,shorthands:n}of _e)for(let o of n)if(r.includes(o)){r=r.replace(o,i.join(" "));break}r=r.replace(Ts,(i,n,o)=>{let c=ze.get(o);return c?`${n}${c[0]}`:i});let s=ze.get(r),a=t.getCardsByExactName(r).length>0;s&&!a&&(r=`set:${s[0]}`);for(let{override:i,text:n}of ms)r.includes(n)&&(r=r.replace(n,i));return r},Ms=e=>{let t=$e.find(({shorthands:s})=>s.includes(e)),r=!!t&&!t.isCardProperty;return{isExpanded:r,tokens:r?t.expanded:[e]}},bs=e=>{let t=[];for(let{end:r,start:s,token:a}of he(e)){let{isExpanded:i,tokens:n}=Ms(a);for(let o of n)t.push({end:r,isExpanded:i,start:s,token:o})}return t},As=e=>{let t=[];for(let r of e){let{modifier:s,value:a}=je(r),i=V(a);i&&t.push({modifier:s,value:i})}return t},Ps=(e,t,r)=>{let s={key:e,reason:"value",values:r},a=Ve(t,r);return a&&(s.suggestedKey=a),s},vs=()=>{let e=new Date,t=`${e.getMonth()+1}`.padStart(2,"0"),r=`${e.getDate()}`.padStart(2,"0");return`${e.getFullYear()}-${t}-${r}`},ie=(e,t,{additionalHeroes:r=[],additionalSets:s=[],today:a=vs()}={})=>{let i=xs(e,t),n={additionalHeroes:r,additionalSets:s,index:t,today:a},o=[],c={artists:[],foilings:[],isExpansionSlot:!1,prints:[],rarities:[],releases:[],treatments:[]},p=[],g=[],f=[];for(let C of bs(i)){let b=Fe(C.token)||He(C.token);if(b){let{isAndList:D,isExcluded:I,key:P,valueText:O}=b,N=ge(P),Q=N?.category,U=Ue(O),$=As(U),H={...C,canonicalValues:$.map(({value:x})=>x),category:Q,filterValues:$,isAnd:D,isExcluded:I,isFilter:!0,isResolved:!0,key:P};if(U.length>0)if(N&&Q){let x=U;if($.length>0){let v=wt({category:Q,filterValues:$,isAnd:H.isAnd,isExcluded:I,key:P,mapping:N},n);o.push(...v.appliedFilters),v.canonicalValues&&(H.canonicalValues=v.canonicalValues),v.attributes&&Object.assign(c,v.attributes),x=v.unresolvedValues}x.length>0&&(H.isResolved=!1,f.push(Ps(P,Q,x)))}else H.isResolved=!1,f.push({key:P,reason:"key",values:[]});g.push(H)}else{let{end:D,start:I,token:P}=C;g.push({end:D,isFilter:!1,start:I,token:P});let O=Te(C.token),N=Ie(O);N.length>0?o.push(...N):O&&p.push(O.replace(k,""))}}return{appliedFilters:o,attributes:c,keywords:p,nodes:g,text:i,unresolvedFilters:f}};var A=require("@flesh-and-blood/types"),Lt={artists:["Hoodwill"],cardIdentifier:"fangs-a-lot-blue",classes:[A.Class.Generic],defaultImage:"FNG000",firstReleaseDate:"2022-06-02",functionalText:"If Fangs A Lot is put into your banished zone from your graveyard, instead put it into your hand.",legalFormats:[],legalHeroes:[A.Hero.Kayo,A.Hero.Levia,A.Hero.Rhinar],printings:[{artists:["Hoodwill"],identifier:"FNG000",image:"FNG000",print:"FNG000",rarity:A.Rarity.Rare,set:A.Release.Promos},{artists:["Hoodwill"],identifier:"FNG000",image:"FNG000_Marvel",print:`FNG000-${A.Treatment.FA}`,rarity:A.Rarity.Marvel,set:A.Release.Promos,treatments:[A.Treatment.FA]}],name:"Fangs A Lot",rarities:[A.Rarity.Rare,A.Rarity.Marvel],rarity:A.Rarity.Rare,sets:[A.Release.Promos],setIdentifiers:["FNG000"],specialImage:"FNG000_Marvel",subtypes:[A.Subtype.Attack],types:[A.Type.Action],typeText:"Generic Action - Attack"},Dt=[{keyword:Lt.name.toLowerCase(),card:Lt}];var Rs={getFn:(e,t)=>{let r=We.default.config.getFn(e,t),s=r;if(Array.isArray(r))s=r.map(a=>{let i=typeof a=="string"?a:a.v;return z(i.replace(k,""))});else if(r){let a=z(r).replace(k,"");s=t.includes("functionalText")?q(a):a}return s},ignoreLocation:!0,includeScore:!0,keys:[{name:"name",weight:10},{name:"functionalText",weight:6},{name:"shorthands",weight:4},{name:"setIdentifiers",weight:2},{name:"traits",weight:4},{name:"typeText",weight:6}],threshold:.15,useExtendedSearch:!0},Ge=class{constructor(t,r=[],s=[]){this.getFuse=()=>(this.fuse||(this.fuse=new We.default(this.cards,Rs)),this.fuse);this.getPoolCards=t=>{this.poolCardByCardIdentifier||(this.poolCardByCardIdentifier=new Map(this.cards.map(s=>[s.cardIdentifier,s])));let r=[];for(let{cardIdentifier:s}of t){let a=this.poolCardByCardIdentifier.get(s);a&&r.push(a)}return r};this.search=(t,r)=>{let s,a,{appliedFilters:i,attributes:n,keywords:o,unresolvedFilters:c}=ie(t,this.index,{additionalHeroes:this.additionalHeroes,additionalSets:this.additionalSets}),p=o.join(" "),g=r?Dt.filter(x=>x.keyword===p):[],f=x=>i.length>0?x.filter(v=>v&&jt(v,i)):x;if(g.length>0)s=f(g.map(({card:x})=>x));else if(o.length){let x=B(p),v=this.getPoolCards(this.index.getCardsByNickname(x)),R=new Map;for(let F of[...this.getPoolCards(this.index.getCardsByExactName(x)),...v])R.set(F.cardIdentifier,F);let u=this.getFuse().search(p).map(F=>F.item).filter(({cardIdentifier:F})=>!R.has(F));s=f([...R.values(),...u]),s.some(F=>v.includes(F))&&(a={kind:"nickname",text:x}),s.length===0&&o.length===1&&(s=f(this.getPoolCards(this.index.getCardsByInitials(x))),s.length>0&&(a={kind:"initials",text:x}))}else s=f([...this.cards]);if(!(o.length>0&&a?.kind!=="initials")){let x="";if(n.releases.length===1){let u=xe.setToSetIdentifierMappings.get(n.releases[0]);u?.length&&(x=u[0].toUpperCase())}if(!x&&n.prints.length===1){let u=n.prints[0];xe.setIdentifierToSetMappings.has(u)&&(x=u.toUpperCase())}x?s.sort((u,y)=>{let h=u.setIdentifiers.find(M=>M.includes(x))?.replace(x,""),F=y.setIdentifiers.find(M=>M.includes(x))?.replace(x,"");return h&&F?h.localeCompare(F):-1}):s.sort((u,y)=>u.name===y.name?`${u.pitch}`.localeCompare(`${y.pitch}`):u.name.localeCompare(y.name))}let b=[],{artists:D,isExpansionSlot:I,foilings:P,prints:O,rarities:N,releases:Q,treatments:U}=n;(D.length>0||I||P.length>0||O.length>0||N.length>0||Q.length>0||U.length>0)&&(b=s.map(x=>{let v=x.printings.filter(R=>{let u=!!R.image,y=D.length===0||D.some(ee=>R.artists.find(Ut=>Ut.replace(k,"").toLowerCase().includes(ee))),h=!I||I===R.isExpansionSlot,F=P.length===0||!!R.foiling&&P.includes(R.foiling),M=O.length===0||O.some(ee=>R.identifier.includes(ee.toUpperCase())),w=N.length===0||N.includes(R.rarity),S=Q.length===0||Q.includes(R.set),Y=U.length===0||R.treatments?.some(ee=>U.includes(ee));return u&&y&&h&&F&&M&&w&&S&&Y});return{...x,matchingPrintings:v}}));let H=b.length>0?b:s;return{alias:a,appliedFilters:i,attributes:n,keywords:o,searchResults:H,unresolvedFilters:c}};let a=Array.isArray(r)?{additionalHeroes:r,additionalSets:s}:r;this.additionalHeroes=a.additionalHeroes||[],this.additionalSets=a.additionalSets||[],this.cards=[...t],this.index=a.index||we(t)}},Ht=Ge,jt=(e,t)=>{let r=!0;for(let s of t){let{isNumber:a,isString:i,isArray:n,isBoolean:o,isDate:c}=s.filterToPropertyMapping;s.isOptional||(a?r=r&&Ss(e,s):i?r=r&&ks(e,s):n?r=r&&Vs(e,s,t):o?r=r&&Is(e,s):c&&(r=r&&ws(e,s)))}return r},Qt=(e,t,r)=>{let s=parseInt(t),a;switch(r){case">=":a=e>=s;break;case">":a=e>s;break;case"<=":a=e<=s;break;case"<":a=e<s;break;default:a=e===s}return a},Ss=(e,t)=>{let{filterValues:r,values:s,modifier:a,isExcluded:i,filterToPropertyMapping:{partialMatch:n}}=t,o=!0;if(oe(t,e)){let c=ne(e,t),p;if(c!=null&&!isNaN(c)){let g=parseInt(c);p=r?r.some(({modifier:f,value:C})=>Qt(g,C,f)):s.some(f=>Qt(g,f,a))}else{let g=Ns(e,t)?.toLowerCase();p=n?s.some(f=>!!g?.includes(f)):s.some(f=>g===f)}o=i?!p:p}return o},ks=(e,t)=>{if(oe(t,e)){let{values:r,valuesSet:s,isAnd:a,isExcluded:i,filterToPropertyMapping:{hasMarkup:n,isNormalized:o,partialMatch:c}}=t,p=ne(e,t),g=o?p:p?.replaceAll(k,"").toLowerCase(),f=n&&g?q(g):g;if(c){let C=a?r?.every(b=>f?.includes(b)):r?.some(b=>f?.includes(b));return i?!C:C}else{let C;return a?C=r?.every(b=>f===b):s?C=s.has(f):C=r?.some(b=>f===b),i?!C:C}}else return!0},Vs=(e,t,r)=>{if(oe(t,e)){let{values:s,isAnd:a,isExcluded:i,filterToPropertyMapping:{partialMatch:n}}=t,o=Es(e,t,r).map(c=>c?.replaceAll(k,""));if(n){let c=a?s.every(g=>o?.some(f=>f?.toLowerCase().includes(g))):s.some(g=>o?.some(f=>f?.toLowerCase().includes(g))),p=o.length===0;return i?!c||p:c}else{let c=a?s.every(p=>o?.some(g=>g?.toLowerCase()===p)):s.some(p=>o?.some(g=>g?.toLowerCase()===p));return i?!c:c}}else return!0},Is=(e,t)=>{if(oe(t,e)){let{isExcluded:r}=t,s=ne(e,t);return r?!s:s}else return!0},ws=(e,t)=>{if(oe(t,e)){let{values:r,isExcluded:s}=t,a=ne(e,t),i=r?.some(n=>a>n);return s?!i:i}else return!0},ne=(e,t)=>{let{filterToPropertyMapping:{property:r}}=t,s;return r!==K&&(s=e[r]),s},Es=(e,t,r)=>{let{filterToPropertyMapping:{isNestedPropertyArray:s,nestedProperty:a}}=t,i=[],n=Object.keys(e.legalOverrides||{}).length>0,o=t.filterToPropertyMapping.property===G.LegalHeroes,c=r.find(({filterToPropertyMapping:g})=>g.property===G.LegalFormats);if(n&&o&&!!c){let g=new Set;for(let{format:f,heroes:C}of e.legalOverrides||[])if(c.values.includes(f.toLowerCase()))for(let b of C)g.add(b);i=Array.from(g)}if(i.length===0)if(a){let g=new Set;for(let f of e.printings){let C=f[a];if(s){if(Array.isArray(C))for(let b of C)g.add(b)}else C&&typeof C=="string"&&g.add(C)}i=Array.from(g)}else{let g=ne(e,t);if(Array.isArray(g))for(let f of g)typeof f=="string"&&i.push(f)}return i},Ns=(e,t)=>{let{filterToPropertyMapping:{specialProperty:r}}=t,s;return r&&(s=e[r]),s},oe=({cardTypes:e},{types:t,subtypes:r})=>!e||e?.some(s=>t.map(a=>a.toLowerCase()).includes(s.toLowerCase())||r.map(a=>a.toLowerCase()).includes(s.toLowerCase()));var Bs=(e,t,r=[],s=[],a)=>{let{appliedFilters:i,attributes:n,keywords:o}=ie(e,t,{additionalHeroes:r,additionalSets:s,today:a});return{appliedFilters:i,attributes:n,keywords:o}};var Os=(e,t)=>{let r=new Set;for(let a of e)for(let i of a.createdExtras||[])r.add(i);let s=[];for(let a of t)r.has(a.cardIdentifier)&&s.push(a);return s};0&&(module.exports={FilterCategory,FilterKind,FilterProperty,MARKUP,NO_CARD_PROPERTY,PUNCTUATION,RARITY_VALUES_MAPPING,aliasesByFilterCategory,availableExclusions,availableModifiers,filterCard,filtersToCardPropertyMappings,getCardsByName,getCardsReferencedBy,getCardsReferencing,getCatalogueIndex,getCleanText,getEscapedForRegExp,getExcludedMetaFilters,getFilterCategory,getFilterMapping,getFilterTokenSpansForKey,getFilterValue,getIncompleteFilterToken,getIsExcludedToken,getIsValueInFilterVocabulary,getKeywordsAndAppliedFiltersFromText,getMetaFilterResolution,getMetaFilters,getNormalizedFilterValue,getNormalizedText,getParsedQuery,getQueryFilterToken,getQueryTokenSpans,getQuotedValue,getResolvedFilterKey,getSuggestedFilterKey,getTextWithoutMarkup,getTokensReferencedByCards,getUnquotedValue,getValuePartsFromFilterValue,getValuesFromFilterValue,multiWordShorthands,shorthands,singleWordShorthands});
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/metaFilters.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Class, Format, Hero, Talent } from "@flesh-and-blood/types";
|
|
2
2
|
import { PUNCTUATION } from "./constants.js";
|
|
3
|
+
import { getCleanText } from "./helpers.js";
|
|
3
4
|
import {
|
|
4
5
|
aliasesByFilterCategory,
|
|
5
6
|
availableExclusions,
|
|
@@ -47,37 +48,23 @@ const formatMappings = Object.values(Format).map((format) => {
|
|
|
47
48
|
const cleanFormat = format.toLowerCase().replaceAll(PUNCTUATION, "");
|
|
48
49
|
return withNicknames ? { ...withNicknames, format: cleanFormat } : { format: cleanFormat };
|
|
49
50
|
});
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
{
|
|
64
|
-
hero: Hero.GravyBones,
|
|
65
|
-
nicknames: ["gravy"]
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
hero: Hero.Iyslander,
|
|
69
|
-
nicknames: ["islander"]
|
|
51
|
+
const cleanHeroes = Object.values(Hero).map(getCleanText);
|
|
52
|
+
const getTextWithoutSpaces = (text) => text.replaceAll(" ", "");
|
|
53
|
+
const getMatchingHero = (value, heroes) => {
|
|
54
|
+
const valueWithoutSpaces = getTextWithoutSpaces(value);
|
|
55
|
+
let wholeNameMatch;
|
|
56
|
+
const heroesStartingWithValue = [];
|
|
57
|
+
for (const hero of heroes) {
|
|
58
|
+
const heroWithoutSpaces = getTextWithoutSpaces(hero);
|
|
59
|
+
if (heroWithoutSpaces === valueWithoutSpaces) {
|
|
60
|
+
wholeNameMatch = hero;
|
|
61
|
+
} else if (heroWithoutSpaces.startsWith(valueWithoutSpaces)) {
|
|
62
|
+
heroesStartingWithValue.push(hero);
|
|
63
|
+
}
|
|
70
64
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
).map((hero) => {
|
|
75
|
-
const withNicknames = nicknameHeroMappings.find(
|
|
76
|
-
({ hero: nicknameHero }) => nicknameHero === hero
|
|
77
|
-
);
|
|
78
|
-
const cleanHero = hero.toLowerCase().replaceAll(PUNCTUATION, "");
|
|
79
|
-
return withNicknames ? { ...withNicknames, hero: cleanHero } : { hero: cleanHero };
|
|
80
|
-
});
|
|
65
|
+
const hasOneHeroStartingWithValue = heroesStartingWithValue.length === 1;
|
|
66
|
+
return wholeNameMatch ?? (hasOneHeroStartingWithValue ? heroesStartingWithValue[0] : void 0);
|
|
67
|
+
};
|
|
81
68
|
const rankedRarity = [
|
|
82
69
|
"common",
|
|
83
70
|
"rare",
|
|
@@ -128,9 +115,10 @@ const getRarityFilter = (values, isExcluded) => {
|
|
|
128
115
|
};
|
|
129
116
|
};
|
|
130
117
|
const getLegalityFilters = (values, isExcluded, additionalHeroes, formatProperty) => {
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
118
|
+
const knownHeroes = /* @__PURE__ */ new Set([
|
|
119
|
+
...cleanHeroes,
|
|
120
|
+
...additionalHeroes.map(getCleanText)
|
|
121
|
+
]);
|
|
134
122
|
const appliedFilters = [];
|
|
135
123
|
const formats = [];
|
|
136
124
|
const heroes = [];
|
|
@@ -143,12 +131,9 @@ const getLegalityFilters = (values, isExcluded, additionalHeroes, formatProperty
|
|
|
143
131
|
if (matchingFormat) {
|
|
144
132
|
formats.push(matchingFormat.format);
|
|
145
133
|
} else {
|
|
146
|
-
const matchingHero =
|
|
147
|
-
const isAMatch = hero === value || !!nicknames && nicknames.includes(value);
|
|
148
|
-
return isAMatch;
|
|
149
|
-
}) || cleanAdditionalHeroes.find(({ hero }) => hero === value);
|
|
134
|
+
const matchingHero = getMatchingHero(value, knownHeroes);
|
|
150
135
|
if (matchingHero) {
|
|
151
|
-
heroes.push(matchingHero
|
|
136
|
+
heroes.push(matchingHero);
|
|
152
137
|
} else {
|
|
153
138
|
unresolvedValues.push(value);
|
|
154
139
|
}
|
package/dist/queryParse.js
CHANGED
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
Release,
|
|
3
3
|
setToSetIdentifierMappings
|
|
4
4
|
} from "@flesh-and-blood/types";
|
|
5
|
-
import { getAbbreviation } from "./abbreviations.js";
|
|
6
5
|
import { PUNCTUATION } from "./constants.js";
|
|
7
6
|
import {
|
|
8
7
|
aliasesByFilterCategory,
|
|
@@ -55,7 +54,7 @@ const setNameInSetFilterPattern = new RegExp(
|
|
|
55
54
|
)}):(?:[^\\s]*[,+])?"?)(${setNamesLongestFirst})(?="?(?:[,+]|\\s|$))`,
|
|
56
55
|
"g"
|
|
57
56
|
);
|
|
58
|
-
const
|
|
57
|
+
const getPreparedText = (text, index) => {
|
|
59
58
|
let preparedText = text.trim().toLowerCase();
|
|
60
59
|
for (const smartQuote of SMART_DOUBLE_QUOTES) {
|
|
61
60
|
preparedText = preparedText.replaceAll(smartQuote, '"');
|
|
@@ -85,12 +84,7 @@ const getPreparedQuery = (text, index) => {
|
|
|
85
84
|
preparedText = preparedText.replace(punctuatedName, override);
|
|
86
85
|
}
|
|
87
86
|
}
|
|
88
|
-
return
|
|
89
|
-
// A query that is nothing but a card's abbreviation names that card whole,
|
|
90
|
-
// so its own spaces and commas are not separators.
|
|
91
|
-
isWholeQueryAbbreviation: !!getAbbreviation(preparedText)?.card,
|
|
92
|
-
text: preparedText
|
|
93
|
-
};
|
|
87
|
+
return preparedText;
|
|
94
88
|
};
|
|
95
89
|
const getExpandedTokens = (token) => {
|
|
96
90
|
const matchingShorthand = singleWordShorthands.find(
|
|
@@ -102,13 +96,9 @@ const getExpandedTokens = (token) => {
|
|
|
102
96
|
tokens: isExpanded ? matchingShorthand.expanded : [token]
|
|
103
97
|
};
|
|
104
98
|
};
|
|
105
|
-
const getQueryTermSpans = ({
|
|
106
|
-
isWholeQueryAbbreviation,
|
|
107
|
-
text
|
|
108
|
-
}) => {
|
|
99
|
+
const getQueryTermSpans = (text) => {
|
|
109
100
|
const termSpans = [];
|
|
110
|
-
const
|
|
111
|
-
for (const { end, start, token } of tokenSpans) {
|
|
101
|
+
for (const { end, start, token } of getQueryTokenSpans(text)) {
|
|
112
102
|
const { isExpanded, tokens } = getExpandedTokens(token);
|
|
113
103
|
for (const expandedToken of tokens) {
|
|
114
104
|
termSpans.push({ end, isExpanded, start, token: expandedToken });
|
|
@@ -146,7 +136,7 @@ const getParsedQuery = (text, index, {
|
|
|
146
136
|
additionalSets = [],
|
|
147
137
|
today = getTodayAsReleaseDate()
|
|
148
138
|
} = {}) => {
|
|
149
|
-
const
|
|
139
|
+
const preparedText = getPreparedText(text, index);
|
|
150
140
|
const context = {
|
|
151
141
|
additionalHeroes,
|
|
152
142
|
additionalSets,
|
|
@@ -166,7 +156,7 @@ const getParsedQuery = (text, index, {
|
|
|
166
156
|
const keywords = [];
|
|
167
157
|
const nodes = [];
|
|
168
158
|
const unresolvedFilters = [];
|
|
169
|
-
for (const termSpan of getQueryTermSpans(
|
|
159
|
+
for (const termSpan of getQueryTermSpans(preparedText)) {
|
|
170
160
|
const filterToken = getQueryFilterToken(termSpan.token) || getIncompleteFilterToken(termSpan.token);
|
|
171
161
|
if (filterToken) {
|
|
172
162
|
const { isAndList, isExcluded, key, valueText } = filterToken;
|
|
@@ -225,13 +215,8 @@ const getParsedQuery = (text, index, {
|
|
|
225
215
|
const { end, start, token } = termSpan;
|
|
226
216
|
nodes.push({ end, isFilter: false, start, token });
|
|
227
217
|
const freeText = getUnquotedValue(termSpan.token);
|
|
228
|
-
const abbreviatedCard = getAbbreviation(freeText)?.card;
|
|
229
218
|
const excludedMetaFilters = getExcludedMetaFilters(freeText);
|
|
230
|
-
if (
|
|
231
|
-
keywords.push(
|
|
232
|
-
`"${abbreviatedCard.toLowerCase().replace(PUNCTUATION, "")}"`
|
|
233
|
-
);
|
|
234
|
-
} else if (excludedMetaFilters.length > 0) {
|
|
219
|
+
if (excludedMetaFilters.length > 0) {
|
|
235
220
|
appliedFilters.push(...excludedMetaFilters);
|
|
236
221
|
} else if (freeText) {
|
|
237
222
|
keywords.push(freeText.replace(PUNCTUATION, ""));
|
|
@@ -243,7 +228,7 @@ const getParsedQuery = (text, index, {
|
|
|
243
228
|
attributes,
|
|
244
229
|
keywords,
|
|
245
230
|
nodes,
|
|
246
|
-
text:
|
|
231
|
+
text: preparedText,
|
|
247
232
|
unresolvedFilters
|
|
248
233
|
};
|
|
249
234
|
};
|
package/dist/search.d.ts
CHANGED
|
@@ -8,7 +8,6 @@ export interface SearchCard extends DoubleSidedCard {
|
|
|
8
8
|
export interface SearchOptions {
|
|
9
9
|
additionalHeroes?: Hero[];
|
|
10
10
|
additionalSets?: Release[];
|
|
11
|
-
debug?: boolean;
|
|
12
11
|
/**
|
|
13
12
|
* The catalogue the parser resolves names and relations against. A pool
|
|
14
13
|
* searched out of a larger catalogue shares the catalogue's index, so a
|
|
@@ -19,7 +18,14 @@ export interface SearchOptions {
|
|
|
19
18
|
*/
|
|
20
19
|
index?: CatalogueIndex;
|
|
21
20
|
}
|
|
21
|
+
/** How the free text named cards other than by their names. */
|
|
22
|
+
export interface SearchAlias {
|
|
23
|
+
kind: "nickname" | "initials";
|
|
24
|
+
text: string;
|
|
25
|
+
}
|
|
22
26
|
export interface SearchResults {
|
|
27
|
+
/** Set when the free text was a nickname or the initials of the cards found. */
|
|
28
|
+
alias?: SearchAlias;
|
|
23
29
|
appliedFilters: AppliedFilter[];
|
|
24
30
|
keywords: string[];
|
|
25
31
|
attributes: QueryAttributes;
|
|
@@ -34,13 +40,17 @@ declare class Search {
|
|
|
34
40
|
private additionalHeroes;
|
|
35
41
|
private additionalSets;
|
|
36
42
|
private cards;
|
|
37
|
-
private debug;
|
|
38
43
|
private fuse;
|
|
39
44
|
private index;
|
|
45
|
+
private poolCardByCardIdentifier;
|
|
40
46
|
constructor(cards: DoubleSidedCard[], options?: SearchOptions);
|
|
41
|
-
constructor(cards: DoubleSidedCard[], additionalHeroes?: Hero[], additionalSets?: Release[]
|
|
47
|
+
constructor(cards: DoubleSidedCard[], additionalHeroes?: Hero[], additionalSets?: Release[]);
|
|
42
48
|
private getFuse;
|
|
43
|
-
|
|
49
|
+
/**
|
|
50
|
+
* The pool's own copies of index cards, dropping any the pool lacks, so a pool
|
|
51
|
+
* searched out of a larger catalogue returns its cards alone.
|
|
52
|
+
*/
|
|
53
|
+
private getPoolCards;
|
|
44
54
|
search: (text: string, includeMemes?: boolean) => SearchResults;
|
|
45
55
|
}
|
|
46
56
|
export default Search;
|
package/dist/search.js
CHANGED
|
@@ -11,7 +11,11 @@ import {
|
|
|
11
11
|
getParsedQuery
|
|
12
12
|
} from "./queryParse.js";
|
|
13
13
|
import { memes } from "./memes.js";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
getCleanText,
|
|
16
|
+
getNormalizedText,
|
|
17
|
+
getTextWithoutMarkup
|
|
18
|
+
} from "./helpers.js";
|
|
15
19
|
import { FilterProperty } from "./metaFilters.js";
|
|
16
20
|
import { getCatalogueIndex } from "./searchIndex.js";
|
|
17
21
|
const searchOptions = {
|
|
@@ -19,9 +23,10 @@ const searchOptions = {
|
|
|
19
23
|
const value = Fuse.config.getFn(obj, path);
|
|
20
24
|
let normalizedValue = value;
|
|
21
25
|
if (Array.isArray(value)) {
|
|
22
|
-
normalizedValue = value.map(
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
normalizedValue = value.map((item) => {
|
|
27
|
+
const text = typeof item === "string" ? item : item.v;
|
|
28
|
+
return getNormalizedText(text.replace(PUNCTUATION, ""));
|
|
29
|
+
});
|
|
25
30
|
} else if (value) {
|
|
26
31
|
const text = getNormalizedText(value).replace(PUNCTUATION, "");
|
|
27
32
|
normalizedValue = path.includes("functionalText") ? getTextWithoutMarkup(text) : text;
|
|
@@ -42,7 +47,7 @@ const searchOptions = {
|
|
|
42
47
|
useExtendedSearch: true
|
|
43
48
|
};
|
|
44
49
|
class Search {
|
|
45
|
-
constructor(cards, additionalHeroesOrOptions = [], additionalSets = []
|
|
50
|
+
constructor(cards, additionalHeroesOrOptions = [], additionalSets = []) {
|
|
46
51
|
// Scoring the corpus is the costly half of a search, so a catalogue that is
|
|
47
52
|
// only ever filtered never pays to index it.
|
|
48
53
|
this.getFuse = () => {
|
|
@@ -51,32 +56,78 @@ class Search {
|
|
|
51
56
|
}
|
|
52
57
|
return this.fuse;
|
|
53
58
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
/**
|
|
60
|
+
* The pool's own copies of index cards, dropping any the pool lacks, so a pool
|
|
61
|
+
* searched out of a larger catalogue returns its cards alone.
|
|
62
|
+
*/
|
|
63
|
+
this.getPoolCards = (indexCards) => {
|
|
64
|
+
if (!this.poolCardByCardIdentifier) {
|
|
65
|
+
this.poolCardByCardIdentifier = new Map(
|
|
66
|
+
this.cards.map((card) => [card.cardIdentifier, card])
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const poolCards = [];
|
|
70
|
+
for (const { cardIdentifier } of indexCards) {
|
|
71
|
+
const poolCard = this.poolCardByCardIdentifier.get(cardIdentifier);
|
|
72
|
+
if (poolCard) {
|
|
73
|
+
poolCards.push(poolCard);
|
|
74
|
+
}
|
|
57
75
|
}
|
|
76
|
+
return poolCards;
|
|
58
77
|
};
|
|
59
78
|
this.search = (text, includeMemes) => {
|
|
60
79
|
let results;
|
|
80
|
+
let alias;
|
|
61
81
|
const { appliedFilters, attributes, keywords, unresolvedFilters } = getParsedQuery(text, this.index, {
|
|
62
82
|
additionalHeroes: this.additionalHeroes,
|
|
63
83
|
additionalSets: this.additionalSets
|
|
64
84
|
});
|
|
65
85
|
const keyword = keywords.join(" ");
|
|
66
86
|
const matchingMemes = includeMemes ? memes.filter((meme) => meme.keyword === keyword) : [];
|
|
87
|
+
const getFilteredCards = (cardsToFilter) => appliedFilters.length > 0 ? cardsToFilter.filter(
|
|
88
|
+
(card) => card && filterCard(card, appliedFilters)
|
|
89
|
+
) : cardsToFilter;
|
|
67
90
|
if (matchingMemes.length > 0) {
|
|
68
|
-
results = matchingMemes.map(({ card }) => card);
|
|
91
|
+
results = getFilteredCards(matchingMemes.map(({ card }) => card));
|
|
69
92
|
} else if (keywords.length) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
(
|
|
93
|
+
const freeText = getCleanText(keyword);
|
|
94
|
+
const nicknamedCards = this.getPoolCards(
|
|
95
|
+
this.index.getCardsByNickname(freeText)
|
|
96
|
+
);
|
|
97
|
+
const namedCardByCardIdentifier = /* @__PURE__ */ new Map();
|
|
98
|
+
for (const card of [
|
|
99
|
+
...this.getPoolCards(this.index.getCardsByExactName(freeText)),
|
|
100
|
+
...nicknamedCards
|
|
101
|
+
]) {
|
|
102
|
+
namedCardByCardIdentifier.set(card.cardIdentifier, card);
|
|
103
|
+
}
|
|
104
|
+
const textMatches = this.getFuse().search(keyword).map((result) => result.item).filter(
|
|
105
|
+
({ cardIdentifier }) => !namedCardByCardIdentifier.has(cardIdentifier)
|
|
77
106
|
);
|
|
107
|
+
results = getFilteredCards([
|
|
108
|
+
...namedCardByCardIdentifier.values(),
|
|
109
|
+
...textMatches
|
|
110
|
+
]);
|
|
111
|
+
const hasNicknamedResult = results.some(
|
|
112
|
+
(card) => nicknamedCards.includes(card)
|
|
113
|
+
);
|
|
114
|
+
if (hasNicknamedResult) {
|
|
115
|
+
alias = { kind: "nickname", text: freeText };
|
|
116
|
+
}
|
|
117
|
+
const canFallBackToInitials = results.length === 0 && keywords.length === 1;
|
|
118
|
+
if (canFallBackToInitials) {
|
|
119
|
+
results = getFilteredCards(
|
|
120
|
+
this.getPoolCards(this.index.getCardsByInitials(freeText))
|
|
121
|
+
);
|
|
122
|
+
if (results.length > 0) {
|
|
123
|
+
alias = { kind: "initials", text: freeText };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
results = getFilteredCards([...this.cards]);
|
|
78
128
|
}
|
|
79
|
-
|
|
129
|
+
const isRankedByText = keywords.length > 0 && alias?.kind !== "initials";
|
|
130
|
+
if (!isRankedByText) {
|
|
80
131
|
let setIdentifierToSortBy = "";
|
|
81
132
|
const shouldSortByRelease = attributes.releases.length === 1;
|
|
82
133
|
if (shouldSortByRelease) {
|
|
@@ -105,18 +156,6 @@ class Search {
|
|
|
105
156
|
(c1, c2) => c1.name === c2.name ? `${c1.pitch}`.localeCompare(`${c2.pitch}`) : c1.name.localeCompare(c2.name)
|
|
106
157
|
);
|
|
107
158
|
}
|
|
108
|
-
} else {
|
|
109
|
-
const nameMatches = [];
|
|
110
|
-
const nonMatches = [];
|
|
111
|
-
const potentialCardName = keywords.map((keyword2) => keyword2.toLowerCase().replace(PUNCTUATION, "")).join(" ");
|
|
112
|
-
for (const card of results) {
|
|
113
|
-
if (card.name.toLowerCase().replace(PUNCTUATION, "") === potentialCardName) {
|
|
114
|
-
nameMatches.push(card);
|
|
115
|
-
} else {
|
|
116
|
-
nonMatches.push(card);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
results = [...nameMatches, ...nonMatches];
|
|
120
159
|
}
|
|
121
160
|
let searchResultsWithMatchingPrinting = [];
|
|
122
161
|
const {
|
|
@@ -159,6 +198,7 @@ class Search {
|
|
|
159
198
|
}
|
|
160
199
|
const searchResults = searchResultsWithMatchingPrinting.length > 0 ? searchResultsWithMatchingPrinting : results;
|
|
161
200
|
return {
|
|
201
|
+
alias,
|
|
162
202
|
appliedFilters,
|
|
163
203
|
attributes,
|
|
164
204
|
keywords,
|
|
@@ -166,11 +206,10 @@ class Search {
|
|
|
166
206
|
unresolvedFilters
|
|
167
207
|
};
|
|
168
208
|
};
|
|
169
|
-
const options = Array.isArray(additionalHeroesOrOptions) ? { additionalHeroes: additionalHeroesOrOptions, additionalSets
|
|
209
|
+
const options = Array.isArray(additionalHeroesOrOptions) ? { additionalHeroes: additionalHeroesOrOptions, additionalSets } : additionalHeroesOrOptions;
|
|
170
210
|
this.additionalHeroes = options.additionalHeroes || [];
|
|
171
211
|
this.additionalSets = options.additionalSets || [];
|
|
172
212
|
this.cards = [...cards];
|
|
173
|
-
this.debug = options.debug || false;
|
|
174
213
|
this.index = options.index || getCatalogueIndex(cards);
|
|
175
214
|
}
|
|
176
215
|
}
|
package/dist/searchIndex.d.ts
CHANGED
|
@@ -26,6 +26,13 @@ export interface CatalogueIndex<CardType extends DoubleSidedCard = DoubleSidedCa
|
|
|
26
26
|
* a fragment of a name the corpus carries finds nothing.
|
|
27
27
|
*/
|
|
28
28
|
getCardsByExactName: (name: string) => readonly CardType[];
|
|
29
|
+
/** Every card carrying the nickname, matched whole, hyphens ignored. */
|
|
30
|
+
getCardsByNickname: (nickname: string) => readonly CardType[];
|
|
31
|
+
/**
|
|
32
|
+
* Every card whose name has the initials, in corpus order, counting a
|
|
33
|
+
* hyphenated word both as one word and as the words the hyphens join.
|
|
34
|
+
*/
|
|
35
|
+
getCardsByInitials: (initials: string) => readonly CardType[];
|
|
29
36
|
/**
|
|
30
37
|
* Every artist the corpus credits, each once, ordered by the `en` locale
|
|
31
38
|
* ignoring case and diacritics so a browser and a server agree on the list.
|
package/dist/searchIndex.js
CHANGED
|
@@ -3,7 +3,37 @@ import {
|
|
|
3
3
|
getCardRole,
|
|
4
4
|
Type
|
|
5
5
|
} from "@flesh-and-blood/types";
|
|
6
|
-
import { getCleanText } from "./helpers.js";
|
|
6
|
+
import { getCleanText, getNormalizedText } from "./helpers.js";
|
|
7
|
+
const MINIMUM_INITIALS_LENGTH = 3;
|
|
8
|
+
const getInitialsOfName = (name) => {
|
|
9
|
+
const letters = getNormalizedText(name.toLowerCase()).replace(
|
|
10
|
+
/[^a-z\s-]/g,
|
|
11
|
+
""
|
|
12
|
+
);
|
|
13
|
+
const initialsOfName = /* @__PURE__ */ new Set();
|
|
14
|
+
for (const wordBreak of [/[\s-]+/, /\s+/]) {
|
|
15
|
+
let initials = "";
|
|
16
|
+
for (const word of letters.split(wordBreak)) {
|
|
17
|
+
const wordLetters = word.replaceAll("-", "");
|
|
18
|
+
if (wordLetters) {
|
|
19
|
+
initials += wordLetters[0];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (initials.length >= MINIMUM_INITIALS_LENGTH) {
|
|
23
|
+
initialsOfName.add(initials);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return [...initialsOfName];
|
|
27
|
+
};
|
|
28
|
+
const getNicknameKey = (nickname) => getCleanText(nickname).replaceAll("-", "");
|
|
29
|
+
const addToCardList = (cardsByKey, key, card) => {
|
|
30
|
+
const cardsForKey = cardsByKey.get(key);
|
|
31
|
+
if (cardsForKey) {
|
|
32
|
+
cardsForKey.push(card);
|
|
33
|
+
} else {
|
|
34
|
+
cardsByKey.set(key, [card]);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
7
37
|
const catalogueIndexByCards = /* @__PURE__ */ new WeakMap();
|
|
8
38
|
const noCards = Object.freeze([]);
|
|
9
39
|
const strayCorpusPosition = Number.MAX_SAFE_INTEGER;
|
|
@@ -44,6 +74,8 @@ const getNewCatalogueIndex = (cards) => {
|
|
|
44
74
|
let creatingCardsByCardIdentifier;
|
|
45
75
|
let cardsByRole;
|
|
46
76
|
let artists;
|
|
77
|
+
let cardsByNicknameKey;
|
|
78
|
+
let cardsByInitials;
|
|
47
79
|
const getCardLookups = () => {
|
|
48
80
|
if (!cardLookups) {
|
|
49
81
|
const cardByCardIdentifier = /* @__PURE__ */ new Map();
|
|
@@ -132,6 +164,28 @@ const getNewCatalogueIndex = (cards) => {
|
|
|
132
164
|
const { pitchCycleByCleanedName } = getCardLookups();
|
|
133
165
|
return pitchCycleByCleanedName.get(getCleanText(name)) ?? noCards;
|
|
134
166
|
};
|
|
167
|
+
const getCardsByNickname = (nickname) => {
|
|
168
|
+
if (!cardsByNicknameKey) {
|
|
169
|
+
cardsByNicknameKey = /* @__PURE__ */ new Map();
|
|
170
|
+
for (const card of cards) {
|
|
171
|
+
for (const cardNickname of card.nicknames ?? []) {
|
|
172
|
+
addToCardList(cardsByNicknameKey, getNicknameKey(cardNickname), card);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return cardsByNicknameKey.get(getNicknameKey(nickname)) ?? noCards;
|
|
177
|
+
};
|
|
178
|
+
const getCardsByInitials = (initials) => {
|
|
179
|
+
if (!cardsByInitials) {
|
|
180
|
+
cardsByInitials = /* @__PURE__ */ new Map();
|
|
181
|
+
for (const card of cards) {
|
|
182
|
+
for (const initialsOfName of getInitialsOfName(card.name)) {
|
|
183
|
+
addToCardList(cardsByInitials, initialsOfName, card);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return cardsByInitials.get(initials) ?? noCards;
|
|
188
|
+
};
|
|
135
189
|
const getArtists = () => {
|
|
136
190
|
if (!artists) {
|
|
137
191
|
const creditedArtists = /* @__PURE__ */ new Set();
|
|
@@ -202,6 +256,8 @@ const getNewCatalogueIndex = (cards) => {
|
|
|
202
256
|
getPitchCycle,
|
|
203
257
|
getCardsByName: getCardsByName2,
|
|
204
258
|
getCardsByExactName,
|
|
259
|
+
getCardsByNickname,
|
|
260
|
+
getCardsByInitials,
|
|
205
261
|
getArtists,
|
|
206
262
|
getOppositeSide,
|
|
207
263
|
getReferences,
|
package/dist/shorthands.d.ts
CHANGED
|
@@ -15,7 +15,6 @@ export declare const shorthands: {
|
|
|
15
15
|
shorthands: string[];
|
|
16
16
|
}[];
|
|
17
17
|
export declare const multiWordShorthands: {
|
|
18
|
-
shorthands: string[];
|
|
19
18
|
description: string;
|
|
20
19
|
expanded: string[];
|
|
21
20
|
filters: {
|
|
@@ -28,9 +27,9 @@ export declare const multiWordShorthands: {
|
|
|
28
27
|
types?: Type[];
|
|
29
28
|
};
|
|
30
29
|
isCardProperty: boolean;
|
|
30
|
+
shorthands: string[];
|
|
31
31
|
}[];
|
|
32
32
|
export declare const singleWordShorthands: {
|
|
33
|
-
shorthands: string[];
|
|
34
33
|
description: string;
|
|
35
34
|
expanded: string[];
|
|
36
35
|
filters: {
|
|
@@ -43,4 +42,5 @@ export declare const singleWordShorthands: {
|
|
|
43
42
|
types?: Type[];
|
|
44
43
|
};
|
|
45
44
|
isCardProperty: boolean;
|
|
45
|
+
shorthands: string[];
|
|
46
46
|
}[];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flesh-and-blood/search",
|
|
3
3
|
"description": "TypeScript search engine for Flesh and Blood cards",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.3.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"main": "dist/index.cjs",
|
|
@@ -31,30 +31,28 @@
|
|
|
31
31
|
"build": "npm run build:esm && npm run build:cjs",
|
|
32
32
|
"build:esm": "esbuild src/*.ts --outdir=dist --format=esm --platform=neutral --target=es2020",
|
|
33
33
|
"build:cjs": "esbuild src/index.ts --outfile=dist/index.cjs --bundle --minify --format=cjs --platform=node --target=es2020 --external:@flesh-and-blood/types --external:fuse.js",
|
|
34
|
-
"postbuild": "tsc --declaration
|
|
35
|
-
"test": "
|
|
36
|
-
"test:specific": "
|
|
34
|
+
"postbuild": "tsc --declaration",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:specific": "vitest run -t 'Matching printing from treatment'",
|
|
37
|
+
"update:snapshots": "vitest run -u",
|
|
37
38
|
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
38
|
-
"full": "npm
|
|
39
|
+
"full": "npm run build && npm test",
|
|
39
40
|
"prepublish": "npm run full",
|
|
40
41
|
"prepublishOnly": "npm run typecheck"
|
|
41
42
|
},
|
|
42
43
|
"dependencies": {
|
|
43
|
-
"fuse.js": "^
|
|
44
|
+
"fuse.js": "^7.5.0"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|
|
46
47
|
"@flesh-and-blood/types": "^5.0.0"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
|
-
"@flesh-and-blood/cards": "^5.
|
|
50
|
-
"@flesh-and-blood/types": "^5.
|
|
51
|
-
"@types/
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"jest": "^29.7.0",
|
|
56
|
-
"ts-node": "^10.9.2",
|
|
57
|
-
"typescript": "^5.7.3"
|
|
50
|
+
"@flesh-and-blood/cards": "^5.3.1",
|
|
51
|
+
"@flesh-and-blood/types": "^5.3.0",
|
|
52
|
+
"@types/node": "^26.6.3",
|
|
53
|
+
"esbuild": "^0.28.2",
|
|
54
|
+
"typescript": "^7.0.2",
|
|
55
|
+
"vitest": "^5.0.3"
|
|
58
56
|
},
|
|
59
57
|
"files": [
|
|
60
58
|
"/dist"
|
|
@@ -77,5 +75,5 @@
|
|
|
77
75
|
"FAB",
|
|
78
76
|
"FABTCG"
|
|
79
77
|
],
|
|
80
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "43349d8a88ac6e277f32c20b5cf36f373efb45e5"
|
|
81
79
|
}
|
package/dist/abbreviations.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Card } from "@flesh-and-blood/types";
|
|
2
|
-
export interface Abbreviation {
|
|
3
|
-
abbreviations: string[];
|
|
4
|
-
card: string;
|
|
5
|
-
isHidden?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export declare const getAbbreviation: (abbreviation: string) => Abbreviation | undefined;
|
|
8
|
-
export declare const getAbbreviationByCard: (c: Card) => Abbreviation | undefined;
|
|
9
|
-
export declare const abbreviations: Abbreviation[];
|
package/dist/abbreviations.js
DELETED
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
const getAbbreviation = (abbreviation) => {
|
|
2
|
-
return abbreviations.find(
|
|
3
|
-
({ abbreviations: abbreviations2 }) => abbreviations2.find((a) => a.toLowerCase() === abbreviation)
|
|
4
|
-
);
|
|
5
|
-
};
|
|
6
|
-
const getAbbreviationByCard = (c) => {
|
|
7
|
-
return abbreviations.find(
|
|
8
|
-
({ card }) => card.toLowerCase() === c.name.toLowerCase()
|
|
9
|
-
);
|
|
10
|
-
};
|
|
11
|
-
const abbreviations = [
|
|
12
|
-
{
|
|
13
|
-
abbreviations: ["10k"],
|
|
14
|
-
card: "10,000 Year Reunion"
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
abbreviations: ["Pajamas", "PJs"],
|
|
18
|
-
card: "Alluvion Constellas"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
abbreviations: [
|
|
22
|
-
"Slippy",
|
|
23
|
-
"Arakni Slipped Through the Cracks",
|
|
24
|
-
"Arakni, Slipped Through the Cracks"
|
|
25
|
-
],
|
|
26
|
-
card: "Arakni, 5L!p3d 7hRu 7h3 cR4X"
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
abbreviations: ["Dullcap"],
|
|
30
|
-
card: "Arcanite Skullcap"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
abbreviations: ["ALS"],
|
|
34
|
-
card: "Arc Light Sentinel"
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
abbreviations: ["AoW"],
|
|
38
|
-
card: "Art of War"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
abbreviations: ["BBD"],
|
|
42
|
-
card: "Barraging Beatdown"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
abbreviations: ["BBS"],
|
|
46
|
-
card: "Big Blue Sky"
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
abbreviations: ["Starvo"],
|
|
50
|
-
card: "Bravo, Star of the Show"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
abbreviations: ["BEB"],
|
|
54
|
-
card: "Bull's Eye Bracers"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
abbreviations: ["BLW"],
|
|
58
|
-
card: "Be Like Water"
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
abbreviations: ["BoJ"],
|
|
62
|
-
card: "Balance of Justice"
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
abbreviations: ["BOHH"],
|
|
66
|
-
card: "Blood on Her Hands"
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
abbreviations: ["BRB"],
|
|
70
|
-
card: "Bloodrush Bellow"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
abbreviations: ["Breezies"],
|
|
74
|
-
card: "Breeze Rider Boots"
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
abbreviations: ["BTA"],
|
|
78
|
-
card: "Burn Them All"
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
abbreviations: ["CStrike", "C-Strike", "C Strike"],
|
|
82
|
-
card: "Celestial Cataclysm"
|
|
83
|
-
},
|
|
84
|
-
{ abbreviations: ["CBelly"], card: "Cerebellum Processor" },
|
|
85
|
-
{
|
|
86
|
-
abbreviations: ["CLF"],
|
|
87
|
-
card: "Channel Lake Frigid"
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
abbreviations: ["CLV"],
|
|
91
|
-
card: "Channel Lightning Valley"
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
abbreviations: ["CMH"],
|
|
95
|
-
card: "Channel Mount Heroic"
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
abbreviations: ["CMI"],
|
|
99
|
-
card: "Channel Mount Isen"
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
abbreviations: ["CMT"],
|
|
103
|
-
card: "Channel the Millennium Tree"
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
abbreviations: ["CnC", "C&C"],
|
|
107
|
-
card: "Command and Conquer"
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
abbreviations: ["Sea and Sea"],
|
|
111
|
-
card: "Conqueror of the High Seas"
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
abbreviations: ["CYB"],
|
|
115
|
-
card: "Count Your Blessings"
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
abbreviations: ["Cat", "Kitty"],
|
|
119
|
-
card: "Crouching Tiger"
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
abbreviations: ["CoD"],
|
|
123
|
-
card: "Crown of Dominion"
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
abbreviations: ["CoP"],
|
|
127
|
-
card: "Crown of Providence"
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
abbreviations: ["CtW"],
|
|
131
|
-
card: "Crush the Weak"
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
abbreviations: ["DD"],
|
|
135
|
-
card: "Death Dealer"
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
abbreviations: ["DnD"],
|
|
139
|
-
card: "Devotion Never Dies"
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
abbreviations: ["DIO"],
|
|
143
|
-
card: "Dash I/O"
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
abbreviations: ["EBTT"],
|
|
147
|
-
card: "Even Bigger Than That!"
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
abbreviations: ["NewNigma"],
|
|
151
|
-
card: "Enigma, New Moon"
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
abbreviations: ["EPot", "E Pot"],
|
|
155
|
-
card: "Energy Potion"
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
abbreviations: ["EStrike", "E-Strike", "E Strike"],
|
|
159
|
-
card: "Enlightened Strike"
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
abbreviations: ["FFS"],
|
|
163
|
-
card: "Fyendal's Fighting Spirit"
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
abbreviations: ["FoN"],
|
|
167
|
-
card: "Force of Nature"
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
abbreviations: ["Frosty", "\u{1F976}", "\u{1F9CA}", "\u2744\uFE0F"],
|
|
171
|
-
card: "Frostbite"
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
abbreviations: ["Yum yum"],
|
|
175
|
-
card: "Fruits of the Forest"
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
abbreviations: ["GnT"],
|
|
179
|
-
card: "Give and Take"
|
|
180
|
-
},
|
|
181
|
-
{ abbreviations: ["Habibi"], card: "Hanabi Blaster" },
|
|
182
|
-
{
|
|
183
|
-
abbreviations: ["HMH"],
|
|
184
|
-
card: "Hope Merchant's Hood"
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
abbreviations: ["HoI"],
|
|
188
|
-
card: "Heart of Ice"
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
abbreviations: ["Pumpkin"],
|
|
192
|
-
card: "Jack-o'-lantern"
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
abbreviations: ["RKO", "Cheato"],
|
|
196
|
-
card: "Kayo, Underhanded Cheat"
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
abbreviations: ["KKBB"],
|
|
200
|
-
card: "Knick Knack Bric-a-brac"
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
abbreviations: ["BStrike"],
|
|
204
|
-
card: "Levels of Enlightenment"
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
abbreviations: ["LAG", "Twominaris"],
|
|
208
|
-
card: "Luminaris, Angel's Glow"
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
abbreviations: ["LCF", "Newminaris"],
|
|
212
|
-
card: "Luminaris, Celestial Fury"
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
abbreviations: ["LDE"],
|
|
216
|
-
card: "Last Ditch Effort"
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
abbreviations: ["LtC"],
|
|
220
|
-
card: "Lead the Charge"
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
abbreviations: ["LNW"],
|
|
224
|
-
card: "Leave No Witnesses"
|
|
225
|
-
},
|
|
226
|
-
{
|
|
227
|
-
abbreviations: ["LFaL", "L4aL"],
|
|
228
|
-
card: "Life for a Life"
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
abbreviations: ["LiT"],
|
|
232
|
-
card: "Lost in Thought"
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
abbreviations: ["MMB"],
|
|
236
|
-
card: "Mage Master Boots"
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
abbreviations: ["MaxV"],
|
|
240
|
-
card: "Maximum Velocity"
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
abbreviations: ["MoM"],
|
|
244
|
-
card: "Mask of Momentum"
|
|
245
|
-
},
|
|
246
|
-
{
|
|
247
|
-
abbreviations: ["MoPL"],
|
|
248
|
-
card: "Mask of the Pouncing Lynx"
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
abbreviations: ["MnG"],
|
|
252
|
-
card: "Meat and Greet"
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
abbreviations: ["Cake", "\u{1F382}"],
|
|
256
|
-
card: "Ninth Blade of the Blood Oath"
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
abbreviations: ["PoM"],
|
|
260
|
-
card: "Peace of Mind"
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
abbreviations: ["P-Bone"],
|
|
264
|
-
card: "Performance Bonus"
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
abbreviations: ["PF", "\u{1F525}"],
|
|
268
|
-
card: "Phoenix Flame"
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
abbreviations: ["PtW"],
|
|
272
|
-
card: "Poison the Well"
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
abbreviations: ["Thanos", "Infinity Gauntlet"],
|
|
276
|
-
card: "Polarity Reversal Script"
|
|
277
|
-
},
|
|
278
|
-
{
|
|
279
|
-
abbreviations: ["DPot", "D Pot"],
|
|
280
|
-
card: "Potion of D\xE9j\xE0 Vu"
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
abbreviations: ["Ponder Run"],
|
|
284
|
-
card: "Premeditate"
|
|
285
|
-
},
|
|
286
|
-
{
|
|
287
|
-
abbreviations: ["Qi Unbound"],
|
|
288
|
-
card: "Qi Unleashed"
|
|
289
|
-
},
|
|
290
|
-
{
|
|
291
|
-
abbreviations: ["RitL"],
|
|
292
|
-
card: "Red in the Ledger"
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
abbreviations: ["Cats", "Ghost cat", "Ghost cats"],
|
|
296
|
-
card: "Restless Coalescence"
|
|
297
|
-
},
|
|
298
|
-
{
|
|
299
|
-
abbreviations: ["Eugene"],
|
|
300
|
-
card: "Rhinar, Reckless Rampage",
|
|
301
|
-
isHidden: true
|
|
302
|
-
},
|
|
303
|
-
{
|
|
304
|
-
abbreviations: ["SSGB"],
|
|
305
|
-
card: "Sandscour Greatbow"
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
abbreviations: ["SSP"],
|
|
309
|
-
card: "Sand Sketched Plan"
|
|
310
|
-
},
|
|
311
|
-
{
|
|
312
|
-
abbreviations: ["SFaS", "S4aS"],
|
|
313
|
-
card: "Scar for a Scar"
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
abbreviations: ["Tyler"],
|
|
317
|
-
card: "Scurv, Stowaway",
|
|
318
|
-
isHidden: true
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
abbreviations: ["SWOMB"],
|
|
322
|
-
card: "Shifting Winds of the Mystic Beast"
|
|
323
|
-
},
|
|
324
|
-
{
|
|
325
|
-
abbreviations: ["Snaps"],
|
|
326
|
-
card: "Snapdragon Scalers"
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
abbreviations: ["SWK"],
|
|
330
|
-
card: "Spinning Wheel Kick"
|
|
331
|
-
},
|
|
332
|
-
{
|
|
333
|
-
abbreviations: ["SFTL"],
|
|
334
|
-
card: "Swing Fist, Think Later"
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
abbreviations: ["TTT"],
|
|
338
|
-
card: "Take the Tempo"
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
abbreviations: ["Ultron"],
|
|
342
|
-
card: "Teklovossen, the Mechropotent"
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
abbreviations: ["ToS"],
|
|
346
|
-
card: "Test of Strength"
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
abbreviations: ["TAYG"],
|
|
350
|
-
card: "That All You Got?"
|
|
351
|
-
},
|
|
352
|
-
{
|
|
353
|
-
abbreviations: ["TROM"],
|
|
354
|
-
card: "This Round's on Me"
|
|
355
|
-
},
|
|
356
|
-
{
|
|
357
|
-
abbreviations: ["3oak"],
|
|
358
|
-
card: "Three of a Kind"
|
|
359
|
-
},
|
|
360
|
-
{
|
|
361
|
-
abbreviations: ["Pox Malone", "Post Malone"],
|
|
362
|
-
card: "Virulent Touch"
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
abbreviations: ["Cast Homes"],
|
|
366
|
-
card: "Visit Goldmane Estate"
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
abbreviations: ["Frosty Hammer"],
|
|
370
|
-
card: "Winter's Wail"
|
|
371
|
-
},
|
|
372
|
-
{
|
|
373
|
-
abbreviations: ["Wreckless Wing"],
|
|
374
|
-
card: "War Cry of Bellona"
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
abbreviations: ["ZTS"],
|
|
378
|
-
card: "Zero to Sixty"
|
|
379
|
-
}
|
|
380
|
-
];
|
|
381
|
-
export {
|
|
382
|
-
abbreviations,
|
|
383
|
-
getAbbreviation,
|
|
384
|
-
getAbbreviationByCard
|
|
385
|
-
};
|