123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158 |
- /*
- THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
- if you want to view the source visit the plugins github repository
- */
- 'use strict';
- var obsidian = require('obsidian');
- var view = require('@codemirror/view');
- var state = require('@codemirror/state');
- var language = require('@codemirror/language');
- /******************************************************************************
- Copyright (c) Microsoft Corporation.
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted.
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
- ***************************************************************************** */
- /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
- function __awaiter(thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- }
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
- var e = new Error(message);
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
- };
- const iconPacks$1 = {
- faBrands: {
- name: 'font-awesome-brands',
- displayName: 'FontAwesome Brands',
- path: 'fontawesome-free-6.5.1-web/svgs/brands/',
- downloadLink: 'https://github.com/FortAwesome/Font-Awesome/releases/download/6.5.1/fontawesome-free-6.5.1-web.zip',
- },
- faRegular: {
- name: 'font-awesome-regular',
- displayName: 'FontAwesome Regular',
- path: 'fontawesome-free-6.5.1-web/svgs/regular/',
- downloadLink: 'https://github.com/FortAwesome/Font-Awesome/releases/download/6.5.1/fontawesome-free-6.5.1-web.zip',
- },
- faSolid: {
- name: 'font-awesome-solid',
- displayName: 'FontAwesome Solid',
- path: 'fontawesome-free-6.5.1-web/svgs/solid/',
- downloadLink: 'https://github.com/FortAwesome/Font-Awesome/releases/download/6.5.1/fontawesome-free-6.5.1-web.zip',
- },
- remixIcons: {
- name: 'remix-icons',
- displayName: 'Remix Icons',
- path: '',
- downloadLink: 'https://github.com/Remix-Design/RemixIcon/releases/download/v4.2.0/RemixIcon_Svg_v4.2.0.zip',
- },
- iconBrew: {
- name: 'icon-brew',
- displayName: 'Icon Brew',
- path: '',
- downloadLink: 'https://github.com/FlorianWoelki/obsidian-iconize/raw/main/iconPacks/icon-brew.zip',
- },
- /** @source https://simpleicons.org/ */
- simpleIcons: {
- name: 'simple-icons',
- displayName: 'Simple Icons',
- path: 'simple-icons-11.10.0/icons/',
- downloadLink: 'https://github.com/simple-icons/simple-icons/archive/refs/tags/11.10.0.zip',
- },
- lucide: {
- name: 'lucide-icons',
- displayName: 'Lucide',
- path: '',
- downloadLink: 'https://github.com/lucide-icons/lucide/releases/download/0.363.0/lucide-icons-0.363.0.zip',
- },
- tablerIcons: {
- name: 'tabler-icons',
- displayName: 'Tabler Icons',
- path: 'svg',
- downloadLink: 'https://github.com/tabler/tabler-icons/releases/download/v3.1.0/tabler-icons-3.1.0.zip',
- },
- /** @source https://boxicons.com/ */
- boxicons: {
- name: 'boxicons',
- displayName: 'Boxicons',
- path: 'svg',
- downloadLink: 'https://github.com/FlorianWoelki/obsidian-iconize/raw/main/iconPacks/boxicons.zip',
- },
- /** @source http://nagoshiashumari.github.io/Rpg-Awesome/ */
- rpgAwesome: {
- name: 'rpg-awesome',
- displayName: 'RPG Awesome',
- path: '',
- downloadLink: 'https://github.com/FlorianWoelki/obsidian-iconize/raw/main/iconPacks/rpg-awesome.zip',
- },
- /** @source https://coolicons.cool/ */
- coolicons: {
- name: 'coolicons',
- displayName: 'Coolicons',
- path: 'cooliocns SVG',
- downloadLink: 'https://github.com/krystonschwarze/coolicons/releases/download/v4.1/coolicons.v4.1.zip',
- },
- /** @source https://feathericons.com/ */
- feathericons: {
- name: 'feather-icons',
- displayName: 'Feather Icons',
- path: 'feather-4.29.1/icons/',
- downloadLink: 'https://github.com/feathericons/feather/archive/refs/tags/v4.29.1.zip',
- },
- /** @source https://github.com/primer/octicons */
- octicons: {
- name: 'octicons',
- displayName: 'Octicons',
- path: 'octicons-19.8.0/icons/',
- downloadLink: 'https://github.com/primer/octicons/archive/refs/tags/v19.8.0.zip',
- },
- };
- /**
- * Returns a possible path to the icon pack.
- * @param name String of the icon pack name.
- * @returns String of the path to the icon pack or undefined if the icon pack does not
- * exist.
- */
- const getExtraPath = (iconPackName) => {
- var _a;
- const path = (_a = Object.values(iconPacks$1).find((iconPack) => iconPack.name === iconPackName)) === null || _a === void 0 ? void 0 : _a.path;
- return (path === null || path === void 0 ? void 0 : path.length) === 0 ? undefined : path;
- };
- // This library file does not include any other dependency and is a standalone file that
- // only include utility functions for manipulating or extracting svg information.
- /**
- * Extracts an SVG string from a given input string and returns a cleaned up and
- * formatted SVG string.
- * @param svgString SVG string to extract from.
- * @returns Cleaned up and formatted SVG string.
- */
- const extract = (svgString) => {
- var _a, _b;
- // Removes unnecessary spaces and newlines.
- svgString = svgString.replace(/(\r\n|\n|\r)/gm, '');
- svgString = svgString.replace(/>\s+</gm, '><');
- // Create a parser for better parsing of HTML.
- const parser = new DOMParser();
- const svg = parser
- .parseFromString(svgString, 'text/html')
- .querySelector('svg');
- // Removes `width` and `height` from the `style` attribute.
- if (svg.hasAttribute('style')) {
- svg.style.width = '';
- svg.style.height = '';
- }
- // Add `viewbox`, if it is not already a attribute.
- if (svg.viewBox.baseVal.width === 0 && svg.viewBox.baseVal.height === 0) {
- const width = (_a = svg.width.baseVal.value) !== null && _a !== void 0 ? _a : 16;
- const height = (_b = svg.height.baseVal.value) !== null && _b !== void 0 ? _b : 16;
- svg.viewBox.baseVal.width = width;
- svg.viewBox.baseVal.height = height;
- }
- if (!svg.hasAttribute('fill')) {
- svg.setAttribute('fill', 'currentColor');
- }
- const possibleTitle = svg.querySelector('title');
- if (possibleTitle) {
- possibleTitle.remove();
- }
- svg.setAttribute('width', '16px');
- svg.setAttribute('height', '16px');
- return svg.outerHTML;
- };
- /**
- * Sets the font size of an SVG string by modifying its width and/or height attributes.
- * The font size will be always set in pixels.
- * @param svgString SVG string to modify.
- * @param fontSize Font size in pixels to set.
- * @returns Modified SVG string.
- */
- const setFontSize = (svgString, fontSize) => {
- const widthRe = new RegExp(/width="[\d.]+(px)?"/);
- const heightRe = new RegExp(/height="[\d.]+(px)?"/);
- if (svgString.match(widthRe)) {
- svgString = svgString.replace(widthRe, `width="${fontSize}px"`);
- }
- if (svgString.match(heightRe)) {
- svgString = svgString.replace(heightRe, `height="${fontSize}px"`);
- }
- return svgString;
- };
- /**
- * Replaces the fill or stroke color of an SVG string with a given color.
- * @param svgString SVG string to modify.
- * @param color Color to set. Defaults to 'currentColor'.
- * @returns The modified SVG string.
- */
- const colorize = (svgString, color) => {
- if (!color) {
- color = 'currentColor';
- }
- const parser = new DOMParser();
- // Tries to parse the string into a HTML node.
- const parsedNode = parser.parseFromString(svgString, 'text/html');
- const svg = parsedNode.querySelector('svg');
- if (svg) {
- if (svg.hasAttribute('fill') && svg.getAttribute('fill') !== 'none') {
- svg.setAttribute('fill', color);
- }
- else if (svg.hasAttribute('stroke') &&
- svg.getAttribute('stroke') !== 'none') {
- svg.setAttribute('stroke', color);
- }
- return svg.outerHTML;
- }
- return svgString;
- };
- var svg = {
- extract,
- colorize,
- setFontSize,
- };
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
- function commonjsRequire(path) {
- throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
- }
- var jszip_min = {exports: {}};
- /*!
- JSZip v3.10.1 - A JavaScript class for generating and reading zip files
- <http://stuartk.com/jszip>
- (c) 2009-2016 Stuart Knightley <stuart [at] stuartk.com>
- Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown.
- JSZip uses the library pako released under the MIT license :
- https://github.com/nodeca/pako/blob/main/LICENSE
- */
- var hasRequiredJszip_min;
- function requireJszip_min () {
- if (hasRequiredJszip_min) return jszip_min.exports;
- hasRequiredJszip_min = 1;
- (function (module, exports) {
- !function(e){module.exports=e();}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof commonjsRequire&&commonjsRequire;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h);}return o[r].exports}for(var l="function"==typeof commonjsRequire&&commonjsRequire,e=0;e<h.length;e++)u(h[e]);return u}({1:[function(e,t,r){var d=e("./utils"),c=e("./support"),p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";r.encode=function(e){for(var t,r,n,i,s,a,o,h=[],u=0,l=e.length,f=l,c="string"!==d.getTypeOf(e);u<e.length;)f=l-u,n=c?(t=e[u++],r=u<l?e[u++]:0,u<l?e[u++]:0):(t=e.charCodeAt(u++),r=u<l?e.charCodeAt(u++):0,u<l?e.charCodeAt(u++):0),i=t>>2,s=(3&t)<<4|r>>4,a=1<f?(15&r)<<2|n>>6:64,o=2<f?63&n:64,h.push(p.charAt(i)+p.charAt(s)+p.charAt(a)+p.charAt(o));return h.join("")},r.decode=function(e){var t,r,n,i,s,a,o=0,h=0,u="data:";if(e.substr(0,u.length)===u)throw new Error("Invalid base64 input, it looks like a data url.");var l,f=3*(e=e.replace(/[^A-Za-z0-9+/=]/g,"")).length/4;if(e.charAt(e.length-1)===p.charAt(64)&&f--,e.charAt(e.length-2)===p.charAt(64)&&f--,f%1!=0)throw new Error("Invalid base64 input, bad content length.");for(l=c.uint8array?new Uint8Array(0|f):new Array(0|f);o<e.length;)t=p.indexOf(e.charAt(o++))<<2|(i=p.indexOf(e.charAt(o++)))>>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l};},{"./support":30,"./utils":32}],2:[function(e,t,r){var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i;}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o;},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate");},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){var n=e("./utils");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e;}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a<s;a++)e=e>>>8^i[255&(e^t[a])];return -1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a<s;a++)e=e>>>8^i[255&(e^t.charCodeAt(a))];return -1^e}(0|t,e,e.length,0):0};},{"./utils":32}],5:[function(e,t,r){r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null;},{}],6:[function(e,t,r){var n=null;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n};},{lie:37}],7:[function(e,t,r){var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function h(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={};}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1);},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0);},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null;},h.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta});};},r.compressWorker=function(e){return new h("Deflate",e)},r.uncompressWorker=function(){return new h("Inflate",{})};},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){function A(e,t){var r,n="";for(r=0;r<t;r++)n+=String.fromCharCode(255&e),e>>>=8;return n}function n(e,t,r,n,i,s){var a,o,h=e.file,u=e.compression,l=s!==O.utf8encode,f=I.transformTo("string",s(h.name)),c=I.transformTo("string",O.utf8encode(h.name)),d=h.comment,p=I.transformTo("string",s(d)),m=I.transformTo("string",O.utf8encode(d)),_=c.length!==h.name.length,g=m.length!==d.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),"UNIX"===i?(C=798,z|=function(e,t){var r=e;return e||(r=t?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(e){return 63&(e||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+c,b+="up"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+="uc"+A(y.length,2)+y);var E="";return E+="\n\0",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+"\0\0\0\0"+A(z,4)+A(n,4)+f+b+p}}var I=e("../utils"),i=e("../stream/GenericWorker"),O=e("../utf8"),B=e("../crc32"),R=e("../signature");function s(e,t,r,n){i.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[];}I.inherits(s,i),s.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,i.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}));},s.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=n(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}});}else this.accumulate=!0;},s.prototype.closedSource=function(e){this.accumulate=!1;var t=this.streamFiles&&!e.file.dir,r=n(e,t,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),t)this.push({data:function(e){return R.DATA_DESCRIPTOR+A(e.crc32,4)+A(e.compressedSize,4)+A(e.uncompressedSize,4)}(e),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null;},s.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t<this.dirRecords.length;t++)this.push({data:this.dirRecords[t],meta:{percent:100}});var r=this.bytesWritten-e,n=function(e,t,r,n,i){var s=I.transformTo("string",i(n));return R.CENTRAL_DIRECTORY_END+"\0\0\0\0"+A(e,2)+A(e,2)+A(t,4)+A(r,4)+A(s.length,2)+s}(this.dirRecords.length,r,e,this.zipComment,this.encodeFileName);this.push({data:n,meta:{percent:100}});},s.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume();},s.prototype.registerPrevious=function(e){this._sources.push(e);var t=this;return e.on("data",function(e){t.processChunk(e);}),e.on("end",function(){t.closedSource(t.previous.streamInfo),t._sources.length?t.prepareNextSource():t.end();}),e.on("error",function(e){t.error(e);}),this},s.prototype.resume=function(){return !!i.prototype.resume.call(this)&&(!this.previous&&this._sources.length?(this.prepareNextSource(),!0):this.previous||this._sources.length||this.generatedError?void 0:(this.end(),!0))},s.prototype.error=function(e){var t=this._sources;if(!i.prototype.error.call(this,e))return !1;for(var r=0;r<t.length;r++)try{t[r].error(e);}catch(e){}return !0},s.prototype.lock=function(){i.prototype.lock.call(this);for(var e=this._sources,t=0;t<e.length;t++)e[t].lock();},t.exports=s;},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(e,t,r){var u=e("../compressions"),n=e("./ZipFileWorker");r.generateWorker=function(e,a,t){var o=new n(a.streamFiles,t,a.platform,a.encodeFileName),h=0;try{e.forEach(function(e,t){h++;var r=function(e,t){var r=e||t,n=u[r];if(!n)throw new Error(r+" is not a valid compression method !");return n}(t.options.compression,a.compression),n=t.options.compressionOptions||a.compressionOptions||{},i=t.dir,s=t.date;t._compressWorker(r,n).withStreamInfo("file",{name:e,dir:i,date:s,comment:t.comment||"",unixPermissions:t.unixPermissions,dosPermissions:t.dosPermissions}).pipe(o);}),o.entriesCount=h;}catch(e){o.error(e);}return o};},{"../compressions":3,"./ZipFileWorker":8}],10:[function(e,t,r){function n(){if(!(this instanceof n))return new n;if(arguments.length)throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");this.files=Object.create(null),this.comment=null,this.root="",this.clone=function(){var e=new n;for(var t in this)"function"!=typeof this[t]&&(e[t]=this[t]);return e};}(n.prototype=e("./object")).loadAsync=e("./load"),n.support=e("./support"),n.defaults=e("./defaults"),n.version="3.10.1",n.loadAsync=function(e,t){return (new n).loadAsync(e,t)},n.external=e("./external"),t.exports=n;},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(e,t,r){var u=e("./utils"),i=e("./external"),n=e("./utf8"),s=e("./zipEntries"),a=e("./stream/Crc32Probe"),l=e("./nodejsUtils");function f(n){return new i.Promise(function(e,t){var r=n.decompressed.getContentWorker().pipe(new a);r.on("error",function(e){t(e);}).on("end",function(){r.streamInfo.crc32!==n.decompressed.crc32?t(new Error("Corrupted zip : CRC32 mismatch")):e();}).resume();})}t.exports=function(e,o){var h=this;return o=u.extend(o||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:n.utf8decode}),l.isNode&&l.isStream(e)?i.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")):u.prepareContent("the loaded zip file",e,!0,o.optimizedBinaryString,o.base64).then(function(e){var t=new s(o);return t.load(e),t}).then(function(e){var t=[i.Promise.resolve(e)],r=e.files;if(o.checkCRC32)for(var n=0;n<r.length;n++)t.push(f(r[n]));return i.Promise.all(t)}).then(function(e){for(var t=e.shift(),r=t.files,n=0;n<r.length;n++){var i=r[n],s=i.fileNameStr,a=u.resolve(i.fileNameStr);h.file(a,i.decompressed,{binary:!0,optimizedBinaryString:!0,date:i.date,dir:i.dir,comment:i.fileCommentStr.length?i.fileCommentStr:null,unixPermissions:i.unixPermissions,dosPermissions:i.dosPermissions,createFolders:o.createFolders}),i.dir||(h.file(a).unsafeOriginalName=s);}return t.zipComment.length&&(h.comment=t.zipComment),h})};},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(e,t,r){var n=e("../utils"),i=e("../stream/GenericWorker");function s(e,t){i.call(this,"Nodejs stream input adapter for "+e),this._upstreamEnded=!1,this._bindStream(t);}n.inherits(s,i),s.prototype._bindStream=function(e){var t=this;(this._stream=e).pause(),e.on("data",function(e){t.push({data:e,meta:{percent:0}});}).on("error",function(e){t.isPaused?this.generatedError=e:t.error(e);}).on("end",function(){t.isPaused?t._upstreamEnded=!0:t.end();});},s.prototype.pause=function(){return !!i.prototype.pause.call(this)&&(this._stream.pause(),!0)},s.prototype.resume=function(){return !!i.prototype.resume.call(this)&&(this._upstreamEnded?this.end():this._stream.resume(),!0)},t.exports=s;},{"../stream/GenericWorker":28,"../utils":32}],13:[function(e,t,r){var i=e("readable-stream").Readable;function n(e,t,r){i.call(this,t),this._helper=e;var n=this;e.on("data",function(e,t){n.push(e)||n._helper.pause(),r&&r(t);}).on("error",function(e){n.emit("error",e);}).on("end",function(){n.push(null);});}e("../utils").inherits(n,i),n.prototype._read=function(){this._helper.resume();},t.exports=n;},{"../utils":32,"readable-stream":16}],14:[function(e,t,r){t.exports={isNode:"undefined"!=typeof Buffer,newBufferFrom:function(e,t){if(Buffer.from&&Buffer.from!==Uint8Array.from)return Buffer.from(e,t);if("number"==typeof e)throw new Error('The "data" argument must not be a number');return new Buffer(e,t)},allocBuffer:function(e){if(Buffer.alloc)return Buffer.alloc(e);var t=new Buffer(e);return t.fill(0),t},isBuffer:function(e){return Buffer.isBuffer(e)},isStream:function(e){return e&&"function"==typeof e.on&&"function"==typeof e.pause&&"function"==typeof e.resume}};},{}],15:[function(e,t,r){function s(e,t,r){var n,i=u.getTypeOf(t),s=u.extend(r||{},f);s.date=s.date||new Date,null!==s.compression&&(s.compression=s.compression.toUpperCase()),"string"==typeof s.unixPermissions&&(s.unixPermissions=parseInt(s.unixPermissions,8)),s.unixPermissions&&16384&s.unixPermissions&&(s.dir=!0),s.dosPermissions&&16&s.dosPermissions&&(s.dir=!0),s.dir&&(e=g(e)),s.createFolders&&(n=_(e))&&b.call(this,n,!0);var a="string"===i&&!1===s.binary&&!1===s.base64;r&&void 0!==r.binary||(s.binary=!a),(t instanceof c&&0===t.uncompressedSize||s.dir||!t||0===t.length)&&(s.base64=!1,s.binary=!0,t="",s.compression="STORE",i="string");var o=null;o=t instanceof c||t instanceof l?t:p.isNode&&p.isStream(t)?new m(e,t):u.prepareContent(e,t,s.binary,s.optimizedBinaryString,s.base64);var h=new d(e,o,s);this.files[e]=h;}var i=e("./utf8"),u=e("./utils"),l=e("./stream/GenericWorker"),a=e("./stream/StreamHelper"),f=e("./defaults"),c=e("./compressedObject"),d=e("./zipObject"),o=e("./generate"),p=e("./nodejsUtils"),m=e("./nodejs/NodejsStreamInputAdapter"),_=function(e){"/"===e.slice(-1)&&(e=e.substring(0,e.length-1));var t=e.lastIndexOf("/");return 0<t?e.substring(0,t):""},g=function(e){return "/"!==e.slice(-1)&&(e+="/"),e},b=function(e,t){return t=void 0!==t?t:f.createFolders,e=g(e),this.files[e]||s.call(this,e,null,{dir:!0,createFolders:t}),this.files[e]};function h(e){return "[object RegExp]"===Object.prototype.toString.call(e)}var n={load:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function(e){var t,r,n;for(t in this.files)n=this.files[t],(r=t.slice(this.root.length,t.length))&&t.slice(0,this.root.length)===this.root&&e(r,n);},filter:function(r){var n=[];return this.forEach(function(e,t){r(e,t)&&n.push(t);}),n},file:function(e,t,r){if(1!==arguments.length)return e=this.root+e,s.call(this,e,t,r),this;if(h(e)){var n=e;return this.filter(function(e,t){return !t.dir&&n.test(e)})}var i=this.files[this.root+e];return i&&!i.dir?i:null},folder:function(r){if(!r)return this;if(h(r))return this.filter(function(e,t){return t.dir&&r.test(e)});var e=this.root+r,t=b.call(this,e),n=this.clone();return n.root=t.name,n},remove:function(r){r=this.root+r;var e=this.files[r];if(e||("/"!==r.slice(-1)&&(r+="/"),e=this.files[r]),e&&!e.dir)delete this.files[r];else for(var t=this.filter(function(e,t){return t.name.slice(0,r.length)===r}),n=0;n<t.length;n++)delete this.files[t[n].name];return this},generate:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},generateInternalStream:function(e){var t,r={};try{if((r=u.extend(e||{},{streamFiles:!1,compression:"STORE",compressionOptions:null,type:"",platform:"DOS",comment:null,mimeType:"application/zip",encodeFileName:i.utf8encode})).type=r.type.toLowerCase(),r.compression=r.compression.toUpperCase(),"binarystring"===r.type&&(r.type="string"),!r.type)throw new Error("No output type specified.");u.checkSupport(r.type),"darwin"!==r.platform&&"freebsd"!==r.platform&&"linux"!==r.platform&&"sunos"!==r.platform||(r.platform="UNIX"),"win32"===r.platform&&(r.platform="DOS");var n=r.comment||this.comment||"";t=o.generateWorker(this,r,n);}catch(e){(t=new l("error")).error(e);}return new a(t,r.type||"string",r.mimeType)},generateAsync:function(e,t){return this.generateInternalStream(e).accumulate(t)},generateNodeStream:function(e,t){return (e=e||{}).type||(e.type="nodebuffer"),this.generateInternalStream(e).toNodejsStream(t)}};t.exports=n;},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(e,t,r){t.exports=e("stream");},{stream:void 0}],17:[function(e,t,r){var n=e("./DataReader");function i(e){n.call(this,e);for(var t=0;t<this.data.length;t++)e[t]=255&e[t];}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data[this.zero+e]},i.prototype.lastIndexOfSignature=function(e){for(var t=e.charCodeAt(0),r=e.charCodeAt(1),n=e.charCodeAt(2),i=e.charCodeAt(3),s=this.length-4;0<=s;--s)if(this.data[s]===t&&this.data[s+1]===r&&this.data[s+2]===n&&this.data[s+3]===i)return s-this.zero;return -1},i.prototype.readAndCheckSignature=function(e){var t=e.charCodeAt(0),r=e.charCodeAt(1),n=e.charCodeAt(2),i=e.charCodeAt(3),s=this.readData(4);return t===s[0]&&r===s[1]&&n===s[2]&&i===s[3]},i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return [];var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./DataReader":18}],18:[function(e,t,r){var n=e("../utils");function i(e){this.data=e,this.length=e.length,this.index=0,this.zero=0;}i.prototype={checkOffset:function(e){this.checkIndex(this.index+e);},checkIndex:function(e){if(this.length<this.zero+e||e<0)throw new Error("End of data reached (data length = "+this.length+", asked index = "+e+"). Corrupted zip ?")},setIndex:function(e){this.checkIndex(e),this.index=e;},skip:function(e){this.setIndex(this.index+e);},byteAt:function(){},readInt:function(e){var t,r=0;for(this.checkOffset(e),t=this.index+e-1;t>=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i;},{"../utils":32}],19:[function(e,t,r){var n=e("./Uint8ArrayReader");function i(e){n.call(this,e);}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){var n=e("./DataReader");function i(e){n.call(this,e);}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){var n=e("./ArrayReader");function i(e){n.call(this,e);}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),h=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new h(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)};},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b";},{}],24:[function(e,t,r){var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e;}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta});},t.exports=s;},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0);}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e);},t.exports=s;},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0);}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length;}i.prototype.processChunk.call(this,e);},t.exports=s;},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat();},function(e){t.error(e);});}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null;},s.prototype.resume=function(){return !!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0));},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return !1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t);}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s;},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){function n(e){this.name=e||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null;}n.prototype={push:function(e){this.emit("data",e);},end:function(){if(this.isFinished)return !1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0;}catch(e){this.emit("error",e);}return !0},error:function(e){return !this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[];},emit:function(e,t){if(this._listeners[e])for(var r=0;r<this._listeners[e].length;r++)this._listeners[e][r].call(this,t);},pipe:function(e){return e.registerPrevious(this)},registerPrevious:function(e){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.streamInfo=e.streamInfo,this.mergeStreamInfo(),this.previous=e;var t=this;return e.on("data",function(e){t.processChunk(e);}),e.on("end",function(){t.end();}),e.on("error",function(e){t.error(e);}),this},pause:function(){return !this.isPaused&&!this.isFinished&&(this.isPaused=!0,this.previous&&this.previous.pause(),!0)},resume:function(){if(!this.isPaused||this.isFinished)return !1;var e=this.isPaused=!1;return this.generatedError&&(this.error(this.generatedError),e=!0),this.previous&&this.previous.resume(),!e},flush:function(){},processChunk:function(e){this.push(e);},withStreamInfo:function(e,t){return this.extraStreamInfo[e]=t,this.mergeStreamInfo(),this},mergeStreamInfo:function(){for(var e in this.extraStreamInfo)Object.prototype.hasOwnProperty.call(this.extraStreamInfo,e)&&(this.streamInfo[e]=this.extraStreamInfo[e]);},lock:function(){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.isLocked=!0,this.previous&&this.previous.lock();},toString:function(){var e="Worker "+this.name;return this.previous?this.previous+" -> "+e:e}},t.exports=n;},{}],29:[function(e,t,r){var h=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),u=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter");}catch(e){}function l(e,o){return new a.Promise(function(t,r){var n=[],i=e._internalType,s=e._outputType,a=e._mimeType;e.on("data",function(e,t){n.push(e),o&&o(t);}).on("error",function(e){n=[],r(e);}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return h.newBlob(h.transformTo("arraybuffer",t),r);case"base64":return u.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r<t.length;r++)s+=t[r].length;switch(e){case"string":return t.join("");case"array":return Array.prototype.concat.apply([],t);case"uint8array":for(i=new Uint8Array(s),r=0;r<t.length;r++)i.set(t[r],n),n+=t[r].length;return i;case"nodebuffer":return Buffer.concat(t);default:throw new Error("concat : unsupported type '"+e+"'")}}(i,n),a);t(e);}catch(e){r(e);}n=[];}).resume();})}function f(e,t,r){var n=t;switch(t){case"blob":case"arraybuffer":n="uint8array";break;case"base64":n="string";}try{this._internalType=n,this._outputType=t,this._mimeType=r,h.checkSupport(n),this._worker=e.pipe(new i(n)),e.lock();}catch(e){this._worker=new s("error"),this._worker.error(e);}}f.prototype={accumulate:function(e){return l(this,e)},on:function(e,t){var r=this;return "data"===e?this._worker.on(e,function(e){t.call(r,e.data,e.meta);}):this._worker.on(e,function(){h.delay(t,arguments,r);}),this},resume:function(){return h.delay(this._worker.resume,[],this._worker),this},pause:function(){return this._worker.pause(),this},toNodejsStream:function(e){if(h.checkSupport("nodestream"),"nodebuffer"!==this._outputType)throw new Error(this._outputType+" is not supported by this method");return new o(this,{objectMode:"nodebuffer"!==this._outputType},e)}},t.exports=f;},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(e,t,r){if(r.base64=!0,r.array=!0,r.string=!0,r.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,r.nodebuffer="undefined"!=typeof Buffer,r.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)r.blob=!1;else {var n=new ArrayBuffer(0);try{r.blob=0===new Blob([n],{type:"application/zip"}).size;}catch(e){try{var i=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);i.append(n),r.blob=0===i.getBlob("application/zip").size;}catch(e){r.blob=!1;}}}try{r.nodestream=!!e("readable-stream").Readable;}catch(e){r.nodestream=!1;}},{"readable-stream":16}],31:[function(e,t,s){for(var o=e("./utils"),h=e("./support"),r=e("./nodejsUtils"),n=e("./stream/GenericWorker"),u=new Array(256),i=0;i<256;i++)u[i]=252<=i?6:248<=i?5:240<=i?4:224<=i?3:192<=i?2:1;u[254]=u[254]=1;function a(){n.call(this,"utf-8 decode"),this.leftOver=null;}function l(){n.call(this,"utf-8 encode");}s.utf8encode=function(e){return h.nodebuffer?r.newBufferFrom(e,"utf-8"):function(e){var t,r,n,i,s,a=e.length,o=0;for(i=0;i<a;i++)55296==(64512&(r=e.charCodeAt(i)))&&i+1<a&&56320==(64512&(n=e.charCodeAt(i+1)))&&(r=65536+(r-55296<<10)+(n-56320),i++),o+=r<128?1:r<2048?2:r<65536?3:4;for(t=h.uint8array?new Uint8Array(o):new Array(o),i=s=0;s<o;i++)55296==(64512&(r=e.charCodeAt(i)))&&i+1<a&&56320==(64512&(n=e.charCodeAt(i+1)))&&(r=65536+(r-55296<<10)+(n-56320),i++),r<128?t[s++]=r:(r<2048?t[s++]=192|r>>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return h.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t<s;)if((n=e[t++])<128)a[r++]=n;else if(4<(i=u[n]))a[r++]=65533,t+=i-1;else {for(n&=2===i?31:3===i?15:7;1<i&&t<s;)n=n<<6|63&e[t++],i--;1<i?a[r++]=65533:n<65536?a[r++]=n:(n-=65536,a[r++]=55296|n>>10&1023,a[r++]=56320|1023&n);}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(h.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(h.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length);}else t=this.leftOver.concat(t);this.leftOver=null;}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}(t),i=t;n!==t.length&&(h.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta});},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null);},s.Utf8DecodeWorker=a,o.inherits(l,n),l.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta});},s.Utf8EncodeWorker=l;},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,a){var o=e("./support"),h=e("./base64"),r=e("./nodejsUtils"),u=e("./external");function n(e){return e}function l(e,t){for(var r=0;r<e.length;++r)t[r]=255&e.charCodeAt(r);return t}e("setimmediate"),a.newBlob=function(t,r){a.checkSupport("blob");try{return new Blob([t],{type:r})}catch(e){try{var n=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);return n.append(t),n.getBlob(r)}catch(e){throw new Error("Bug : can't construct the Blob.")}}};var i={stringifyByChunk:function(e,t,r){var n=[],i=0,s=e.length;if(s<=r)return String.fromCharCode.apply(null,e);for(;i<s;)"array"===t||"nodebuffer"===t?n.push(String.fromCharCode.apply(null,e.slice(i,Math.min(i+r,s)))):n.push(String.fromCharCode.apply(null,e.subarray(i,Math.min(i+r,s)))),i+=r;return n.join("")},stringifyByChar:function(e){for(var t="",r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return t},applyCanBeUsed:{uint8array:function(){try{return o.uint8array&&1===String.fromCharCode.apply(null,new Uint8Array(1)).length}catch(e){return !1}}(),nodebuffer:function(){try{return o.nodebuffer&&1===String.fromCharCode.apply(null,r.allocBuffer(1)).length}catch(e){return !1}}()}};function s(e){var t=65536,r=a.getTypeOf(e),n=!0;if("uint8array"===r?n=i.applyCanBeUsed.uint8array:"nodebuffer"===r&&(n=i.applyCanBeUsed.nodebuffer),n)for(;1<t;)try{return i.stringifyByChunk(e,r,t)}catch(e){t=Math.floor(t/2);}return i.stringifyByChar(e)}function f(e,t){for(var r=0;r<e.length;r++)t[r]=e[r];return t}a.applyFromCharCode=s;var c={};c.string={string:n,array:function(e){return l(e,new Array(e.length))},arraybuffer:function(e){return c.string.uint8array(e).buffer},uint8array:function(e){return l(e,new Uint8Array(e.length))},nodebuffer:function(e){return l(e,r.allocBuffer(e.length))}},c.array={string:s,array:n,arraybuffer:function(e){return new Uint8Array(e).buffer},uint8array:function(e){return new Uint8Array(e)},nodebuffer:function(e){return r.newBufferFrom(e)}},c.arraybuffer={string:function(e){return s(new Uint8Array(e))},array:function(e){return f(new Uint8Array(e),new Array(e.byteLength))},arraybuffer:n,uint8array:function(e){return new Uint8Array(e)},nodebuffer:function(e){return r.newBufferFrom(new Uint8Array(e))}},c.uint8array={string:s,array:function(e){return f(e,new Array(e.length))},arraybuffer:function(e){return e.buffer},uint8array:n,nodebuffer:function(e){return r.newBufferFrom(e)}},c.nodebuffer={string:s,array:function(e){return f(e,new Array(e.length))},arraybuffer:function(e){return c.nodebuffer.uint8array(e).buffer},uint8array:function(e){return f(e,new Uint8Array(e.length))},nodebuffer:n},a.transformTo=function(e,t){if(t=t||"",!e)return t;a.checkSupport(e);var r=a.getTypeOf(t);return c[r][e](t)},a.resolve=function(e){for(var t=e.split("/"),r=[],n=0;n<t.length;n++){var i=t[n];"."===i||""===i&&0!==n&&n!==t.length-1||(".."===i?r.pop():r.push(i));}return r.join("/")},a.getTypeOf=function(e){return "string"==typeof e?"string":"[object Array]"===Object.prototype.toString.call(e)?"array":o.nodebuffer&&r.isBuffer(e)?"nodebuffer":o.uint8array&&e instanceof Uint8Array?"uint8array":o.arraybuffer&&e instanceof ArrayBuffer?"arraybuffer":void 0},a.checkSupport=function(e){if(!o[e.toLowerCase()])throw new Error(e+" is not supported by this platform")},a.MAX_VALUE_16BITS=65535,a.MAX_VALUE_32BITS=-1,a.pretty=function(e){var t,r,n="";for(r=0;r<(e||"").length;r++)n+="\\x"+((t=e.charCodeAt(r))<16?"0":"")+t.toString(16).toUpperCase();return n},a.delay=function(e,t,r){setImmediate(function(){e.apply(r||null,t||[]);});},a.inherits=function(e,t){function r(){}r.prototype=t.prototype,e.prototype=new r;},a.extend=function(){var e,t,r={};for(e=0;e<arguments.length;e++)for(t in arguments[e])Object.prototype.hasOwnProperty.call(arguments[e],t)&&void 0===r[t]&&(r[t]=arguments[e][t]);return r},a.prepareContent=function(r,e,n,i,s){return u.Promise.resolve(e).then(function(n){return o.blob&&(n instanceof Blob||-1!==["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(n)))&&"undefined"!=typeof FileReader?new u.Promise(function(t,r){var e=new FileReader;e.onload=function(e){t(e.target.result);},e.onerror=function(e){r(e.target.error);},e.readAsArrayBuffer(n);}):n}).then(function(e){var t=a.getTypeOf(e);return t?("arraybuffer"===t?e=a.transformTo("uint8array",e):"string"===t&&(s?e=h.decode(e):n&&!0!==i&&(e=function(e){return l(e,o.uint8array?new Uint8Array(e.length):new Array(e.length))}(e))),e):u.Promise.reject(new Error("Can't read the data of '"+r+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"))})};},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,setimmediate:54}],33:[function(e,t,r){var n=e("./reader/readerFor"),i=e("./utils"),s=e("./signature"),a=e("./zipEntry"),o=e("./support");function h(e){this.files=[],this.loadOptions=e;}h.prototype={checkSignature:function(e){if(!this.reader.readAndCheckSignature(e)){this.reader.index-=4;var t=this.reader.readString(4);throw new Error("Corrupted zip or bug: unexpected signature ("+i.pretty(t)+", expected "+i.pretty(e)+")")}},isSignature:function(e,t){var r=this.reader.index;this.reader.setIndex(e);var n=this.reader.readString(4)===t;return this.reader.setIndex(r),n},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2);var e=this.reader.readData(this.zipCommentLength),t=o.uint8array?"uint8array":"array",r=i.transformTo(t,e);this.zipComment=this.loadOptions.decodeFileName(r);},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.reader.skip(4),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var e,t,r,n=this.zip64EndOfCentralSize-44;0<n;)e=this.reader.readInt(2),t=this.reader.readInt(4),r=this.reader.readData(t),this.zip64ExtensibleData[e]={id:e,length:t,value:r};},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),1<this.disksCount)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var e,t;for(e=0;e<this.files.length;e++)t=this.files[e],this.reader.setIndex(t.localHeaderOffset),this.checkSignature(s.LOCAL_FILE_HEADER),t.readLocalPart(this.reader),t.handleUTF8(),t.processAttributes();},readCentralDir:function(){var e;for(this.reader.setIndex(this.centralDirOffset);this.reader.readAndCheckSignature(s.CENTRAL_FILE_HEADER);)(e=new a({zip64:this.zip64},this.loadOptions)).readCentralPart(this.reader),this.files.push(e);if(this.centralDirRecords!==this.files.length&&0!==this.centralDirRecords&&0===this.files.length)throw new Error("Corrupted zip or bug: expected "+this.centralDirRecords+" records in central dir, got "+this.files.length)},readEndOfCentral:function(){var e=this.reader.lastIndexOfSignature(s.CENTRAL_DIRECTORY_END);if(e<0)throw !this.isSignature(0,s.LOCAL_FILE_HEADER)?new Error("Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html"):new Error("Corrupted zip: can't find end of central directory");this.reader.setIndex(e);var t=e;if(this.checkSignature(s.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===i.MAX_VALUE_16BITS||this.diskWithCentralDirStart===i.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===i.MAX_VALUE_16BITS||this.centralDirRecords===i.MAX_VALUE_16BITS||this.centralDirSize===i.MAX_VALUE_32BITS||this.centralDirOffset===i.MAX_VALUE_32BITS){if(this.zip64=!0,(e=this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR))<0)throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");if(this.reader.setIndex(e),this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,s.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_END),this.relativeOffsetEndOfZip64CentralDir<0))throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral();}var r=this.centralDirOffset+this.centralDirSize;this.zip64&&(r+=20,r+=12+this.zip64EndOfCentralSize);var n=t-r;if(0<n)this.isSignature(t,s.CENTRAL_FILE_HEADER)||(this.reader.zero=n);else if(n<0)throw new Error("Corrupted zip: missing "+Math.abs(n)+" bytes.")},prepareReader:function(e){this.reader=n(e);},load:function(e){this.prepareReader(e),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles();}},t.exports=h;},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utils":32,"./zipEntry":34}],34:[function(e,t,r){var n=e("./reader/readerFor"),s=e("./utils"),i=e("./compressedObject"),a=e("./crc32"),o=e("./utf8"),h=e("./compressions"),u=e("./support");function l(e,t){this.options=e,this.loadOptions=t;}l.prototype={isEncrypted:function(){return 1==(1&this.bitFlag)},useUTF8:function(){return 2048==(2048&this.bitFlag)},readLocalPart:function(e){var t,r;if(e.skip(22),this.fileNameLength=e.readInt(2),r=e.readInt(2),this.fileName=e.readData(this.fileNameLength),e.skip(r),-1===this.compressedSize||-1===this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough information from the central directory (compressedSize === -1 || uncompressedSize === -1)");if(null===(t=function(e){for(var t in h)if(Object.prototype.hasOwnProperty.call(h,t)&&h[t].magic===e)return h[t];return null}(this.compressionMethod)))throw new Error("Corrupted zip : compression "+s.pretty(this.compressionMethod)+" unknown (inner file : "+s.transformTo("string",this.fileName)+")");this.decompressed=new i(this.compressedSize,this.uncompressedSize,this.crc32,t,e.readData(this.compressedSize));},readCentralPart:function(e){this.versionMadeBy=e.readInt(2),e.skip(2),this.bitFlag=e.readInt(2),this.compressionMethod=e.readString(2),this.date=e.readDate(),this.crc32=e.readInt(4),this.compressedSize=e.readInt(4),this.uncompressedSize=e.readInt(4);var t=e.readInt(2);if(this.extraFieldsLength=e.readInt(2),this.fileCommentLength=e.readInt(2),this.diskNumberStart=e.readInt(2),this.internalFileAttributes=e.readInt(2),this.externalFileAttributes=e.readInt(4),this.localHeaderOffset=e.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");e.skip(t),this.readExtraFields(e),this.parseZIP64ExtraField(e),this.fileComment=e.readData(this.fileCommentLength);},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var e=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0);},parseZIP64ExtraField:function(){if(this.extraFields[1]){var e=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4));}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4<i;)t=e.readInt(2),r=e.readInt(2),n=e.readData(r),this.extraFields[t]={id:t,length:r,value:n};e.setIndex(i);},handleUTF8:function(){var e=u.uint8array?"uint8array":"array";if(this.useUTF8())this.fileNameStr=o.utf8decode(this.fileName),this.fileCommentStr=o.utf8decode(this.fileComment);else {var t=this.findExtraFieldUnicodePath();if(null!==t)this.fileNameStr=t;else {var r=s.transformTo(e,this.fileName);this.fileNameStr=this.loadOptions.decodeFileName(r);}var n=this.findExtraFieldUnicodeComment();if(null!==n)this.fileCommentStr=n;else {var i=s.transformTo(e,this.fileComment);this.fileCommentStr=this.loadOptions.decodeFileName(i);}}},findExtraFieldUnicodePath:function(){var e=this.extraFields[28789];if(e){var t=n(e.value);return 1!==t.readInt(1)?null:a(this.fileName)!==t.readInt(4)?null:o.utf8decode(t.readData(e.length-5))}return null},findExtraFieldUnicodeComment:function(){var e=this.extraFields[25461];if(e){var t=n(e.value);return 1!==t.readInt(1)?null:a(this.fileComment)!==t.readInt(4)?null:o.utf8decode(t.readData(e.length-5))}return null}},t.exports=l;},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(e,t,r){function n(e,t,r){this.name=e,this.dir=r.dir,this.date=r.date,this.comment=r.comment,this.unixPermissions=r.unixPermissions,this.dosPermissions=r.dosPermissions,this._data=t,this._dataBinary=r.binary,this.options={compression:r.compression,compressionOptions:r.compressionOptions};}var s=e("./stream/StreamHelper"),i=e("./stream/DataWorker"),a=e("./utf8"),o=e("./compressedObject"),h=e("./stream/GenericWorker");n.prototype={internalStream:function(e){var t=null,r="string";try{if(!e)throw new Error("No output type specified.");var n="string"===(r=e.toLowerCase())||"text"===r;"binarystring"!==r&&"text"!==r||(r="string"),t=this._decompressWorker();var i=!this._dataBinary;i&&!n&&(t=t.pipe(new a.Utf8EncodeWorker)),!i&&n&&(t=t.pipe(new a.Utf8DecodeWorker));}catch(e){(t=new h("error")).error(e);}return new s(t,r,"")},async:function(e,t){return this.internalStream(e).accumulate(t)},nodeStream:function(e,t){return this.internalStream(e||"nodebuffer").toNodejsStream(t)},_compressWorker:function(e,t){if(this._data instanceof o&&this._data.compression.magic===e.magic)return this._data.getCompressedWorker();var r=this._decompressWorker();return this._dataBinary||(r=r.pipe(new a.Utf8EncodeWorker)),o.createWorkerFrom(r,e,t)},_decompressWorker:function(){return this._data instanceof o?this._data.getContentWorker():this._data instanceof h?this._data:new i(this._data)}};for(var u=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],l=function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},f=0;f<u.length;f++)n.prototype[u[f]]=l;t.exports=n;},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(e,l,t){(function(t){var r,n,e=t.MutationObserver||t.WebKitMutationObserver;if(e){var i=0,s=new e(u),a=t.document.createTextNode("");s.observe(a,{characterData:!0}),r=function(){a.data=i=++i%2;};}else if(t.setImmediate||void 0===t.MessageChannel)r="document"in t&&"onreadystatechange"in t.document.createElement("script")?function(){var e=t.document.createElement("script");e.onreadystatechange=function(){u(),e.onreadystatechange=null,e.parentNode.removeChild(e),e=null;},t.document.documentElement.appendChild(e);}:function(){setTimeout(u,0);};else {var o=new t.MessageChannel;o.port1.onmessage=u,r=function(){o.port2.postMessage(0);};}var h=[];function u(){var e,t;n=!0;for(var r=h.length;r;){for(t=h,h=[],e=-1;++e<r;)t[e]();r=h.length;}n=!1;}l.exports=function(e){1!==h.push(e)||n||r();};}).call(this,"undefined"!=typeof commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}],37:[function(e,t,r){var i=e("immediate");function u(){}var l={},s=["REJECTED"],a=["FULFILLED"],n=["PENDING"];function o(e){if("function"!=typeof e)throw new TypeError("resolver must be a function");this.state=n,this.queue=[],this.outcome=void 0,e!==u&&d(this,e);}function h(e,t,r){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof r&&(this.onRejected=r,this.callRejected=this.otherCallRejected);}function f(t,r,n){i(function(){var e;try{e=r(n);}catch(e){return l.reject(t,e)}e===t?l.reject(t,new TypeError("Cannot resolve promise with itself")):l.resolve(t,e);});}function c(e){var t=e&&e.then;if(e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof t)return function(){t.apply(e,arguments);}}function d(t,e){var r=!1;function n(e){r||(r=!0,l.reject(t,e));}function i(e){r||(r=!0,l.resolve(t,e));}var s=p(function(){e(i,n);});"error"===s.status&&n(s.value);}function p(e,t){var r={};try{r.value=e(t),r.status="success";}catch(e){r.status="error",r.value=e;}return r}(t.exports=o).prototype.finally=function(t){if("function"!=typeof t)return this;var r=this.constructor;return this.then(function(e){return r.resolve(t()).then(function(){return e})},function(e){return r.resolve(t()).then(function(){throw e})})},o.prototype.catch=function(e){return this.then(null,e)},o.prototype.then=function(e,t){if("function"!=typeof e&&this.state===a||"function"!=typeof t&&this.state===s)return this;var r=new this.constructor(u);this.state!==n?f(r,this.state===a?e:t,this.outcome):this.queue.push(new h(r,e,t));return r},h.prototype.callFulfilled=function(e){l.resolve(this.promise,e);},h.prototype.otherCallFulfilled=function(e){f(this.promise,this.onFulfilled,e);},h.prototype.callRejected=function(e){l.reject(this.promise,e);},h.prototype.otherCallRejected=function(e){f(this.promise,this.onRejected,e);},l.resolve=function(e,t){var r=p(c,t);if("error"===r.status)return l.reject(e,r.value);var n=r.value;if(n)d(e,n);else {e.state=a,e.outcome=t;for(var i=-1,s=e.queue.length;++i<s;)e.queue[i].callFulfilled(t);}return e},l.reject=function(e,t){e.state=s,e.outcome=t;for(var r=-1,n=e.queue.length;++r<n;)e.queue[r].callRejected(t);return e},o.resolve=function(e){if(e instanceof this)return e;return l.resolve(new this(u),e)},o.reject=function(e){var t=new this(u);return l.reject(t,e)},o.all=function(e){var r=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var n=e.length,i=!1;if(!n)return this.resolve([]);var s=new Array(n),a=0,t=-1,o=new this(u);for(;++t<n;)h(e[t],t);return o;function h(e,t){r.resolve(e).then(function(e){s[t]=e,++a!==n||i||(i=!0,l.resolve(o,s));},function(e){i||(i=!0,l.reject(o,e));});}},o.race=function(e){var t=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var r=e.length,n=!1;if(!r)return this.resolve([]);var i=-1,s=new this(u);for(;++i<r;)a=e[i],t.resolve(a).then(function(e){n||(n=!0,l.resolve(s,e));},function(e){n||(n=!0,l.reject(s,e));});var a;return s};},{immediate:36}],38:[function(e,t,r){var n={};(0, e("./lib/utils/common").assign)(n,e("./lib/deflate"),e("./lib/inflate"),e("./lib/zlib/constants")),t.exports=n;},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(e,t,r){var a=e("./zlib/deflate"),o=e("./utils/common"),h=e("./utils/strings"),i=e("./zlib/messages"),s=e("./zlib/zstream"),u=Object.prototype.toString,l=0,f=-1,c=0,d=8;function p(e){if(!(this instanceof p))return new p(e);this.options=o.assign({level:f,method:d,chunkSize:16384,windowBits:15,memLevel:8,strategy:c,to:""},e||{});var t=this.options;t.raw&&0<t.windowBits?t.windowBits=-t.windowBits:t.gzip&&0<t.windowBits&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new s,this.strm.avail_out=0;var r=a.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(r!==l)throw new Error(i[r]);if(t.header&&a.deflateSetHeader(this.strm,t.header),t.dictionary){var n;if(n="string"==typeof t.dictionary?h.string2buf(t.dictionary):"[object ArrayBuffer]"===u.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,(r=a.deflateSetDictionary(this.strm,n))!==l)throw new Error(i[r]);this._dict_set=!0;}}function n(e,t){var r=new p(t);if(r.push(e,!0),r.err)throw r.msg||i[r.err];return r.result}p.prototype.push=function(e,t){var r,n,i=this.strm,s=this.options.chunkSize;if(this.ended)return !1;n=t===~~t?t:!0===t?4:0,"string"==typeof e?i.input=h.string2buf(e):"[object ArrayBuffer]"===u.call(e)?i.input=new Uint8Array(e):i.input=e,i.next_in=0,i.avail_in=i.input.length;do{if(0===i.avail_out&&(i.output=new o.Buf8(s),i.next_out=0,i.avail_out=s),1!==(r=a.deflate(i,n))&&r!==l)return this.onEnd(r),!(this.ended=!0);0!==i.avail_out&&(0!==i.avail_in||4!==n&&2!==n)||("string"===this.options.to?this.onData(h.buf2binstring(o.shrinkBuf(i.output,i.next_out))):this.onData(o.shrinkBuf(i.output,i.next_out)));}while((0<i.avail_in||0===i.avail_out)&&1!==r);return 4===n?(r=a.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===l):2!==n||(this.onEnd(l),!(i.avail_out=0))},p.prototype.onData=function(e){this.chunks.push(e);},p.prototype.onEnd=function(e){e===l&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=o.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},r.Deflate=p,r.deflate=n,r.deflateRaw=function(e,t){return (t=t||{}).raw=!0,n(e,t)},r.gzip=function(e,t){return (t=t||{}).gzip=!0,n(e,t)};},{"./utils/common":41,"./utils/strings":42,"./zlib/deflate":46,"./zlib/messages":51,"./zlib/zstream":53}],40:[function(e,t,r){var c=e("./zlib/inflate"),d=e("./utils/common"),p=e("./utils/strings"),m=e("./zlib/constants"),n=e("./zlib/messages"),i=e("./zlib/zstream"),s=e("./zlib/gzheader"),_=Object.prototype.toString;function a(e){if(!(this instanceof a))return new a(e);this.options=d.assign({chunkSize:16384,windowBits:0,to:""},e||{});var t=this.options;t.raw&&0<=t.windowBits&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(0<=t.windowBits&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),15<t.windowBits&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new i,this.strm.avail_out=0;var r=c.inflateInit2(this.strm,t.windowBits);if(r!==m.Z_OK)throw new Error(n[r]);this.header=new s,c.inflateGetHeader(this.strm,this.header);}function o(e,t){var r=new a(t);if(r.push(e,!0),r.err)throw r.msg||n[r.err];return r.result}a.prototype.push=function(e,t){var r,n,i,s,a,o,h=this.strm,u=this.options.chunkSize,l=this.options.dictionary,f=!1;if(this.ended)return !1;n=t===~~t?t:!0===t?m.Z_FINISH:m.Z_NO_FLUSH,"string"==typeof e?h.input=p.binstring2buf(e):"[object ArrayBuffer]"===_.call(e)?h.input=new Uint8Array(e):h.input=e,h.next_in=0,h.avail_in=h.input.length;do{if(0===h.avail_out&&(h.output=new d.Buf8(u),h.next_out=0,h.avail_out=u),(r=c.inflate(h,m.Z_NO_FLUSH))===m.Z_NEED_DICT&&l&&(o="string"==typeof l?p.string2buf(l):"[object ArrayBuffer]"===_.call(l)?new Uint8Array(l):l,r=c.inflateSetDictionary(this.strm,o)),r===m.Z_BUF_ERROR&&!0===f&&(r=m.Z_OK,f=!1),r!==m.Z_STREAM_END&&r!==m.Z_OK)return this.onEnd(r),!(this.ended=!0);h.next_out&&(0!==h.avail_out&&r!==m.Z_STREAM_END&&(0!==h.avail_in||n!==m.Z_FINISH&&n!==m.Z_SYNC_FLUSH)||("string"===this.options.to?(i=p.utf8border(h.output,h.next_out),s=h.next_out-i,a=p.buf2string(h.output,i),h.next_out=s,h.avail_out=u-s,s&&d.arraySet(h.output,h.output,i,s,0),this.onData(a)):this.onData(d.shrinkBuf(h.output,h.next_out)))),0===h.avail_in&&0===h.avail_out&&(f=!0);}while((0<h.avail_in||0===h.avail_out)&&r!==m.Z_STREAM_END);return r===m.Z_STREAM_END&&(n=m.Z_FINISH),n===m.Z_FINISH?(r=c.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===m.Z_OK):n!==m.Z_SYNC_FLUSH||(this.onEnd(m.Z_OK),!(h.avail_out=0))},a.prototype.onData=function(e){this.chunks.push(e);},a.prototype.onEnd=function(e){e===m.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=d.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},r.Inflate=a,r.inflate=o,r.inflateRaw=function(e,t){return (t=t||{}).raw=!0,o(e,t)},r.ungzip=o;},{"./utils/common":41,"./utils/strings":42,"./zlib/constants":44,"./zlib/gzheader":47,"./zlib/inflate":49,"./zlib/messages":51,"./zlib/zstream":53}],41:[function(e,t,r){var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;r.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var r=t.shift();if(r){if("object"!=typeof r)throw new TypeError(r+"must be non-object");for(var n in r)r.hasOwnProperty(n)&&(e[n]=r[n]);}}return e},r.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var i={arraySet:function(e,t,r,n,i){if(t.subarray&&e.subarray)e.set(t.subarray(r,r+n),i);else for(var s=0;s<n;s++)e[i+s]=t[r+s];},flattenChunks:function(e){var t,r,n,i,s,a;for(t=n=0,r=e.length;t<r;t++)n+=e[t].length;for(a=new Uint8Array(n),t=i=0,r=e.length;t<r;t++)s=e[t],a.set(s,i),i+=s.length;return a}},s={arraySet:function(e,t,r,n,i){for(var s=0;s<n;s++)e[i+s]=t[r+s];},flattenChunks:function(e){return [].concat.apply([],e)}};r.setTyped=function(e){e?(r.Buf8=Uint8Array,r.Buf16=Uint16Array,r.Buf32=Int32Array,r.assign(r,i)):(r.Buf8=Array,r.Buf16=Array,r.Buf32=Array,r.assign(r,s));},r.setTyped(n);},{}],42:[function(e,t,r){var h=e("./common"),i=!0,s=!0;try{String.fromCharCode.apply(null,[0]);}catch(e){i=!1;}try{String.fromCharCode.apply(null,new Uint8Array(1));}catch(e){s=!1;}for(var u=new h.Buf8(256),n=0;n<256;n++)u[n]=252<=n?6:248<=n?5:240<=n?4:224<=n?3:192<=n?2:1;function l(e,t){if(t<65537&&(e.subarray&&s||!e.subarray&&i))return String.fromCharCode.apply(null,h.shrinkBuf(e,t));for(var r="",n=0;n<t;n++)r+=String.fromCharCode(e[n]);return r}u[254]=u[254]=1,r.string2buf=function(e){var t,r,n,i,s,a=e.length,o=0;for(i=0;i<a;i++)55296==(64512&(r=e.charCodeAt(i)))&&i+1<a&&56320==(64512&(n=e.charCodeAt(i+1)))&&(r=65536+(r-55296<<10)+(n-56320),i++),o+=r<128?1:r<2048?2:r<65536?3:4;for(t=new h.Buf8(o),i=s=0;s<o;i++)55296==(64512&(r=e.charCodeAt(i)))&&i+1<a&&56320==(64512&(n=e.charCodeAt(i+1)))&&(r=65536+(r-55296<<10)+(n-56320),i++),r<128?t[s++]=r:(r<2048?t[s++]=192|r>>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return l(e,e.length)},r.binstring2buf=function(e){for(var t=new h.Buf8(e.length),r=0,n=t.length;r<n;r++)t[r]=e.charCodeAt(r);return t},r.buf2string=function(e,t){var r,n,i,s,a=t||e.length,o=new Array(2*a);for(r=n=0;r<a;)if((i=e[r++])<128)o[n++]=i;else if(4<(s=u[i]))o[n++]=65533,r+=s-1;else {for(i&=2===s?31:3===s?15:7;1<s&&r<a;)i=i<<6|63&e[r++],s--;1<s?o[n++]=65533:i<65536?o[n++]=i:(i-=65536,o[n++]=55296|i>>10&1023,o[n++]=56320|1023&i);}return l(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t};},{"./common":41}],43:[function(e,t,r){t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3<r?2e3:r;s=s+(i=i+t[n++]|0)|0,--a;);i%=65521,s%=65521;}return i|s<<16|0};},{}],44:[function(e,t,r){t.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};},{}],45:[function(e,t,r){var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e;}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a<s;a++)e=e>>>8^i[255&(e^t[a])];return -1^e};},{}],46:[function(e,t,r){var h,c=e("../utils/common"),u=e("./trees"),d=e("./adler32"),p=e("./crc32"),n=e("./messages"),l=0,f=4,m=0,_=-2,g=-1,b=4,i=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(e,t){return e.msg=n[t],t}function T(e){return (e<<1)-(4<e?9:0)}function D(e){for(var t=e.length;0<=--t;)e[t]=0;}function F(e){var t=e.state,r=t.pending;r>e.avail_out&&(r=e.avail_out),0!==r&&(c.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0));}function N(e,t){u._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,F(e.strm);}function U(e,t){e.pending_buf[e.pending++]=t;}function P(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t;}function L(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,h=e.strstart>e.w_size-z?e.strstart-(e.w_size-z):0,u=e.window,l=e.w_mask,f=e.prev,c=e.strstart+S,d=u[s+a-1],p=u[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(u[(r=t)+a]===p&&u[r+a-1]===d&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&s<c);if(n=S-(c-s),s=c-S,a<n){if(e.match_start=t,o<=(a=n))break;d=u[s+a-1],p=u[s+a];}}}while((t=f[t&l])>h&&0!=--i);return a<=e.lookahead?a:e.lookahead}function j(e){var t,r,n,i,s,a,o,h,u,l,f=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=f+(f-z)){for(c.arraySet(e.window,e.window,f,f,0),e.match_start-=f,e.strstart-=f,e.block_start-=f,t=r=e.hash_size;n=e.head[--t],e.head[t]=f<=n?n-f:0,--r;);for(t=r=f;n=e.prev[--t],e.prev[t]=f<=n?n-f:0,--r;);i+=f;}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,h=e.strstart+e.lookahead,u=i,l=void 0,l=a.avail_in,u<l&&(l=u),r=0===l?0:(a.avail_in-=l,c.arraySet(o,a.input,a.next_in,l,h),1===a.state.wrap?a.adler=d(a.adler,o,l,h):2===a.state.wrap&&(a.adler=p(a.adler,o,l,h)),a.next_in+=l,a.total_in+=l,l),e.lookahead+=r,e.lookahead+e.insert>=x)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<<e.hash_shift^e.window[s+1])&e.hash_mask;e.insert&&(e.ins_h=(e.ins_h<<e.hash_shift^e.window[s+x-1])&e.hash_mask,e.prev[s&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=s,s++,e.insert--,!(e.lookahead+e.insert<x)););}while(e.lookahead<z&&0!==e.strm.avail_in)}function Z(e,t){for(var r,n;;){if(e.lookahead<z){if(j(e),e.lookahead<z&&t===l)return A;if(0===e.lookahead)break}if(r=0,e.lookahead>=x&&(e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+x-1])&e.hash_mask,r=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),0!==r&&e.strstart-r<=e.w_size-z&&(e.match_length=L(e,r)),e.match_length>=x)if(n=u._tr_tally(e,e.strstart-e.match_start,e.match_length-x),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=x){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+x-1])&e.hash_mask,r=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart,0!=--e.match_length;);e.strstart++;}else e.strstart+=e.match_length,e.match_length=0,e.ins_h=e.window[e.strstart],e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+1])&e.hash_mask;else n=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++;if(n&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=e.strstart<x-1?e.strstart:x-1,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}function W(e,t){for(var r,n,i;;){if(e.lookahead<z){if(j(e),e.lookahead<z&&t===l)return A;if(0===e.lookahead)break}if(r=0,e.lookahead>=x&&(e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+x-1])&e.hash_mask,r=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),e.prev_length=e.match_length,e.prev_match=e.match_start,e.match_length=x-1,0!==r&&e.prev_length<e.max_lazy_match&&e.strstart-r<=e.w_size-z&&(e.match_length=L(e,r),e.match_length<=5&&(1===e.strategy||e.match_length===x&&4096<e.strstart-e.match_start)&&(e.match_length=x-1)),e.prev_length>=x&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-x,n=u._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-x),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+x-1])&e.hash_mask,r=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),0!=--e.prev_length;);if(e.match_available=0,e.match_length=x-1,e.strstart++,n&&(N(e,!1),0===e.strm.avail_out))return A}else if(e.match_available){if((n=u._tr_tally(e,0,e.window[e.strstart-1]))&&N(e,!1),e.strstart++,e.lookahead--,0===e.strm.avail_out)return A}else e.match_available=1,e.strstart++,e.lookahead--;}return e.match_available&&(n=u._tr_tally(e,0,e.window[e.strstart-1]),e.match_available=0),e.insert=e.strstart<x-1?e.strstart:x-1,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}function M(e,t,r,n,i){this.good_length=e,this.max_lazy=t,this.nice_length=r,this.max_chain=n,this.func=i;}function H(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=v,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new c.Buf16(2*w),this.dyn_dtree=new c.Buf16(2*(2*a+1)),this.bl_tree=new c.Buf16(2*(2*o+1)),D(this.dyn_ltree),D(this.dyn_dtree),D(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new c.Buf16(k+1),this.heap=new c.Buf16(2*s+1),D(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new c.Buf16(2*s+1),D(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0;}function G(e){var t;return e&&e.state?(e.total_in=e.total_out=0,e.data_type=i,(t=e.state).pending=0,t.pending_out=0,t.wrap<0&&(t.wrap=-t.wrap),t.status=t.wrap?C:E,e.adler=2===t.wrap?0:1,t.last_flush=l,u._tr_init(t),m):R(e,_)}function K(e){var t=G(e);return t===m&&function(e){e.window_size=2*e.w_size,D(e.head),e.max_lazy_match=h[e.level].max_lazy,e.good_match=h[e.level].good_length,e.nice_match=h[e.level].nice_length,e.max_chain_length=h[e.level].max_chain,e.strstart=0,e.block_start=0,e.lookahead=0,e.insert=0,e.match_length=e.prev_length=x-1,e.match_available=0,e.ins_h=0;}(e.state),t}function Y(e,t,r,n,i,s){if(!e)return _;var a=1;if(t===g&&(t=6),n<0?(a=0,n=-n):15<n&&(a=2,n-=16),i<1||y<i||r!==v||n<8||15<n||t<0||9<t||s<0||b<s)return R(e,_);8===n&&(n=9);var o=new H;return (e.state=o).strm=e,o.wrap=a,o.gzhead=null,o.w_bits=n,o.w_size=1<<o.w_bits,o.w_mask=o.w_size-1,o.hash_bits=i+7,o.hash_size=1<<o.hash_bits,o.hash_mask=o.hash_size-1,o.hash_shift=~~((o.hash_bits+x-1)/x),o.window=new c.Buf8(2*o.w_size),o.head=new c.Buf16(o.hash_size),o.prev=new c.Buf16(o.w_size),o.lit_bufsize=1<<i+6,o.pending_buf_size=4*o.lit_bufsize,o.pending_buf=new c.Buf8(o.pending_buf_size),o.d_buf=1*o.lit_bufsize,o.l_buf=3*o.lit_bufsize,o.level=t,o.strategy=s,o.method=r,K(e)}h=[new M(0,0,0,0,function(e,t){var r=65535;for(r>e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(j(e),0===e.lookahead&&t===l)return A;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,N(e,!1),0===e.strm.avail_out))return A;if(e.strstart-e.block_start>=e.w_size-z&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):(e.strstart>e.block_start&&(N(e,!1),e.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(e,t){return Y(e,t,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?_:(e.state.gzhead=t,m):_},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5<t||t<0)return e?R(e,_):_;if(n=e.state,!e.output||!e.input&&0!==e.avail_in||666===n.status&&t!==f)return R(e,0===e.avail_out?-5:_);if(n.strm=e,r=n.last_flush,n.last_flush=t,n.status===C)if(2===n.wrap)e.adler=0,U(n,31),U(n,139),U(n,8),n.gzhead?(U(n,(n.gzhead.text?1:0)+(n.gzhead.hcrc?2:0)+(n.gzhead.extra?4:0)+(n.gzhead.name?8:0)+(n.gzhead.comment?16:0)),U(n,255&n.gzhead.time),U(n,n.gzhead.time>>8&255),U(n,n.gzhead.time>>16&255),U(n,n.gzhead.time>>24&255),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(U(n,255&n.gzhead.extra.length),U(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(U(n,0),U(n,0),U(n,0),U(n,0),U(n,0),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,3),n.status=E);else {var a=v+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=E,P(n,a),0!==n.strstart&&(P(n,e.adler>>>16),P(n,65535&e.adler)),e.adler=1;}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending!==n.pending_buf_size));)U(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73);}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindex<n.gzhead.name.length?255&n.gzhead.name.charCodeAt(n.gzindex++):0,U(n,s);}while(0!==s);n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91);}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindex<n.gzhead.comment.length?255&n.gzhead.comment.charCodeAt(n.gzindex++):0,U(n,s);}while(0!==s);n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103);}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&F(e),n.pending+2<=n.pending_buf_size&&(U(n,255&e.adler),U(n,e.adler>>8&255),e.adler=0,n.status=E)):n.status=E),0!==n.pending){if(F(e),0===e.avail_out)return n.last_flush=-1,m}else if(0===e.avail_in&&T(t)<=T(r)&&t!==f)return R(e,-5);if(666===n.status&&0!==e.avail_in)return R(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==l&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(j(e),0===e.lookahead)){if(t===l)return A;break}if(e.match_length=0,r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=S){if(j(e),e.lookahead<=S&&t===l)return A;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=x&&0<e.strstart&&(n=a[i=e.strstart-1])===a[++i]&&n===a[++i]&&n===a[++i]){s=e.strstart+S;do{}while(n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&i<s);e.match_length=S-(s-i),e.match_length>e.lookahead&&(e.match_length=e.lookahead);}if(e.match_length>=x?(r=u._tr_tally(e,1,e.match_length-x),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):h[n.level].func(n,t);if(o!==O&&o!==B||(n.status=666),o===A||o===O)return 0===e.avail_out&&(n.last_flush=-1),m;if(o===I&&(1===t?u._tr_align(n):5!==t&&(u._tr_stored_block(n,0,0,!1),3===t&&(D(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),F(e),0===e.avail_out))return n.last_flush=-1,m}return t!==f?m:n.wrap<=0?1:(2===n.wrap?(U(n,255&e.adler),U(n,e.adler>>8&255),U(n,e.adler>>16&255),U(n,e.adler>>24&255),U(n,255&e.total_in),U(n,e.total_in>>8&255),U(n,e.total_in>>16&255),U(n,e.total_in>>24&255)):(P(n,e.adler>>>16),P(n,65535&e.adler)),F(e),0<n.wrap&&(n.wrap=-n.wrap),0!==n.pending?m:1)},r.deflateEnd=function(e){var t;return e&&e.state?(t=e.state.status)!==C&&69!==t&&73!==t&&91!==t&&103!==t&&t!==E&&666!==t?R(e,_):(e.state=null,t===E?R(e,-3):m):_},r.deflateSetDictionary=function(e,t){var r,n,i,s,a,o,h,u,l=t.length;if(!e||!e.state)return _;if(2===(s=(r=e.state).wrap)||1===s&&r.status!==C||r.lookahead)return _;for(1===s&&(e.adler=d(e.adler,t,l,0)),r.wrap=0,l>=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new c.Buf8(r.w_size),c.arraySet(u,t,l-r.w_size,r.w_size,0),t=u,l=r.w_size),a=e.avail_in,o=e.next_in,h=e.input,e.avail_in=l,e.next_in=0,e.input=t,j(r);r.lookahead>=x;){for(n=r.strstart,i=r.lookahead-(x-1);r.ins_h=(r.ins_h<<r.hash_shift^r.window[n+x-1])&r.hash_mask,r.prev[n&r.w_mask]=r.head[r.ins_h],r.head[r.ins_h]=n,n++,--i;);r.strstart=n,r.lookahead=x-1,j(r);}return r.strstart+=r.lookahead,r.block_start=r.strstart,r.insert=r.lookahead,r.lookahead=0,r.match_length=r.prev_length=x-1,r.match_available=0,e.next_in=o,e.input=h,e.avail_in=a,r.wrap=s,m},r.deflateInfo="pako deflate (from Nodeca project)";},{"../utils/common":41,"./adler32":43,"./crc32":45,"./messages":51,"./trees":52}],47:[function(e,t,r){t.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1;};},{}],48:[function(e,t,r){t.exports=function(e,t){var r,n,i,s,a,o,h,u,l,f,c,d,p,m,_,g,b,v,y,w,k,x,S,z,C;r=e.state,n=e.next_in,z=e.input,i=n+(e.avail_in-5),s=e.next_out,C=e.output,a=s-(t-e.avail_out),o=s+(e.avail_out-257),h=r.dmax,u=r.wsize,l=r.whave,f=r.wnext,c=r.window,d=r.hold,p=r.bits,m=r.lencode,_=r.distcode,g=(1<<r.lenbits)-1,b=(1<<r.distbits)-1;e:do{p<15&&(d+=z[n++]<<p,p+=8,d+=z[n++]<<p,p+=8),v=m[d&g];t:for(;;){if(d>>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else {if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(d&(1<<y)-1)];continue t}if(32&y){r.mode=12;break e}e.msg="invalid literal/length code",r.mode=30;break e}w=65535&v,(y&=15)&&(p<y&&(d+=z[n++]<<p,p+=8),w+=d&(1<<y)-1,d>>>=y,p-=y),p<15&&(d+=z[n++]<<p,p+=8,d+=z[n++]<<p,p+=8),v=_[d&b];r:for(;;){if(d>>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(d&(1<<y)-1)];continue r}e.msg="invalid distance code",r.mode=30;break e}if(k=65535&v,p<(y&=15)&&(d+=z[n++]<<p,(p+=8)<y&&(d+=z[n++]<<p,p+=8)),h<(k+=d&(1<<y)-1)){e.msg="invalid distance too far back",r.mode=30;break e}if(d>>>=y,p-=y,(y=s-a)<k){if(l<(y=k-y)&&r.sane){e.msg="invalid distance too far back",r.mode=30;break e}if(S=c,(x=0)===f){if(x+=u-y,y<w){for(w-=y;C[s++]=c[x++],--y;);x=s-k,S=C;}}else if(f<y){if(x+=u+f-y,(y-=f)<w){for(w-=y;C[s++]=c[x++],--y;);if(x=0,f<w){for(w-=y=f;C[s++]=c[x++],--y;);x=s-k,S=C;}}}else if(x+=f-y,y<w){for(w-=y;C[s++]=c[x++],--y;);x=s-k,S=C;}for(;2<w;)C[s++]=S[x++],C[s++]=S[x++],C[s++]=S[x++],w-=3;w&&(C[s++]=S[x++],1<w&&(C[s++]=S[x++]));}else {for(x=s-k;C[s++]=C[x++],C[s++]=C[x++],C[s++]=C[x++],2<(w-=3););w&&(C[s++]=C[x++],1<w&&(C[s++]=C[x++]));}break}}break}}while(n<i&&s<o);n-=w=p>>3,d&=(1<<(p-=w<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n<i?i-n+5:5-(n-i),e.avail_out=s<o?o-s+257:257-(s-o),r.hold=d,r.bits=p;};},{}],49:[function(e,t,r){var I=e("../utils/common"),O=e("./adler32"),B=e("./crc32"),R=e("./inffast"),T=e("./inftrees"),D=1,F=2,N=0,U=-2,P=1,n=852,i=592;function L(e){return (e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0;}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function h(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15<t)?U:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=r,n.wbits=t,o(e))):U}function u(e,t){var r,n;return e?(n=new s,(e.state=n).window=null,(r=h(e,t))!==N&&(e.state=null),r):U}var l,f,c=!0;function j(e){if(c){var t;for(l=new I.Buf32(512),f=new I.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(T(D,e.lens,0,288,l,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;T(F,e.lens,0,32,f,0,e.work,{bits:5}),c=!1;}e.lencode=l,e.lenbits=9,e.distcode=f,e.distbits=5;}function Z(e,t,r,n){var i,s=e.state;return null===s.window&&(s.wsize=1<<s.wbits,s.wnext=0,s.whave=0,s.window=new I.Buf8(s.wsize)),n>=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave<s.wsize&&(s.whave+=i))),0}r.inflateReset=o,r.inflateReset2=h,r.inflateResetKeep=a,r.inflateInit=function(e){return u(e,15)},r.inflateInit2=u,r.inflate=function(e,t){var r,n,i,s,a,o,h,u,l,f,c,d,p,m,_,g,b,v,y,w,k,x,S,z,C=0,E=new I.Buf8(4),A=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!e||!e.state||!e.output||!e.input&&0!==e.avail_in)return U;12===(r=e.state).mode&&(r.mode=13),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,f=o,c=h,x=N;e:for(;;)switch(r.mode){case P:if(0===r.wrap){r.mode=13;break}for(;l<16;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if(2&r.wrap&&35615===u){E[r.check=0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){e.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<<k,e.adler=r.check=1,r.mode=512&u?10:12,l=u=0;break;case 2:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if(r.flags=u,8!=(255&r.flags)){e.msg="unknown compression method",r.mode=30;break}if(57344&r.flags){e.msg="unknown header flags set",r.mode=30;break}r.head&&(r.head.text=u>>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}r.head&&(r.head.time=u),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}r.head&&(r.head.xflags=255&u,r.head.os=u>>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}r.length=u,r.head&&(r.head.extra_len=u),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0;}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(d=r.length)&&(d=o),d&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,d,k)),512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,r.length-=d),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(d=0;k=n[s+d++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&d<o;);if(512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,k)break e}else r.head&&(r.head.name=null);r.length=0,r.mode=8;case 8:if(4096&r.flags){if(0===o)break e;for(d=0;k=n[s+d++],r.head&&k&&r.length<65536&&(r.head.comment+=String.fromCharCode(k)),k&&d<o;);if(512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,k)break e}else r.head&&(r.head.comment=null);r.mode=9;case 9:if(512&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if(u!==(65535&r.check)){e.msg="header crc mismatch",r.mode=30;break}l=u=0;}r.head&&(r.head.hcrc=r.flags>>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}e.adler=r.check=L(u),l=u=0,r.mode=11;case 11:if(0===r.havedict)return e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,2;e.adler=r.check=1,r.mode=12;case 12:if(5===t||6===t)break e;case 13:if(r.last){u>>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}switch(r.last=1&u,l-=1,3&(u>>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;u>>>=2,l-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30;}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if((65535&u)!=(u>>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(d=r.length){if(o<d&&(d=o),h<d&&(d=h),0===d)break e;I.arraySet(i,n,s,d,a),o-=d,s+=d,h-=d,a+=d,r.length-=d;break}r.mode=12;break;case 17:for(;l<14;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if(r.nlen=257+(31&u),u>>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286<r.nlen||30<r.ndist){e.msg="too many length or distance symbols",r.mode=30;break}r.have=0,r.mode=18;case 18:for(;r.have<r.ncode;){for(;l<3;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}r.lens[A[r.have++]]=7&u,u>>>=3,l-=3;}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have<r.nlen+r.ndist;){for(;g=(C=r.lencode[u&(1<<r.lenbits)-1])>>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if(b<16)u>>>=_,l-=_,r.lens[r.have++]=b;else {if(16===b){for(z=_+2;l<z;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if(u>>>=_,l-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],d=3+(3&u),u>>>=2,l-=2;}else if(17===b){for(z=_+3;l<z;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}l-=_,k=0,d=3+(7&(u>>>=_)),u>>>=3,l-=3;}else {for(z=_+7;l<z;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}l-=_,k=0,d=11+(127&(u>>>=_)),u>>>=7,l-=7;}if(r.have+d>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;d--;)r.lens[r.have++]=k;}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=h){e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,R(e,c),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<<r.lenbits)-1])>>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if(g&&0==(240&g)){for(v=_,y=g,w=b;g=(C=r.lencode[w+((u&(1<<v+y)-1)>>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}u>>>=v,l-=v,r.back+=v;}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l<z;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}r.length+=u&(1<<r.extra)-1,u>>>=r.extra,l-=r.extra,r.back+=r.extra;}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<<r.distbits)-1])>>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if(0==(240&g)){for(v=_,y=g,w=b;g=(C=r.distcode[w+((u&(1<<v+y)-1)>>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}u>>>=v,l-=v,r.back+=v;}if(u>>>=_,l-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l<z;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}r.offset+=u&(1<<r.extra)-1,u>>>=r.extra,l-=r.extra,r.back+=r.extra;}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break e;if(d=c-h,r.offset>d){if((d=r.offset-d)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=d>r.wnext?(d-=r.wnext,r.wsize-d):r.wnext-d,d>r.length&&(d=r.length),m=r.window;}else m=i,p=a-r.offset,d=r.length;for(h<d&&(d=h),h-=d,r.length-=d;i[a++]=m[p++],--d;);0===r.length&&(r.mode=21);break;case 26:if(0===h)break e;i[a++]=r.length,h--,r.mode=21;break;case 27:if(r.wrap){for(;l<32;){if(0===o)break e;o--,u|=n[s++]<<l,l+=8;}if(c-=h,e.total_out+=c,r.total+=c,c&&(e.adler=r.check=r.flags?B(r.check,i,c,a-c):O(r.check,i,c,a-c)),c=h,(r.flags?u:L(u))!==r.check){e.msg="incorrect data check",r.mode=30;break}l=u=0;}r.mode=28;case 28:if(r.wrap&&r.flags){for(;l<32;){if(0===o)break e;o--,u+=n[s++]<<l,l+=8;}if(u!==(4294967295&r.total)){e.msg="incorrect length check",r.mode=30;break}l=u=0;}r.mode=29;case 29:x=1;break e;case 30:x=-3;break e;case 31:return -4;case 32:default:return U}return e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,(r.wsize||c!==e.avail_out&&r.mode<30&&(r.mode<27||4!==t))&&Z(e,e.output,e.next_out,c-e.avail_out)?(r.mode=31,-4):(f-=e.avail_in,c-=e.avail_out,e.total_in+=f,e.total_out+=c,r.total+=c,r.wrap&&c&&(e.adler=r.check=r.flags?B(r.check,i,c,e.next_out-c):O(r.check,i,c,e.next_out-c)),e.data_type=r.bits+(r.last?64:0)+(12===r.mode?128:0)+(20===r.mode||15===r.mode?256:0),(0==f&&0===c||4===t)&&x===N&&(x=-5),x)},r.inflateEnd=function(e){if(!e||!e.state)return U;var t=e.state;return t.window&&(t.window=null),e.state=null,N},r.inflateGetHeader=function(e,t){var r;return e&&e.state?0==(2&(r=e.state).wrap)?U:((r.head=t).done=!1,N):U},r.inflateSetDictionary=function(e,t){var r,n=t.length;return e&&e.state?0!==(r=e.state).wrap&&11!==r.mode?U:11===r.mode&&O(1,t,n,0)!==r.check?-3:Z(e,t,n,n)?(r.mode=31,-4):(r.havedict=1,N):U},r.inflateInfo="pako inflate (from Nodeca project)";},{"../utils/common":41,"./adler32":43,"./crc32":45,"./inffast":48,"./inftrees":50}],50:[function(e,t,r){var D=e("../utils/common"),F=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],N=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],U=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],P=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];t.exports=function(e,t,r,n,i,s,a,o){var h,u,l,f,c,d,p,m,_,g=o.bits,b=0,v=0,y=0,w=0,k=0,x=0,S=0,z=0,C=0,E=0,A=null,I=0,O=new D.Buf16(16),B=new D.Buf16(16),R=null,T=0;for(b=0;b<=15;b++)O[b]=0;for(v=0;v<n;v++)O[t[r+v]]++;for(k=g,w=15;1<=w&&0===O[w];w--);if(w<k&&(k=w),0===w)return i[s++]=20971520,i[s++]=20971520,o.bits=1,0;for(y=1;y<w&&0===O[y];y++);for(k<y&&(k=y),b=z=1;b<=15;b++)if(z<<=1,(z-=O[b])<0)return -1;if(0<z&&(0===e||1!==w))return -1;for(B[1]=0,b=1;b<15;b++)B[b+1]=B[b]+O[b];for(v=0;v<n;v++)0!==t[r+v]&&(a[B[t[r+v]]++]=v);if(d=0===e?(A=R=a,19):1===e?(A=F,I-=257,R=N,T-=257,256):(A=U,R=P,-1),b=y,c=s,S=v=E=0,l=-1,f=(C=1<<(x=k))-1,1===e&&852<C||2===e&&592<C)return 1;for(;;){for(p=b-S,_=a[v]<d?(m=0,a[v]):a[v]>d?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<<b-S,y=u=1<<x;i[c+(E>>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<<b-1;E&h;)h>>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=t[r+a[v]];}if(k<b&&(E&f)!==l){for(0===S&&(S=k),c+=y,z=1<<(x=b-S);x+S<w&&!((z-=O[x+S])<=0);)x++,z<<=1;if(C+=1<<x,1===e&&852<C||2===e&&592<C)return 1;i[l=E&f]=k<<24|x<<16|c-s|0;}}return 0!==E&&(i[c+E]=b-S<<24|64<<16|0),o.bits=k,0};},{"../utils/common":41}],51:[function(e,t,r){t.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"};},{}],52:[function(e,t,r){var i=e("../utils/common"),o=0,h=1;function n(e){for(var t=e.length;0<=--t;)e[t]=0;}var s=0,a=29,u=256,l=u+1+a,f=30,c=19,_=2*l+1,g=15,d=16,p=7,m=256,b=16,v=17,y=18,w=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],k=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],x=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],S=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],z=new Array(2*(l+2));n(z);var C=new Array(2*f);n(C);var E=new Array(512);n(E);var A=new Array(256);n(A);var I=new Array(a);n(I);var O,B,R,T=new Array(f);function D(e,t,r,n,i){this.static_tree=e,this.extra_bits=t,this.extra_base=r,this.elems=n,this.max_length=i,this.has_stree=e&&e.length;}function F(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t;}function N(e){return e<256?E[e]:E[256+(e>>>7)]}function U(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255;}function P(e,t,r){e.bi_valid>d-r?(e.bi_buf|=t<<e.bi_valid&65535,U(e,e.bi_buf),e.bi_buf=t>>d-e.bi_valid,e.bi_valid+=r-d):(e.bi_buf|=t<<e.bi_valid&65535,e.bi_valid+=r);}function L(e,t,r){P(e,r[2*t],r[2*t+1]);}function j(e,t){for(var r=0;r|=1&e,e>>>=1,r<<=1,0<--t;);return r>>>1}function Z(e,t,r){var n,i,s=new Array(g+1),a=0;for(n=1;n<=g;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=j(s[o]++,o));}}function W(e){var t;for(t=0;t<l;t++)e.dyn_ltree[2*t]=0;for(t=0;t<f;t++)e.dyn_dtree[2*t]=0;for(t=0;t<c;t++)e.bl_tree[2*t]=0;e.dyn_ltree[2*m]=1,e.opt_len=e.static_len=0,e.last_lit=e.matches=0;}function M(e){8<e.bi_valid?U(e,e.bi_buf):0<e.bi_valid&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0;}function H(e,t,r,n){var i=2*t,s=2*r;return e[i]<e[s]||e[i]===e[s]&&n[t]<=n[r]}function G(e,t,r){for(var n=e.heap[r],i=r<<1;i<=e.heap_len&&(i<e.heap_len&&H(t,e.heap[i+1],e.heap[i],e.depth)&&i++,!H(t,n,e.heap[i],e.depth));)e.heap[r]=e.heap[i],r=i,i<<=1;e.heap[r]=n;}function K(e,t,r){var n,i,s,a,o=0;if(0!==e.last_lit)for(;n=e.pending_buf[e.d_buf+2*o]<<8|e.pending_buf[e.d_buf+2*o+1],i=e.pending_buf[e.l_buf+o],o++,0===n?L(e,i,t):(L(e,(s=A[i])+u+1,t),0!==(a=w[s])&&P(e,i-=I[s],a),L(e,s=N(--n),r),0!==(a=k[s])&&P(e,n-=T[s],a)),o<e.last_lit;);L(e,m,t);}function Y(e,t){var r,n,i,s=t.dyn_tree,a=t.stat_desc.static_tree,o=t.stat_desc.has_stree,h=t.stat_desc.elems,u=-1;for(e.heap_len=0,e.heap_max=_,r=0;r<h;r++)0!==s[2*r]?(e.heap[++e.heap_len]=u=r,e.depth[r]=0):s[2*r+1]=0;for(;e.heap_len<2;)s[2*(i=e.heap[++e.heap_len]=u<2?++u:0)]=1,e.depth[i]=0,e.opt_len--,o&&(e.static_len-=a[2*i+1]);for(t.max_code=u,r=e.heap_len>>1;1<=r;r--)G(e,s,r);for(i=h;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],G(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,G(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,f=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=g;s++)e.bl_count[s]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<_;r++)p<(s=h[2*h[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),h[2*n+1]=s,u<n||(e.bl_count[s]++,a=0,d<=n&&(a=c[n-d]),o=h[2*n],e.opt_len+=o*(s+a),f&&(e.static_len+=o*(l[2*n+1]+a)));if(0!==m){do{for(s=p-1;0===e.bl_count[s];)s--;e.bl_count[s]--,e.bl_count[s+1]+=2,e.bl_count[p]--,m-=2;}while(0<m);for(s=p;0!==s;s--)for(n=e.bl_count[s];0!==n;)u<(i=e.heap[--r])||(h[2*i+1]!==s&&(e.opt_len+=(s-h[2*i+1])*h[2*i],h[2*i+1]=s),n--);}}(e,t),Z(s,u,e.bl_count);}function X(e,t,r){var n,i,s=-1,a=t[1],o=0,h=7,u=4;for(0===a&&(h=138,u=3),t[2*(r+1)+1]=65535,n=0;n<=r;n++)i=a,a=t[2*(n+1)+1],++o<h&&i===a||(o<u?e.bl_tree[2*i]+=o:0!==i?(i!==s&&e.bl_tree[2*i]++,e.bl_tree[2*b]++):o<=10?e.bl_tree[2*v]++:e.bl_tree[2*y]++,s=i,u=(o=0)===a?(h=138,3):i===a?(h=6,3):(h=7,4));}function V(e,t,r){var n,i,s=-1,a=t[1],o=0,h=7,u=4;for(0===a&&(h=138,u=3),n=0;n<=r;n++)if(i=a,a=t[2*(n+1)+1],!(++o<h&&i===a)){if(o<u)for(;L(e,i,e.bl_tree),0!=--o;);else 0!==i?(i!==s&&(L(e,i,e.bl_tree),o--),L(e,b,e.bl_tree),P(e,o-3,2)):o<=10?(L(e,v,e.bl_tree),P(e,o-3,3)):(L(e,y,e.bl_tree),P(e,o-11,7));s=i,u=(o=0)===a?(h=138,3):i===a?(h=6,3):(h=7,4);}}n(T);var q=!1;function J(e,t,r,n){P(e,(s<<1)+(n?1:0),3),function(e,t,r,n){M(e),(U(e,r),U(e,~r)),i.arraySet(e.pending_buf,e.window,t,r,e.pending),e.pending+=r;}(e,t,r);}r._tr_init=function(e){q||(function(){var e,t,r,n,i,s=new Array(g+1);for(n=r=0;n<a-1;n++)for(I[n]=r,e=0;e<1<<w[n];e++)A[r++]=n;for(A[r-1]=n,n=i=0;n<16;n++)for(T[n]=i,e=0;e<1<<k[n];e++)E[i++]=n;for(i>>=7;n<f;n++)for(T[n]=i<<7,e=0;e<1<<k[n]-7;e++)E[256+i++]=n;for(t=0;t<=g;t++)s[t]=0;for(e=0;e<=143;)z[2*e+1]=8,e++,s[8]++;for(;e<=255;)z[2*e+1]=9,e++,s[9]++;for(;e<=279;)z[2*e+1]=7,e++,s[7]++;for(;e<=287;)z[2*e+1]=8,e++,s[8]++;for(Z(z,l+1,s),e=0;e<f;e++)C[2*e+1]=5,C[2*e]=j(e,5);O=new D(z,w,u+1,l,g),B=new D(C,k,0,f,g),R=new D(new Array(0),x,0,c,p);}(),q=!0),e.l_desc=new F(e.dyn_ltree,O),e.d_desc=new F(e.dyn_dtree,B),e.bl_desc=new F(e.bl_tree,R),e.bi_buf=0,e.bi_valid=0,W(e);},r._tr_stored_block=J,r._tr_flush_block=function(e,t,r,n){var i,s,a=0;0<e.level?(2===e.strm.data_type&&(e.strm.data_type=function(e){var t,r=4093624447;for(t=0;t<=31;t++,r>>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return o;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return h;for(t=32;t<u;t++)if(0!==e.dyn_ltree[2*t])return h;return o}(e)),Y(e,e.l_desc),Y(e,e.d_desc),a=function(e){var t;for(X(e,e.dyn_ltree,e.l_desc.max_code),X(e,e.dyn_dtree,e.d_desc.max_code),Y(e,e.bl_desc),t=c-1;3<=t&&0===e.bl_tree[2*S[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}(e),i=e.opt_len+3+7>>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?J(e,t,r,n):4===e.strategy||s===i?(P(e,2+(n?1:0),3),K(e,z,C)):(P(e,4+(n?1:0),3),function(e,t,r,n){var i;for(P(e,t-257,5),P(e,r-1,5),P(e,n-4,4),i=0;i<n;i++)P(e,e.bl_tree[2*S[i]+1],3);V(e,e.dyn_ltree,t-1),V(e,e.dyn_dtree,r-1);}(e,e.l_desc.max_code+1,e.d_desc.max_code+1,a+1),K(e,e.dyn_ltree,e.dyn_dtree)),W(e),n&&M(e);},r._tr_tally=function(e,t,r){return e.pending_buf[e.d_buf+2*e.last_lit]=t>>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(A[r]+u+1)]++,e.dyn_dtree[2*N(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){P(e,2,3),L(e,m,z),function(e){16===e.bi_valid?(U(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):8<=e.bi_valid&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8);}(e);};},{"../utils/common":41}],53:[function(e,t,r){t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0;};},{}],54:[function(e,t,r){(function(e){!function(r,n){if(!r.setImmediate){var i,s,t,a,o=1,h={},u=!1,l=r.document,e=Object.getPrototypeOf&&Object.getPrototypeOf(r);e=e&&e.setTimeout?e:r,i="[object process]"==={}.toString.call(r.process)?function(e){process.nextTick(function(){c(e);});}:function(){if(r.postMessage&&!r.importScripts){var e=!0,t=r.onmessage;return r.onmessage=function(){e=!1;},r.postMessage("","*"),r.onmessage=t,e}}()?(a="setImmediate$"+Math.random()+"$",r.addEventListener?r.addEventListener("message",d,!1):r.attachEvent("onmessage",d),function(e){r.postMessage(a+e,"*");}):r.MessageChannel?((t=new MessageChannel).port1.onmessage=function(e){c(e.data);},function(e){t.port2.postMessage(e);}):l&&"onreadystatechange"in l.createElement("script")?(s=l.documentElement,function(e){var t=l.createElement("script");t.onreadystatechange=function(){c(e),t.onreadystatechange=null,s.removeChild(t),t=null;},s.appendChild(t);}):function(e){setTimeout(c,0,e);},e.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),r=0;r<t.length;r++)t[r]=arguments[r+1];var n={callback:e,args:t};return h[o]=n,i(o),o++},e.clearImmediate=f;}function f(e){delete h[e];}function c(e){if(u)setTimeout(c,0,e);else {var t=h[e];if(t){u=!0;try{!function(e){var t=e.callback,r=e.args;switch(r.length){case 0:t();break;case 1:t(r[0]);break;case 2:t(r[0],r[1]);break;case 3:t(r[0],r[1],r[2]);break;default:t.apply(n,r);}}(t);}finally{f(e),u=!1;}}}}function d(e){e.source===r&&"string"==typeof e.data&&0===e.data.indexOf(a)&&c(+e.data.slice(a.length));}}("undefined"==typeof self?void 0===e?this:e:self);}).call(this,"undefined"!=typeof commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}]},{},[10])(10)});
- } (jszip_min));
- return jszip_min.exports;
- }
- var jszip_minExports = requireJszip_min();
- /**
- * Download a zip file from a url and return the bytes of the file as an ArrayBuffer.
- * @param url String url of the zip file to download.
- * @returns ArrayBuffer of the zip file.
- */
- const downloadZipFile = (url) => __awaiter(void 0, void 0, void 0, function* () {
- const fetched = yield obsidian.requestUrl({ url });
- const bytes = fetched.arrayBuffer;
- return bytes;
- });
- /**
- * Transforms a JSZip file into a File object.
- * @param file JSZip file to transform.
- * @returns File object of the JSZip file.
- */
- const getFileFromJSZipFile = (file) => __awaiter(void 0, void 0, void 0, function* () {
- const fileData = yield file.async('blob');
- const filename = file.name.split('/').pop();
- return new File([fileData], filename);
- });
- /**
- * Read a zip file and return the files inside it.
- * @param bytes ArrayBuffer of the zip file.
- * @param extraPath String path to filter the files inside the zip file. This can be used
- * to set an extra path (like a directory inside the zip file) to filter the files.
- * @returns Array of loaded files inside the zip file.
- */
- const readZipFile = (bytes_1, ...args_1) => __awaiter(void 0, [bytes_1, ...args_1], void 0, function* (bytes, extraPath = '') {
- const unzippedFiles = yield jszip_minExports.loadAsync(bytes);
- return Promise.resolve(unzippedFiles).then((unzipped) => {
- if (!Object.keys(unzipped.files).length) {
- return Promise.reject('No file was found');
- }
- const files = [];
- // Regex for retrieving the files inside the zip file or inside the directory of a
- // zip file.
- const regex = new RegExp(extraPath + '(.+)\\.svg', 'g');
- Object.entries(unzippedFiles.files).forEach(([_, v]) => {
- const matched = v.name.match(regex);
- if (!v.dir && matched && matched.length > 0) {
- files.push(v);
- }
- });
- return files;
- });
- });
- const PLUGIN_NAME = 'iconize';
- const TITLE_ICON_CLASS = 'iconize-title-icon';
- const INLINE_TITLE_WRAPPER_CLASS = 'iconize-inline-title-wrapper';
- /**
- * The name of the attribute that is used to store the icon name in the node.
- * The value of this attributes contains the prefix and the name of the icon.
- */
- const ICON_ATTRIBUTE_NAME = 'data-icon';
- var config = {
- PLUGIN_NAME,
- TITLE_ICON_CLASS,
- INLINE_TITLE_WRAPPER_CLASS,
- ICON_ATTRIBUTE_NAME,
- };
- var LoggerPrefix;
- (function (LoggerPrefix) {
- LoggerPrefix["Outline"] = "Outline";
- })(LoggerPrefix || (LoggerPrefix = {}));
- class ConsoleLogger {
- constructor(projectPrefix, enabled = false) {
- this.logLevels = {
- log: { label: 'LOG:' },
- info: { label: 'INFO:' },
- warn: { label: 'WARN:' },
- error: { label: 'ERROR:' },
- };
- this.projectPrefix = projectPrefix;
- this.enabled = enabled;
- }
- formatMessage(level, message, prefix, optionalParams) {
- const timestamp = new Date().toISOString();
- const { label } = this.logLevels[level];
- const prefixAsStr = !prefix ? '' : `/${prefix}`;
- return [
- `${this.projectPrefix}${prefixAsStr}: [${timestamp}] ${label} ${message}`,
- ...optionalParams,
- ];
- }
- log(message, prefix, ...optionalParams) {
- if (this.enabled) {
- console.log(...this.formatMessage('log', message, prefix, optionalParams));
- }
- }
- info(message, prefix, ...optionalParams) {
- if (this.enabled) {
- console.info(...this.formatMessage('info', message, prefix, optionalParams));
- }
- }
- warn(message, prefix, ...optionalParams) {
- if (this.enabled) {
- console.warn(...this.formatMessage('warn', message, prefix, optionalParams));
- }
- }
- error(message, prefix, ...optionalParams) {
- if (this.enabled) {
- console.error(...this.formatMessage('error', message, prefix, optionalParams));
- }
- }
- toggleLogging(enabled) {
- this.enabled = enabled;
- }
- }
- const logger = new ConsoleLogger(config.PLUGIN_NAME);
- const LUCIDE_ICON_PACK_NAME = 'lucide-icons';
- let path;
- const getPath = () => {
- return path;
- };
- const setPath = (newPath) => {
- if (newPath === 'plugins/obsidian-icon-folder/icons') {
- newPath = '.obsidian/plugins/obsidian-icon-folder/icons';
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Due to a change in version v1.2.2, the icon pack folder changed. Please change it in the settings to not be directly in /plugins.`, 8000);
- }
- path = newPath;
- };
- let preloadedIcons = [];
- const getPreloadedIcons = () => {
- return preloadedIcons;
- };
- const resetPreloadedIcons = () => {
- preloadedIcons = [];
- };
- let iconPacks = [];
- const addLucideIconsPack = (plugin) => {
- iconPacks.push({
- name: LUCIDE_ICON_PACK_NAME,
- prefix: 'Li',
- custom: false,
- icons: plugin.doesUseNativeLucideIconPack()
- ? obsidian.getIconIds()
- .map((iconId) => iconId.replace(/^lucide-/, ''))
- .map((iconId) => {
- const iconEl = obsidian.getIcon(iconId);
- iconEl.removeClass('svg-icon'); // Removes native `svg-icon` class.
- return {
- name: getNormalizedName(iconId),
- filename: iconId,
- prefix: 'Li',
- svgElement: iconEl === null || iconEl === void 0 ? void 0 : iconEl.outerHTML,
- svgContent: iconEl === null || iconEl === void 0 ? void 0 : iconEl.innerHTML,
- svgViewbox: '',
- iconPackName: LUCIDE_ICON_PACK_NAME,
- };
- })
- : [],
- });
- };
- const addCustomLucideIconPack = (plugin) => __awaiter(void 0, void 0, void 0, function* () {
- const iconPackIndex = iconPacks.findIndex((iconPack) => iconPack.name === LUCIDE_ICON_PACK_NAME);
- if (iconPackIndex > -1) {
- iconPacks.splice(iconPackIndex);
- }
- const iconPack = iconPacks$1['lucide'];
- const arrayBuffer = yield downloadZipFile(iconPack.downloadLink);
- yield createZipFile(plugin, `${iconPack.name}.zip`, arrayBuffer);
- yield registerIconPack(iconPack.name, arrayBuffer);
- });
- const removeCustomLucideIconPack = (plugin) => __awaiter(void 0, void 0, void 0, function* () {
- const iconPackIndex = iconPacks.findIndex((iconPack) => iconPack.name === LUCIDE_ICON_PACK_NAME);
- if (iconPackIndex > -1) {
- iconPacks.splice(iconPackIndex);
- }
- yield deleteIconPack(plugin, LUCIDE_ICON_PACK_NAME);
- });
- const moveIconPackDirectories = (plugin, from, to) => __awaiter(void 0, void 0, void 0, function* () {
- // Tries to move all icon packs to the new folder.
- for (let i = 0; i < iconPacks.length; i++) {
- const iconPack = iconPacks[i];
- if (yield plugin.app.vault.adapter.exists(`${from}/${iconPack.name}`)) {
- // Tries to create a new directory in the new path.
- const doesDirExist = yield createDirectory(plugin, iconPack.name);
- if (doesDirExist) {
- new obsidian.Notice(`Directory with name ${iconPack.name} already exists.`);
- continue;
- }
- }
- new obsidian.Notice(`Moving ${iconPack.name}...`);
- // Move the zip file.
- if (yield plugin.app.vault.adapter.exists(`${from}/${iconPack.name}.zip`)) {
- yield plugin.app.vault.adapter.copy(`${from}/${iconPack.name}.zip`, `${to}/${iconPack.name}.zip`);
- }
- // Move all other files inside of the iconpack directory.
- const filesInDirectory = yield getFilesInDirectory(plugin, `${from}/${iconPack.name}`);
- for (const file of filesInDirectory) {
- const fileName = file.split('/').pop();
- yield plugin.app.vault.adapter.copy(`${from}/${iconPack.name}/${fileName}`, `${to}/${iconPack.name}/${fileName}`);
- }
- new obsidian.Notice(`...moved ${iconPack.name}`);
- }
- // Removes all the existing icon packs in the `from` directory.
- for (let i = 0; i < iconPacks.length; i++) {
- const iconPack = iconPacks[i];
- if (yield plugin.app.vault.adapter.exists(`${from}/${iconPack.name}`)) {
- yield plugin.app.vault.adapter.rmdir(`${from}/${iconPack.name}`, true);
- }
- }
- // Remove root directory that contains all the icon packs.
- if (!to.startsWith(from)) {
- yield plugin.app.vault.adapter.rmdir(`${from}`, true);
- }
- });
- const createCustomIconPackDirectory = (plugin, dir) => __awaiter(void 0, void 0, void 0, function* () {
- yield createDirectory(plugin, dir);
- const prefix = createIconPackPrefix(dir);
- iconPacks.push({ name: dir, icons: [], prefix, custom: true });
- });
- const deleteIconPack = (plugin, dir) => __awaiter(void 0, void 0, void 0, function* () {
- iconPacks = iconPacks.filter((iconPack) => iconPack.name !== dir);
- // Check for the icon pack directory and delete it.
- if (yield plugin.app.vault.adapter.exists(`${path}/${dir}`)) {
- yield plugin.app.vault.adapter.rmdir(`${path}/${dir}`, true);
- }
- // Check for the icon pack zip file and delete it.
- if (yield plugin.app.vault.adapter.exists(`${path}/${dir}.zip`)) {
- yield plugin.app.vault.adapter.remove(`${path}/${dir}.zip`);
- }
- });
- const doesIconPackExist = (plugin, iconPackName) => {
- return plugin.app.vault.adapter.exists(`${path}/${iconPackName}`);
- };
- const createDirectory = (plugin, dir) => __awaiter(void 0, void 0, void 0, function* () {
- const doesDirExist = yield plugin.app.vault.adapter.exists(`${path}/${dir}`);
- if (!doesDirExist) {
- yield plugin.app.vault.adapter.mkdir(`${path}/${dir}`);
- }
- return doesDirExist;
- });
- const getNormalizedName = (s) => {
- return s
- .split(/[ -]|[ _]/g)
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
- .join('');
- };
- // export const normalizeFileName = async (plugin: Plugin, oldPath: string) => {
- // const fileName = oldPath.split('/').pop();
- // const newPath = oldPath.substring(0, oldPath.indexOf(fileName)) + getNormalizedName(fileName);
- // await plugin.app.vault.adapter.rename(oldPath, newPath);
- // };
- const createZipFile = (plugin, filename, buffer) => __awaiter(void 0, void 0, void 0, function* () {
- yield plugin.app.vault.adapter.writeBinary(`${path}/${filename}`, buffer);
- });
- const createFile = (plugin, iconPackName, filename, content, absoluteFilename) => __awaiter(void 0, void 0, void 0, function* () {
- const normalizedFilename = getNormalizedName(filename);
- const exists = yield plugin.app.vault.adapter.exists(`${path}/${iconPackName}/${normalizedFilename}`);
- if (exists) {
- const folderSplit = absoluteFilename.split('/');
- if (folderSplit.length >= 2) {
- const folderName = folderSplit[folderSplit.length - 2];
- const newFilename = folderName + normalizedFilename;
- yield plugin.app.vault.adapter.write(`${path}/${iconPackName}/${newFilename}`, content);
- logger.info(`Renamed old file ${normalizedFilename} to ${newFilename} due to duplication`);
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Renamed ${normalizedFilename} to ${newFilename} to avoid duplication.`, 8000);
- }
- else {
- logger.warn(`Could not create icons with duplicated file names (file name: ${normalizedFilename})`);
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Could not create duplicated icon name (${normalizedFilename})`, 8000);
- }
- }
- else {
- yield plugin.app.vault.adapter.write(`${path}/${iconPackName}/${normalizedFilename}`, content);
- }
- });
- const createDefaultDirectory = (plugin) => __awaiter(void 0, void 0, void 0, function* () {
- yield createDirectory(plugin, '');
- });
- const getAllIconPacks = () => {
- return iconPacks;
- };
- const getFilesInDirectory = (plugin, dir) => __awaiter(void 0, void 0, void 0, function* () {
- if (!(yield plugin.app.vault.adapter.exists(dir))) {
- return [];
- }
- return (yield plugin.app.vault.adapter.list(dir)).files;
- });
- const validIconName = /^[(A-Z)|(0-9)]/;
- const svgViewboxRegex = /viewBox="([^"]*)"/g;
- const svgContentRegex = /<svg.*>(.*?)<\/svg>/g;
- const generateIcon = (iconPackName, iconName, content) => {
- if (content.length === 0) {
- return;
- }
- content = content.replace(/(\r\n|\n|\r)/gm, '');
- content = content.replace(/>\s+</gm, '><');
- const normalizedName = iconName.charAt(0).toUpperCase() + iconName.substring(1);
- if (!validIconName.exec(normalizedName)) {
- logger.info(`Skipping icon with invalid name: ${iconName}`);
- return null;
- }
- const svgViewboxMatch = content.match(svgViewboxRegex);
- let svgViewbox = '';
- if (svgViewboxMatch && svgViewboxMatch.length !== 0) {
- svgViewbox = svgViewboxMatch[0];
- }
- const svgContentMatch = content.match(svgContentRegex);
- if (!svgContentMatch) {
- logger.info(`Skipping icon with invalid svg content: ${iconName}`);
- return null;
- }
- const svgContent = svgContentMatch.map((val) => val.replace(/<\/?svg>/g, '').replace(/<svg.+?>/g, ''))[0];
- const iconPackPrefix = createIconPackPrefix(iconPackName);
- const icon = {
- name: normalizedName.split('.svg')[0],
- prefix: iconPackPrefix,
- iconPackName,
- filename: iconName,
- svgContent,
- svgViewbox,
- svgElement: svg.extract(content),
- };
- return icon;
- };
- const createIconPackPrefix = (iconPackName) => {
- if (iconPackName.includes('-')) {
- const splitted = iconPackName.split('-');
- let result = splitted[0].charAt(0).toUpperCase();
- for (let i = 1; i < splitted.length; i++) {
- result += splitted[i].charAt(0).toLowerCase();
- }
- return result;
- }
- return (iconPackName.charAt(0).toUpperCase() + iconPackName.charAt(1).toLowerCase());
- };
- const loadUsedIcons = (plugin, icons) => __awaiter(void 0, void 0, void 0, function* () {
- const iconPacks = (yield listPath(plugin)).folders.map((iconPack) => iconPack.split('/').pop());
- if (plugin.doesUseNativeLucideIconPack()) {
- iconPacks.push(LUCIDE_ICON_PACK_NAME);
- }
- for (let i = 0; i < icons.length; i++) {
- const entry = icons[i];
- if (!entry) {
- continue;
- }
- yield loadIcon(plugin, iconPacks, entry);
- }
- });
- const listPath = (plugin, listPath) => {
- return plugin.app.vault.adapter.list(path);
- };
- const getIconPackNameByPrefix = (prefix) => {
- var _a;
- return (_a = iconPacks.find((iconPack) => iconPack.prefix === prefix)) === null || _a === void 0 ? void 0 : _a.name;
- };
- const nextIdentifier = (iconName) => {
- return iconName.substring(1).search(/[(A-Z)|(0-9)]/) + 1;
- };
- const loadIcon = (plugin, iconPackNames, iconName) => __awaiter(void 0, void 0, void 0, function* () {
- const nextLetter = nextIdentifier(iconName);
- const prefix = iconName.substring(0, nextLetter);
- const name = iconName.substring(nextLetter);
- const iconPack = iconPackNames.find((folder) => {
- const folderPrefix = createIconPackPrefix(folder);
- return prefix === folderPrefix;
- });
- if (!iconPack) {
- // Ignore because background check automatically adds the icons and icon pack
- // directories.
- if (!plugin.getSettings().iconsBackgroundCheckEnabled) {
- new obsidian.Notice(`Seems like you do not have an icon pack installed. (${iconName})`, 5000);
- }
- return;
- }
- if (iconPack === LUCIDE_ICON_PACK_NAME &&
- plugin.doesUseNativeLucideIconPack()) {
- // Native lucide icons already exist for Obsidian.
- const lucideIcons = iconPacks.find((iconPack) => iconPack.name === LUCIDE_ICON_PACK_NAME);
- const icon = lucideIcons.icons.find((icon) => icon.name === name);
- if (!icon) {
- logger.warn(`Icon ${icon} does not exist in the native Lucide icon pack.`);
- return;
- }
- preloadedIcons.push(icon);
- return;
- }
- const fullPath = path + '/' + iconPack + '/' + name + '.svg';
- if (!(yield plugin.app.vault.adapter.exists(fullPath))) {
- logger.info(`Icon with name '${name}' was not found (full path: ${fullPath})`);
- return;
- }
- const content = yield plugin.app.vault.adapter.read(fullPath);
- const icon = generateIcon(iconPack, name, content);
- preloadedIcons.push(icon);
- });
- const initIconPacks = (plugin) => __awaiter(void 0, void 0, void 0, function* () {
- // Remove the beginning slash because paths which start with `/` are the same as without
- // a slash.
- if (path.startsWith('/')) {
- path = path.slice(1);
- }
- const loadedIconPacks = yield plugin.app.vault.adapter.list(path);
- // Extract all zip files which will be downloaded icon packs.
- const zipFiles = {};
- for (let i = 0; i < loadedIconPacks.files.length; i++) {
- const fileName = loadedIconPacks.files[i];
- if (fileName.endsWith('.zip')) {
- const arrayBuffer = yield plugin.app.vault.adapter.readBinary(fileName);
- const files = yield readZipFile(arrayBuffer);
- const iconPackName = fileName.split('/').pop().split('.zip')[0];
- zipFiles[iconPackName] = files;
- }
- }
- // Check for custom-made icon packs.
- for (let i = 0; i < loadedIconPacks.folders.length; i++) {
- const folderName = loadedIconPacks.folders[i].split('/').pop();
- // Continue if the icon pack does have a zip file.
- if (zipFiles[folderName]) {
- continue;
- }
- const files = yield getFilesInDirectory(plugin, `${path}/${folderName}`);
- const loadedIcons = [];
- // Convert files into loaded svgs.
- for (let j = 0; j < files.length; j++) {
- const iconNameRegex = files[j].match(new RegExp(path + '/' + folderName + '/(.*)'));
- const iconName = getNormalizedName(iconNameRegex[1]);
- const iconContent = yield plugin.app.vault.adapter.read(files[j]);
- const icon = generateIcon(folderName, iconName, iconContent);
- if (icon) {
- loadedIcons.push(icon);
- }
- }
- const prefix = createIconPackPrefix(folderName);
- if (!iconPacks.some((iconPack) => iconPack.name === folderName)) {
- iconPacks.push({
- name: folderName,
- icons: loadedIcons,
- prefix,
- custom: true,
- });
- logger.info(`Loaded icon pack '${folderName}' (amount of icons: ${loadedIcons.length})`);
- }
- }
- // Extract all files from the zip files.
- for (const zipFile in zipFiles) {
- const files = zipFiles[zipFile];
- const loadedIcons = yield getLoadedIconsFromZipFile(zipFile, files);
- const prefix = createIconPackPrefix(zipFile);
- if (zipFile === LUCIDE_ICON_PACK_NAME &&
- !plugin.doesUseCustomLucideIconPack()) {
- continue;
- }
- if (!iconPacks.some((iconPack) => iconPack.name === zipFile)) {
- iconPacks.push({
- name: zipFile,
- icons: loadedIcons,
- prefix,
- custom: false,
- });
- logger.info(`Loaded icon pack '${zipFile}' (amount of icons: ${loadedIcons.length})`);
- }
- }
- });
- const getLoadedIconsFromZipFile = (iconPackName, files) => __awaiter(void 0, void 0, void 0, function* () {
- const loadedIcons = [];
- const extraPath = getExtraPath(iconPackName);
- for (let j = 0; j < files.length; j++) {
- // Checks if the icon pack has an extra path. Also ignores files which do not start
- // with the extra path.
- if (extraPath && !files[j].name.startsWith(extraPath)) {
- continue;
- }
- const file = yield getFileFromJSZipFile(files[j]);
- const iconContent = yield file.text();
- const iconName = getNormalizedName(file.name);
- const icon = generateIcon(iconPackName, iconName, iconContent);
- if (icon) {
- loadedIcons.push(icon);
- }
- }
- return loadedIcons;
- });
- const addIconToIconPack = (iconPackName, iconName, iconContent) => {
- // Normalize the icon name to remove `-` or `_` in the name.
- iconName = getNormalizedName(iconName);
- const icon = generateIcon(iconPackName, iconName, iconContent);
- if (!icon) {
- logger.warn(`Icon could not be generated (icon: ${iconName}, content: ${iconContent})`);
- return undefined;
- }
- const iconPack = iconPacks.find((iconPack) => iconPack.name === iconPackName);
- if (!iconPack) {
- logger.warn(`Iconpack with name '${iconPackName}' was not found`);
- return undefined;
- }
- iconPack.icons.push(icon);
- return icon;
- };
- const removeIconFromIconPackDirectory = (plugin, iconPackName, iconName) => {
- const iconPack = iconPacks.find((iconPack) => iconPack.name === iconPackName);
- // Checks if icon pack is custom-made.
- if (!iconPack.custom) {
- return plugin.app.vault.adapter.rmdir(`${path}/${iconPackName}/${iconName}.svg`, true);
- }
- };
- const extractIconToIconPack = (plugin, icon, iconContent) => __awaiter(void 0, void 0, void 0, function* () {
- const doesIconPackDirExist = yield plugin.app.vault.adapter.exists(`${path}/${icon.iconPackName}`);
- if (!doesIconPackDirExist) {
- yield plugin.app.vault.adapter.mkdir(`${path}/${icon.iconPackName}`);
- }
- const doesIconFileExists = yield plugin.app.vault.adapter.exists(`${path}/${icon.iconPackName}/${icon.name}.svg`);
- if (!doesIconFileExists) {
- yield createFile(plugin, icon.iconPackName, `${icon.name}.svg`, iconContent);
- }
- });
- const getAllLoadedIconNames = () => {
- return iconPacks.reduce((total, iconPack) => {
- total.push(...iconPack.icons);
- return total;
- }, []);
- };
- const registerIconPack = (name, arrayBuffer) => __awaiter(void 0, void 0, void 0, function* () {
- const files = yield readZipFile(arrayBuffer);
- const loadedIcons = yield getLoadedIconsFromZipFile(name, files);
- const prefix = createIconPackPrefix(name);
- iconPacks.push({ name, icons: loadedIcons, prefix, custom: false });
- logger.info(`Loaded icon pack ${name} (amount of icons: ${loadedIcons.length})`);
- });
- const doesIconExists = (iconName) => {
- const icons = getAllLoadedIconNames();
- return (icons.find((icon) => icon.name === iconName || icon.prefix + icon.name === iconName) !== undefined);
- };
- const getIconsFromIconPack = (iconPackName) => {
- return iconPacks.find((iconPack) => iconPack.name === iconPackName);
- };
- const getIconFromIconPack = (iconPackName, iconPrefix, iconName) => {
- const foundIcon = preloadedIcons.find((icon) => icon.prefix.toLowerCase() === iconPrefix.toLowerCase() &&
- icon.name.toLowerCase() === iconName.toLowerCase());
- if (foundIcon) {
- return foundIcon;
- }
- const iconPack = iconPacks.find((iconPack) => iconPack.name === iconPackName);
- if (!iconPack) {
- return undefined;
- }
- return iconPack.icons.find((icon) => getNormalizedName(icon.name) === iconName);
- };
- const getSvgFromLoadedIcon = (iconPrefix, iconName) => {
- let icon = '';
- let foundIcon = preloadedIcons.find((icon) => icon.prefix.toLowerCase() === iconPrefix.toLowerCase() &&
- icon.name.toLowerCase() === iconName.toLowerCase());
- if (!foundIcon) {
- iconPacks.forEach((iconPack) => {
- const icon = iconPack.icons.find((icon) => {
- return (icon.prefix.toLowerCase() === iconPrefix.toLowerCase() &&
- getNormalizedName(icon.name).toLowerCase() === iconName.toLowerCase());
- });
- if (icon) {
- foundIcon = icon;
- }
- });
- }
- if (foundIcon) {
- icon = foundIcon.svgElement;
- }
- return icon;
- };
- /*! Copyright Twitter Inc. and other contributors. Licensed under MIT */
- var twemoji=function(){var twemoji={base:"https://cdn.jsdelivr.net/gh/jdecked/twemoji@15.1.0/assets/",ext:".png",size:"72x72",className:"emoji",convert:{fromCodePoint:fromCodePoint,toCodePoint:toCodePoint},onerror:function onerror(){if(this.parentNode){this.parentNode.replaceChild(createText(this.alt,false),this);}},parse:parse,replace:replace,test:test},escaper={"&":"&","<":"<",">":">","'":"'",'"':"""},re=/(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91]|\ud83e\udd1d)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])(?:\u200d\u27a1\ufe0f)?|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f(?:\u200d\u27a1\ufe0f)?)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f(?:\u200d\u27a1\ufe0f)?|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u26d3\ufe0f\u200d\ud83d\udca5|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udf44\u200d\ud83d\udfeb|\ud83c\udf4b\u200d\ud83d\udfe9|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc26\u200d\ud83d\udd25|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83d\ude42\u200d\u2194\ufe0f|\ud83d\ude42\u200d\u2195\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b|\ud83d\udc26\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|\ud83e\udef0|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c\udfc3|\ud83d\udeb6|\ud83e\uddce)(?:\ud83c[\udffb-\udfff])?(?:\u200d\u27a1\ufe0f)?|(?:\ud83c[\udf85\udfc2\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4\udeb5\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd\uddcf\uddd1-\udddd\udec3-\udec5\udef1-\udef8]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedc-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude7c\ude80-\ude88\ude90-\udebd\udebf-\udec2\udece-\udedb\udee0-\udee8]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,UFE0Fg=/\uFE0F/g,U200D=String.fromCharCode(8205),rescaper=/[&<>'"]/g,shouldntBeParsed=/^(?:iframe|noframes|noscript|script|select|style|textarea)$/,fromCharCode=String.fromCharCode;return twemoji;function createText(text,clean){return document.createTextNode(clean?text.replace(UFE0Fg,""):text)}function escapeHTML(s){return s.replace(rescaper,replacer)}function defaultImageSrcGenerator(icon,options){return "".concat(options.base,options.size,"/",icon,options.ext)}function grabAllTextNodes(node,allText){var childNodes=node.childNodes,length=childNodes.length,subnode,nodeType;while(length--){subnode=childNodes[length];nodeType=subnode.nodeType;if(nodeType===3){allText.push(subnode);}else if(nodeType===1&&!("ownerSVGElement"in subnode)&&!shouldntBeParsed.test(subnode.nodeName.toLowerCase())){grabAllTextNodes(subnode,allText);}}return allText}function grabTheRightIcon(rawText){return toCodePoint(rawText.indexOf(U200D)<0?rawText.replace(UFE0Fg,""):rawText)}function parseNode(node,options){var allText=grabAllTextNodes(node,[]),length=allText.length,attrib,attrname,modified,fragment,subnode,text,match,i,index,img,rawText,iconId,src;while(length--){modified=false;fragment=document.createDocumentFragment();subnode=allText[length];text=subnode.nodeValue;i=0;while(match=re.exec(text)){index=match.index;if(index!==i){fragment.appendChild(createText(text.slice(i,index),true));}rawText=match[0];iconId=grabTheRightIcon(rawText);i=index+rawText.length;src=options.callback(iconId,options);if(iconId&&src){img=new Image;img.onerror=options.onerror;img.setAttribute("draggable","false");attrib=options.attributes(rawText,iconId);for(attrname in attrib){if(attrib.hasOwnProperty(attrname)&&attrname.indexOf("on")!==0&&!img.hasAttribute(attrname)){img.setAttribute(attrname,attrib[attrname]);}}img.className=options.className;img.alt=rawText;img.src=src;modified=true;fragment.appendChild(img);}if(!img)fragment.appendChild(createText(rawText,false));img=null;}if(modified){if(i<text.length){fragment.appendChild(createText(text.slice(i),true));}subnode.parentNode.replaceChild(fragment,subnode);}}return node}function parseString(str,options){return replace(str,function(rawText){var ret=rawText,iconId=grabTheRightIcon(rawText),src=options.callback(iconId,options),attrib,attrname;if(iconId&&src){ret="<img ".concat('class="',options.className,'" ','draggable="false" ','alt="',rawText,'"',' src="',src,'"');attrib=options.attributes(rawText,iconId);for(attrname in attrib){if(attrib.hasOwnProperty(attrname)&&attrname.indexOf("on")!==0&&ret.indexOf(" "+attrname+"=")===-1){ret=ret.concat(" ",attrname,'="',escapeHTML(attrib[attrname]),'"');}}ret=ret.concat("/>");}return ret})}function replacer(m){return escaper[m]}function returnNull(){return null}function toSizeSquaredAsset(value){return typeof value==="number"?value+"x"+value:value}function fromCodePoint(codepoint){var code=typeof codepoint==="string"?parseInt(codepoint,16):codepoint;if(code<65536){return fromCharCode(code)}code-=65536;return fromCharCode(55296+(code>>10),56320+(code&1023))}function parse(what,how){if(!how||typeof how==="function"){how={callback:how};}return (typeof what==="string"?parseString:parseNode)(what,{callback:how.callback||defaultImageSrcGenerator,attributes:typeof how.attributes==="function"?how.attributes:returnNull,base:typeof how.base==="string"?how.base:twemoji.base,ext:how.ext||twemoji.ext,size:how.folder||toSizeSquaredAsset(how.size||twemoji.size),className:how.className||twemoji.className,onerror:how.onerror||twemoji.onerror})}function replace(text,callback){return String(text).replace(re,callback)}function test(text){re.lastIndex=0;var result=re.test(text);re.lastIndex=0;return result}function toCodePoint(unicodeSurrogates,sep){var r=[],c=0,p=0,i=0;while(i<unicodeSurrogates.length){c=unicodeSurrogates.charCodeAt(i++);if(p){r.push((65536+(p-55296<<10)+(c-56320)).toString(16));p=0;}else if(55296<=c&&c<=56319){p=c;}else {r.push(c.toString(16));}}return r.join(sep||"-")}}();
- const getRegex = () => {
- return new RegExp(/[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC2\uDECE-\uDEDB\uDEE0-\uDEE8]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/, 'g');
- };
- const shortNames = {
- '😀': 'grinning face',
- '😃': 'grinning face with big eyes',
- '😄': 'grinning face with smiling eyes',
- '😁': 'beaming face with smiling eyes',
- '😆': 'grinning squinting face',
- '😅': 'grinning face with sweat',
- '🤣': 'rolling on the floor laughing',
- '😂': 'face with tears of joy',
- '🙂': 'slightly smiling face',
- '🙃': 'upside-down face',
- '🫠': '⊛ melting face',
- '😉': 'winking face',
- '😊': 'smiling face with smiling eyes',
- '😇': 'smiling face with halo',
- '🥰': 'smiling face with hearts',
- '😍': 'smiling face with heart-eyes',
- '🤩': 'star-struck',
- '😘': 'face blowing a kiss',
- '😗': 'kissing face',
- '☺': 'smiling face',
- '😚': 'kissing face with closed eyes',
- '😙': 'kissing face with smiling eyes',
- '🥲': 'smiling face with tear',
- '😋': 'face savoring food',
- '😛': 'face with tongue',
- '😜': 'winking face with tongue',
- '🤪': 'zany face',
- '😝': 'squinting face with tongue',
- '🤑': 'money-mouth face',
- '🤗': 'smiling face with open hands',
- '🤭': 'face with hand over mouth',
- '🫢': '⊛ face with open eyes and hand over mouth',
- '🫣': '⊛ face with peeking eye',
- '🤫': 'shushing face',
- '🤔': 'thinking face',
- '🫡': '⊛ saluting face',
- '🤐': 'zipper-mouth face',
- '🤨': 'face with raised eyebrow',
- '😐': 'neutral face',
- '😑': 'expressionless face',
- '😶': 'face without mouth',
- '🫥': '⊛ dotted line face',
- '😶🌫️': 'face in clouds',
- '😏': 'smirking face',
- '😒': 'unamused face',
- '🙄': 'face with rolling eyes',
- '😬': 'grimacing face',
- '😮💨': 'face exhaling',
- '🤥': 'lying face',
- '😌': 'relieved face',
- '😔': 'pensive face',
- '😪': 'sleepy face',
- '🤤': 'drooling face',
- '😴': 'sleeping face',
- '😷': 'face with medical mask',
- '🤒': 'face with thermometer',
- '🤕': 'face with head-bandage',
- '🤢': 'nauseated face',
- '🤮': 'face vomiting',
- '🤧': 'sneezing face',
- '🥵': 'hot face',
- '🥶': 'cold face',
- '🥴': 'woozy face',
- '😵': 'face with crossed-out eyes',
- '😵💫': 'face with spiral eyes',
- '🤯': 'exploding head',
- '🤠': 'cowboy hat face',
- '🥳': 'partying face',
- '🥸': 'disguised face',
- '😎': 'smiling face with sunglasses',
- '🤓': 'nerd face',
- '🧐': 'face with monocle',
- '😕': 'confused face',
- '🫤': '⊛ face with diagonal mouth',
- '😟': 'worried face',
- '🙁': 'slightly frowning face',
- '☹': 'frowning face',
- '😮': 'face with open mouth',
- '😯': 'hushed face',
- '😲': 'astonished face',
- '😳': 'flushed face',
- '🥺': 'pleading face',
- '🥹': '⊛ face holding back tears',
- '😦': 'frowning face with open mouth',
- '😧': 'anguished face',
- '😨': 'fearful face',
- '😰': 'anxious face with sweat',
- '😥': 'sad but relieved face',
- '😢': 'crying face',
- '😭': 'loudly crying face',
- '😱': 'face screaming in fear',
- '😖': 'confounded face',
- '😣': 'persevering face',
- '😞': 'disappointed face',
- '😓': 'downcast face with sweat',
- '😩': 'weary face',
- '😫': 'tired face',
- '🥱': 'yawning face',
- '😤': 'face with steam from nose',
- '😡': 'pouting face',
- '😠': 'angry face',
- '🤬': 'face with symbols on mouth',
- '😈': 'smiling face with horns',
- '👿': 'angry face with horns',
- '💀': 'skull',
- '☠': 'skull and crossbones',
- '💩': 'pile of poo',
- '🤡': 'clown face',
- '👹': 'ogre',
- '👺': 'goblin',
- '👻': 'ghost',
- '👽': 'alien',
- '👾': 'alien monster',
- '🤖': 'robot',
- '😺': 'grinning cat',
- '😸': 'grinning cat with smiling eyes',
- '😹': 'cat with tears of joy',
- '😻': 'smiling cat with heart-eyes',
- '😼': 'cat with wry smile',
- '😽': 'kissing cat',
- '🙀': 'weary cat',
- '😿': 'crying cat',
- '😾': 'pouting cat',
- '🙈': 'see-no-evil monkey',
- '🙉': 'hear-no-evil monkey',
- '🙊': 'speak-no-evil monkey',
- '💋': 'kiss mark',
- '💌': 'love letter',
- '💘': 'heart with arrow',
- '💝': 'heart with ribbon',
- '💖': 'sparkling heart',
- '💗': 'growing heart',
- '💓': 'beating heart',
- '💞': 'revolving hearts',
- '💕': 'two hearts',
- '💟': 'heart decoration',
- '❣': 'heart exclamation',
- '💔': 'broken heart',
- '❤️🔥': 'heart on fire',
- '❤️🩹': 'mending heart',
- '❤': 'red heart',
- '🧡': 'orange heart',
- '💛': 'yellow heart',
- '💚': 'green heart',
- '💙': 'blue heart',
- '💜': 'purple heart',
- '🤎': 'brown heart',
- '🖤': 'black heart',
- '🤍': 'white heart',
- '💯': 'hundred points',
- '💢': 'anger symbol',
- '💥': 'collision',
- '💫': 'dizzy',
- '💦': 'sweat droplets',
- '💨': 'dashing away',
- '🕳': 'hole',
- '💣': 'bomb',
- '💬': 'speech balloon',
- '👁️🗨️': 'eye in speech bubble',
- '🗨': 'left speech bubble',
- '🗯': 'right anger bubble',
- '💭': 'thought balloon',
- '💤': 'zzz',
- '👋': 'waving hand',
- '🤚': 'raised back of hand',
- '🖐': 'hand with fingers splayed',
- '✋': 'raised hand',
- '🖖': 'vulcan salute',
- '🫱': '⊛ rightwards hand',
- '🫲': '⊛ leftwards hand',
- '🫳': '⊛ palm down hand',
- '🫴': '⊛ palm up hand',
- '👌': 'OK hand',
- '🤌': 'pinched fingers',
- '🤏': 'pinching hand',
- '✌': 'victory hand',
- '🤞': 'crossed fingers',
- '🫰': '⊛ hand with index finger and thumb crossed',
- '🤟': 'love-you gesture',
- '🤘': 'sign of the horns',
- '🤙': 'call me hand',
- '👈': 'backhand index pointing left',
- '👉': 'backhand index pointing right',
- '👆': 'backhand index pointing up',
- '🖕': 'middle finger',
- '👇': 'backhand index pointing down',
- '☝': 'index pointing up',
- '🫵': '⊛ index pointing at the viewer',
- '👍': 'thumbs up',
- '👎': 'thumbs down',
- '✊': 'raised fist',
- '👊': 'oncoming fist',
- '🤛': 'left-facing fist',
- '🤜': 'right-facing fist',
- '👏': 'clapping hands',
- '🙌': 'raising hands',
- '🫶': '⊛ heart hands',
- '👐': 'open hands',
- '🤲': 'palms up together',
- '🤝': 'handshake',
- '🙏': 'folded hands',
- '✍': 'writing hand',
- '💅': 'nail polish',
- '🤳': 'selfie',
- '💪': 'flexed biceps',
- '🦾': 'mechanical arm',
- '🦿': 'mechanical leg',
- '🦵': 'leg',
- '🦶': 'foot',
- '👂': 'ear',
- '🦻': 'ear with hearing aid',
- '👃': 'nose',
- '🧠': 'brain',
- '🫀': 'anatomical heart',
- '🫁': 'lungs',
- '🦷': 'tooth',
- '🦴': 'bone',
- '👀': 'eyes',
- '👁': 'eye',
- '👅': 'tongue',
- '👄': 'mouth',
- '🫦': '⊛ biting lip',
- '👶': 'baby',
- '🧒': 'child',
- '👦': 'boy',
- '👧': 'girl',
- '🧑': 'person',
- '👱': 'person: blond hair',
- '👨': 'man',
- '🧔': 'person: beard',
- '🧔♂️': 'man: beard',
- '🧔♀️': 'woman: beard',
- '👨🦰': 'man: red hair',
- '👨🦱': 'man: curly hair',
- '👨🦳': 'man: white hair',
- '👨🦲': 'man: bald',
- '👩': 'woman',
- '👩🦰': 'woman: red hair',
- '🧑🦰': 'person: red hair',
- '👩🦱': 'woman: curly hair',
- '🧑🦱': 'person: curly hair',
- '👩🦳': 'woman: white hair',
- '🧑🦳': 'person: white hair',
- '👩🦲': 'woman: bald',
- '🧑🦲': 'person: bald',
- '👱♀️': 'woman: blond hair',
- '👱♂️': 'man: blond hair',
- '🧓': 'older person',
- '👴': 'old man',
- '👵': 'old woman',
- '🙍': 'person frowning',
- '🙍♂️': 'man frowning',
- '🙍♀️': 'woman frowning',
- '🙎': 'person pouting',
- '🙎♂️': 'man pouting',
- '🙎♀️': 'woman pouting',
- '🙅': 'person gesturing NO',
- '🙅♂️': 'man gesturing NO',
- '🙅♀️': 'woman gesturing NO',
- '🙆': 'person gesturing OK',
- '🙆♂️': 'man gesturing OK',
- '🙆♀️': 'woman gesturing OK',
- '💁': 'person tipping hand',
- '💁♂️': 'man tipping hand',
- '💁♀️': 'woman tipping hand',
- '🙋': 'person raising hand',
- '🙋♂️': 'man raising hand',
- '🙋♀️': 'woman raising hand',
- '🧏': 'deaf person',
- '🧏♂️': 'deaf man',
- '🧏♀️': 'deaf woman',
- '🙇': 'person bowing',
- '🙇♂️': 'man bowing',
- '🙇♀️': 'woman bowing',
- '🤦': 'person facepalming',
- '🤦♂️': 'man facepalming',
- '🤦♀️': 'woman facepalming',
- '🤷': 'person shrugging',
- '🤷♂️': 'man shrugging',
- '🤷♀️': 'woman shrugging',
- '🧑⚕️': 'health worker',
- '👨⚕️': 'man health worker',
- '👩⚕️': 'woman health worker',
- '🧑🎓': 'student',
- '👨🎓': 'man student',
- '👩🎓': 'woman student',
- '🧑🏫': 'teacher',
- '👨🏫': 'man teacher',
- '👩🏫': 'woman teacher',
- '🧑⚖️': 'judge',
- '👨⚖️': 'man judge',
- '👩⚖️': 'woman judge',
- '🧑🌾': 'farmer',
- '👨🌾': 'man farmer',
- '👩🌾': 'woman farmer',
- '🧑🍳': 'cook',
- '👨🍳': 'man cook',
- '👩🍳': 'woman cook',
- '🧑🔧': 'mechanic',
- '👨🔧': 'man mechanic',
- '👩🔧': 'woman mechanic',
- '🧑🏭': 'factory worker',
- '👨🏭': 'man factory worker',
- '👩🏭': 'woman factory worker',
- '🧑💼': 'office worker',
- '👨💼': 'man office worker',
- '👩💼': 'woman office worker',
- '🧑🔬': 'scientist',
- '👨🔬': 'man scientist',
- '👩🔬': 'woman scientist',
- '🧑💻': 'technologist',
- '👨💻': 'man technologist',
- '👩💻': 'woman technologist',
- '🧑🎤': 'singer',
- '👨🎤': 'man singer',
- '👩🎤': 'woman singer',
- '🧑🎨': 'artist',
- '👨🎨': 'man artist',
- '👩🎨': 'woman artist',
- '🧑✈️': 'pilot',
- '👨✈️': 'man pilot',
- '👩✈️': 'woman pilot',
- '🧑🚀': 'astronaut',
- '👨🚀': 'man astronaut',
- '👩🚀': 'woman astronaut',
- '🧑🚒': 'firefighter',
- '👨🚒': 'man firefighter',
- '👩🚒': 'woman firefighter',
- '👮': 'police officer',
- '👮♂️': 'man police officer',
- '👮♀️': 'woman police officer',
- '🕵': 'detective',
- '🕵️♂️': 'man detective',
- '🕵️♀️': 'woman detective',
- '💂': 'guard',
- '💂♂️': 'man guard',
- '💂♀️': 'woman guard',
- '🥷': 'ninja',
- '👷': 'construction worker',
- '👷♂️': 'man construction worker',
- '👷♀️': 'woman construction worker',
- '🫅': '⊛ person with crown',
- '🤴': 'prince',
- '👸': 'princess',
- '👳': 'person wearing turban',
- '👳♂️': 'man wearing turban',
- '👳♀️': 'woman wearing turban',
- '👲': 'person with skullcap',
- '🧕': 'woman with headscarf',
- '🤵': 'person in tuxedo',
- '🤵♂️': 'man in tuxedo',
- '🤵♀️': 'woman in tuxedo',
- '👰': 'person with veil',
- '👰♂️': 'man with veil',
- '👰♀️': 'woman with veil',
- '🤰': 'pregnant woman',
- '🫃': '⊛ pregnant man',
- '🫄': '⊛ pregnant person',
- '🤱': 'breast-feeding',
- '👩🍼': 'woman feeding baby',
- '👨🍼': 'man feeding baby',
- '🧑🍼': 'person feeding baby',
- '👼': 'baby angel',
- '🎅': 'Santa Claus',
- '🤶': 'Mrs. Claus',
- '🧑🎄': 'mx claus',
- '🦸': 'superhero',
- '🦸♂️': 'man superhero',
- '🦸♀️': 'woman superhero',
- '🦹': 'supervillain',
- '🦹♂️': 'man supervillain',
- '🦹♀️': 'woman supervillain',
- '🧙': 'mage',
- '🧙♂️': 'man mage',
- '🧙♀️': 'woman mage',
- '🧚': 'fairy',
- '🧚♂️': 'man fairy',
- '🧚♀️': 'woman fairy',
- '🧛': 'vampire',
- '🧛♂️': 'man vampire',
- '🧛♀️': 'woman vampire',
- '🧜': 'merperson',
- '🧜♂️': 'merman',
- '🧜♀️': 'mermaid',
- '🧝': 'elf',
- '🧝♂️': 'man elf',
- '🧝♀️': 'woman elf',
- '🧞': 'genie',
- '🧞♂️': 'man genie',
- '🧞♀️': 'woman genie',
- '🧟': 'zombie',
- '🧟♂️': 'man zombie',
- '🧟♀️': 'woman zombie',
- '🧌': '⊛ troll',
- '💆': 'person getting massage',
- '💆♂️': 'man getting massage',
- '💆♀️': 'woman getting massage',
- '💇': 'person getting haircut',
- '💇♂️': 'man getting haircut',
- '💇♀️': 'woman getting haircut',
- '🚶': 'person walking',
- '🚶♂️': 'man walking',
- '🚶♀️': 'woman walking',
- '🧍': 'person standing',
- '🧍♂️': 'man standing',
- '🧍♀️': 'woman standing',
- '🧎': 'person kneeling',
- '🧎♂️': 'man kneeling',
- '🧎♀️': 'woman kneeling',
- '🧑🦯': 'person with white cane',
- '👨🦯': 'man with white cane',
- '👩🦯': 'woman with white cane',
- '🧑🦼': 'person in motorized wheelchair',
- '👨🦼': 'man in motorized wheelchair',
- '👩🦼': 'woman in motorized wheelchair',
- '🧑🦽': 'person in manual wheelchair',
- '👨🦽': 'man in manual wheelchair',
- '👩🦽': 'woman in manual wheelchair',
- '🏃': 'person running',
- '🏃♂️': 'man running',
- '🏃♀️': 'woman running',
- '💃': 'woman dancing',
- '🕺': 'man dancing',
- '🕴': 'person in suit levitating',
- '👯': 'people with bunny ears',
- '👯♂️': 'men with bunny ears',
- '👯♀️': 'women with bunny ears',
- '🧖': 'person in steamy room',
- '🧖♂️': 'man in steamy room',
- '🧖♀️': 'woman in steamy room',
- '🧗': 'person climbing',
- '🧗♂️': 'man climbing',
- '🧗♀️': 'woman climbing',
- '🤺': 'person fencing',
- '🏇': 'horse racing',
- '⛷': 'skier',
- '🏂': 'snowboarder',
- '🏌': 'person golfing',
- '🏌️♂️': 'man golfing',
- '🏌️♀️': 'woman golfing',
- '🏄': 'person surfing',
- '🏄♂️': 'man surfing',
- '🏄♀️': 'woman surfing',
- '🚣': 'person rowing boat',
- '🚣♂️': 'man rowing boat',
- '🚣♀️': 'woman rowing boat',
- '🏊': 'person swimming',
- '🏊♂️': 'man swimming',
- '🏊♀️': 'woman swimming',
- '⛹': 'person bouncing ball',
- '⛹️♂️': 'man bouncing ball',
- '⛹️♀️': 'woman bouncing ball',
- '🏋': 'person lifting weights',
- '🏋️♂️': 'man lifting weights',
- '🏋️♀️': 'woman lifting weights',
- '🚴': 'person biking',
- '🚴♂️': 'man biking',
- '🚴♀️': 'woman biking',
- '🚵': 'person mountain biking',
- '🚵♂️': 'man mountain biking',
- '🚵♀️': 'woman mountain biking',
- '🤸': 'person cartwheeling',
- '🤸♂️': 'man cartwheeling',
- '🤸♀️': 'woman cartwheeling',
- '🤼': 'people wrestling',
- '🤼♂️': 'men wrestling',
- '🤼♀️': 'women wrestling',
- '🤽': 'person playing water polo',
- '🤽♂️': 'man playing water polo',
- '🤽♀️': 'woman playing water polo',
- '🤾': 'person playing handball',
- '🤾♂️': 'man playing handball',
- '🤾♀️': 'woman playing handball',
- '🤹': 'person juggling',
- '🤹♂️': 'man juggling',
- '🤹♀️': 'woman juggling',
- '🧘': 'person in lotus position',
- '🧘♂️': 'man in lotus position',
- '🧘♀️': 'woman in lotus position',
- '🛀': 'person taking bath',
- '🛌': 'person in bed',
- '🧑🤝🧑': 'people holding hands',
- '👭': 'women holding hands',
- '👫': 'woman and man holding hands',
- '👬': 'men holding hands',
- '💏': 'kiss',
- '👩❤️💋👨': 'kiss: woman, man',
- '👨❤️💋👨': 'kiss: man, man',
- '👩❤️💋👩': 'kiss: woman, woman',
- '💑': 'couple with heart',
- '👩❤️👨': 'couple with heart: woman, man',
- '👨❤️👨': 'couple with heart: man, man',
- '👩❤️👩': 'couple with heart: woman, woman',
- '👪': 'family',
- '👨👩👦': 'family: man, woman, boy',
- '👨👩👧': 'family: man, woman, girl',
- '👨👩👧👦': 'family: man, woman, girl, boy',
- '👨👩👦👦': 'family: man, woman, boy, boy',
- '👨👩👧👧': 'family: man, woman, girl, girl',
- '👨👨👦': 'family: man, man, boy',
- '👨👨👧': 'family: man, man, girl',
- '👨👨👧👦': 'family: man, man, girl, boy',
- '👨👨👦👦': 'family: man, man, boy, boy',
- '👨👨👧👧': 'family: man, man, girl, girl',
- '👩👩👦': 'family: woman, woman, boy',
- '👩👩👧': 'family: woman, woman, girl',
- '👩👩👧👦': 'family: woman, woman, girl, boy',
- '👩👩👦👦': 'family: woman, woman, boy, boy',
- '👩👩👧👧': 'family: woman, woman, girl, girl',
- '👨👦': 'family: man, boy',
- '👨👦👦': 'family: man, boy, boy',
- '👨👧': 'family: man, girl',
- '👨👧👦': 'family: man, girl, boy',
- '👨👧👧': 'family: man, girl, girl',
- '👩👦': 'family: woman, boy',
- '👩👦👦': 'family: woman, boy, boy',
- '👩👧': 'family: woman, girl',
- '👩👧👦': 'family: woman, girl, boy',
- '👩👧👧': 'family: woman, girl, girl',
- '🗣': 'speaking head',
- '👤': 'bust in silhouette',
- '👥': 'busts in silhouette',
- '🫂': 'people hugging',
- '👣': 'footprints',
- '🦰': 'red hair',
- '🦱': 'curly hair',
- '🦳': 'white hair',
- '🦲': 'bald',
- '🐵': 'monkey face',
- '🐒': 'monkey',
- '🦍': 'gorilla',
- '🦧': 'orangutan',
- '🐶': 'dog face',
- '🐕': 'dog',
- '🦮': 'guide dog',
- '🐕🦺': 'service dog',
- '🐩': 'poodle',
- '🐺': 'wolf',
- '🦊': 'fox',
- '🦝': 'raccoon',
- '🐱': 'cat face',
- '🐈': 'cat',
- '🐈⬛': 'black cat',
- '🦁': 'lion',
- '🐯': 'tiger face',
- '🐅': 'tiger',
- '🐆': 'leopard',
- '🐴': 'horse face',
- '🐎': 'horse',
- '🦄': 'unicorn',
- '🦓': 'zebra',
- '🦌': 'deer',
- '🦬': 'bison',
- '🐮': 'cow face',
- '🐂': 'ox',
- '🐃': 'water buffalo',
- '🐄': 'cow',
- '🐷': 'pig face',
- '🐖': 'pig',
- '🐗': 'boar',
- '🐽': 'pig nose',
- '🐏': 'ram',
- '🐑': 'ewe',
- '🐐': 'goat',
- '🐪': 'camel',
- '🐫': 'two-hump camel',
- '🦙': 'llama',
- '🦒': 'giraffe',
- '🐘': 'elephant',
- '🦣': 'mammoth',
- '🦏': 'rhinoceros',
- '🦛': 'hippopotamus',
- '🐭': 'mouse face',
- '🐁': 'mouse',
- '🐀': 'rat',
- '🐹': 'hamster',
- '🐰': 'rabbit face',
- '🐇': 'rabbit',
- '🐿': 'chipmunk',
- '🦫': 'beaver',
- '🦔': 'hedgehog',
- '🦇': 'bat',
- '🐻': 'bear',
- '🐻❄️': 'polar bear',
- '🐨': 'koala',
- '🐼': 'panda',
- '🦥': 'sloth',
- '🦦': 'otter',
- '🦨': 'skunk',
- '🦘': 'kangaroo',
- '🦡': 'badger',
- '🐾': 'paw prints',
- '🦃': 'turkey',
- '🐔': 'chicken',
- '🐓': 'rooster',
- '🐣': 'hatching chick',
- '🐤': 'baby chick',
- '🐥': 'front-facing baby chick',
- '🐦': 'bird',
- '🐧': 'penguin',
- '🕊': 'dove',
- '🦅': 'eagle',
- '🦆': 'duck',
- '🦢': 'swan',
- '🦉': 'owl',
- '🦤': 'dodo',
- '🪶': 'feather',
- '🦩': 'flamingo',
- '🦚': 'peacock',
- '🦜': 'parrot',
- '🐸': 'frog',
- '🐊': 'crocodile',
- '🐢': 'turtle',
- '🦎': 'lizard',
- '🐍': 'snake',
- '🐲': 'dragon face',
- '🐉': 'dragon',
- '🦕': 'sauropod',
- '🦖': 'T-Rex',
- '🐳': 'spouting whale',
- '🐋': 'whale',
- '🐬': 'dolphin',
- '🦭': 'seal',
- '🐟': 'fish',
- '🐠': 'tropical fish',
- '🐡': 'blowfish',
- '🦈': 'shark',
- '🐙': 'octopus',
- '🐚': 'spiral shell',
- '🪸': '⊛ coral',
- '🐌': 'snail',
- '🦋': 'butterfly',
- '🐛': 'bug',
- '🐜': 'ant',
- '🐝': 'honeybee',
- '🪲': 'beetle',
- '🐞': 'lady beetle',
- '🦗': 'cricket',
- '🪳': 'cockroach',
- '🕷': 'spider',
- '🕸': 'spider web',
- '🦂': 'scorpion',
- '🦟': 'mosquito',
- '🪰': 'fly',
- '🪱': 'worm',
- '🦠': 'microbe',
- '💐': 'bouquet',
- '🌸': 'cherry blossom',
- '💮': 'white flower',
- '🪷': '⊛ lotus',
- '🏵': 'rosette',
- '🌹': 'rose',
- '🥀': 'wilted flower',
- '🌺': 'hibiscus',
- '🌻': 'sunflower',
- '🌼': 'blossom',
- '🌷': 'tulip',
- '🌱': 'seedling',
- '🪴': 'potted plant',
- '🌲': 'evergreen tree',
- '🌳': 'deciduous tree',
- '🌴': 'palm tree',
- '🌵': 'cactus',
- '🌾': 'sheaf of rice',
- '🌿': 'herb',
- '☘': 'shamrock',
- '🍀': 'four leaf clover',
- '🍁': 'maple leaf',
- '🍂': 'fallen leaf',
- '🍃': 'leaf fluttering in wind',
- '🪹': '⊛ empty nest',
- '🪺': '⊛ nest with eggs',
- '🍇': 'grapes',
- '🍈': 'melon',
- '🍉': 'watermelon',
- '🍊': 'tangerine',
- '🍋': 'lemon',
- '🍌': 'banana',
- '🍍': 'pineapple',
- '🥭': 'mango',
- '🍎': 'red apple',
- '🍏': 'green apple',
- '🍐': 'pear',
- '🍑': 'peach',
- '🍒': 'cherries',
- '🍓': 'strawberry',
- '🫐': 'blueberries',
- '🥝': 'kiwi fruit',
- '🍅': 'tomato',
- '🫒': 'olive',
- '🥥': 'coconut',
- '🥑': 'avocado',
- '🍆': 'eggplant',
- '🥔': 'potato',
- '🥕': 'carrot',
- '🌽': 'ear of corn',
- '🌶': 'hot pepper',
- '🫑': 'bell pepper',
- '🥒': 'cucumber',
- '🥬': 'leafy green',
- '🥦': 'broccoli',
- '🧄': 'garlic',
- '🧅': 'onion',
- '🍄': 'mushroom',
- '🥜': 'peanuts',
- '🫘': '⊛ beans',
- '🌰': 'chestnut',
- '🍞': 'bread',
- '🥐': 'croissant',
- '🥖': 'baguette bread',
- '🫓': 'flatbread',
- '🥨': 'pretzel',
- '🥯': 'bagel',
- '🥞': 'pancakes',
- '🧇': 'waffle',
- '🧀': 'cheese wedge',
- '🍖': 'meat on bone',
- '🍗': 'poultry leg',
- '🥩': 'cut of meat',
- '🥓': 'bacon',
- '🍔': 'hamburger',
- '🍟': 'french fries',
- '🍕': 'pizza',
- '🌭': 'hot dog',
- '🥪': 'sandwich',
- '🌮': 'taco',
- '🌯': 'burrito',
- '🫔': 'tamale',
- '🥙': 'stuffed flatbread',
- '🧆': 'falafel',
- '🥚': 'egg',
- '🍳': 'cooking',
- '🥘': 'shallow pan of food',
- '🍲': 'pot of food',
- '🫕': 'fondue',
- '🥣': 'bowl with spoon',
- '🥗': 'green salad',
- '🍿': 'popcorn',
- '🧈': 'butter',
- '🧂': 'salt',
- '🥫': 'canned food',
- '🍱': 'bento box',
- '🍘': 'rice cracker',
- '🍙': 'rice ball',
- '🍚': 'cooked rice',
- '🍛': 'curry rice',
- '🍜': 'steaming bowl',
- '🍝': 'spaghetti',
- '🍠': 'roasted sweet potato',
- '🍢': 'oden',
- '🍣': 'sushi',
- '🍤': 'fried shrimp',
- '🍥': 'fish cake with swirl',
- '🥮': 'moon cake',
- '🍡': 'dango',
- '🥟': 'dumpling',
- '🥠': 'fortune cookie',
- '🥡': 'takeout box',
- '🦀': 'crab',
- '🦞': 'lobster',
- '🦐': 'shrimp',
- '🦑': 'squid',
- '🦪': 'oyster',
- '🍦': 'soft ice cream',
- '🍧': 'shaved ice',
- '🍨': 'ice cream',
- '🍩': 'doughnut',
- '🍪': 'cookie',
- '🎂': 'birthday cake',
- '🍰': 'shortcake',
- '🧁': 'cupcake',
- '🥧': 'pie',
- '🍫': 'chocolate bar',
- '🍬': 'candy',
- '🍭': 'lollipop',
- '🍮': 'custard',
- '🍯': 'honey pot',
- '🍼': 'baby bottle',
- '🥛': 'glass of milk',
- '☕': 'hot beverage',
- '🫖': 'teapot',
- '🍵': 'teacup without handle',
- '🍶': 'sake',
- '🍾': 'bottle with popping cork',
- '🍷': 'wine glass',
- '🍸': 'cocktail glass',
- '🍹': 'tropical drink',
- '🍺': 'beer mug',
- '🍻': 'clinking beer mugs',
- '🥂': 'clinking glasses',
- '🥃': 'tumbler glass',
- '🫗': '⊛ pouring liquid',
- '🥤': 'cup with straw',
- '🧋': 'bubble tea',
- '🧃': 'beverage box',
- '🧉': 'mate',
- '🧊': 'ice',
- '🥢': 'chopsticks',
- '🍽': 'fork and knife with plate',
- '🍴': 'fork and knife',
- '🥄': 'spoon',
- '🔪': 'kitchen knife',
- '🫙': '⊛ jar',
- '🏺': 'amphora',
- '🌍': 'globe showing Europe-Africa',
- '🌎': 'globe showing Americas',
- '🌏': 'globe showing Asia-Australia',
- '🌐': 'globe with meridians',
- '🗺': 'world map',
- '🗾': 'map of Japan',
- '🧭': 'compass',
- '🏔': 'snow-capped mountain',
- '⛰': 'mountain',
- '🌋': 'volcano',
- '🗻': 'mount fuji',
- '🏕': 'camping',
- '🏖': 'beach with umbrella',
- '🏜': 'desert',
- '🏝': 'desert island',
- '🏞': 'national park',
- '🏟': 'stadium',
- '🏛': 'classical building',
- '🏗': 'building construction',
- '🧱': 'brick',
- '🪨': 'rock',
- '🪵': 'wood',
- '🛖': 'hut',
- '🏘': 'houses',
- '🏚': 'derelict house',
- '🏠': 'house',
- '🏡': 'house with garden',
- '🏢': 'office building',
- '🏣': 'Japanese post office',
- '🏤': 'post office',
- '🏥': 'hospital',
- '🏦': 'bank',
- '🏨': 'hotel',
- '🏩': 'love hotel',
- '🏪': 'convenience store',
- '🏫': 'school',
- '🏬': 'department store',
- '🏭': 'factory',
- '🏯': 'Japanese castle',
- '🏰': 'castle',
- '💒': 'wedding',
- '🗼': 'Tokyo tower',
- '🗽': 'Statue of Liberty',
- '⛪': 'church',
- '🕌': 'mosque',
- '🛕': 'hindu temple',
- '🕍': 'synagogue',
- '⛩': 'shinto shrine',
- '🕋': 'kaaba',
- '⛲': 'fountain',
- '⛺': 'tent',
- '🌁': 'foggy',
- '🌃': 'night with stars',
- '🏙': 'cityscape',
- '🌄': 'sunrise over mountains',
- '🌅': 'sunrise',
- '🌆': 'cityscape at dusk',
- '🌇': 'sunset',
- '🌉': 'bridge at night',
- '♨': 'hot springs',
- '🎠': 'carousel horse',
- '🛝': '⊛ playground slide',
- '🎡': 'ferris wheel',
- '🎢': 'roller coaster',
- '💈': 'barber pole',
- '🎪': 'circus tent',
- '🚂': 'locomotive',
- '🚃': 'railway car',
- '🚄': 'high-speed train',
- '🚅': 'bullet train',
- '🚆': 'train',
- '🚇': 'metro',
- '🚈': 'light rail',
- '🚉': 'station',
- '🚊': 'tram',
- '🚝': 'monorail',
- '🚞': 'mountain railway',
- '🚋': 'tram car',
- '🚌': 'bus',
- '🚍': 'oncoming bus',
- '🚎': 'trolleybus',
- '🚐': 'minibus',
- '🚑': 'ambulance',
- '🚒': 'fire engine',
- '🚓': 'police car',
- '🚔': 'oncoming police car',
- '🚕': 'taxi',
- '🚖': 'oncoming taxi',
- '🚗': 'automobile',
- '🚘': 'oncoming automobile',
- '🚙': 'sport utility vehicle',
- '🛻': 'pickup truck',
- '🚚': 'delivery truck',
- '🚛': 'articulated lorry',
- '🚜': 'tractor',
- '🏎': 'racing car',
- '🏍': 'motorcycle',
- '🛵': 'motor scooter',
- '🦽': 'manual wheelchair',
- '🦼': 'motorized wheelchair',
- '🛺': 'auto rickshaw',
- '🚲': 'bicycle',
- '🛴': 'kick scooter',
- '🛹': 'skateboard',
- '🛼': 'roller skate',
- '🚏': 'bus stop',
- '🛣': 'motorway',
- '🛤': 'railway track',
- '🛢': 'oil drum',
- '⛽': 'fuel pump',
- '🛞': '⊛ wheel',
- '🚨': 'police car light',
- '🚥': 'horizontal traffic light',
- '🚦': 'vertical traffic light',
- '🛑': 'stop sign',
- '🚧': 'construction',
- '⚓': 'anchor',
- '🛟': '⊛ ring buoy',
- '⛵': 'sailboat',
- '🛶': 'canoe',
- '🚤': 'speedboat',
- '🛳': 'passenger ship',
- '⛴': 'ferry',
- '🛥': 'motor boat',
- '🚢': 'ship',
- '✈': 'airplane',
- '🛩': 'small airplane',
- '🛫': 'airplane departure',
- '🛬': 'airplane arrival',
- '🪂': 'parachute',
- '💺': 'seat',
- '🚁': 'helicopter',
- '🚟': 'suspension railway',
- '🚠': 'mountain cableway',
- '🚡': 'aerial tramway',
- '🛰': 'satellite',
- '🚀': 'rocket',
- '🛸': 'flying saucer',
- '🛎': 'bellhop bell',
- '🧳': 'luggage',
- '⌛': 'hourglass done',
- '⏳': 'hourglass not done',
- '⌚': 'watch',
- '⏰': 'alarm clock',
- '⏱': 'stopwatch',
- '⏲': 'timer clock',
- '🕰': 'mantelpiece clock',
- '🕛': 'twelve o’clock',
- '🕧': 'twelve-thirty',
- '🕐': 'one o’clock',
- '🕜': 'one-thirty',
- '🕑': 'two o’clock',
- '🕝': 'two-thirty',
- '🕒': 'three o’clock',
- '🕞': 'three-thirty',
- '🕓': 'four o’clock',
- '🕟': 'four-thirty',
- '🕔': 'five o’clock',
- '🕠': 'five-thirty',
- '🕕': 'six o’clock',
- '🕡': 'six-thirty',
- '🕖': 'seven o’clock',
- '🕢': 'seven-thirty',
- '🕗': 'eight o’clock',
- '🕣': 'eight-thirty',
- '🕘': 'nine o’clock',
- '🕤': 'nine-thirty',
- '🕙': 'ten o’clock',
- '🕥': 'ten-thirty',
- '🕚': 'eleven o’clock',
- '🕦': 'eleven-thirty',
- '🌑': 'new moon',
- '🌒': 'waxing crescent moon',
- '🌓': 'first quarter moon',
- '🌔': 'waxing gibbous moon',
- '🌕': 'full moon',
- '🌖': 'waning gibbous moon',
- '🌗': 'last quarter moon',
- '🌘': 'waning crescent moon',
- '🌙': 'crescent moon',
- '🌚': 'new moon face',
- '🌛': 'first quarter moon face',
- '🌜': 'last quarter moon face',
- '🌡': 'thermometer',
- '☀': 'sun',
- '🌝': 'full moon face',
- '🌞': 'sun with face',
- '🪐': 'ringed planet',
- '⭐': 'star',
- '🌟': 'glowing star',
- '🌠': 'shooting star',
- '🌌': 'milky way',
- '☁': 'cloud',
- '⛅': 'sun behind cloud',
- '⛈': 'cloud with lightning and rain',
- '🌤': 'sun behind small cloud',
- '🌥': 'sun behind large cloud',
- '🌦': 'sun behind rain cloud',
- '🌧': 'cloud with rain',
- '🌨': 'cloud with snow',
- '🌩': 'cloud with lightning',
- '🌪': 'tornado',
- '🌫': 'fog',
- '🌬': 'wind face',
- '🌀': 'cyclone',
- '🌈': 'rainbow',
- '🌂': 'closed umbrella',
- '☂': 'umbrella',
- '☔': 'umbrella with rain drops',
- '⛱': 'umbrella on ground',
- '⚡': 'high voltage',
- '❄': 'snowflake',
- '☃': 'snowman',
- '⛄': 'snowman without snow',
- '☄': 'comet',
- '🔥': 'fire',
- '💧': 'droplet',
- '🌊': 'water wave',
- '🎃': 'jack-o-lantern',
- '🎄': 'Christmas tree',
- '🎆': 'fireworks',
- '🎇': 'sparkler',
- '🧨': 'firecracker',
- '✨': 'sparkles',
- '🎈': 'balloon',
- '🎉': 'party popper',
- '🎊': 'confetti ball',
- '🎋': 'tanabata tree',
- '🎍': 'pine decoration',
- '🎎': 'Japanese dolls',
- '🎏': 'carp streamer',
- '🎐': 'wind chime',
- '🎑': 'moon viewing ceremony',
- '🧧': 'red envelope',
- '🎀': 'ribbon',
- '🎁': 'wrapped gift',
- '🎗': 'reminder ribbon',
- '🎟': 'admission tickets',
- '🎫': 'ticket',
- '🎖': 'military medal',
- '🏆': 'trophy',
- '🏅': 'sports medal',
- '🥇': '1st place medal',
- '🥈': '2nd place medal',
- '🥉': '3rd place medal',
- '⚽': 'soccer ball',
- '⚾': 'baseball',
- '🥎': 'softball',
- '🏀': 'basketball',
- '🏐': 'volleyball',
- '🏈': 'american football',
- '🏉': 'rugby football',
- '🎾': 'tennis',
- '🥏': 'flying disc',
- '🎳': 'bowling',
- '🏏': 'cricket game',
- '🏑': 'field hockey',
- '🏒': 'ice hockey',
- '🥍': 'lacrosse',
- '🏓': 'ping pong',
- '🏸': 'badminton',
- '🥊': 'boxing glove',
- '🥋': 'martial arts uniform',
- '🥅': 'goal net',
- '⛳': 'flag in hole',
- '⛸': 'ice skate',
- '🎣': 'fishing pole',
- '🤿': 'diving mask',
- '🎽': 'running shirt',
- '🎿': 'skis',
- '🛷': 'sled',
- '🥌': 'curling stone',
- '🎯': 'bullseye',
- '🪀': 'yo-yo',
- '🪁': 'kite',
- '🎱': 'pool 8 ball',
- '🔮': 'crystal ball',
- '🪄': 'magic wand',
- '🧿': 'nazar amulet',
- '🪬': '⊛ hamsa',
- '🎮': 'video game',
- '🕹': 'joystick',
- '🎰': 'slot machine',
- '🎲': 'game die',
- '🧩': 'puzzle piece',
- '🧸': 'teddy bear',
- '🪅': 'piñata',
- '🪩': '⊛ mirror ball',
- '🪆': 'nesting dolls',
- '♠': 'spade suit',
- '♥': 'heart suit',
- '♦': 'diamond suit',
- '♣': 'club suit',
- '♟': 'chess pawn',
- '🃏': 'joker',
- '🀄': 'mahjong red dragon',
- '🎴': 'flower playing cards',
- '🎭': 'performing arts',
- '🖼': 'framed picture',
- '🎨': 'artist palette',
- '🧵': 'thread',
- '🪡': 'sewing needle',
- '🧶': 'yarn',
- '🪢': 'knot',
- '👓': 'glasses',
- '🕶': 'sunglasses',
- '🥽': 'goggles',
- '🥼': 'lab coat',
- '🦺': 'safety vest',
- '👔': 'necktie',
- '👕': 't-shirt',
- '👖': 'jeans',
- '🧣': 'scarf',
- '🧤': 'gloves',
- '🧥': 'coat',
- '🧦': 'socks',
- '👗': 'dress',
- '👘': 'kimono',
- '🥻': 'sari',
- '🩱': 'one-piece swimsuit',
- '🩲': 'briefs',
- '🩳': 'shorts',
- '👙': 'bikini',
- '👚': 'woman’s clothes',
- '👛': 'purse',
- '👜': 'handbag',
- '👝': 'clutch bag',
- '🛍': 'shopping bags',
- '🎒': 'backpack',
- '🩴': 'thong sandal',
- '👞': 'man’s shoe',
- '👟': 'running shoe',
- '🥾': 'hiking boot',
- '🥿': 'flat shoe',
- '👠': 'high-heeled shoe',
- '👡': 'woman’s sandal',
- '🩰': 'ballet shoes',
- '👢': 'woman’s boot',
- '👑': 'crown',
- '👒': 'woman’s hat',
- '🎩': 'top hat',
- '🎓': 'graduation cap',
- '🧢': 'billed cap',
- '🪖': 'military helmet',
- '⛑': 'rescue worker’s helmet',
- '📿': 'prayer beads',
- '💄': 'lipstick',
- '💍': 'ring',
- '💎': 'gem stone',
- '🔇': 'muted speaker',
- '🔈': 'speaker low volume',
- '🔉': 'speaker medium volume',
- '🔊': 'speaker high volume',
- '📢': 'loudspeaker',
- '📣': 'megaphone',
- '📯': 'postal horn',
- '🔔': 'bell',
- '🔕': 'bell with slash',
- '🎼': 'musical score',
- '🎵': 'musical note',
- '🎶': 'musical notes',
- '🎙': 'studio microphone',
- '🎚': 'level slider',
- '🎛': 'control knobs',
- '🎤': 'microphone',
- '🎧': 'headphone',
- '📻': 'radio',
- '🎷': 'saxophone',
- '🪗': 'accordion',
- '🎸': 'guitar',
- '🎹': 'musical keyboard',
- '🎺': 'trumpet',
- '🎻': 'violin',
- '🪕': 'banjo',
- '🥁': 'drum',
- '🪘': 'long drum',
- '📱': 'mobile phone',
- '📲': 'mobile phone with arrow',
- '☎': 'telephone',
- '📞': 'telephone receiver',
- '📟': 'pager',
- '📠': 'fax machine',
- '🔋': 'battery',
- '🪫': '⊛ low battery',
- '🔌': 'electric plug',
- '💻': 'laptop',
- '🖥': 'desktop computer',
- '🖨': 'printer',
- '⌨': 'keyboard',
- '🖱': 'computer mouse',
- '🖲': 'trackball',
- '💽': 'computer disk',
- '💾': 'floppy disk',
- '💿': 'optical disk',
- '📀': 'dvd',
- '🧮': 'abacus',
- '🎥': 'movie camera',
- '🎞': 'film frames',
- '📽': 'film projector',
- '🎬': 'clapper board',
- '📺': 'television',
- '📷': 'camera',
- '📸': 'camera with flash',
- '📹': 'video camera',
- '📼': 'videocassette',
- '🔍': 'magnifying glass tilted left',
- '🔎': 'magnifying glass tilted right',
- '🕯': 'candle',
- '💡': 'light bulb',
- '🔦': 'flashlight',
- '🏮': 'red paper lantern',
- '🪔': 'diya lamp',
- '📔': 'notebook with decorative cover',
- '📕': 'closed book',
- '📖': 'open book',
- '📗': 'green book',
- '📘': 'blue book',
- '📙': 'orange book',
- '📚': 'books',
- '📓': 'notebook',
- '📒': 'ledger',
- '📃': 'page with curl',
- '📜': 'scroll',
- '📄': 'page facing up',
- '📰': 'newspaper',
- '🗞': 'rolled-up newspaper',
- '📑': 'bookmark tabs',
- '🔖': 'bookmark',
- '🏷': 'label',
- '💰': 'money bag',
- '🪙': 'coin',
- '💴': 'yen banknote',
- '💵': 'dollar banknote',
- '💶': 'euro banknote',
- '💷': 'pound banknote',
- '💸': 'money with wings',
- '💳': 'credit card',
- '🧾': 'receipt',
- '💹': 'chart increasing with yen',
- '✉': 'envelope',
- '📧': 'e-mail',
- '📨': 'incoming envelope',
- '📩': 'envelope with arrow',
- '📤': 'outbox tray',
- '📥': 'inbox tray',
- '📦': 'package',
- '📫': 'closed mailbox with raised flag',
- '📪': 'closed mailbox with lowered flag',
- '📬': 'open mailbox with raised flag',
- '📭': 'open mailbox with lowered flag',
- '📮': 'postbox',
- '🗳': 'ballot box with ballot',
- '✏': 'pencil',
- '✒': 'black nib',
- '🖋': 'fountain pen',
- '🖊': 'pen',
- '🖌': 'paintbrush',
- '🖍': 'crayon',
- '📝': 'memo',
- '💼': 'briefcase',
- '📁': 'file folder',
- '📂': 'open file folder',
- '🗂': 'card index dividers',
- '📅': 'calendar',
- '📆': 'tear-off calendar',
- '🗒': 'spiral notepad',
- '🗓': 'spiral calendar',
- '📇': 'card index',
- '📈': 'chart increasing',
- '📉': 'chart decreasing',
- '📊': 'bar chart',
- '📋': 'clipboard',
- '📌': 'pushpin',
- '📍': 'round pushpin',
- '📎': 'paperclip',
- '🖇': 'linked paperclips',
- '📏': 'straight ruler',
- '📐': 'triangular ruler',
- '✂': 'scissors',
- '🗃': 'card file box',
- '🗄': 'file cabinet',
- '🗑': 'wastebasket',
- '🔒': 'locked',
- '🔓': 'unlocked',
- '🔏': 'locked with pen',
- '🔐': 'locked with key',
- '🔑': 'key',
- '🗝': 'old key',
- '🔨': 'hammer',
- '🪓': 'axe',
- '⛏': 'pick',
- '⚒': 'hammer and pick',
- '🛠': 'hammer and wrench',
- '🗡': 'dagger',
- '⚔': 'crossed swords',
- '🔫': 'water pistol',
- '🪃': 'boomerang',
- '🏹': 'bow and arrow',
- '🛡': 'shield',
- '🪚': 'carpentry saw',
- '🔧': 'wrench',
- '🪛': 'screwdriver',
- '🔩': 'nut and bolt',
- '⚙': 'gear',
- '🗜': 'clamp',
- '⚖': 'balance scale',
- '🦯': 'white cane',
- '🔗': 'link',
- '⛓': 'chains',
- '🪝': 'hook',
- '🧰': 'toolbox',
- '🧲': 'magnet',
- '🪜': 'ladder',
- '⚗': 'alembic',
- '🧪': 'test tube',
- '🧫': 'petri dish',
- '🧬': 'dna',
- '🔬': 'microscope',
- '🔭': 'telescope',
- '📡': 'satellite antenna',
- '💉': 'syringe',
- '🩸': 'drop of blood',
- '💊': 'pill',
- '🩹': 'adhesive bandage',
- '🩼': '⊛ crutch',
- '🩺': 'stethoscope',
- '🩻': '⊛ x-ray',
- '🚪': 'door',
- '🛗': 'elevator',
- '🪞': 'mirror',
- '🪟': 'window',
- '🛏': 'bed',
- '🛋': 'couch and lamp',
- '🪑': 'chair',
- '🚽': 'toilet',
- '🪠': 'plunger',
- '🚿': 'shower',
- '🛁': 'bathtub',
- '🪤': 'mouse trap',
- '🪒': 'razor',
- '🧴': 'lotion bottle',
- '🧷': 'safety pin',
- '🧹': 'broom',
- '🧺': 'basket',
- '🧻': 'roll of paper',
- '🪣': 'bucket',
- '🧼': 'soap',
- '🫧': '⊛ bubbles',
- '🪥': 'toothbrush',
- '🧽': 'sponge',
- '🧯': 'fire extinguisher',
- '🛒': 'shopping cart',
- '🚬': 'cigarette',
- '⚰': 'coffin',
- '🪦': 'headstone',
- '⚱': 'funeral urn',
- '🗿': 'moai',
- '🪧': 'placard',
- '🪪': '⊛ identification card',
- '🏧': 'ATM sign',
- '🚮': 'litter in bin sign',
- '🚰': 'potable water',
- '♿': 'wheelchair symbol',
- '🚹': 'men’s room',
- '🚺': 'women’s room',
- '🚻': 'restroom',
- '🚼': 'baby symbol',
- '🚾': 'water closet',
- '🛂': 'passport control',
- '🛃': 'customs',
- '🛄': 'baggage claim',
- '🛅': 'left luggage',
- '⚠': 'warning',
- '🚸': 'children crossing',
- '⛔': 'no entry',
- '🚫': 'prohibited',
- '🚳': 'no bicycles',
- '🚭': 'no smoking',
- '🚯': 'no littering',
- '🚱': 'non-potable water',
- '🚷': 'no pedestrians',
- '📵': 'no mobile phones',
- '🔞': 'no one under eighteen',
- '☢': 'radioactive',
- '☣': 'biohazard',
- '⬆': 'up arrow',
- '↗': 'up-right arrow',
- '➡': 'right arrow',
- '↘': 'down-right arrow',
- '⬇': 'down arrow',
- '↙': 'down-left arrow',
- '⬅': 'left arrow',
- '↖': 'up-left arrow',
- '↕': 'up-down arrow',
- '↔': 'left-right arrow',
- '↩': 'right arrow curving left',
- '↪': 'left arrow curving right',
- '⤴': 'right arrow curving up',
- '⤵': 'right arrow curving down',
- '🔃': 'clockwise vertical arrows',
- '🔄': 'counterclockwise arrows button',
- '🔙': 'BACK arrow',
- '🔚': 'END arrow',
- '🔛': 'ON! arrow',
- '🔜': 'SOON arrow',
- '🔝': 'TOP arrow',
- '🛐': 'place of worship',
- '⚛': 'atom symbol',
- '🕉': 'om',
- '✡': 'star of David',
- '☸': 'wheel of dharma',
- '☯': 'yin yang',
- '✝': 'latin cross',
- '☦': 'orthodox cross',
- '☪': 'star and crescent',
- '☮': 'peace symbol',
- '🕎': 'menorah',
- '🔯': 'dotted six-pointed star',
- '♈': 'Aries',
- '♉': 'Taurus',
- '♊': 'Gemini',
- '♋': 'Cancer',
- '♌': 'Leo',
- '♍': 'Virgo',
- '♎': 'Libra',
- '♏': 'Scorpio',
- '♐': 'Sagittarius',
- '♑': 'Capricorn',
- '♒': 'Aquarius',
- '♓': 'Pisces',
- '⛎': 'Ophiuchus',
- '🔀': 'shuffle tracks button',
- '🔁': 'repeat button',
- '🔂': 'repeat single button',
- '▶': 'play button',
- '⏩': 'fast-forward button',
- '⏭': 'next track button',
- '⏯': 'play or pause button',
- '◀': 'reverse button',
- '⏪': 'fast reverse button',
- '⏮': 'last track button',
- '🔼': 'upwards button',
- '⏫': 'fast up button',
- '🔽': 'downwards button',
- '⏬': 'fast down button',
- '⏸': 'pause button',
- '⏹': 'stop button',
- '⏺': 'record button',
- '⏏': 'eject button',
- '🎦': 'cinema',
- '🔅': 'dim button',
- '🔆': 'bright button',
- '📶': 'antenna bars',
- '📳': 'vibration mode',
- '📴': 'mobile phone off',
- '♀': 'female sign',
- '♂': 'male sign',
- '⚧': 'transgender symbol',
- '✖': 'multiply',
- '➕': 'plus',
- '➖': 'minus',
- '➗': 'divide',
- '🟰': '⊛ heavy equals sign',
- '♾': 'infinity',
- '‼': 'double exclamation mark',
- '⁉': 'exclamation question mark',
- '❓': 'red question mark',
- '❔': 'white question mark',
- '❕': 'white exclamation mark',
- '❗': 'red exclamation mark',
- '〰': 'wavy dash',
- '💱': 'currency exchange',
- '💲': 'heavy dollar sign',
- '⚕': 'medical symbol',
- '♻': 'recycling symbol',
- '⚜': 'fleur-de-lis',
- '🔱': 'trident emblem',
- '📛': 'name badge',
- '🔰': 'Japanese symbol for beginner',
- '⭕': 'hollow red circle',
- '✅': 'check mark button',
- '☑': 'check box with check',
- '✔': 'check mark',
- '❌': 'cross mark',
- '❎': 'cross mark button',
- '➰': 'curly loop',
- '➿': 'double curly loop',
- '〽': 'part alternation mark',
- '✳': 'eight-spoked asterisk',
- '✴': 'eight-pointed star',
- '❇': 'sparkle',
- '©': 'copyright',
- '®': 'registered',
- '™': 'trade mark',
- '#️⃣': 'keycap: #',
- '*️⃣': 'keycap: *',
- '0️⃣': 'keycap: 0',
- '1️⃣': 'keycap: 1',
- '2️⃣': 'keycap: 2',
- '3️⃣': 'keycap: 3',
- '4️⃣': 'keycap: 4',
- '5️⃣': 'keycap: 5',
- '6️⃣': 'keycap: 6',
- '7️⃣': 'keycap: 7',
- '8️⃣': 'keycap: 8',
- '9️⃣': 'keycap: 9',
- '🔟': 'keycap: 10',
- '🔠': 'input latin uppercase',
- '🔡': 'input latin lowercase',
- '🔢': 'input numbers',
- '🔣': 'input symbols',
- '🔤': 'input latin letters',
- '🅰': 'A button (blood type)',
- '🆎': 'AB button (blood type)',
- '🅱': 'B button (blood type)',
- '🆑': 'CL button',
- '🆒': 'COOL button',
- '🆓': 'FREE button',
- ℹ: 'information',
- '🆔': 'ID button',
- 'Ⓜ': 'circled M',
- '🆕': 'NEW button',
- '🆖': 'NG button',
- '🅾': 'O button (blood type)',
- '🆗': 'OK button',
- '🅿': 'P button',
- '🆘': 'SOS button',
- '🆙': 'UP! button',
- '🆚': 'VS button',
- '🈁': 'Japanese “here” button',
- '🈂': 'Japanese “service charge” button',
- '🈷': 'Japanese “monthly amount” button',
- '🈶': 'Japanese “not free of charge” button',
- '🈯': 'Japanese “reserved” button',
- '🉐': 'Japanese “bargain” button',
- '🈹': 'Japanese “discount” button',
- '🈚': 'Japanese “free of charge” button',
- '🈲': 'Japanese “prohibited” button',
- '🉑': 'Japanese “acceptable” button',
- '🈸': 'Japanese “application” button',
- '🈴': 'Japanese “passing grade” button',
- '🈳': 'Japanese “vacancy” button',
- '㊗': 'Japanese “congratulations” button',
- '㊙': 'Japanese “secret” button',
- '🈺': 'Japanese “open for business” button',
- '🈵': 'Japanese “no vacancy” button',
- '🔴': 'red circle',
- '🟠': 'orange circle',
- '🟡': 'yellow circle',
- '🟢': 'green circle',
- '🔵': 'blue circle',
- '🟣': 'purple circle',
- '🟤': 'brown circle',
- '⚫': 'black circle',
- '⚪': 'white circle',
- '🟥': 'red square',
- '🟧': 'orange square',
- '🟨': 'yellow square',
- '🟩': 'green square',
- '🟦': 'blue square',
- '🟪': 'purple square',
- '🟫': 'brown square',
- '⬛': 'black large square',
- '⬜': 'white large square',
- '◼': 'black medium square',
- '◻': 'white medium square',
- '◾': 'black medium-small square',
- '◽': 'white medium-small square',
- '▪': 'black small square',
- '▫': 'white small square',
- '🔶': 'large orange diamond',
- '🔷': 'large blue diamond',
- '🔸': 'small orange diamond',
- '🔹': 'small blue diamond',
- '🔺': 'red triangle pointed up',
- '🔻': 'red triangle pointed down',
- '💠': 'diamond with a dot',
- '🔘': 'radio button',
- '🔳': 'white square button',
- '🔲': 'black square button',
- '🏁': 'chequered flag',
- '🚩': 'triangular flag',
- '🎌': 'crossed flags',
- '🏴': 'black flag',
- '🏳': 'white flag',
- '🏳️🌈': 'rainbow flag',
- '🏳️⚧️': 'transgender flag',
- '🏴☠️': 'pirate flag',
- '🇦🇨': 'flag: Ascension Island',
- '🇦🇩': 'flag: Andorra',
- '🇦🇪': 'flag: United Arab Emirates',
- '🇦🇫': 'flag: Afghanistan',
- '🇦🇬': 'flag: Antigua & Barbuda',
- '🇦🇮': 'flag: Anguilla',
- '🇦🇱': 'flag: Albania',
- '🇦🇲': 'flag: Armenia',
- '🇦🇴': 'flag: Angola',
- '🇦🇶': 'flag: Antarctica',
- '🇦🇷': 'flag: Argentina',
- '🇦🇸': 'flag: American Samoa',
- '🇦🇹': 'flag: Austria',
- '🇦🇺': 'flag: Australia',
- '🇦🇼': 'flag: Aruba',
- '🇦🇽': 'flag: Åland Islands',
- '🇦🇿': 'flag: Azerbaijan',
- '🇧🇦': 'flag: Bosnia & Herzegovina',
- '🇧🇧': 'flag: Barbados',
- '🇧🇩': 'flag: Bangladesh',
- '🇧🇪': 'flag: Belgium',
- '🇧🇫': 'flag: Burkina Faso',
- '🇧🇬': 'flag: Bulgaria',
- '🇧🇭': 'flag: Bahrain',
- '🇧🇮': 'flag: Burundi',
- '🇧🇯': 'flag: Benin',
- '🇧🇱': 'flag: St. Barthélemy',
- '🇧🇲': 'flag: Bermuda',
- '🇧🇳': 'flag: Brunei',
- '🇧🇴': 'flag: Bolivia',
- '🇧🇶': 'flag: Caribbean Netherlands',
- '🇧🇷': 'flag: Brazil',
- '🇧🇸': 'flag: Bahamas',
- '🇧🇹': 'flag: Bhutan',
- '🇧🇻': 'flag: Bouvet Island',
- '🇧🇼': 'flag: Botswana',
- '🇧🇾': 'flag: Belarus',
- '🇧🇿': 'flag: Belize',
- '🇨🇦': 'flag: Canada',
- '🇨🇨': 'flag: Cocos (Keeling) Islands',
- '🇨🇩': 'flag: Congo - Kinshasa',
- '🇨🇫': 'flag: Central African Republic',
- '🇨🇬': 'flag: Congo - Brazzaville',
- '🇨🇭': 'flag: Switzerland',
- '🇨🇮': 'flag: Côte d’Ivoire',
- '🇨🇰': 'flag: Cook Islands',
- '🇨🇱': 'flag: Chile',
- '🇨🇲': 'flag: Cameroon',
- '🇨🇳': 'flag: China',
- '🇨🇴': 'flag: Colombia',
- '🇨🇵': 'flag: Clipperton Island',
- '🇨🇷': 'flag: Costa Rica',
- '🇨🇺': 'flag: Cuba',
- '🇨🇻': 'flag: Cape Verde',
- '🇨🇼': 'flag: Curaçao',
- '🇨🇽': 'flag: Christmas Island',
- '🇨🇾': 'flag: Cyprus',
- '🇨🇿': 'flag: Czechia',
- '🇩🇪': 'flag: Germany',
- '🇩🇬': 'flag: Diego Garcia',
- '🇩🇯': 'flag: Djibouti',
- '🇩🇰': 'flag: Denmark',
- '🇩🇲': 'flag: Dominica',
- '🇩🇴': 'flag: Dominican Republic',
- '🇩🇿': 'flag: Algeria',
- '🇪🇦': 'flag: Ceuta & Melilla',
- '🇪🇨': 'flag: Ecuador',
- '🇪🇪': 'flag: Estonia',
- '🇪🇬': 'flag: Egypt',
- '🇪🇭': 'flag: Western Sahara',
- '🇪🇷': 'flag: Eritrea',
- '🇪🇸': 'flag: Spain',
- '🇪🇹': 'flag: Ethiopia',
- '🇪🇺': 'flag: European Union',
- '🇫🇮': 'flag: Finland',
- '🇫🇯': 'flag: Fiji',
- '🇫🇰': 'flag: Falkland Islands',
- '🇫🇲': 'flag: Micronesia',
- '🇫🇴': 'flag: Faroe Islands',
- '🇫🇷': 'flag: France',
- '🇬🇦': 'flag: Gabon',
- '🇬🇧': 'flag: United Kingdom',
- '🇬🇩': 'flag: Grenada',
- '🇬🇪': 'flag: Georgia',
- '🇬🇫': 'flag: French Guiana',
- '🇬🇬': 'flag: Guernsey',
- '🇬🇭': 'flag: Ghana',
- '🇬🇮': 'flag: Gibraltar',
- '🇬🇱': 'flag: Greenland',
- '🇬🇲': 'flag: Gambia',
- '🇬🇳': 'flag: Guinea',
- '🇬🇵': 'flag: Guadeloupe',
- '🇬🇶': 'flag: Equatorial Guinea',
- '🇬🇷': 'flag: Greece',
- '🇬🇸': 'flag: South Georgia & South Sandwich Islands',
- '🇬🇹': 'flag: Guatemala',
- '🇬🇺': 'flag: Guam',
- '🇬🇼': 'flag: Guinea-Bissau',
- '🇬🇾': 'flag: Guyana',
- '🇭🇰': 'flag: Hong Kong SAR China',
- '🇭🇲': 'flag: Heard & McDonald Islands',
- '🇭🇳': 'flag: Honduras',
- '🇭🇷': 'flag: Croatia',
- '🇭🇹': 'flag: Haiti',
- '🇭🇺': 'flag: Hungary',
- '🇮🇨': 'flag: Canary Islands',
- '🇮🇩': 'flag: Indonesia',
- '🇮🇪': 'flag: Ireland',
- '🇮🇱': 'flag: Israel',
- '🇮🇲': 'flag: Isle of Man',
- '🇮🇳': 'flag: India',
- '🇮🇴': 'flag: British Indian Ocean Territory',
- '🇮🇶': 'flag: Iraq',
- '🇮🇷': 'flag: Iran',
- '🇮🇸': 'flag: Iceland',
- '🇮🇹': 'flag: Italy',
- '🇯🇪': 'flag: Jersey',
- '🇯🇲': 'flag: Jamaica',
- '🇯🇴': 'flag: Jordan',
- '🇯🇵': 'flag: Japan',
- '🇰🇪': 'flag: Kenya',
- '🇰🇬': 'flag: Kyrgyzstan',
- '🇰🇭': 'flag: Cambodia',
- '🇰🇮': 'flag: Kiribati',
- '🇰🇲': 'flag: Comoros',
- '🇰🇳': 'flag: St. Kitts & Nevis',
- '🇰🇵': 'flag: North Korea',
- '🇰🇷': 'flag: South Korea',
- '🇰🇼': 'flag: Kuwait',
- '🇰🇾': 'flag: Cayman Islands',
- '🇰🇿': 'flag: Kazakhstan',
- '🇱🇦': 'flag: Laos',
- '🇱🇧': 'flag: Lebanon',
- '🇱🇨': 'flag: St. Lucia',
- '🇱🇮': 'flag: Liechtenstein',
- '🇱🇰': 'flag: Sri Lanka',
- '🇱🇷': 'flag: Liberia',
- '🇱🇸': 'flag: Lesotho',
- '🇱🇹': 'flag: Lithuania',
- '🇱🇺': 'flag: Luxembourg',
- '🇱🇻': 'flag: Latvia',
- '🇱🇾': 'flag: Libya',
- '🇲🇦': 'flag: Morocco',
- '🇲🇨': 'flag: Monaco',
- '🇲🇩': 'flag: Moldova',
- '🇲🇪': 'flag: Montenegro',
- '🇲🇫': 'flag: St. Martin',
- '🇲🇬': 'flag: Madagascar',
- '🇲🇭': 'flag: Marshall Islands',
- '🇲🇰': 'flag: North Macedonia',
- '🇲🇱': 'flag: Mali',
- '🇲🇲': 'flag: Myanmar (Burma)',
- '🇲🇳': 'flag: Mongolia',
- '🇲🇴': 'flag: Macao SAR China',
- '🇲🇵': 'flag: Northern Mariana Islands',
- '🇲🇶': 'flag: Martinique',
- '🇲🇷': 'flag: Mauritania',
- '🇲🇸': 'flag: Montserrat',
- '🇲🇹': 'flag: Malta',
- '🇲🇺': 'flag: Mauritius',
- '🇲🇻': 'flag: Maldives',
- '🇲🇼': 'flag: Malawi',
- '🇲🇽': 'flag: Mexico',
- '🇲🇾': 'flag: Malaysia',
- '🇲🇿': 'flag: Mozambique',
- '🇳🇦': 'flag: Namibia',
- '🇳🇨': 'flag: New Caledonia',
- '🇳🇪': 'flag: Niger',
- '🇳🇫': 'flag: Norfolk Island',
- '🇳🇬': 'flag: Nigeria',
- '🇳🇮': 'flag: Nicaragua',
- '🇳🇱': 'flag: Netherlands',
- '🇳🇴': 'flag: Norway',
- '🇳🇵': 'flag: Nepal',
- '🇳🇷': 'flag: Nauru',
- '🇳🇺': 'flag: Niue',
- '🇳🇿': 'flag: New Zealand',
- '🇴🇲': 'flag: Oman',
- '🇵🇦': 'flag: Panama',
- '🇵🇪': 'flag: Peru',
- '🇵🇫': 'flag: French Polynesia',
- '🇵🇬': 'flag: Papua New Guinea',
- '🇵🇭': 'flag: Philippines',
- '🇵🇰': 'flag: Pakistan',
- '🇵🇱': 'flag: Poland',
- '🇵🇲': 'flag: St. Pierre & Miquelon',
- '🇵🇳': 'flag: Pitcairn Islands',
- '🇵🇷': 'flag: Puerto Rico',
- '🇵🇸': 'flag: Palestinian Territories',
- '🇵🇹': 'flag: Portugal',
- '🇵🇼': 'flag: Palau',
- '🇵🇾': 'flag: Paraguay',
- '🇶🇦': 'flag: Qatar',
- '🇷🇪': 'flag: Réunion',
- '🇷🇴': 'flag: Romania',
- '🇷🇸': 'flag: Serbia',
- '🇷🇺': 'flag: Russia',
- '🇷🇼': 'flag: Rwanda',
- '🇸🇦': 'flag: Saudi Arabia',
- '🇸🇧': 'flag: Solomon Islands',
- '🇸🇨': 'flag: Seychelles',
- '🇸🇩': 'flag: Sudan',
- '🇸🇪': 'flag: Sweden',
- '🇸🇬': 'flag: Singapore',
- '🇸🇭': 'flag: St. Helena',
- '🇸🇮': 'flag: Slovenia',
- '🇸🇯': 'flag: Svalbard & Jan Mayen',
- '🇸🇰': 'flag: Slovakia',
- '🇸🇱': 'flag: Sierra Leone',
- '🇸🇲': 'flag: San Marino',
- '🇸🇳': 'flag: Senegal',
- '🇸🇴': 'flag: Somalia',
- '🇸🇷': 'flag: Suriname',
- '🇸🇸': 'flag: South Sudan',
- '🇸🇹': 'flag: São Tomé & Príncipe',
- '🇸🇻': 'flag: El Salvador',
- '🇸🇽': 'flag: Sint Maarten',
- '🇸🇾': 'flag: Syria',
- '🇸🇿': 'flag: Eswatini',
- '🇹🇦': 'flag: Tristan da Cunha',
- '🇹🇨': 'flag: Turks & Caicos Islands',
- '🇹🇩': 'flag: Chad',
- '🇹🇫': 'flag: French Southern Territories',
- '🇹🇬': 'flag: Togo',
- '🇹🇭': 'flag: Thailand',
- '🇹🇯': 'flag: Tajikistan',
- '🇹🇰': 'flag: Tokelau',
- '🇹🇱': 'flag: Timor-Leste',
- '🇹🇲': 'flag: Turkmenistan',
- '🇹🇳': 'flag: Tunisia',
- '🇹🇴': 'flag: Tonga',
- '🇹🇷': 'flag: Turkey',
- '🇹🇹': 'flag: Trinidad & Tobago',
- '🇹🇻': 'flag: Tuvalu',
- '🇹🇼': 'flag: Taiwan',
- '🇹🇿': 'flag: Tanzania',
- '🇺🇦': 'flag: Ukraine',
- '🇺🇬': 'flag: Uganda',
- '🇺🇲': 'flag: U.S. Outlying Islands',
- '🇺🇳': 'flag: United Nations',
- '🇺🇸': 'flag: United States',
- '🇺🇾': 'flag: Uruguay',
- '🇺🇿': 'flag: Uzbekistan',
- '🇻🇦': 'flag: Vatican City',
- '🇻🇨': 'flag: St. Vincent & Grenadines',
- '🇻🇪': 'flag: Venezuela',
- '🇻🇬': 'flag: British Virgin Islands',
- '🇻🇮': 'flag: U.S. Virgin Islands',
- '🇻🇳': 'flag: Vietnam',
- '🇻🇺': 'flag: Vanuatu',
- '🇼🇫': 'flag: Wallis & Futuna',
- '🇼🇸': 'flag: Samoa',
- '🇽🇰': 'flag: Kosovo',
- '🇾🇪': 'flag: Yemen',
- '🇾🇹': 'flag: Mayotte',
- '🇿🇦': 'flag: South Africa',
- '🇿🇲': 'flag: Zambia',
- '🇿🇼': 'flag: Zimbabwe',
- '🏴': 'flag: England',
- '🏴': 'flag: Scotland',
- '🏴': 'flag: Wales',
- };
- const isEmoji = (str) => {
- const regex = getRegex();
- const emojiMatches = str.match(regex);
- const emojiString = emojiMatches ? emojiMatches.join('') : '';
- return !/\d/.test(str) && emojiString === str;
- };
- const parseEmoji = (style, str, size = 16) => {
- switch (style) {
- case 'twemoji':
- return twemoji.parse(str, {
- folder: 'svg',
- ext: '.svg',
- attributes: () => ({
- width: `${size}px`,
- height: `${size}px`,
- }),
- });
- case 'native':
- return str;
- default:
- return null;
- }
- };
- /**
- * Gets the shortcode for a given emoji by the name of the emoji. This function replaces
- * spaces with underscores and removes colons.
- * @param key String to replace with shortcode.
- * @returns String with shortcode, or `undefined` if no shortcode exists.
- */
- const getShortcode = (key) => {
- var _a;
- // Removable of colons is necessary for the flag shortcodes.
- return (_a = shortNames[key]) === null || _a === void 0 ? void 0 : _a.replace(/\s/g, '_').replace(/:/g, '').toLowerCase();
- };
- var emoji = {
- shortNames,
- isEmoji,
- getShortcode,
- parseEmoji,
- getRegex,
- };
- // Default obsidian file icon.
- const DEFAULT_FILE_ICON = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-file"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path><polyline points="14 2 14 8 20 8"></polyline></svg>';
- // Default obsidian folder icon.
- const DEFAULT_FOLDER_ICON = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-folder"><path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"></path></svg>';
- /**
- * Tries to read the file synchronously.
- * @param file File that will be read.
- * @returns A promise that will resolve to a string which is the content of the file.
- */
- const readFileSync = (file) => __awaiter(void 0, void 0, void 0, function* () {
- const content = yield new Promise((resolve) => {
- const reader = new FileReader();
- reader.readAsText(file, 'UTF-8');
- reader.onload = (readerEvent) => resolve(readerEvent.target.result);
- });
- return content;
- });
- /**
- * Gets all the currently opened files by getting the markdown leaves and then checking
- * for the `file` property in the view. This also returns the leaf of the file.
- * @param plugin Instance of the IconizePlugin.
- * @returns An array of {@link FileWithLeaf} objects.
- */
- const getAllOpenedFiles = (plugin) => {
- return plugin.app.workspace
- .getLeavesOfType('markdown')
- .reduce((prev, curr) => {
- const file = curr.view.file;
- if (file) {
- prev.push(Object.assign(Object.assign({}, file), { leaf: curr, pinned: false }));
- }
- return prev;
- }, []);
- };
- /**
- * Gets the file item title element by either accessing `titleEl` or `selfEl`.
- * @param fileItem FileItem which will be used to retrieve the title element from.
- * @returns HTMLElement which is the title element.
- */
- const getFileItemTitleEl = (fileItem) => {
- var _a;
- return (_a = fileItem.titleEl) !== null && _a !== void 0 ? _a : fileItem.selfEl;
- };
- /**
- * Gets the file item inner title element by either accessing `titleInnerEl` or `innerEl`.
- * @param fileItem FileItem which will be used to retrieve the inner title element from.
- * @returns HTMLElement which is the inner title element.
- */
- const getFileItemInnerTitleEl = (fileItem) => {
- var _a;
- return (_a = fileItem.titleInnerEl) !== null && _a !== void 0 ? _a : fileItem.innerEl;
- };
- /**
- * A utility function which will add the icon to the icon pack and then extract the icon
- * to the icon pack.
- * @param plugin IconizePlugin that will be used for extracting the icon.
- * @param iconNameWithPrefix String that will be used to add the icon to the icon pack.
- */
- const saveIconToIconPack = (plugin, iconNameWithPrefix) => {
- const iconNextIdentifier = nextIdentifier(iconNameWithPrefix);
- const iconName = iconNameWithPrefix.substring(iconNextIdentifier);
- const iconPrefix = iconNameWithPrefix.substring(0, iconNextIdentifier);
- const possibleIcon = getSvgFromLoadedIcon(iconPrefix, iconName);
- if (!possibleIcon) {
- throw new Error(`Icon ${iconNameWithPrefix} could not be found.`);
- }
- const iconPackName = getIconPackNameByPrefix(iconPrefix);
- if (iconPackName === LUCIDE_ICON_PACK_NAME &&
- !plugin.doesUseCustomLucideIconPack()) {
- return;
- }
- const icon = getIconFromIconPack(iconPackName, iconPrefix, iconName);
- extractIconToIconPack(plugin, icon, possibleIcon);
- };
- /**
- * A utility function which will remove the icon from the icon pack by removing the icon
- * file from the icon pack directory.
- * @param plugin IconizePlugin that will be used for removing the icon.
- * @param iconNameWithPrefix String that will be used to remove the icon from the icon pack.
- */
- const removeIconFromIconPack = (plugin, iconNameWithPrefix) => {
- const identifier = nextIdentifier(iconNameWithPrefix);
- const prefix = iconNameWithPrefix.substring(0, identifier);
- const iconName = iconNameWithPrefix.substring(identifier);
- const iconPackName = getIconPackNameByPrefix(prefix);
- const duplicatedIcon = plugin.getDataPathByValue(iconNameWithPrefix);
- if (!duplicatedIcon) {
- removeIconFromIconPackDirectory(plugin, iconPackName, iconName);
- }
- };
- /**
- * A utility function which will convert a string to a hexadecimal color.
- * @param str String that will be converted to a hexadecimal color.
- * @returns A string which is the hexadecimal color.
- */
- const stringToHex = (str) => {
- const validHex = str.replace(/[^0-9a-fA-F]/g, '');
- const hex = validHex.padStart(6, '0').substring(0, 6);
- return `#${hex}`;
- };
- /**
- * A utility function which will check if a string is a hexadecimal color.
- * @param str String that will be checked if it is a hexadecimal color.
- * @param includeHash Boolean which will include the hash in the check.
- * @returns A boolean which is true if the string is a hexadecimal color.
- */
- const isHexadecimal = (str, includeHash = false) => {
- const regex = new RegExp(`^${includeHash ? '#' : ''}[0-9A-Fa-f]{1,6}$`);
- return regex.test(str);
- };
- // This library file does not include any other dependency and is a standalone file that
- // only include utility functions for setting styles for nodes or icons. The only
- // dependency is the `svg` library.
- /**
- * Sets the margin for a specific node.
- * @param el Node where the margin will be set.
- * @param margin Margin that will be applied to the node.
- * @returns The modified node with the applied margin.
- */
- const setMargin = (el, margin) => {
- el.style.margin = `${margin.top}px ${margin.right}px ${margin.bottom}px ${margin.left}px`;
- return el;
- };
- /**
- * Applies all stylings to the specified svg icon string and applies styling to the node
- * (container). The styling to the specified element is only modified when it is an emoji
- * or extra margin is defined in the settings.
- * @param plugin Instance of the IconizePlugin.
- * @param iconString SVG that will be used to apply the svg styles to.
- * @param el Node for manipulating the style.
- * @returns Icon svg string with the manipulate style attributes.
- */
- const applyAll = (plugin, iconString, container) => {
- iconString = svg.setFontSize(iconString, plugin.getSettings().fontSize);
- container.style.color = plugin.getSettings().iconColor;
- iconString = svg.colorize(iconString, plugin.getSettings().iconColor);
- // Sets the margin of an element.
- const margin = plugin.getSettings().extraMargin;
- const normalizedMargin = {
- top: margin.top !== undefined ? margin.top : 4,
- right: margin.right !== undefined ? margin.right : 4,
- left: margin.left !== undefined ? margin.left : 4,
- bottom: margin.bottom !== undefined ? margin.bottom : 4,
- };
- if (plugin.getSettings().extraMargin) {
- setMargin(container, normalizedMargin);
- }
- if (emoji.isEmoji(iconString)) {
- container.style.fontSize = `${plugin.getSettings().fontSize}px`;
- container.style.lineHeight = `${plugin.getSettings().fontSize}px`;
- }
- return iconString;
- };
- /**
- * Refreshes all the styles of all the applied icons where a `.iconize-icon`
- * class is defined. This function only modifies the styling of the node.
- * @param plugin Instance of the IconizePlugin.
- * @param applyStyles Function that is getting called when the icon node is found and
- * typically applies all the styles to the icon.
- */
- const refreshIconNodes = (plugin, applyStyles = applyAll) => {
- const fileExplorers = plugin.app.workspace.getLeavesOfType('file-explorer');
- for (const fileExplorer of fileExplorers) {
- Object.keys(plugin.getData()).forEach((path) => {
- const fileItem = fileExplorer.view.fileItems[path];
- if (fileItem) {
- const titleEl = getFileItemTitleEl(fileItem);
- const iconNode = titleEl.querySelector('.iconize-icon');
- if (iconNode) {
- const pathValue = plugin.getData()[path];
- const hasIndividualColor = typeof pathValue === 'object' && pathValue.iconColor;
- iconNode.innerHTML = applyStyles(plugin, iconNode.innerHTML, iconNode);
- if (hasIndividualColor) {
- iconNode.style.color = pathValue.iconColor;
- const colorizedInnerHtml = svg.colorize(iconNode.innerHTML, pathValue.iconColor);
- iconNode.innerHTML = colorizedInnerHtml;
- }
- }
- }
- });
- }
- };
- var style = {
- applyAll,
- setMargin,
- refreshIconNodes,
- };
- /**
- * Removes the `iconize-icon` icon node from the provided HTMLElement.
- * @param el HTMLElement from which the icon node will be removed.
- */
- const removeIconInNode = (el) => {
- const iconNode = el.querySelector('.iconize-icon');
- if (!iconNode) {
- return;
- }
- iconNode.remove();
- };
- /**
- * Removes the 'iconize-icon' icon node from the HTMLElement corresponding
- * to the specified file path.
- * @param path File path for which the icon node will be removed.
- */
- const removeIconInPath = (path, options) => {
- var _a;
- const node = (_a = options === null || options === void 0 ? void 0 : options.container) !== null && _a !== void 0 ? _a : document.querySelector(`[data-path="${path}"]`);
- if (!node) {
- logger.warn(`Element with data path not found (path: ${path})`);
- return;
- }
- removeIconInNode(node);
- };
- /**
- * Sets an icon or emoji for an HTMLElement based on the specified icon name and color.
- * The function manipulates the specified node inline.
- * @param plugin Instance of the IconizePlugin.
- * @param iconName Name of the icon or emoji to add.
- * @param node HTMLElement to which the icon or emoji will be added.
- * @param options Options for adjusting settings while the icon is being set.
- */
- const setIconForNode = (plugin, iconName, node, options) => {
- var _a, _b;
- options !== null && options !== void 0 ? options : (options = {});
- (_a = options.shouldApplyAllStyles) !== null && _a !== void 0 ? _a : (options.shouldApplyAllStyles = true);
- // Gets the possible icon based on the icon name.
- const iconNextIdentifier = nextIdentifier(iconName);
- const possibleIcon = getSvgFromLoadedIcon(iconName.substring(0, iconNextIdentifier), iconName.substring(iconNextIdentifier));
- if (possibleIcon) {
- // The icon is possibly not an emoji.
- let iconContent = (options === null || options === void 0 ? void 0 : options.shouldApplyAllStyles)
- ? style.applyAll(plugin, possibleIcon, node)
- : possibleIcon;
- if (options === null || options === void 0 ? void 0 : options.color) {
- node.style.color = options.color;
- iconContent = svg.colorize(iconContent, options.color);
- }
- node.innerHTML = iconContent;
- }
- else {
- const parsedEmoji = (_b = emoji.parseEmoji(plugin.getSettings().emojiStyle, iconName)) !== null && _b !== void 0 ? _b : iconName;
- node.innerHTML = (options === null || options === void 0 ? void 0 : options.shouldApplyAllStyles)
- ? style.applyAll(plugin, parsedEmoji, node)
- : parsedEmoji;
- }
- node.setAttribute('title', iconName);
- };
- /**
- * Creates an icon node for the specified path and inserts it to the DOM.
- * @param plugin Instance of the IconizePlugin.
- * @param path Path for which the icon node will be created.
- * @param iconName Name of the icon or emoji to add.
- * @param color Optional color of the icon to add.
- */
- const createIconNode = (plugin, path, iconName, options) => {
- var _a;
- // Get the container from the provided options or try to find the node that has the
- // path from the document itself.
- const node = (_a = options === null || options === void 0 ? void 0 : options.container) !== null && _a !== void 0 ? _a : document.querySelector(`[data-path="${path}"]`);
- if (!node) {
- logger.warn(`Element with data path not found (path: ${path})`);
- return;
- }
- // Get the folder or file title node.
- let titleNode = node.querySelector('.nav-folder-title-content');
- if (!titleNode) {
- titleNode = node.querySelector('.nav-file-title-content');
- if (!titleNode) {
- logger.warn(`Element with title node not found (path: ${path})`);
- return;
- }
- }
- let iconNode = node.querySelector('.iconize-icon');
- // If the icon is already set in the path, we do not need to create a new div element.
- if (iconNode) {
- setIconForNode(plugin, iconName, iconNode, { color: options === null || options === void 0 ? void 0 : options.color });
- }
- else {
- // Creates a new icon node and inserts it to the DOM.
- iconNode = document.createElement('div');
- iconNode.setAttribute(config.ICON_ATTRIBUTE_NAME, iconName);
- iconNode.classList.add('iconize-icon');
- setIconForNode(plugin, iconName, iconNode, { color: options === null || options === void 0 ? void 0 : options.color });
- node.insertBefore(iconNode, titleNode);
- }
- };
- /**
- * Checks if the element has an icon node by checking if the element has a child with the
- * class `iconize-icon`.
- * @param element HTMLElement which will be checked if it has an icon.
- * @returns Boolean whether the element has an icon node or not.
- */
- const doesElementHasIconNode = (element) => {
- return element.querySelector('.iconize-icon') !== null;
- };
- /**
- * Gets the icon name of the element if it has an icon node.
- * @param element HTMLElement parent which includes a node with the icon.
- * @returns String with the icon name if the element has an icon, `undefined` otherwise.
- */
- const getIconFromElement = (element) => {
- const iconNode = element.querySelector('.iconize-icon');
- const existingIcon = iconNode === null || iconNode === void 0 ? void 0 : iconNode.getAttribute(config.ICON_ATTRIBUTE_NAME);
- return existingIcon;
- };
- const getIconNodeFromPath = (path) => {
- var _a;
- return (_a = document
- .querySelector(`[data-path="${path}"]`)) === null || _a === void 0 ? void 0 : _a.querySelector('[data-icon]');
- };
- var dom = {
- setIconForNode,
- createIconNode,
- doesElementHasIconNode,
- getIconFromElement,
- getIconNodeFromPath,
- removeIconInNode,
- removeIconInPath,
- };
- class IconsPickerModal extends obsidian.FuzzySuggestModal {
- constructor(app, plugin, path) {
- super(app);
- this.renderIndex = 0;
- this.plugin = plugin;
- this.path = path;
- this.limit = 150;
- const pluginRecentltyUsedItems = [
- ...plugin.getSettings().recentlyUsedIcons,
- ];
- this.recentlyUsedItems = new Set(pluginRecentltyUsedItems.reverse().filter((iconName) => {
- return doesIconExists(iconName) || emoji.isEmoji(iconName);
- }));
- this.resultContainerEl.classList.add('iconize-modal');
- }
- onOpen() {
- super.onOpen();
- }
- onClose() {
- const { contentEl } = this;
- contentEl.empty();
- }
- getItemText(item) {
- return `${item.name} (${item.prefix})`;
- }
- getItems() {
- const iconKeys = [];
- if (this.inputEl.value.length === 0) {
- this.renderIndex = 0;
- this.recentlyUsedItems.forEach((iconName) => {
- if (emoji.isEmoji(iconName)) {
- iconKeys.push({
- name: emoji.shortNames[iconName],
- prefix: 'Emoji',
- displayName: iconName,
- iconPackName: null,
- });
- return;
- }
- const nextLetter = nextIdentifier(iconName);
- const iconPrefix = iconName.substring(0, nextLetter);
- const iconPackName = getIconPackNameByPrefix(iconPrefix);
- iconKeys.push({
- name: iconName.substring(nextLetter),
- prefix: iconPrefix,
- displayName: iconName,
- iconPackName: iconPackName,
- });
- });
- }
- for (const icon of getAllLoadedIconNames()) {
- iconKeys.push({
- name: icon.name,
- prefix: icon.prefix,
- displayName: icon.prefix + icon.name,
- iconPackName: icon.iconPackName,
- });
- }
- Object.entries(emoji.shortNames).forEach(([unicode, shortName]) => {
- iconKeys.push({
- name: shortName,
- prefix: 'Emoji',
- displayName: unicode,
- iconPackName: null,
- });
- iconKeys.push({
- name: unicode,
- prefix: 'Emoji',
- displayName: unicode,
- iconPackName: null,
- });
- });
- return iconKeys;
- }
- onChooseItem(item) {
- var _a;
- const iconNameWithPrefix = typeof item === 'object' ? item.displayName : item;
- dom.createIconNode(this.plugin, this.path, iconNameWithPrefix);
- (_a = this.onSelect) === null || _a === void 0 ? void 0 : _a.call(this, iconNameWithPrefix);
- this.plugin.addFolderIcon(this.path, item);
- // Extracts the icon file to the icon pack.
- if (typeof item === 'object' && !emoji.isEmoji(iconNameWithPrefix)) {
- saveIconToIconPack(this.plugin, iconNameWithPrefix);
- }
- this.plugin.notifyPlugins();
- }
- renderSuggestion(item, el) {
- super.renderSuggestion(item, el);
- // if (getAllIconPacks().length === 0) {
- // this.resultContainerEl.style.display = 'block';
- // this.resultContainerEl.innerHTML = '<div class="suggestion-empty">You need to create an icon pack.</div>';
- // return;
- // }
- // Render subheadlines for modal.
- if (this.recentlyUsedItems.size !== 0 && this.inputEl.value.length === 0) {
- if (this.renderIndex === 0) {
- const subheadline = this.resultContainerEl.createDiv();
- subheadline.classList.add('iconize-subheadline');
- subheadline.innerText = 'Recently used Icons:';
- this.resultContainerEl.prepend(subheadline);
- }
- else if (this.renderIndex === this.recentlyUsedItems.size - 1) {
- const subheadline = this.resultContainerEl.createDiv();
- subheadline.classList.add('iconize-subheadline');
- subheadline.innerText = 'All Icons:';
- this.resultContainerEl.append(subheadline);
- }
- }
- if (item.item.name !== 'default') {
- if (item.item.prefix === 'Emoji') {
- const displayName = emoji.parseEmoji(this.plugin.getSettings().emojiStyle, item.item.displayName);
- if (!displayName) {
- return;
- }
- el.innerHTML = `<div>${el.innerHTML}</div><div class="iconize-icon-preview">${displayName}</div>`;
- }
- else {
- el.innerHTML = `<div>${el.innerHTML}</div><div class="iconize-icon-preview">${getSvgFromLoadedIcon(item.item.prefix, item.item.name)}</div>`;
- }
- }
- this.renderIndex++;
- }
- }
- var IconInTitlePosition;
- (function (IconInTitlePosition) {
- IconInTitlePosition["Above"] = "above";
- IconInTitlePosition["Inline"] = "inline";
- })(IconInTitlePosition || (IconInTitlePosition = {}));
- const DEFAULT_SETTINGS = {
- migrated: 2,
- iconPacksPath: '.obsidian/icons',
- fontSize: 16,
- emojiStyle: 'native',
- iconColor: null,
- recentlyUsedIcons: [],
- recentlyUsedIconsSize: 5,
- rules: [],
- extraMargin: {
- top: 0,
- right: 4,
- bottom: 0,
- left: 0,
- },
- iconInTabsEnabled: false,
- iconInTitleEnabled: false,
- iconInTitlePosition: IconInTitlePosition.Above,
- iconInFrontmatterEnabled: false,
- iconInFrontmatterFieldName: 'icon',
- iconColorInFrontmatterFieldName: 'iconColor',
- iconsBackgroundCheckEnabled: false,
- iconsInNotesEnabled: true,
- iconsInLinksEnabled: true,
- iconIdentifier: ':',
- lucideIconPackType: 'native',
- debugMode: false,
- useInternalPlugins: false,
- };
- function migrate$5(plugin) {
- return __awaiter(this, void 0, void 0, function* () {
- // Migration for new syncing mechanism.
- if (plugin.getSettings().migrated === 1) {
- new obsidian.Notice('Please delete your old icon packs and redownload your icon packs to use the new syncing mechanism.', 20000);
- plugin.getSettings().migrated++;
- }
- });
- }
- function migrate$4(plugin) {
- return __awaiter(this, void 0, void 0, function* () {
- // Migration for new order functionality of custom rules.
- if (plugin.getSettings().migrated === 2) {
- // Sorting alphabetically was the default behavior before.
- plugin
- .getSettings()
- .rules.sort((a, b) => a.rule.localeCompare(b.rule))
- .forEach((rule, i) => {
- rule.order = i;
- });
- plugin.getSettings().migrated++;
- }
- });
- }
- class IconCache {
- constructor() {
- this.cache = new Map();
- this.set = (path, result) => {
- this.cache.set(path, result);
- };
- this.invalidate = (path) => {
- this.cache.delete(path);
- };
- this.clear = () => {
- this.cache.clear();
- };
- this.get = (path) => {
- var _a;
- return (_a = this.cache.get(path)) !== null && _a !== void 0 ? _a : null;
- };
- this.doesRecordExist = (path) => {
- return this.get(path) !== null;
- };
- if (IconCache.instance) {
- throw new Error('Error: Instantiation failed: Use `IconCache.getInstance()` instead of new.');
- }
- IconCache.instance = this;
- }
- }
- IconCache.instance = new IconCache();
- IconCache.getInstance = () => {
- return IconCache.instance;
- };
- /**
- * Checks if the file type is equal to the `for` property of the custom rule.
- * @param rule CustomRule that will be checked.
- * @param fileType CustomRuleFileType that will be checked. Can be either `file` or `folder`.
- * @returns Boolean whether the custom rule `for` matches the file type or not.
- */
- const doesMatchFileType = (rule, fileType) => {
- return (rule.for === 'everything' ||
- (rule.for === 'files' && fileType === 'file') ||
- (rule.for === 'folders' && fileType === 'folder'));
- };
- /**
- * Determines whether a given file or folder matches a specified custom rule.
- * @param plugin Plugin instance.
- * @param rule CustomRule to check against the file or folder.
- * @param filePath String to check against the custom rule.
- * @returns Promise that resolves to `true` if the file matches the rule, `false` otherwise.
- */
- const isApplicable = (plugin, rule, filePath) => __awaiter(void 0, void 0, void 0, function* () {
- const metadata = yield plugin.app.vault.adapter.stat(filePath);
- if (!metadata) {
- return false;
- }
- const fileType = metadata.type;
- const doesMatch = doesMatchFileType(rule, fileType);
- if (!doesMatch) {
- return false;
- }
- return doesMatchPath(rule, filePath);
- });
- /**
- * Removes the icon from the custom rule from all the files and folders, if applicable.
- * @param plugin IconizePlugin instance.
- * @param rule CustomRule where the icons will be removed based on this rule.
- */
- const removeFromAllFiles = (plugin, rule) => __awaiter(void 0, void 0, void 0, function* () {
- const nodesWithIcon = document.querySelectorAll(`[${config.ICON_ATTRIBUTE_NAME}="${rule.icon}"]`);
- for (let i = 0; i < nodesWithIcon.length; i++) {
- const node = nodesWithIcon[i];
- // Parent element is the node which contains the data path.
- const parent = node.parentElement;
- if (!parent) {
- continue;
- }
- const dataPath = parent.getAttribute('data-path');
- if (!dataPath) {
- continue;
- }
- const fileType = (yield plugin.app.vault.adapter.stat(dataPath)).type;
- if (doesMatchPath(rule, dataPath) && doesMatchFileType(rule, fileType)) {
- dom.removeIconInNode(parent);
- IconCache.getInstance().invalidate(dataPath);
- }
- }
- });
- /**
- * Gets all the custom rules sorted by their order property in ascending order.
- * @param plugin IconizePlugin instance.
- * @returns CustomRule array sorted by their order property in ascending order.
- */
- const getSortedRules = (plugin) => {
- return plugin.getSettings().rules.sort((a, b) => a.order - b.order);
- };
- /**
- * Tries to add all specific custom rule icons to all registered files and directories.
- * It does that by calling the {@link add} function. Custom rules should have the lowest
- * priority and will get ignored if an icon already exists in the file or directory.
- * @param plugin IconizePlugin instance.
- * @param rule CustomRule that will be applied, if applicable, to all files and folders.
- */
- const addToAllFiles = (plugin, rule) => __awaiter(void 0, void 0, void 0, function* () {
- const fileItems = yield getFileItems(plugin, rule);
- for (const fileItem of fileItems) {
- yield add$2(plugin, rule, fileItem.file, getFileItemTitleEl(fileItem));
- }
- });
- /**
- * Tries to add the icon of the custom rule to a file or folder. This function also checks
- * if the file type matches the `for` property of the custom rule.
- * @param plugin IconizePlugin instance.
- * @param rule CustomRule that will be used to check if the rule is applicable to the file
- * or directory.
- * @param file TAbstractFile that will be used to possibly create the icon for.
- * @param container HTMLElement where the icon will be added if the custom rules matches.
- * @returns A promise that resolves to `true` if the icon was added, `false` otherwise.
- */
- const add$2 = (plugin, rule, file, container) => __awaiter(void 0, void 0, void 0, function* () {
- if (container && dom.doesElementHasIconNode(container)) {
- return false;
- }
- // Checks if the file or directory already has an icon.
- const hasIcon = plugin.getIconNameFromPath(file.path);
- if (hasIcon) {
- return false;
- }
- const doesMatch = yield isApplicable(plugin, rule, file.path);
- if (doesMatch) {
- IconCache.getInstance().set(file.path, {
- iconNameWithPrefix: rule.icon,
- inCustomRule: true,
- });
- dom.createIconNode(plugin, file.path, rule.icon, {
- color: rule.color,
- container,
- });
- return true;
- }
- return false;
- });
- /**
- * Determines whether a given rule exists in a given path.
- * @param rule Rule to check for.
- * @param path Path to check in.
- * @returns True if the rule exists in the path, false otherwise.
- */
- const doesMatchPath = (rule, path) => {
- const toMatch = rule.useFilePath ? path : path.split('/').pop();
- try {
- // Rule is in some sort of regex.
- const regex = new RegExp(rule.rule);
- if (toMatch.match(regex)) {
- return true;
- }
- }
- catch (_a) {
- // Rule is not in some sort of regex, check for basic string match.
- return toMatch.includes(rule.rule);
- }
- return false;
- };
- /**
- * Gets all the file items that can be applied to the specific custom rule.
- * @param plugin Instance of IconizePlugin.
- * @param rule Custom rule that will be checked for.
- * @returns A promise that resolves to an array of file items that match the custom rule.
- */
- const getFileItems = (plugin, rule) => __awaiter(void 0, void 0, void 0, function* () {
- const result = [];
- for (const fileExplorer of plugin.getRegisteredFileExplorers()) {
- const files = Object.values(fileExplorer.fileItems || {});
- for (const fileItem of files) {
- if (yield isApplicable(plugin, rule, fileItem.file.path)) {
- result.push(fileItem);
- }
- }
- }
- return result;
- });
- var customRule = {
- getFileItems,
- doesMatchPath,
- doesMatchFileType,
- getSortedRules,
- removeFromAllFiles,
- add: add$2,
- addToAllFiles,
- isApplicable,
- };
- function migrate$3(plugin) {
- return __awaiter(this, void 0, void 0, function* () {
- // Migration for inheritance to custom rule.
- if (plugin.getSettings().migrated === 3) {
- let hasRemovedInheritance = false;
- for (const [key, value] of Object.entries(plugin.getData())) {
- if (key === 'settings' || typeof value !== 'object') {
- continue;
- }
- const folderData = value;
- const inheritanceIcon = folderData.inheritanceIcon;
- if (!inheritanceIcon) {
- continue;
- }
- const folderIconName = folderData.iconName;
- // Clean up old data.
- if (folderData.iconColor && folderIconName) {
- delete folderData.inheritanceIcon;
- }
- else if (folderIconName) {
- delete plugin.getData()[key];
- plugin.getData()[key] = folderIconName;
- }
- else if (!folderIconName) {
- delete plugin.getData()[key];
- }
- const folderPath = key + '\\/[\\w\\d\\s]+';
- const newRule = {
- icon: inheritanceIcon,
- rule: `${folderPath}\\.(?:\\w+\\.)*\\w+`,
- for: 'files',
- order: 0,
- useFilePath: true,
- };
- // Reorder existing custom rules so that the new inheritance custom rule
- // is at the top.
- plugin.getSettings().rules.map((rule) => {
- rule.order++;
- });
- plugin.getSettings().rules.unshift(newRule);
- // Apply the custom rule.
- yield customRule.addToAllFiles(plugin, newRule);
- hasRemovedInheritance = true;
- }
- if (hasRemovedInheritance) {
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Inheritance has been removed and replaced with custom rules.`);
- }
- plugin.getSettings().migrated++;
- }
- });
- }
- function migrate$2(plugin) {
- return __awaiter(this, void 0, void 0, function* () {
- if (plugin.getSettings().migrated === 4) {
- if (plugin.getSettings().emojiStyle === 'none') {
- plugin.getSettings().emojiStyle = 'native';
- }
- plugin.getSettings().migrated++;
- }
- });
- }
- function migrate$1(plugin) {
- return __awaiter(this, void 0, void 0, function* () {
- if (plugin.getSettings().migrated === 5) {
- yield deleteIconPack(plugin, LUCIDE_ICON_PACK_NAME);
- plugin.getSettings().migrated++;
- }
- });
- }
- const migrate = (plugin) => __awaiter(void 0, void 0, void 0, function* () {
- // eslint-disable-next-line
- // @ts-ignore - Required because an older version of the plugin saved the `migrated`
- // property as a boolean instead of a number.
- if (plugin.getSettings().migrated === true) {
- plugin.getSettings().migrated = 1;
- }
- yield migrate$5(plugin);
- yield migrate$4(plugin);
- yield migrate$3(plugin);
- yield migrate$2(plugin);
- yield migrate$1(plugin);
- yield plugin.saveIconFolderData();
- });
- class IconFolderSetting {
- constructor(plugin, containerEl) {
- this.plugin = plugin;
- this.containerEl = containerEl;
- }
- }
- /**
- * Gets the tab leaves of a specific file path by looping through all opened files and
- * checking if the file path matches.
- * @param plugin IconizePlugin instance.
- * @param path String of the file path to get the tab leaf of.
- * @returns TabHeaderLeaf array that includes all tab leaves of the file path.
- */
- const getTabLeavesOfFilePath = (plugin, path) => {
- const openedFiles = getAllOpenedFiles(plugin);
- const openedFile = openedFiles.filter((openedFile) => openedFile.path === path);
- const leaves = openedFile.map((openedFile) => openedFile.leaf);
- return leaves;
- };
- /**
- * Adds an icon to the tab and its container. This function respects the
- * custom rules and individually icon set.
- * @param plugin IconizePlugin instance.
- * @param filePath String file path to add the icon to.
- * @param iconContainer HTMLElement where the icon will be added to.
- * @param options AddOptions for the add function which can optionally be used.
- */
- const add$1 = (plugin, filePath, iconContainer, options) => __awaiter(void 0, void 0, void 0, function* () {
- var _a;
- const iconColor = (_a = options === null || options === void 0 ? void 0 : options.iconColor) !== null && _a !== void 0 ? _a : plugin.getSettings().iconColor;
- const data = Object.entries(plugin.getData());
- // Removes the `display: none` from the obsidian styling.
- iconContainer.style.display = 'flex';
- // Only add the icon name manually when it is defined in the options.
- if (options === null || options === void 0 ? void 0 : options.iconName) {
- dom.setIconForNode(plugin, options.iconName, iconContainer, {
- color: iconColor,
- });
- // TODO: Refactor to include option to `insertIconToNode` function.
- iconContainer.style.margin = null;
- return;
- }
- // Add icons to tabs if a custom rule is applicable.
- for (const rule of customRule.getSortedRules(plugin)) {
- const isApplicable = yield customRule.isApplicable(plugin, rule, filePath);
- if (isApplicable) {
- dom.setIconForNode(plugin, rule.icon, iconContainer, {
- color: rule.color,
- });
- // TODO: Refactor to include option to `insertIconToNode` function.
- iconContainer.style.margin = null;
- break;
- }
- }
- // Add icons to tabs if there is an icon set.
- const iconData = data.find(([dataPath]) => dataPath === filePath);
- if (!iconData) {
- return;
- }
- const value = iconData[1];
- if (typeof value !== 'string' && typeof value !== 'object') {
- return;
- }
- let iconName;
- if (typeof value === 'object') {
- const v = value;
- if (v.iconName === null) {
- return;
- }
- iconName = v.iconName;
- }
- else {
- iconName = value;
- }
- dom.setIconForNode(plugin, iconName, iconContainer, {
- color: iconColor,
- shouldApplyAllStyles: true,
- });
- // TODO: Refactor to include option to `insertIconToNode` function.
- iconContainer.style.margin = null;
- });
- /**
- * Updates the icon in the tab and container by setting calling the `setIconForNode`
- * function and removing the margin from the icon container.
- * @param plugin IconizePlugin instance.
- * @param iconName String of the icon name to update to.
- * @param iconContainer HTMLElement where the icon is located and will be updated.
- */
- const update = (plugin, iconName, iconContainer) => {
- dom.setIconForNode(plugin, iconName, iconContainer);
- // TODO: Refactor to include option to `insertIconToNode` function.
- iconContainer.style.margin = null;
- };
- /**
- * Removes the icon from the tab and container by setting the `display` style property
- * to `none`. Optionally, the icon can be replaced with the default obsidian icon.
- * @param iconContainer HTMLElement where the icon is located and will be removed from.
- * @param options RemoveOptions for the remove function which can optionally be used.
- */
- const remove$1 = (iconContainer, options) => {
- if (!(options === null || options === void 0 ? void 0 : options.replaceWithDefaultIcon)) {
- // Removes the display of the icon container to remove the icons from the tabs.
- iconContainer.style.display = 'none';
- }
- else {
- iconContainer.innerHTML = DEFAULT_FILE_ICON;
- }
- };
- var iconTabs = {
- add: add$1,
- update,
- remove: remove$1,
- getTabLeavesOfFilePath,
- };
- const checkMissingIcons = (plugin, data) => __awaiter(void 0, void 0, void 0, function* () {
- const missingIcons = new Set();
- const allIcons = new Map();
- const getMissingIcon = (iconNameWithPrefix) => __awaiter(void 0, void 0, void 0, function* () {
- const iconNextIdentifier = nextIdentifier(iconNameWithPrefix);
- const iconName = iconNameWithPrefix.substring(iconNextIdentifier);
- const iconPrefix = iconNameWithPrefix.substring(0, iconNextIdentifier);
- const iconPackName = getIconPackNameByPrefix(iconPrefix);
- if (iconPackName === LUCIDE_ICON_PACK_NAME &&
- !plugin.doesUseCustomLucideIconPack()) {
- return;
- }
- const icon = getIconFromIconPack(iconPackName, iconPrefix, iconName);
- if (!icon) {
- logger.error(`Icon file with name ${iconNameWithPrefix} could not be found`);
- return null;
- }
- const doesIconFileExists = yield plugin.app.vault.adapter.exists(`${getPath()}/${iconPackName}/${iconName}.svg`);
- if (!doesIconFileExists) {
- const possibleIcon = getSvgFromLoadedIcon(iconPrefix, iconName);
- if (!possibleIcon) {
- logger.error(`Icon SVG with name ${iconNameWithPrefix} could not be found`);
- return null;
- }
- yield extractIconToIconPack(plugin, icon, possibleIcon);
- return icon;
- }
- return null;
- });
- for (const rule of plugin.getSettings().rules) {
- if (!emoji.isEmoji(rule.icon)) {
- allIcons.set(rule.icon, true);
- const icon = yield getMissingIcon(rule.icon);
- if (icon) {
- missingIcons.add(icon);
- }
- }
- }
- for (const [_, value] of data) {
- // Check for missing icon names.
- let iconNameWithPrefix = value;
- if (typeof value === 'object') {
- iconNameWithPrefix = value.iconName;
- }
- if (iconNameWithPrefix && !emoji.isEmoji(iconNameWithPrefix)) {
- allIcons.set(iconNameWithPrefix, true);
- const icon = yield getMissingIcon(iconNameWithPrefix);
- if (icon) {
- missingIcons.add(icon);
- }
- }
- }
- // Show notice that background check is running.
- if (missingIcons.size !== 0) {
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Background Check: found missing icons. Adding missing icons...`, 10000);
- }
- // Iterates over all the missing icons with its path and adds the icon to the node.
- for (const icon of missingIcons) {
- const normalizedName = getNormalizedName(icon.prefix + icon.name);
- const nodesWithIcon = document.querySelectorAll(`[${config.ICON_ATTRIBUTE_NAME}="${normalizedName}"]`);
- nodesWithIcon.forEach((node) => {
- dom.setIconForNode(plugin, normalizedName, node);
- });
- }
- // Show notice that background check was finished.
- if (missingIcons.size !== 0) {
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Background Check: added missing icons`, 10000);
- }
- // Remove all icon files that can not be found in the data.
- for (const iconPack of getAllIconPacks()) {
- // Checks if the icon pack exists.
- const doesIconPackExist = yield plugin.app.vault.adapter.exists(`${getPath()}/${iconPack.name}`);
- if (!doesIconPackExist) {
- continue;
- }
- const iconFiles = yield plugin.app.vault.adapter.list(`${getPath()}/${iconPack.name}`);
- for (const iconFilePath of iconFiles.files) {
- const iconNameWithExtension = iconFilePath.split('/').pop();
- // Removes the file extension.
- const iconName = iconNameWithExtension === null || iconNameWithExtension === void 0 ? void 0 : iconNameWithExtension.substring(0, iconNameWithExtension.length - 4);
- const iconNameWithPrefix = iconPack.prefix + iconName;
- const doesIconExist = allIcons.get(iconNameWithPrefix);
- if (!doesIconExist) {
- const path = `${getPath()}/${iconPack.name}/${iconName}.svg`;
- const doesPathExist = yield plugin.app.vault.adapter.exists(path);
- if (doesPathExist) {
- logger.info(`Removing icon with path '${path}' because it is not used anymore`);
- // Removes the icon file.
- yield plugin.app.vault.adapter.remove(`${getPath()}/${iconPack.name}/${iconName}.svg`);
- }
- }
- }
- }
- });
- /**
- * This function adds all the possible icons to the corresponding nodes. It
- * adds the icons, that are defined in the data as a basic string to the nodes
- * and the custom rule icons.
- * @param plugin Instance of IconizePlugin.
- * @param data Data that will be used to add all the icons to the nodes.
- * @param registeredFileExplorers A WeakSet of file explorers that are being used as a
- * cache for already handled file explorers.
- * @param callback Callback is being called whenever the icons are added to one file
- * explorer.
- */
- const addAll = (plugin, data, registeredFileExplorers, callback) => {
- const fileExplorers = plugin.app.workspace.getLeavesOfType('file-explorer');
- for (const fileExplorer of fileExplorers) {
- if (registeredFileExplorers.has(fileExplorer.view)) {
- continue;
- }
- registeredFileExplorers.add(fileExplorer.view);
- const setIcons = () => {
- var _a, _b;
- // Adds icons to already open file tabs.
- if (plugin.getSettings().iconInTabsEnabled) {
- for (const leaf of plugin.app.workspace.getLeavesOfType('markdown')) {
- const filePath = (_b = (_a = leaf.view.file) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : leaf.view.getState().file;
- if (typeof filePath === 'string') {
- const tabHeaderLeaf = leaf;
- const iconColor = plugin.getIconColor(filePath);
- iconTabs.add(plugin, filePath, tabHeaderLeaf.tabHeaderInnerIconEl, {
- iconColor,
- });
- }
- }
- }
- for (const [dataPath, value] of data) {
- const fileItem = fileExplorer.view.fileItems[dataPath];
- if (fileItem) {
- const titleEl = getFileItemTitleEl(fileItem);
- const titleInnerEl = getFileItemInnerTitleEl(fileItem);
- // Need to check this because refreshing the plugin will duplicate all the icons.
- if (titleEl.children.length === 2 || titleEl.children.length === 1) {
- const iconName = typeof value === 'string' ? value : value.iconName;
- const iconColor = typeof value === 'string' ? undefined : value.iconColor;
- if (iconName) {
- // Removes a possible existing icon.
- const existingIcon = titleEl.querySelector('.iconize-icon');
- if (existingIcon) {
- existingIcon.remove();
- }
- // Creates the new node with the icon inside.
- const iconNode = titleEl.createDiv();
- iconNode.setAttribute(config.ICON_ATTRIBUTE_NAME, iconName);
- iconNode.classList.add('iconize-icon');
- IconCache.getInstance().set(dataPath, {
- iconNameWithPrefix: iconName,
- });
- dom.setIconForNode(plugin, iconName, iconNode, {
- color: iconColor,
- });
- titleEl.insertBefore(iconNode, titleInnerEl);
- }
- }
- }
- }
- // Callback function to register other events to this file explorer.
- callback === null || callback === void 0 ? void 0 : callback();
- };
- if (obsidian.requireApiVersion('1.7.2')) {
- // TODO: Remove loading deferred view to improve performance.
- fileExplorer.loadIfDeferred().then(setIcons);
- }
- else {
- setIcons();
- }
- }
- // Handles the custom rules.
- for (const rule of customRule.getSortedRules(plugin)) {
- customRule.addToAllFiles(plugin, rule);
- }
- };
- /**
- * Gets the icon of a given path. This function returns the first occurrence of an icon.
- * @param plugin Instance of the IconizePlugin.
- * @param path Path to get the icon of.
- * @returns The icon of the path if it exists, undefined otherwise.
- */
- const getByPath = (plugin, path) => {
- if (path === 'settings' || path === 'migrated') {
- return undefined;
- }
- const value = plugin.getData()[path];
- if (typeof value === 'string') {
- // If the value is a plain icon name, return it.
- return value;
- }
- else if (typeof value === 'object') {
- const v = value;
- if (v.iconName !== null) {
- return v.iconName;
- }
- }
- // Tries to get the custom rule for the path and returns its icon if it exists.
- const rule = customRule.getSortedRules(plugin).find((rule) => {
- return customRule.doesMatchPath(rule, path);
- });
- if (rule) {
- return rule.icon;
- }
- return undefined;
- };
- /**
- * Gets all the icons with their paths as an object.
- * @param plugin Instance of the IconizePlugin.
- * @returns An object that consists of the path and the icon name for the data
- * or custom rule.
- */
- const getAllWithPath = (plugin) => {
- const result = [];
- Object.keys(plugin.getData()).forEach((path) => {
- if (path === 'settings' || path === 'migrated') {
- return;
- }
- const icon = getByPath(plugin, path);
- if (icon && !emoji.isEmoji(icon)) {
- result.push({ path, icon });
- }
- });
- // Add all icons for the custom rules with the rule as the path.
- for (const rule of plugin.getSettings().rules) {
- if (!emoji.isEmoji(rule.icon)) {
- result.push({ path: rule.rule, icon: rule.icon });
- }
- }
- return result;
- };
- /**
- * Returns the {@link Icon} for the given icon name. It is important, that the icon name
- * contains the icon pack prefix.
- * @param iconNameWithPrefix String that contains the icon pack prefix combined with the
- * icon name.
- * @returns Icon if it exists, `null` otherwise.
- */
- const getIconByName = (iconNameWithPrefix) => {
- const iconNextIdentifier = nextIdentifier(iconNameWithPrefix);
- const iconName = iconNameWithPrefix.substring(iconNextIdentifier);
- const iconPrefix = iconNameWithPrefix.substring(0, iconNextIdentifier);
- const iconPackName = getIconPackNameByPrefix(iconPrefix);
- const icon = getIconFromIconPack(iconPackName, iconPrefix, iconName);
- if (!icon) {
- return null;
- }
- return icon;
- };
- /**
- * Returns the {@link Icon} for the given path.
- * @param plugin IconizePlugin instance.
- * @param path String which is the path to get the icon of.
- * @returns Icon or Emoji as string if it exists, `null` otherwise.
- */
- const getIconByPath = (plugin, path) => {
- const iconNameWithPrefix = getByPath(plugin, path);
- if (!iconNameWithPrefix) {
- return null;
- }
- if (emoji.isEmoji(iconNameWithPrefix)) {
- return iconNameWithPrefix;
- }
- return getIconByName(iconNameWithPrefix);
- };
- var icon = {
- addAll,
- getByPath,
- getAllWithPath,
- getIconByPath,
- getIconByName,
- checkMissingIcons,
- };
- class CustomIconPackSetting extends IconFolderSetting {
- constructor(plugin, containerEl, refreshDisplay) {
- super(plugin, containerEl);
- this.refreshDisplay = refreshDisplay;
- this.dragOverElement = document.createElement('div');
- this.dragOverElement.addClass('iconize-dragover-el');
- this.dragOverElement.style.display = 'hidden';
- this.dragOverElement.innerHTML = '<p>Drop to add icon.</p>';
- }
- normalizeIconPackName(value) {
- return value.toLowerCase().replace(/\s/g, '-');
- }
- preventDefaults(event) {
- event.preventDefault();
- event.stopPropagation();
- }
- highlight(el) {
- clearTimeout(this.closeTimer);
- if (!this.dragTargetElement) {
- el.appendChild(this.dragOverElement);
- el.classList.add('iconize-dragover');
- this.dragTargetElement = el;
- }
- }
- unhighlight(target, el) {
- if (this.dragTargetElement && this.dragTargetElement !== target) {
- this.dragTargetElement.removeChild(this.dragOverElement);
- this.dragTargetElement.classList.remove('iconize-dragover');
- this.dragTargetElement = undefined;
- }
- clearTimeout(this.closeTimer);
- this.closeTimer = setTimeout(() => {
- if (this.dragTargetElement) {
- el.removeChild(this.dragOverElement);
- el.classList.remove('iconize-dragover');
- this.dragTargetElement = undefined;
- }
- }, 100);
- }
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Add custom icon pack')
- .setDesc('Add a custom icon pack.')
- .addText((text) => {
- text.setPlaceholder('Your icon pack name');
- this.textComponent = text;
- })
- .addButton((btn) => {
- btn.setButtonText('Add icon pack');
- btn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- const name = this.textComponent.getValue();
- if (name.length === 0) {
- return;
- }
- const normalizedName = this.normalizeIconPackName(this.textComponent.getValue());
- if (yield doesIconPackExist(this.plugin, normalizedName)) {
- new obsidian.Notice('Icon pack already exists.');
- return;
- }
- yield createCustomIconPackDirectory(this.plugin, normalizedName);
- this.textComponent.setValue('');
- this.refreshDisplay();
- new obsidian.Notice('Icon pack successfully created.');
- }));
- });
- // Sorts lucide icon pack always to the top.
- const iconPacks = [...getAllIconPacks()].sort((a, b) => {
- if (a.name === LUCIDE_ICON_PACK_NAME)
- return -1;
- if (b.name === LUCIDE_ICON_PACK_NAME)
- return 1;
- return a.name.localeCompare(b.name);
- });
- iconPacks.forEach((iconPack) => {
- const isLucideIconPack = iconPack.name === LUCIDE_ICON_PACK_NAME;
- const additionalLucideDescription = '(Native Pack has fewer icons but 100% Obsidian Sync support)';
- const iconPackSetting = new obsidian.Setting(this.containerEl)
- .setName(`${iconPack.name} (${iconPack.prefix})`)
- .setDesc(`Total icons: ${iconPack.icons.length}${isLucideIconPack ? ` ${additionalLucideDescription}` : ''}`);
- // iconPackSetting.addButton((btn) => {
- // btn.setIcon('broken-link');
- // btn.setTooltip('Try to fix icon pack');
- // btn.onClick(async () => {
- // new Notice('Try to fix icon pack...');
- // getIconPack(iconPack.name).icons = [];
- // const icons = await getFilesInDirectory(this.plugin, `${getPath()}/${iconPack.name}`);
- // for (let i = 0; i < icons.length; i++) {
- // const filePath = icons[i];
- // const fileName = filePath.split('/').pop();
- // const file = await this.plugin.app.vault.adapter.read(filePath);
- // const iconContent = file
- // .replace(/stroke="#fff"/g, 'stroke="currentColor"')
- // .replace(/fill="#fff"/g, 'fill="currentColor"');
- // await this.plugin.app.vault.adapter.write(filePath, iconContent);
- // await normalizeFileName(this.plugin, filePath);
- // addIconToIconPack(iconPack.name, fileName, iconContent);
- // }
- // new Notice('...tried to fix icon pack');
- // // Refreshes the DOM.
- // Object.entries(this.plugin.getData()).forEach(async ([k, v]) => {
- // const doesPathExist = await this.plugin.app.vault.adapter.exists(k, true);
- // if (doesPathExist && typeof v === 'string') {
- // // dom.removeIconInPath(k);
- // dom.createIconNode(this.plugin, k, v);
- // }
- // });
- // });
- // });
- if (isLucideIconPack) {
- iconPackSetting.addDropdown((dropdown) => {
- dropdown.addOptions({
- native: 'Native',
- custom: 'Custom',
- none: 'None',
- });
- dropdown.setValue(this.plugin.getSettings().lucideIconPackType);
- dropdown.onChange((value) => __awaiter(this, void 0, void 0, function* () {
- dropdown.setDisabled(true);
- new obsidian.Notice('Changing icon packs...');
- this.plugin.getSettings().lucideIconPackType = value;
- yield this.plugin.saveIconFolderData();
- if (value === 'native' || value === 'none') {
- yield removeCustomLucideIconPack(this.plugin);
- addLucideIconsPack(this.plugin);
- }
- else {
- yield addCustomLucideIconPack(this.plugin);
- yield icon.checkMissingIcons(this.plugin, Object.entries(this.plugin.getData()));
- }
- dropdown.setDisabled(false);
- new obsidian.Notice('Done. This change requires a restart of Obsidian');
- }));
- });
- return;
- }
- iconPackSetting.addButton((btn) => {
- btn.setIcon('plus');
- btn.setTooltip('Add an icon');
- btn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- const fileSelector = document.createElement('input');
- fileSelector.setAttribute('type', 'file');
- fileSelector.setAttribute('multiple', 'multiple');
- fileSelector.setAttribute('accept', '.svg');
- fileSelector.click();
- fileSelector.onchange = (e) => __awaiter(this, void 0, void 0, function* () {
- const target = e.target;
- for (let i = 0; i < target.files.length; i++) {
- const file = target.files[i];
- const content = yield readFileSync(file);
- yield createFile(this.plugin, iconPack.name, file.name, content);
- addIconToIconPack(iconPack.name, file.name, content);
- iconPackSetting.setDesc(`Total icons: ${iconPack.icons.length} (added: ${file.name})`);
- }
- new obsidian.Notice('Icons successfully added.');
- });
- }));
- });
- iconPackSetting.addButton((btn) => {
- btn.setIcon('trash');
- btn.setTooltip('Remove the icon pack');
- btn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- yield deleteIconPack(this.plugin, iconPack.name);
- this.refreshDisplay();
- new obsidian.Notice('Icon pack successfully deleted.');
- }));
- });
- ['dragenter', 'dragover', 'dragleave', 'drop'].forEach((event) => {
- iconPackSetting.settingEl.addEventListener(event, this.preventDefaults, false);
- });
- ['dragenter', 'dragover'].forEach((event) => {
- iconPackSetting.settingEl.addEventListener(event, () => this.highlight(iconPackSetting.settingEl), false);
- });
- ['dragleave', 'drop'].forEach((event) => {
- iconPackSetting.settingEl.addEventListener(event, (event) => this.unhighlight(event.currentTarget, iconPackSetting.settingEl), false);
- });
- iconPackSetting.settingEl.addEventListener('drop', (event) => __awaiter(this, void 0, void 0, function* () {
- const files = event.dataTransfer.files;
- let successful = false;
- for (let i = 0; i < files.length; i++) {
- const file = files[i];
- if (file.type !== 'image/svg+xml') {
- new obsidian.Notice(`File ${file.name} is not a SVG file.`);
- continue;
- }
- successful = true;
- const content = yield readFileSync(file);
- yield createFile(this.plugin, iconPack.name, file.name, content);
- addIconToIconPack(iconPack.name, file.name, content);
- iconPackSetting.setDesc(`Total icons: ${iconPack.icons.length} (added: ${file.name})`);
- }
- if (successful) {
- new obsidian.Notice('Icons successfully added.');
- }
- }), false);
- });
- }
- }
- class CustomIconRuleSetting extends IconFolderSetting {
- constructor(plugin, containerEl, app, refreshDisplay) {
- super(plugin, containerEl);
- this.app = app;
- this.refreshDisplay = refreshDisplay;
- }
- /**
- * Updates all the open files based on the custom rule that was specified.
- * @param rule Rule that will be used to update all the icons for all opened files.
- * @param remove Whether to remove the icons that are applicable to the rule or not.
- */
- updateIconTabs(rule_1, remove_1) {
- return __awaiter(this, arguments, void 0, function* (rule, remove, cachedPaths = []) {
- if (this.plugin.getSettings().iconInTabsEnabled) {
- for (const openedFile of getAllOpenedFiles(this.plugin)) {
- if (cachedPaths.includes(openedFile.path)) {
- continue;
- }
- const applicable = yield customRule.isApplicable(this.plugin, rule, openedFile.path);
- if (!applicable) {
- continue;
- }
- const leaf = openedFile.leaf;
- if (remove) {
- iconTabs.remove(leaf.tabHeaderInnerIconEl, {
- replaceWithDefaultIcon: true,
- });
- }
- else {
- iconTabs.add(this.plugin, openedFile.path, leaf.tabHeaderInnerIconEl, {
- iconName: rule.icon,
- iconColor: rule.color,
- });
- }
- }
- }
- });
- }
- createDescriptionEl(container, text) {
- const description = container.createEl('p', {
- text,
- cls: 'setting-item-description',
- });
- description.style.marginBottom = 'var(--size-2-2)';
- }
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Add icon rule')
- .setDesc('Will add the icon based on the defined rule (as a plain string or in regex format).')
- .addText((text) => {
- text.onChange((value) => {
- this.chooseIconBtn.setDisabled(value.length === 0);
- this.chooseIconBtn.buttonEl.style.cursor =
- value.length === 0 ? 'not-allowed' : 'default';
- this.chooseIconBtn.buttonEl.style.opacity =
- value.length === 0 ? '50%' : '100%';
- });
- text.setPlaceholder('regex or simple string');
- this.textComponent = text;
- })
- .addButton((btn) => {
- btn.setDisabled(true);
- btn.setButtonText('Choose icon');
- btn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- if (this.textComponent.getValue().length === 0) {
- return;
- }
- const modal = new IconsPickerModal(this.app, this.plugin, '');
- modal.onChooseItem = (item) => __awaiter(this, void 0, void 0, function* () {
- const icon = getNormalizedName(typeof item === 'object' ? item.displayName : item);
- const rule = {
- rule: this.textComponent.getValue(),
- icon,
- for: 'everything',
- order: this.plugin.getSettings().rules.length,
- };
- this.plugin.getSettings().rules = [
- ...this.plugin.getSettings().rules,
- rule,
- ];
- yield this.plugin.saveIconFolderData();
- this.refreshDisplay();
- new obsidian.Notice('Icon rule added.');
- this.textComponent.setValue('');
- saveIconToIconPack(this.plugin, rule.icon);
- yield customRule.addToAllFiles(this.plugin, rule);
- this.updateIconTabs(rule, false);
- });
- modal.open();
- }));
- this.chooseIconBtn = btn;
- });
- this.plugin.getSettings().rules.forEach((rule) => {
- // Keeping track of the old rule so that we can get a reference to it for old values.
- const oldRule = Object.assign({}, rule);
- const settingRuleEl = new obsidian.Setting(this.containerEl)
- .setName(rule.rule)
- .setDesc(`Icon: ${rule.icon}`);
- const currentOrder = rule.order;
- /**
- * Re-orders the custom rule based on the value that is passed in.
- * @param valueForReorder Number that will be used to determine whether to swap the
- * custom rule with the next rule or the previous rule.
- */
- const orderCustomRules = (valueForReorder) => __awaiter(this, void 0, void 0, function* () {
- const otherRule = this.plugin.getSettings().rules[currentOrder + valueForReorder];
- // Swap the current rule with the next rule.
- otherRule.order = otherRule.order - valueForReorder;
- rule.order = currentOrder + valueForReorder;
- // Refreshes the DOM.
- yield customRule.removeFromAllFiles(this.plugin, oldRule);
- yield this.plugin.saveIconFolderData();
- const addedPaths = [];
- for (const fileExplorer of this.plugin.getRegisteredFileExplorers()) {
- const files = Object.values(fileExplorer.fileItems || {});
- for (const rule of customRule.getSortedRules(this.plugin)) {
- // Removes the icon tabs from all opened files.
- this.updateIconTabs(rule, true, addedPaths);
- // Adds the icon tabs to all opened files.
- this.updateIconTabs(rule, false, addedPaths);
- for (const fileItem of files) {
- if (addedPaths.includes(fileItem.file.path)) {
- continue;
- }
- const added = yield customRule.add(this.plugin, rule, fileItem.file, getFileItemTitleEl(fileItem));
- if (added) {
- addedPaths.push(fileItem.file.path);
- }
- }
- }
- }
- this.refreshDisplay();
- });
- // Add the move down custom rule button to re-order the custom rule.
- settingRuleEl.addExtraButton((btn) => {
- const isFirstOrder = currentOrder === 0;
- btn.setDisabled(isFirstOrder);
- btn.extraSettingsEl.style.cursor = isFirstOrder
- ? 'not-allowed'
- : 'default';
- btn.extraSettingsEl.style.opacity = isFirstOrder ? '50%' : '100%';
- btn.setIcon('arrow-up');
- btn.setTooltip('Prioritize the custom rule');
- btn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- yield orderCustomRules(-1);
- }));
- });
- // Add the move up custom rule button to re-order the custom rule.
- settingRuleEl.addExtraButton((btn) => {
- const isLastOrder = currentOrder === this.plugin.getSettings().rules.length - 1;
- btn.setDisabled(isLastOrder);
- btn.extraSettingsEl.style.cursor = isLastOrder
- ? 'not-allowed'
- : 'default';
- btn.extraSettingsEl.style.opacity = isLastOrder ? '50%' : '100%';
- btn.setIcon('arrow-down');
- btn.setTooltip('Deprioritize the custom rule');
- btn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- yield orderCustomRules(1);
- }));
- });
- // Add the edit custom rule button.
- settingRuleEl.addButton((btn) => {
- btn.setIcon('pencil');
- btn.setTooltip('Edit the custom rule');
- btn.onClick(() => {
- var _a, _b;
- // Create modal and its children elements.
- const modal = new obsidian.Modal(this.plugin.app);
- modal.contentEl.style.display = 'block';
- modal.modalEl.classList.add('iconize-custom-modal');
- modal.titleEl.setText('Edit custom rule');
- // Create the input for the rule.
- this.createDescriptionEl(modal.contentEl, 'Regex or simple string');
- const input = new obsidian.TextComponent(modal.contentEl);
- input.setValue(rule.rule);
- input.onChange((value) => __awaiter(this, void 0, void 0, function* () {
- rule.rule = value;
- }));
- const useFilePathContainer = modal.contentEl.createDiv();
- useFilePathContainer.style.display = 'flex';
- useFilePathContainer.style.alignItems = 'center';
- useFilePathContainer.style.justifyContent = 'space-between';
- useFilePathContainer.style.marginTop = 'var(--size-4-5)';
- const useFilePathDescription = useFilePathContainer.createEl('p', {
- text: 'Include folders and files that are part of the path.',
- cls: 'setting-item-description',
- });
- useFilePathDescription.style.margin = '0';
- useFilePathDescription.style.marginBottom = 'var(--size-2-2)';
- new obsidian.ToggleComponent(useFilePathContainer)
- .setValue(rule.useFilePath === true)
- .onChange((value) => {
- rule.useFilePath = value;
- });
- // Create the toggle for changing the rule type.
- const ruleTypeContainer = modal.contentEl.createDiv();
- ruleTypeContainer.style.display = 'flex';
- ruleTypeContainer.style.alignItems = 'center';
- ruleTypeContainer.style.justifyContent = 'space-between';
- ruleTypeContainer.style.marginTop = 'var(--size-4-5)';
- const ruleTypeDescription = ruleTypeContainer.createEl('p', {
- text: 'Where the custom rule gets applied to.',
- cls: 'setting-item-description',
- });
- ruleTypeDescription.style.margin = '0';
- ruleTypeDescription.style.marginBottom = 'var(--size-2-2)';
- const ruleTypeButton = new obsidian.ButtonComponent(ruleTypeContainer);
- const setButtonContent = (isFor) => {
- if (isFor === 'folders') {
- ruleTypeButton.setIcon('folder');
- }
- else if (isFor === 'files') {
- ruleTypeButton.setIcon('document');
- }
- else {
- ruleTypeButton.setIcon('documents');
- }
- ruleTypeButton.setTooltip(`Icon applicable to: ${isFor}`);
- };
- setButtonContent((_a = rule.for) !== null && _a !== void 0 ? _a : 'everything');
- ruleTypeButton.onClick(() => __awaiter(this, void 0, void 0, function* () {
- var _a;
- const isFor = (_a = rule.for) !== null && _a !== void 0 ? _a : 'everything';
- this.updateIconTabs(rule, true);
- yield customRule.removeFromAllFiles(this.plugin, Object.assign(Object.assign({}, rule), { for: isFor }));
- if (isFor === 'folders') {
- rule.for = 'everything';
- }
- else if (isFor === 'files') {
- rule.for = 'folders';
- }
- else {
- rule.for = 'files';
- }
- setButtonContent(rule.for);
- }));
- // Create the change icon button with icon preview.
- this.createDescriptionEl(modal.contentEl, 'Custom rule icon');
- const iconContainer = modal.contentEl.createDiv();
- iconContainer.style.display = 'flex';
- iconContainer.style.alignItems = 'center';
- iconContainer.style.justifyContent = 'space-between';
- const iconEl = iconContainer.createDiv();
- const iconPreviewEl = iconEl.createDiv();
- dom.setIconForNode(this.plugin, rule.icon, iconPreviewEl);
- iconEl.style.display = 'flex';
- iconEl.style.alignItems = 'center';
- iconEl.style.justifyContent = 'space-between';
- iconEl.style.margin = null;
- iconPreviewEl.innerHTML = svg.setFontSize(iconPreviewEl.innerHTML, 20);
- const iconNameEl = iconEl.createEl('div', {
- cls: 'setting-item-description',
- });
- iconNameEl.style.paddingTop = '0';
- iconNameEl.style.marginLeft = 'var(--size-2-2)';
- iconNameEl.innerText = rule.icon;
- const changeIconBtn = new obsidian.ButtonComponent(iconContainer);
- changeIconBtn.setButtonText('Change icon');
- changeIconBtn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- const modal = new IconsPickerModal(this.app, this.plugin, rule.icon);
- modal.onChooseItem = (item) => __awaiter(this, void 0, void 0, function* () {
- const icon = typeof item === 'object' ? item.displayName : item;
- rule.icon = icon;
- dom.setIconForNode(this.plugin, rule.icon, iconPreviewEl);
- iconPreviewEl.innerHTML = svg.setFontSize(iconPreviewEl.innerHTML, 20);
- iconNameEl.innerText = getNormalizedName(rule.icon);
- });
- modal.open();
- }));
- // Create the color picker for the rule.
- this.createDescriptionEl(modal.contentEl, 'Color of the icon');
- const colorContainer = modal.contentEl.createDiv();
- colorContainer.style.display = 'flex';
- colorContainer.style.alignItems = 'center';
- colorContainer.style.justifyContent = 'space-between';
- const colorPicker = new obsidian.ColorComponent(colorContainer)
- .setValue((_b = rule.color) !== null && _b !== void 0 ? _b : '#000000')
- .onChange((value) => {
- rule.color = value;
- });
- const defaultColorButton = new obsidian.ButtonComponent(colorContainer);
- defaultColorButton.setTooltip('Set color to the default one');
- defaultColorButton.setButtonText('Default');
- defaultColorButton.onClick(() => {
- colorPicker.setValue('#000000');
- rule.color = undefined;
- });
- // Create the save button.
- const button = new obsidian.ButtonComponent(modal.contentEl);
- button.buttonEl.style.marginTop = 'var(--size-4-4)';
- button.buttonEl.style.float = 'right';
- button.setButtonText('Save Changes');
- button.onClick(() => __awaiter(this, void 0, void 0, function* () {
- if (!emoji.isEmoji(oldRule.icon)) {
- // Tries to remove the previously used icon from the icon pack.
- removeIconFromIconPack(this.plugin, oldRule.icon);
- }
- if (!emoji.isEmoji(rule.icon)) {
- // Tries to add the newly used icon to the icon pack.
- saveIconToIconPack(this.plugin, rule.icon);
- rule.icon = getNormalizedName(rule.icon);
- }
- this.refreshDisplay();
- new obsidian.Notice('Custom rule updated.');
- // Refresh the DOM.
- yield customRule.removeFromAllFiles(this.plugin, oldRule);
- this.updateIconTabs(rule, true);
- this.plugin.getSettings().rules.forEach((rule) => __awaiter(this, void 0, void 0, function* () {
- yield customRule.addToAllFiles(this.plugin, rule);
- this.updateIconTabs(rule, false);
- }));
- yield this.plugin.saveIconFolderData();
- modal.close();
- }));
- modal.open();
- });
- });
- // Add the delete custom rule button.
- settingRuleEl.addButton((btn) => {
- btn.setIcon('trash');
- btn.setTooltip('Remove the custom rule');
- btn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- const newRules = this.plugin
- .getSettings()
- .rules.filter((r) => rule.rule !== r.rule ||
- rule.color !== r.color ||
- rule.icon !== r.icon ||
- rule.for !== r.for);
- this.plugin.getSettings().rules = newRules;
- yield this.plugin.saveIconFolderData();
- this.refreshDisplay();
- new obsidian.Notice('Custom rule deleted.');
- yield customRule.removeFromAllFiles(this.plugin, rule);
- removeIconFromIconPack(this.plugin, rule.icon);
- this.updateIconTabs(rule, true);
- const previousRules = this.plugin
- .getSettings()
- .rules.filter((r) => rule.for === r.for);
- previousRules.forEach((previousRule) => __awaiter(this, void 0, void 0, function* () {
- yield customRule.addToAllFiles(this.plugin, previousRule);
- this.updateIconTabs(previousRule, false);
- }));
- }));
- });
- });
- }
- }
- const getTitleIcon = (leaf) => {
- return leaf.querySelector(`.${config.TITLE_ICON_CLASS}`);
- };
- const add = (plugin, inlineTitleEl, svgElement, options) => {
- var _a;
- if (!inlineTitleEl.parentElement) {
- return;
- }
- if (options === null || options === void 0 ? void 0 : options.fontSize) {
- svgElement = svg.setFontSize(svgElement, options.fontSize);
- }
- let titleIcon = getTitleIcon(inlineTitleEl.parentElement);
- if (!titleIcon) {
- titleIcon = document.createElement('div');
- }
- const isInline = plugin.getSettings().iconInTitlePosition === IconInTitlePosition.Inline;
- if (isInline) {
- titleIcon.style.display = 'inline-block';
- titleIcon.style.removeProperty('margin-inline');
- titleIcon.style.removeProperty('width');
- }
- else {
- titleIcon.style.display = 'block';
- titleIcon.style.width = 'var(--line-width)';
- titleIcon.style.marginInline = '0';
- }
- titleIcon.classList.add(config.TITLE_ICON_CLASS);
- // Checks if the passed element is an emoji.
- if (emoji.isEmoji(svgElement) && options.fontSize) {
- svgElement =
- (_a = emoji.parseEmoji(plugin.getSettings().emojiStyle, svgElement, options.fontSize)) !== null && _a !== void 0 ? _a : svgElement;
- titleIcon.style.fontSize = `${options.fontSize}px`;
- }
- titleIcon.innerHTML = svgElement;
- let wrapperElement = inlineTitleEl.parentElement;
- // Checks the parent and selects the correct wrapper element.
- // This should only happen in the beginning.
- if (wrapperElement &&
- !wrapperElement.classList.contains(config.INLINE_TITLE_WRAPPER_CLASS)) {
- wrapperElement = wrapperElement.querySelector(`.${config.INLINE_TITLE_WRAPPER_CLASS}`);
- }
- // Whenever there is no correct wrapper element, we create one.
- if (!wrapperElement) {
- wrapperElement = inlineTitleEl.parentElement.createDiv();
- wrapperElement.classList.add(config.INLINE_TITLE_WRAPPER_CLASS);
- }
- // Avoiding adding the same nodes together when changing the title.
- if (wrapperElement !== inlineTitleEl.parentElement) {
- inlineTitleEl.parentElement.prepend(wrapperElement);
- }
- if (isInline) {
- wrapperElement.style.display = 'flex';
- wrapperElement.style.alignItems = 'flex-start';
- const inlineTitlePaddingTop = getComputedStyle(inlineTitleEl, null).getPropertyValue('padding-top');
- titleIcon.style.paddingTop = inlineTitlePaddingTop;
- if (emoji.isEmoji(svgElement)) {
- titleIcon.style.transform = 'translateY(-9%)';
- }
- else {
- titleIcon.style.transform = 'translateY(9%)';
- }
- }
- else {
- wrapperElement.style.display = 'block';
- titleIcon.style.transform = 'translateY(9%)';
- }
- wrapperElement.append(titleIcon);
- wrapperElement.append(inlineTitleEl);
- };
- const updateStyle = (inlineTitleEl, options) => {
- if (!inlineTitleEl.parentElement) {
- return;
- }
- const titleIcon = getTitleIcon(inlineTitleEl.parentElement);
- if (!titleIcon) {
- return;
- }
- if (options.fontSize) {
- if (!emoji.isEmoji(titleIcon.innerHTML)) {
- titleIcon.innerHTML = svg.setFontSize(titleIcon.innerHTML, options.fontSize);
- }
- else {
- titleIcon.style.fontSize = `${options.fontSize}px`;
- }
- }
- };
- /**
- * Hides the title icon from the provided HTMLElement.
- * @param contentEl HTMLElement to hide the title icon from.
- */
- const hide = (inlineTitleEl) => {
- if (!inlineTitleEl.parentElement) {
- return;
- }
- const titleIconContainer = getTitleIcon(inlineTitleEl.parentElement);
- if (!titleIconContainer) {
- return;
- }
- titleIconContainer.style.display = 'none';
- };
- const remove = (inlineTitleEl) => {
- if (!inlineTitleEl.parentElement) {
- return;
- }
- const titleIconContainer = getTitleIcon(inlineTitleEl.parentElement);
- if (!titleIconContainer) {
- return;
- }
- titleIconContainer.remove();
- };
- var titleIcon = {
- add,
- updateStyle,
- hide,
- remove,
- };
- // Cache for font size
- let cachedFontSize = null;
- let fontSizeCacheTime = 0;
- const calculateFontTextSize = () => {
- var _a;
- // get cached font size if available
- const now = Date.now();
- if (cachedFontSize !== null && now - fontSizeCacheTime < 2000) {
- return cachedFontSize;
- }
- let fontSize = parseFloat((_a = getComputedStyle(document.body).getPropertyValue('--font-text-size')) !== null && _a !== void 0 ? _a : '0');
- if (!fontSize) {
- fontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
- }
- // set font size cache
- cachedFontSize = fontSize;
- fontSizeCacheTime = now;
- return fontSize;
- };
- const calculateInlineTitleSize = () => {
- const fontSize = calculateFontTextSize();
- const inlineTitleSizeValue = getComputedStyle(document.body).getPropertyValue('--inline-title-size');
- const unit = inlineTitleSizeValue.replace(/[\d.]/g, '');
- let inlineTitleSize = parseFloat(inlineTitleSizeValue);
- if (unit === 'px') {
- inlineTitleSize /= 16;
- }
- return fontSize * inlineTitleSize;
- };
- const isHeader = (value) => {
- return /^h[1-6]$/.test(value);
- };
- const getHTMLHeaderByToken = (header) => {
- for (let i = 1; i <= 6; i++) {
- if (header === `header-${i}`) {
- return `h${i}`;
- }
- }
- return null;
- };
- const calculateHeaderSize = (header) => {
- var _a;
- const fontSize = calculateFontTextSize();
- const htmlHeader = (_a = getHTMLHeaderByToken(header)) !== null && _a !== void 0 ? _a : header;
- const headerComputedStyle = getComputedStyle(document.body).getPropertyValue(`--${htmlHeader}-size`);
- let headerSize = parseFloat(headerComputedStyle);
- if (isPx(headerComputedStyle)) {
- headerSize = pxToRem(headerSize, fontSize);
- }
- // If there is some `calc` operation going on, it has to be evaluated.
- if (headerComputedStyle.includes('calc')) {
- const temp = document.createElement('div');
- temp.style.setProperty('font-size', `var(--${htmlHeader}-size)`);
- document.body.appendChild(temp);
- const computedStyle = window.getComputedStyle(temp);
- const computedValue = computedStyle.getPropertyValue('font-size');
- headerSize = parseFloat(computedValue);
- if (isPx(computedValue)) {
- headerSize = pxToRem(headerSize, fontSize);
- }
- document.body.removeChild(temp);
- }
- return fontSize * headerSize;
- };
- const pxToRem = (px, baseSize = 16) => {
- return px / baseSize;
- };
- const isPx = (value) => {
- return /^-?\d+(\.\d+)?px$/.test(value);
- };
- class EmojiStyleSetting extends IconFolderSetting {
- display() {
- const emojiStyle = new obsidian.Setting(this.containerEl)
- .setName('Emoji style')
- .setDesc('Change the style of your emojis.');
- emojiStyle.addDropdown((dropdown) => {
- dropdown.addOption('native', 'Native');
- dropdown.addOption('twemoji', 'Twemoji');
- dropdown.setValue(this.plugin.getSettings().emojiStyle);
- dropdown.onChange((value) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().emojiStyle = value;
- this.updateDOM();
- yield this.plugin.saveIconFolderData();
- }));
- });
- }
- updateDOM() {
- for (const fileExplorer of this.plugin.getRegisteredFileExplorers()) {
- const fileItems = Object.entries(fileExplorer.fileItems || {});
- for (const [path, _] of fileItems) {
- let iconName = this.plugin.getData()[path];
- if (!iconName) {
- continue;
- }
- const data = this.plugin.getData()[path];
- if (typeof data === 'object') {
- const data = this.plugin.getData()[path];
- if (data.iconName) {
- iconName = data.iconName;
- }
- }
- if (emoji.isEmoji(iconName)) {
- dom.createIconNode(this.plugin, path, iconName);
- if (this.plugin.getSettings().iconInTabsEnabled) {
- const tabLeaves = iconTabs.getTabLeavesOfFilePath(this.plugin, path);
- for (const tabLeaf of tabLeaves) {
- iconTabs.update(this.plugin, iconName, tabLeaf.tabHeaderInnerIconEl);
- }
- }
- if (this.plugin.getSettings().iconInTitleEnabled) {
- for (const openedFile of getAllOpenedFiles(this.plugin)) {
- const activeView = openedFile.leaf.view;
- if (activeView instanceof obsidian.MarkdownView &&
- openedFile.path === path) {
- titleIcon.add(this.plugin, activeView.inlineTitleEl, iconName, {
- fontSize: calculateInlineTitleSize(),
- });
- }
- }
- }
- }
- }
- }
- for (const rule of customRule.getSortedRules(this.plugin)) {
- customRule.addToAllFiles(this.plugin, rule);
- }
- }
- }
- /**
- * Helper function that refreshes the style of all the icons that are defined
- * or in a custom rule involved.
- * @param plugin Instance of the IconizePlugin.
- */
- const refreshStyleOfIcons = (plugin) => __awaiter(void 0, void 0, void 0, function* () {
- // Refreshes the icon style for all normally added icons.
- style.refreshIconNodes(plugin);
- // Refreshes the icon style for all custom icon rules, when the color of the rule is
- // not defined.
- for (const rule of customRule.getSortedRules(plugin)) {
- const fileItems = yield customRule.getFileItems(plugin, rule);
- for (const fileItem of fileItems) {
- const titleEl = getFileItemTitleEl(fileItem);
- const iconNode = titleEl.querySelector('.iconize-icon');
- let iconContent = iconNode.innerHTML;
- iconContent = style.applyAll(plugin, iconContent, iconNode);
- if (rule.color) {
- iconContent = svg.colorize(iconContent, rule.color);
- iconNode.style.color = rule.color;
- }
- iconNode.innerHTML = iconContent;
- }
- }
- });
- var helper = {
- refreshStyleOfIcons,
- };
- class ExtraMarginSetting extends IconFolderSetting {
- display() {
- var _a, _b;
- const extraMarginSetting = new obsidian.Setting(this.containerEl)
- .setName('Extra margin (in pixels)')
- .setDesc('Change the margin of the icons.')
- .setClass('iconize-setting');
- const extraMarginDropdown = new obsidian.DropdownComponent(extraMarginSetting.controlEl).addOptions({
- top: 'Top',
- right: 'Right',
- bottom: 'Bottom',
- left: 'Left',
- });
- const extraMarginSlider = new obsidian.SliderComponent(extraMarginSetting.controlEl)
- .setLimits(-24, 24, 1)
- .setDynamicTooltip()
- .setValue((_b = (_a = this.plugin.getSettings().extraMargin) === null || _a === void 0 ? void 0 : _a.top) !== null && _b !== void 0 ? _b : 2)
- .onChange((val) => __awaiter(this, void 0, void 0, function* () {
- const dropdownValue = extraMarginDropdown.getValue();
- if (this.plugin.getSettings().extraMargin) {
- this.plugin.getSettings().extraMargin[dropdownValue] = val;
- }
- else {
- this.plugin.getSettings().extraMargin = {
- [dropdownValue]: val,
- };
- }
- yield this.plugin.saveIconFolderData();
- helper.refreshStyleOfIcons(this.plugin);
- }));
- extraMarginDropdown.onChange((val) => {
- var _a;
- if (this.plugin.getSettings().extraMargin) {
- extraMarginSlider.setValue((_a = this.plugin.getSettings().extraMargin[val]) !== null && _a !== void 0 ? _a : 2);
- }
- else {
- extraMarginSlider.setValue(2);
- }
- });
- extraMarginSetting.components.push(extraMarginDropdown, extraMarginSlider);
- }
- }
- class ResetButtonComponent extends obsidian.ButtonComponent {
- constructor(contentEl) {
- super(contentEl);
- this.contentEl = contentEl;
- this.setTooltip('Restore default');
- this.setIcon('rotate-ccw');
- this.render();
- }
- render() {
- this.buttonEl.classList.add('clickable-icon');
- this.buttonEl.classList.add('extra-setting-button');
- }
- }
- const DEFAULT_VALUE = DEFAULT_SETTINGS.iconColor;
- class IconColorSetting extends IconFolderSetting {
- display() {
- var _a;
- const setting = new obsidian.Setting(this.containerEl)
- .setName('Icon color')
- .setDesc('Change the color of the displayed icons.');
- new ResetButtonComponent(setting.controlEl).onClick(() => __awaiter(this, void 0, void 0, function* () {
- colorPicker.setValue(DEFAULT_VALUE);
- this.plugin.getSettings().iconColor = null;
- // Custom saving to not save the color black in the data.
- yield this.plugin.saveIconFolderData();
- helper.refreshStyleOfIcons(this.plugin);
- }));
- const colorPicker = new obsidian.ColorComponent(setting.controlEl)
- .setValue((_a = this.plugin.getSettings().iconColor) !== null && _a !== void 0 ? _a : DEFAULT_VALUE)
- .onChange((value) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().iconColor = value;
- yield this.plugin.saveIconFolderData();
- helper.refreshStyleOfIcons(this.plugin);
- }));
- }
- }
- const values = {
- min: 10,
- max: 64,
- default: DEFAULT_SETTINGS.fontSize,
- step: 1,
- };
- class IconFontSizeSetting extends IconFolderSetting {
- display() {
- const setting = new obsidian.Setting(this.containerEl)
- .setName('Icon font size (in pixels)')
- .setDesc('Change the font size of the displayed icons.');
- new ResetButtonComponent(setting.controlEl).onClick(() => {
- this.slider.setValue(values.default);
- });
- setting.addSlider((slider) => {
- var _a;
- this.slider = slider;
- slider
- .setLimits(values.min, values.max, values.step)
- .setDynamicTooltip()
- .setValue((_a = this.plugin.getSettings().fontSize) !== null && _a !== void 0 ? _a : DEFAULT_SETTINGS.fontSize)
- .onChange((val) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().fontSize = val;
- yield this.plugin.saveIconFolderData();
- helper.refreshStyleOfIcons(this.plugin);
- }));
- });
- }
- }
- class IconPacksPathSetting extends IconFolderSetting {
- display() {
- const iconPacksPathSetting = new obsidian.Setting(this.containerEl)
- .setName('Icon packs folder path')
- .setDesc('Change the default icon packs folder path.');
- iconPacksPathSetting.addText((text) => {
- this.iconPacksSettingTextComp = text;
- text.setValue(this.plugin.getSettings().iconPacksPath);
- });
- iconPacksPathSetting.addButton((btn) => {
- btn.setButtonText('Save');
- btn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- const newPath = this.iconPacksSettingTextComp.getValue();
- const oldPath = this.plugin.getSettings().iconPacksPath;
- if (oldPath === this.iconPacksSettingTextComp.getValue()) {
- return;
- }
- new obsidian.Notice('Saving in progress...');
- setPath(newPath);
- yield createDefaultDirectory(this.plugin);
- yield moveIconPackDirectories(this.plugin, oldPath, newPath);
- this.plugin.getSettings().iconPacksPath = newPath;
- yield this.plugin.saveIconFolderData();
- new obsidian.Notice('...saved successfully');
- }));
- });
- }
- }
- class IconPacksBackgroundChecker extends IconFolderSetting {
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Icons background check')
- .setDesc('Check in the background on every load of Obsidian, if icons are missing and it will try to add them to the specific icon pack.')
- .addToggle((toggle) => {
- toggle
- .setValue(this.plugin.getSettings().iconsBackgroundCheckEnabled)
- .onChange((enabled) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().iconsBackgroundCheckEnabled = enabled;
- yield this.plugin.saveIconFolderData();
- if (enabled) {
- new obsidian.Notice('You need to reload Obsidian for this to take effect.', 10000);
- }
- }));
- });
- }
- }
- class IconPackBrowserModal extends obsidian.FuzzySuggestModal {
- constructor(app, plugin) {
- super(app);
- this.plugin = plugin;
- this.resultContainerEl.classList.add('iconize-browse-modal');
- this.inputEl.placeholder = 'Select to download icon pack';
- }
- // eslint-disable-next-line
- onAddedIconPack() { }
- onOpen() {
- super.onOpen();
- }
- onClose() {
- this.contentEl.empty();
- }
- getItemText(item) {
- const prefix = createIconPackPrefix(item.name);
- return `${item.displayName} (${prefix})`;
- }
- getItems() {
- const predefinedIconPacks = Object.values(iconPacks$1);
- const allIconPacks = getAllIconPacks();
- return predefinedIconPacks.filter((iconPack) => allIconPacks.find((ip) => iconPack.name === ip.name) === undefined);
- }
- onChooseItem(item, _event) {
- return __awaiter(this, void 0, void 0, function* () {
- new obsidian.Notice(`Adding ${item.displayName}...`);
- const arrayBuffer = yield downloadZipFile(item.downloadLink);
- yield createZipFile(this.plugin, `${item.name}.zip`, arrayBuffer);
- yield registerIconPack(item.name, arrayBuffer);
- new obsidian.Notice(`...${item.displayName} added`);
- this.onAddedIconPack();
- });
- }
- renderSuggestion(item, el) {
- super.renderSuggestion(item, el);
- el.innerHTML = `<div>${el.innerHTML}</div>`;
- }
- }
- class PredefinedIconPacksSetting extends IconFolderSetting {
- constructor(plugin, containerEl, app, refreshDisplay) {
- super(plugin, containerEl);
- this.app = app;
- this.refreshDisplay = refreshDisplay;
- }
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Add predefined icon pack')
- .setDesc('Add a predefined icon pack that is officially supported.')
- .addButton((btn) => {
- btn.setButtonText('Browse icon packs');
- btn.onClick(() => {
- const modal = new IconPackBrowserModal(this.app, this.plugin);
- modal.onAddedIconPack = () => {
- this.refreshDisplay();
- };
- modal.open();
- });
- });
- }
- }
- class RecentlyUsedIconsSetting extends IconFolderSetting {
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Recently used icons limit')
- .setDesc('Change the limit for the recently used icons displayed in the icon selection modal.')
- .addSlider((slider) => {
- var _a;
- slider
- .setLimits(1, 25, 1)
- .setDynamicTooltip()
- .setValue((_a = this.plugin.getSettings().recentlyUsedIconsSize) !== null && _a !== void 0 ? _a : DEFAULT_SETTINGS.recentlyUsedIconsSize)
- .onChange((val) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().recentlyUsedIconsSize = val;
- yield this.plugin.checkRecentlyUsedIcons();
- yield this.plugin.saveIconFolderData();
- }));
- });
- }
- }
- class ToggleIconInTabs extends IconFolderSetting {
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Toggle icon in tabs')
- .setDesc('Toggles the visibility of an icon for a file in the tab bar.')
- .addToggle((toggle) => {
- toggle
- .setValue(this.plugin.getSettings().iconInTabsEnabled)
- .onChange((enabled) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().iconInTabsEnabled = enabled;
- yield this.plugin.saveIconFolderData();
- // Updates the already opened files.
- this.plugin.app.workspace
- .getLeavesOfType('markdown')
- .forEach((leaf) => {
- const file = leaf.view.file;
- if (file) {
- const tabHeaderLeaf = leaf;
- if (enabled) {
- // Adds the icons to already opened files.
- iconTabs.add(this.plugin, file.path, tabHeaderLeaf.tabHeaderInnerIconEl);
- }
- else {
- // Removes the icons from already opened files.
- iconTabs.remove(tabHeaderLeaf.tabHeaderInnerIconEl);
- }
- }
- });
- }));
- });
- }
- }
- class ToggleIconInTitle extends IconFolderSetting {
- updateLeaves(options) {
- this.plugin.app.workspace.getLeavesOfType('markdown').forEach((leaf) => {
- const view = leaf.view;
- if (view instanceof obsidian.MarkdownView) {
- const foundIcon = icon.getIconByPath(this.plugin, view.file.path);
- if (foundIcon && options.enabled) {
- if (options.removeBeforeReAdd) {
- // Remove the icon before re-adding it. This is needed to update the DOM because
- // the icon node will be inserted in the beginning inline title node.
- titleIcon.remove(view.contentEl);
- }
- const content = typeof foundIcon === 'string' ? foundIcon : foundIcon.svgElement;
- titleIcon.add(this.plugin, view.inlineTitleEl, content, {
- fontSize: calculateInlineTitleSize(),
- });
- }
- else {
- titleIcon.remove(view.contentEl);
- }
- }
- });
- }
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Toggle icon in title')
- .setDesc('Toggles the visibility of an icon above the title of a file.')
- .addDropdown((dropdown) => {
- this.dropdown = dropdown;
- dropdown.setDisabled(!this.plugin.getSettings().iconInTitleEnabled);
- dropdown.addOptions({
- above: 'Above title',
- inline: 'Next to title',
- });
- dropdown.setValue(this.plugin.getSettings().iconInTitlePosition);
- dropdown.onChange((value) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().iconInTitlePosition =
- value;
- yield this.plugin.saveIconFolderData();
- this.updateLeaves({ enabled: true, removeBeforeReAdd: true });
- }));
- })
- .addToggle((toggle) => {
- toggle
- .setValue(this.plugin.getSettings().iconInTitleEnabled)
- .onChange((enabled) => __awaiter(this, void 0, void 0, function* () {
- if (this.dropdown) {
- this.dropdown.setDisabled(!enabled);
- }
- this.plugin.getSettings().iconInTitleEnabled = enabled;
- yield this.plugin.saveIconFolderData();
- this.updateLeaves({ enabled });
- }));
- });
- }
- }
- class FrontmatterOptions extends IconFolderSetting {
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Use icon in frontmatter')
- .setDesc('Toggles whether to set the icon based on the frontmatter property `icon`.')
- .addToggle((toggle) => {
- toggle
- .setValue(this.plugin.getSettings().iconInFrontmatterEnabled)
- .onChange((enabled) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().iconInFrontmatterEnabled = enabled;
- yield this.plugin.saveIconFolderData();
- }));
- });
- new obsidian.Setting(this.containerEl)
- .setName('Frontmatter icon field name')
- .setDesc('Sets the name of the frontmatter field which contains the icon.')
- .addText((text) => {
- this.iconFieldNameTextComp = text;
- text.setValue(this.plugin.getSettings().iconInFrontmatterFieldName);
- })
- .addButton((button) => {
- button.setButtonText('Save');
- button.onClick(() => __awaiter(this, void 0, void 0, function* () {
- const newValue = this.iconFieldNameTextComp.getValue();
- const oldValue = this.plugin.getSettings().iconInFrontmatterFieldName;
- if (newValue === oldValue) {
- return;
- }
- this.plugin.getSettings().iconInFrontmatterFieldName = newValue;
- yield this.plugin.saveIconFolderData();
- new obsidian.Notice('...saved successfully');
- }));
- });
- new obsidian.Setting(this.containerEl)
- .setName('Frontmatter icon color field name')
- .setDesc('Sets the name of the frontmatter field which contains the icon color.')
- .addText((text) => {
- this.iconColorFieldNameTextComp = text;
- text.setValue(this.plugin.getSettings().iconColorInFrontmatterFieldName);
- })
- .addButton((button) => {
- button.setButtonText('Save');
- button.onClick(() => __awaiter(this, void 0, void 0, function* () {
- const newValue = this.iconColorFieldNameTextComp.getValue();
- const oldValue = this.plugin.getSettings().iconColorInFrontmatterFieldName;
- if (newValue === oldValue) {
- return;
- }
- this.plugin.getSettings().iconColorInFrontmatterFieldName = newValue;
- yield this.plugin.saveIconFolderData();
- new obsidian.Notice('...saved successfully');
- }));
- });
- new obsidian.Setting(this.containerEl)
- .setName('Refresh icons from frontmatter')
- .setDesc('Sets the icon and color for each note in the vault based on the frontmatter properties. WARNING: This will change any manually set icons to the one defined in the frontmatter. IF A NOTE HAS NO FRONTMATTER, THE CURRENT ICON WILL BE REMOVED. Please restart Obsidian after this completes to see the changes.')
- .addButton((btn) => {
- btn.setButtonText('Refresh').onClick(() => __awaiter(this, void 0, void 0, function* () {
- var _a, _b;
- if (!this.plugin.getSettings().iconInFrontmatterEnabled) {
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Please enable "Use icon in frontmatter".`);
- return;
- }
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Refreshing icons from frontmatter, please wait...`);
- const files = this.plugin.app.vault.getMarkdownFiles();
- for (const file of files) {
- const fileCache = this.plugin.app.metadataCache.getFileCache(file);
- const frontmatterIconKey = this.plugin.getSettings().iconInFrontmatterFieldName;
- const frontmatterIconColorKey = this.plugin.getSettings().iconColorInFrontmatterFieldName;
- const iconName = (_a = fileCache.frontmatter) === null || _a === void 0 ? void 0 : _a[frontmatterIconKey];
- let iconColor = (_b = fileCache.frontmatter) === null || _b === void 0 ? void 0 : _b[frontmatterIconColorKey];
- if (!iconName) {
- yield this.plugin.removeFolderIcon(file.path);
- continue;
- }
- if (typeof iconName !== 'string') {
- const message = `${file.path}\nFrontmatter property type \`${frontmatterIconKey}\` has to be of type \`text\`.`;
- logger.warn(message);
- new obsidian.Notice(`[${config.PLUGIN_NAME}]\n${message}`);
- continue;
- }
- this.plugin.addFolderIcon(file.path, iconName);
- if (!iconColor) {
- yield this.plugin.removeIconColor(file.path);
- continue;
- }
- if (typeof iconColor !== 'string') {
- const message = `${file.path}\nFrontmatter property type \`${frontmatterIconColorKey}\` has to be of type \`text\`.`;
- logger.warn(message);
- new obsidian.Notice(`[${config.PLUGIN_NAME}]\n${message}`);
- continue;
- }
- iconColor = isHexadecimal(iconColor)
- ? stringToHex(iconColor)
- : iconColor;
- this.plugin.addIconColor(file.path, iconColor);
- }
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Refreshed icons from frontmatter. Please restart Obsidian to see the changes.`);
- }));
- });
- }
- }
- class ToggleIconsInEditor extends IconFolderSetting {
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Toggle icons while editing notes')
- .setDesc('Toggles whether you are able to add and see icons in your notes and editor (e.g., ability to have :LiSofa: as an icon in your notes).')
- .addToggle((toggle) => {
- toggle
- .setValue(this.plugin.getSettings().iconsInNotesEnabled)
- .onChange((enabled) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().iconsInNotesEnabled = enabled;
- yield this.plugin.saveIconFolderData();
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Obsidian has to be restarted for this change to take effect.`);
- }));
- });
- }
- }
- class ToggleIconsInLinks extends IconFolderSetting {
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Toggle icons in links')
- .setDesc('Toggles whether you are able to see icons in the links to other notes')
- .addToggle((toggle) => {
- toggle
- .setValue(this.plugin.getSettings().iconsInLinksEnabled)
- .onChange((enabled) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().iconsInLinksEnabled = enabled;
- yield this.plugin.saveIconFolderData();
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Obsidian has to be restarted for this change to take effect.`);
- }));
- });
- }
- }
- class IconIdentifierSetting extends IconFolderSetting {
- display() {
- const setting = new obsidian.Setting(this.containerEl)
- .setName('Icon identifier')
- .setDesc('Change the icon identifier used in notes.')
- .setClass('iconize-setting');
- setting.addText((text) => {
- this.textComp = text;
- text.setValue(this.plugin.getSettings().iconIdentifier);
- });
- setting.addButton((btn) => {
- btn.setButtonText('Save');
- btn.onClick(() => __awaiter(this, void 0, void 0, function* () {
- const newIdentifier = this.textComp.getValue();
- const oldIdentifier = this.plugin.getSettings().iconIdentifier;
- if (newIdentifier === oldIdentifier) {
- return;
- }
- this.plugin.getSettings().iconIdentifier = newIdentifier;
- yield this.plugin.saveIconFolderData();
- new obsidian.Notice('...saved successfully');
- }));
- });
- }
- }
- class DebugMode extends IconFolderSetting {
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('Toggle Debug Mode')
- .setDesc('Toggle debug mode to see more detailed logs in the console. Do not touch this unless you know what you are doing.')
- .addToggle((toggle) => {
- toggle
- .setValue(this.plugin.getSettings().debugMode)
- .onChange((enabled) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().debugMode = enabled;
- yield this.plugin.saveIconFolderData();
- }));
- });
- }
- }
- class UseInternalPlugins extends IconFolderSetting {
- display() {
- new obsidian.Setting(this.containerEl)
- .setName('EXPERIMENTAL: Use internal plugins')
- .setDesc('Toggles whether to try to add icons to the bookmark and outline internal plugins.')
- .addToggle((toggle) => {
- toggle
- .setValue(this.plugin.getSettings().useInternalPlugins)
- .onChange((enabled) => __awaiter(this, void 0, void 0, function* () {
- this.plugin.getSettings().useInternalPlugins = enabled;
- yield this.plugin.saveIconFolderData();
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Obsidian has to be restarted for this change to take effect.`);
- }));
- });
- }
- }
- class IconFolderSettings extends obsidian.PluginSettingTab {
- constructor(app, plugin) {
- super(app, plugin);
- this.plugin = plugin;
- }
- display() {
- const { plugin, containerEl, app } = this;
- containerEl.empty();
- containerEl.createEl('h1', { text: 'General' });
- new RecentlyUsedIconsSetting(plugin, containerEl).display();
- new IconPacksPathSetting(plugin, containerEl).display();
- new IconPacksBackgroundChecker(plugin, containerEl).display();
- new EmojiStyleSetting(plugin, containerEl).display();
- new IconIdentifierSetting(plugin, containerEl).display();
- new UseInternalPlugins(plugin, containerEl).display();
- new DebugMode(plugin, containerEl).display();
- containerEl.createEl('h3', { text: 'Visibility of icons' });
- new ToggleIconInTabs(plugin, containerEl).display();
- new ToggleIconInTitle(plugin, containerEl).display();
- new FrontmatterOptions(plugin, containerEl).display();
- new ToggleIconsInEditor(plugin, containerEl).display();
- new ToggleIconsInLinks(plugin, containerEl).display();
- containerEl.createEl('h1', {
- text: 'Icon customization for files/folders',
- });
- new IconFontSizeSetting(plugin, containerEl).display();
- new IconColorSetting(plugin, containerEl).display();
- new ExtraMarginSetting(plugin, containerEl).display();
- containerEl.createEl('h1', { text: 'Custom icon rules' });
- new CustomIconRuleSetting(plugin, containerEl, app, () => this.display()).display();
- containerEl.createEl('h1', { text: 'Icon packs' });
- new PredefinedIconPacksSetting(plugin, containerEl, app, () => this.display()).display();
- new CustomIconPackSetting(plugin, containerEl, () => this.display()).display();
- }
- }
- function around(obj, factories) {
- const removers = Object.keys(factories).map(key => around1(obj, key, factories[key]));
- return removers.length === 1 ? removers[0] : function () { removers.forEach(r => r()); };
- }
- function around1(obj, method, createWrapper) {
- const original = obj[method], hadOwn = obj.hasOwnProperty(method);
- let current = createWrapper(original);
- // Let our wrapper inherit static props from the wrapping method,
- // and the wrapping method, props from the original method
- if (original)
- Object.setPrototypeOf(current, original);
- Object.setPrototypeOf(wrapper, current);
- obj[method] = wrapper;
- // Return a callback to allow safe removal
- return remove;
- function wrapper(...args) {
- // If we have been deactivated and are no longer wrapped, remove ourselves
- if (current === original && obj[method] === wrapper)
- remove();
- return current.apply(this, args);
- }
- function remove() {
- // If no other patches, just do a direct removal
- if (obj[method] === wrapper) {
- if (hadOwn)
- obj[method] = original;
- else
- delete obj[method];
- }
- if (current === original)
- return;
- // Else pass future calls through, and remove wrapper from the prototype chain
- current = original;
- Object.setPrototypeOf(wrapper, original || Function);
- }
- }
- class InternalPluginInjector {
- constructor(plugin) {
- this.plugin = plugin;
- }
- get fileExplorers() {
- return this.plugin.app.workspace.getLeavesOfType('file-explorer');
- }
- onMount() { }
- }
- /**
- * @deprecated After obsidian 1.2.6 in favor of the bookmarks plugin.
- */
- class StarredInternalPlugin extends InternalPluginInjector {
- constructor(plugin) {
- super(plugin);
- }
- get starred() {
- return this.plugin.app.internalPlugins.getPluginById('starred');
- }
- get enabled() {
- return this.plugin.app.internalPlugins.getPluginById('starred').enabled;
- }
- get leaf() {
- const leaf = this.plugin.app.workspace.getLeavesOfType('starred');
- if (!leaf) {
- return undefined;
- }
- if (leaf.length === 1) {
- return leaf[0].view;
- }
- return undefined;
- }
- setIcon(filePath, node) {
- const iconName = icon.getByPath(this.plugin, filePath);
- const iconNode = node.querySelector('.nav-file-icon');
- if (!iconNode || !iconName) {
- return;
- }
- dom.setIconForNode(this.plugin, iconName, iconNode);
- }
- computeNodesWithPath(callback) {
- const { itemLookup, containerEl } = this.leaf;
- const navFileEls = containerEl.querySelectorAll('.nav-file');
- navFileEls.forEach((navFileEl) => {
- const lookupFile = itemLookup.get(navFileEl);
- if (!lookupFile) {
- return;
- }
- callback(navFileEl, lookupFile.path);
- });
- }
- onMount() {
- const nodesWithPath = {};
- this.computeNodesWithPath((node, filePath) => {
- nodesWithPath[filePath] = node;
- });
- Object.entries(nodesWithPath).forEach(([filePath, node]) => this.setIcon(filePath, node));
- }
- register() {
- if (!this.plugin.app.internalPlugins.getPluginById('file-explorer').enabled) {
- console.info(`[${config.PLUGIN_NAME}/Starred] Skipping starred internal plugin registration because file-explorer is not enabled.`);
- return;
- }
- if (!this.enabled) {
- console.info(`[${config.PLUGIN_NAME}/Starred] Skipping starred internal plugin registration because it's not enabled.`);
- return;
- }
- // eslint-disable-next-line
- const self = this;
- this.plugin.register(around(this.starred.instance, {
- addItem: function (next) {
- return function (file) {
- next.call(this, file);
- self.onMount();
- };
- },
- removeItem: function (next) {
- return function (file) {
- next.call(this, file);
- self.onMount();
- };
- },
- }));
- }
- }
- class BookmarkInternalPlugin extends InternalPluginInjector {
- constructor(plugin) {
- super(plugin);
- }
- get bookmark() {
- return this.plugin.app.internalPlugins.getPluginById('bookmarks');
- }
- get enabled() {
- return this.plugin.app.internalPlugins.getPluginById('bookmarks').enabled;
- }
- get leaf() {
- const leaf = this.plugin.app.workspace.getLeavesOfType('bookmarks');
- if (!leaf) {
- return undefined;
- }
- if (leaf.length === 1) {
- return leaf[0];
- }
- return undefined;
- }
- setIconOrRemove(filePath, node) {
- var _a;
- const iconName = icon.getByPath(this.plugin, filePath);
- let iconNode = node.querySelector('.tree-item-icon');
- if (!iconName) {
- if (iconNode) {
- // Reset the icon to the default obsidian icon.
- const items = this.bookmark.instance.items;
- const item = items.find((item) => item.path === filePath);
- if ((item === null || item === void 0 ? void 0 : item.type) === 'file') {
- iconNode.innerHTML = DEFAULT_FILE_ICON;
- }
- else if ((item === null || item === void 0 ? void 0 : item.type) === 'folder') {
- iconNode.innerHTML = DEFAULT_FOLDER_ICON;
- }
- }
- return;
- }
- // If the icon node is not defined, then we need to recreate it.
- if (!iconNode) {
- // Get the tree-item-self element where the original icon is set.
- const treeItemSelf = node.querySelector('.tree-item-self');
- if (!treeItemSelf) {
- return;
- }
- iconNode = node.createDiv({ cls: 'tree-item-icon' });
- // Prepends the icon to the tree-item-self element as a first child.
- treeItemSelf.prepend(iconNode);
- }
- const defaultMargin = iconNode.style.margin;
- const iconColor = (_a = this.plugin.getIconColor(filePath)) !== null && _a !== void 0 ? _a : this.plugin.getSettings().iconColor;
- dom.setIconForNode(this.plugin, iconName, iconNode, { color: iconColor });
- // Reset the margin to the default value to prevent overlapping with the text.
- iconNode.style.margin = defaultMargin;
- }
- computeNodesWithPath(callback) {
- if (!this.leaf || !this.leaf.view) {
- return;
- }
- /**
- * Retrieves the lookup item from the bookmark plugin and calls the callback with the
- * element and the path of the item.
- * @param item BookmarkItem object which can be a folder or a file.
- * @param itemDoms WeakMap of the bookmark plugin which contains the lookup item.
- */
- const retrieveLookupItem = (item, itemDoms) => {
- const lookupItem = itemDoms.get(item);
- if (!lookupItem) {
- return;
- }
- if (item.items) {
- // If the item is a folder, then we need to retrieve all the items inside it.
- for (const subItem of item.items) {
- retrieveLookupItem(subItem, itemDoms);
- }
- }
- // If the item is a `file` or a `folder` (not of type `group`), then we can call the callback.
- if (item.type === 'file' || item.type === 'folder') {
- callback(lookupItem.el, item.path);
- }
- };
- const { itemDoms } = this.leaf.view;
- // Retrieves all the items of the bookmark plugin which areo objects.
- const items = this.bookmark.instance.items;
- items.forEach((item) => {
- retrieveLookupItem(item, itemDoms);
- });
- }
- onMount() {
- var _a;
- const setBookmarkIcon = () => {
- const nodesWithPath = {};
- this.computeNodesWithPath((node, filePath) => {
- nodesWithPath[filePath] = node;
- });
- Object.entries(nodesWithPath).forEach(([filePath, node]) => this.setIconOrRemove(filePath, node));
- };
- if (obsidian.requireApiVersion('1.7.2')) {
- // TODO: Might improve the performance here.
- (_a = this.leaf) === null || _a === void 0 ? void 0 : _a.loadIfDeferred().then(setBookmarkIcon);
- }
- else {
- setBookmarkIcon();
- }
- }
- register() {
- if (!this.plugin.app.internalPlugins.getPluginById('file-explorer').enabled) {
- console.info(`[${config.PLUGIN_NAME}/Bookmarks] Skipping bookmark internal plugin registration because file-explorer is not enabled.`);
- return;
- }
- if (!this.enabled) {
- console.info(`[${config.PLUGIN_NAME}/Bookmarks] Skipping bookmark internal plugin registration because it's not enabled.`);
- return;
- }
- // eslint-disable-next-line
- const self = this;
- this.plugin.register(around(this.bookmark.instance, {
- addItem: function (next) {
- return function (...args) {
- next.call(this, ...args);
- // TODO: Remove in the future, I could not think of a better way to do this.
- setTimeout(() => {
- self.onMount();
- }, 1000);
- };
- },
- removeItem: function (next) {
- return function (...args) {
- next.call(this, ...args);
- self.onMount();
- };
- },
- }));
- }
- }
- // TODO: Optimize the code to reduce the number of iterations and improve the
- // performance.
- const createIconShortcodeRegex = (plugin) => {
- return new RegExp(`(${plugin.getSettings().iconIdentifier})((\\w{1,64}:\\d{17,18})|(\\w{1,64}))(${plugin.getSettings().iconIdentifier})`, 'g');
- };
- const createTreeWalker = (plugin, root) => {
- return document.createTreeWalker(root, NodeFilter.SHOW_ALL, {
- acceptNode: function (node) {
- if (node.nodeName === 'CODE') {
- return NodeFilter.FILTER_REJECT;
- }
- else if (node.nodeName === '#text') {
- if (node.nodeValue &&
- (emoji.getRegex().test(node.nodeValue) ||
- createIconShortcodeRegex(plugin).test(node.nodeValue))) {
- return NodeFilter.FILTER_ACCEPT;
- }
- else {
- return NodeFilter.FILTER_REJECT;
- }
- }
- return NodeFilter.FILTER_SKIP;
- },
- });
- };
- const checkForTextNodes = (treeWalker, match, cb) => {
- let currentNode = treeWalker.currentNode;
- while (currentNode) {
- if (currentNode.nodeType === Node.TEXT_NODE) {
- const text = currentNode;
- const textNodes = [...Array.from(text.parentElement.childNodes)].filter((n) => n instanceof Text);
- for (const text of textNodes) {
- for (const code of [...text.wholeText.matchAll(match)]
- .sort((a, b) => b.index - a.index)
- .map((arr) => ({ text: arr[0], index: arr.index }))) {
- if (!text.textContent) {
- continue;
- }
- cb(text, code);
- }
- }
- }
- currentNode = treeWalker.nextNode();
- }
- };
- const processIconInTextMarkdown = (plugin, element) => {
- // Ignore if codeblock
- const codeElement = element.querySelector('pre > code');
- const callOut = element.querySelector('.callout');
- if (codeElement && !callOut) {
- return;
- }
- const iconTreeWalker = createTreeWalker(plugin, element);
- const iconShortcodeRegex = createIconShortcodeRegex(plugin);
- const iconIdentifierLength = plugin.getSettings().iconIdentifier.length;
- checkForTextNodes(iconTreeWalker, iconShortcodeRegex, (text, code) => {
- var _a, _b;
- const shortcode = code.text;
- const iconName = shortcode.slice(iconIdentifierLength, shortcode.length - iconIdentifierLength);
- const iconObject = icon.getIconByName(iconName);
- if (iconObject) {
- const toReplace = text.splitText(code.index);
- const rootSpan = createSpan({
- cls: 'cm-iconize-icon',
- attr: {
- 'aria-label': iconName,
- 'data-icon': iconName,
- 'aria-hidden': 'true',
- },
- });
- rootSpan.style.display = 'inline-flex';
- rootSpan.style.transform = 'translateY(13%)';
- const parentElement = toReplace.parentElement;
- const tagName = (_b = (_a = parentElement === null || parentElement === void 0 ? void 0 : parentElement.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : '';
- let fontSize = calculateFontTextSize();
- if (isHeader(tagName)) {
- fontSize = calculateHeaderSize(tagName);
- const svgElement = svg.setFontSize(iconObject.svgElement, fontSize);
- rootSpan.innerHTML = svgElement;
- }
- else {
- const svgElement = svg.setFontSize(iconObject.svgElement, fontSize);
- rootSpan.innerHTML = svgElement;
- }
- parentElement === null || parentElement === void 0 ? void 0 : parentElement.insertBefore(rootSpan, toReplace);
- toReplace.textContent = toReplace.wholeText.substring(code.text.length);
- // Set the font size to its parent font size if defined.
- // We do this after that to not freeze the insertion while iterating over the tree.
- // We are also updating the size after the animation because the styling won't be set
- // in the first place.
- requestAnimationFrame(() => {
- const parentFontSize = parseFloat(getComputedStyle(parentElement).fontSize);
- if (!isNaN(parentFontSize)) {
- rootSpan.innerHTML = svg.setFontSize(rootSpan.innerHTML, parentFontSize);
- }
- });
- }
- });
- const emojiTreeWalker = createTreeWalker(plugin, element);
- checkForTextNodes(emojiTreeWalker, emoji.getRegex(), (text, code) => {
- var _a, _b, _c, _d;
- if (!emoji.isEmoji(code.text)) {
- return;
- }
- if (plugin.getSettings().emojiStyle === 'twemoji') {
- const toReplace = text.splitText(code.index);
- const tagName = (_c = (_b = (_a = toReplace.parentElement) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : '';
- let fontSize = calculateFontTextSize();
- if (isHeader(tagName)) {
- fontSize = calculateHeaderSize(tagName);
- }
- const emojiValue = emoji.parseEmoji(plugin.getSettings().emojiStyle, code.text, fontSize);
- if (!emojiValue) {
- return;
- }
- const emojiNode = createSpan();
- emojiNode.innerHTML = emojiValue;
- (_d = toReplace.parentElement) === null || _d === void 0 ? void 0 : _d.insertBefore(emojiNode, toReplace);
- toReplace.textContent = toReplace.wholeText.substring(code.text.length);
- }
- });
- };
- const processIconInLinkMarkdown = (plugin, element, ctx) => {
- const linkElements = element.querySelectorAll('a');
- if (!linkElements || linkElements.length === 0) {
- return;
- }
- linkElements.forEach((linkElement) => {
- var _a, _b, _c, _d, _e;
- // Skip if the link element e.g., is a tag.
- if (!linkElement.hasAttribute('data-href')) {
- return;
- }
- const linkHref = linkElement.getAttribute('href');
- if (!linkHref) {
- logger.warn('Link element does not have an `href` attribute');
- return;
- }
- const file = plugin.app.metadataCache.getFirstLinkpathDest(linkHref, ctx.sourcePath);
- if (!file) {
- logger.warn('Link element does not have a linkpath to a file');
- return;
- }
- const path = file.path;
- const iconValue = icon.getIconByPath(plugin, path);
- if (!iconValue) {
- return;
- }
- let fontSize = calculateFontTextSize();
- const tagName = (_c = (_b = (_a = linkElement.parentElement) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : '';
- if (isHeader(tagName)) {
- fontSize = calculateHeaderSize(tagName);
- }
- const iconName = typeof iconValue === 'string'
- ? iconValue
- : iconValue.prefix + iconValue.name;
- const rootSpan = createSpan({
- cls: 'iconize-icon-in-link',
- attr: {
- title: iconName,
- 'aria-label': iconName,
- 'data-icon': iconName,
- 'aria-hidden': 'true',
- },
- });
- rootSpan.style.color =
- (_d = plugin.getIconColor(path)) !== null && _d !== void 0 ? _d : plugin.getSettings().iconColor;
- if (emoji.isEmoji(iconName)) {
- const parsedEmoji = (_e = emoji.parseEmoji(plugin.getSettings().emojiStyle, iconName, fontSize)) !== null && _e !== void 0 ? _e : iconName;
- rootSpan.style.transform = 'translateY(0)';
- rootSpan.innerHTML = parsedEmoji;
- }
- else {
- let svgEl = icon.getIconByName(iconName).svgElement;
- svgEl = svg.setFontSize(svgEl, fontSize);
- if (svgEl) {
- rootSpan.style.transform = 'translateY(20%)';
- rootSpan.innerHTML = svgEl;
- }
- }
- linkElement.prepend(rootSpan);
- });
- };
- const TREE_ITEM_CLASS = 'tree-item-self';
- const TREE_ITEM_INNER = 'tree-item-inner';
- class OutlineInternalPlugin extends InternalPluginInjector {
- constructor(plugin) {
- super(plugin);
- }
- onMount() {
- // TODO: Might improve the performance here.
- }
- register() {
- if (!this.enabled) {
- logger.info('Skipping internal plugin registration because it is not enabled.', LoggerPrefix.Outline);
- return;
- }
- const updateTreeItems = () => {
- var _a, _b, _c;
- if (!((_b = (_a = this.leaf) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.tree)) {
- return;
- }
- const treeItems = Array.from(this.leaf.view.tree.containerEl.querySelectorAll(`.${TREE_ITEM_CLASS}`));
- for (const treeItem of treeItems) {
- const treeItemInner = treeItem.querySelector(`.${TREE_ITEM_INNER}`);
- let text = treeItemInner === null || treeItemInner === void 0 ? void 0 : treeItemInner.getText();
- if (!text) {
- continue;
- }
- const iconShortcodeRegex = createIconShortcodeRegex(this.plugin);
- const iconIdentifierLength = this.plugin.getSettings().iconIdentifier.length;
- let trimmedLength = 0;
- for (const code of [...text.matchAll(iconShortcodeRegex)]
- .sort((a, b) => a.index - b.index)
- .map((arr) => ({ text: arr[0], index: arr.index }))) {
- const shortcode = code.text;
- const iconName = shortcode.slice(iconIdentifierLength, shortcode.length - iconIdentifierLength);
- const iconObject = icon.getIconByName(iconName);
- if (iconObject) {
- const startIndex = code.index - trimmedLength;
- const endIndex = code.index + code.text.length - trimmedLength;
- const str = text.substring(0, startIndex) + text.substring(endIndex);
- const iconSpan = createSpan({
- cls: 'cm-iconize-icon',
- attr: {
- 'aria-label': iconName,
- 'data-icon': iconName,
- 'aria-hidden': 'true',
- },
- });
- const fontSize = parseFloat((_c = getComputedStyle(document.body).getPropertyValue('--nav-item-size')) !== null && _c !== void 0 ? _c : '16');
- const svgElement = svg.setFontSize(iconObject.svgElement, fontSize);
- iconSpan.style.display = 'inline-flex';
- iconSpan.style.transform = 'translateY(13%)';
- iconSpan.innerHTML = svgElement;
- treeItemInner.innerHTML = treeItemInner.innerHTML.replace(shortcode, iconSpan.outerHTML);
- text = str;
- trimmedLength += code.text.length;
- }
- }
- }
- };
- const setOutlineIcons = () => {
- this.plugin.getEventEmitter().once('allIconsLoaded', () => {
- updateTreeItems();
- const callback = (mutations) => {
- mutations.forEach((mutation) => {
- if (mutation.type !== 'childList') {
- return;
- }
- const addedNodes = mutation.addedNodes;
- if (addedNodes.length === 0) {
- return;
- }
- updateTreeItems();
- });
- if (!this.enabled) {
- observer.disconnect();
- }
- };
- const observer = new MutationObserver(callback);
- observer.observe(this.leaf.view.tree.containerEl, {
- childList: true,
- subtree: true,
- });
- });
- };
- if (obsidian.requireApiVersion('1.7.2')) {
- // TODO: Might improve the performance here.
- this.leaf.loadIfDeferred().then(setOutlineIcons);
- }
- else {
- setOutlineIcons();
- }
- }
- get leaf() {
- const leaf = this.plugin.app.workspace.getLeavesOfType('outline');
- if (!leaf) {
- logger.log('`leaf` in outline is undefined', LoggerPrefix.Outline);
- return undefined;
- }
- if (leaf.length === 0) {
- logger.log('`leaf` length in outline is 0', LoggerPrefix.Outline);
- return undefined;
- }
- return leaf[0];
- }
- get outline() {
- return this.plugin.app.internalPlugins.getPluginById('outline');
- }
- get enabled() {
- return this.plugin.app.internalPlugins.getPluginById('outline').enabled;
- }
- }
- class SuggestionIcon extends obsidian.EditorSuggest {
- constructor(app, plugin) {
- super(app);
- this.plugin = plugin;
- }
- onTrigger(cursor, editor) {
- // Isolate shortcode starting position closest to the cursor.
- const shortcodeStart = editor
- .getLine(cursor.line)
- .substring(0, cursor.ch)
- .lastIndexOf(this.plugin.getSettings().iconIdentifier);
- // `onTrigger` needs to return `null` as soon as possible to save processing performance.
- if (shortcodeStart === -1) {
- return null;
- }
- // Regex for checking if the shortcode is not done yet.
- const regex = new RegExp(`^(${this.plugin.getSettings().iconIdentifier})\\w+$`, 'g');
- const regexOngoingShortcode = editor
- .getLine(cursor.line)
- .substring(shortcodeStart, cursor.ch)
- .match(regex);
- if (regexOngoingShortcode === null) {
- return null;
- }
- const startingIndex = editor
- .getLine(cursor.line)
- .indexOf(regexOngoingShortcode[0]);
- return {
- start: {
- line: cursor.line,
- ch: startingIndex,
- },
- end: {
- line: cursor.line,
- ch: startingIndex + regexOngoingShortcode[0].length,
- },
- query: regexOngoingShortcode[0],
- };
- }
- getSuggestions(context) {
- const queryLowerCase = context.query
- .substring(this.plugin.getSettings().iconIdentifier.length)
- .toLowerCase();
- // Store all icons corresponding to the current query.
- const iconsNameArray = getAllLoadedIconNames()
- .filter((iconObject) => {
- const name = iconObject.prefix.toLowerCase() + iconObject.name.toLowerCase();
- return name.toLowerCase().includes(queryLowerCase);
- })
- .map((iconObject) => iconObject.prefix + iconObject.name);
- // Store all emojis correspoding to the current query - parsing whitespaces and
- // colons for shortcodes compatibility.
- const emojisNameArray = Object.keys(emoji.shortNames).filter((e) => { var _a; return (_a = emoji.getShortcode(e)) === null || _a === void 0 ? void 0 : _a.includes(queryLowerCase); });
- return [...iconsNameArray, ...emojisNameArray];
- }
- renderSuggestion(value, el) {
- const iconObject = icon.getIconByName(value);
- el.style.display = 'flex';
- el.style.alignItems = 'center';
- el.style.gap = '0.25rem';
- if (iconObject) {
- // Suggest an icon.
- el.innerHTML = `${iconObject.svgElement} <span>${value}</span>`;
- }
- else {
- // Suggest an emoji - display its shortcode version.
- const shortcode = emoji.getShortcode(value);
- if (shortcode) {
- el.innerHTML = `<span>${value}</span> <span>${shortcode}</span>`;
- }
- }
- }
- selectSuggestion(value) {
- const isEmoji = emoji.isEmoji(value.replace(/_/g, ' '));
- if (!isEmoji) {
- saveIconToIconPack(this.plugin, value);
- }
- // Replace query with iconNameWithPrefix or emoji unicode directly.
- const updatedValue = isEmoji
- ? value
- : `${this.plugin.getSettings().iconIdentifier}${value}${this.plugin.getSettings().iconIdentifier}`;
- this.context.editor.replaceRange(updatedValue, this.context.start, this.context.end);
- }
- }
- class IconInTextWidget extends view.WidgetType {
- constructor(plugin, id) {
- super();
- this.plugin = plugin;
- this.id = id;
- this.start = -1;
- this.end = -1;
- }
- setPosition(start, end) {
- this.start = start;
- this.end = end;
- }
- eq(other) {
- return other instanceof IconInTextWidget && other.id === this.id;
- }
- getSize(view) {
- let fontSize = calculateFontTextSize();
- const line = view.state.doc.lineAt(this.end);
- const headerMatch = line.text.match(/^#{1,6}\s/);
- if (headerMatch && headerMatch[0].trim()) {
- const mapping = {
- '#': 'h1',
- '##': 'h2',
- '###': 'h3',
- '####': 'h4',
- '#####': 'h5',
- '######': 'h6',
- };
- const header = mapping[headerMatch[0].trim()];
- fontSize = calculateHeaderSize(header);
- }
- return fontSize;
- }
- toDOM(view) {
- const wrap = createSpan({
- cls: 'cm-iconize-icon',
- attr: {
- 'aria-label': this.id,
- 'data-icon': this.id,
- 'aria-hidden': 'true',
- },
- });
- const foundIcon = icon.getIconByName(this.id);
- const fontSize = this.getSize(view);
- if (foundIcon) {
- const svgElement = svg.setFontSize(foundIcon.svgElement, fontSize);
- wrap.style.display = 'inline-flex';
- wrap.style.transform = 'translateY(13%)';
- wrap.innerHTML = svgElement;
- }
- else if (emoji.isEmoji(this.id)) {
- wrap.innerHTML = emoji.parseEmoji(this.plugin.getSettings().emojiStyle, this.id, fontSize);
- }
- else {
- wrap.append(`${this.plugin.getSettings().iconIdentifier}${this.id}${this.plugin.getSettings().iconIdentifier}`);
- }
- return wrap;
- }
- ignoreEvent() {
- return false;
- }
- }
- class IconInLinkWidget extends view.WidgetType {
- constructor(plugin, iconData, path, headerType) {
- super();
- this.plugin = plugin;
- this.iconData = iconData;
- this.path = path;
- this.headerType = headerType;
- }
- toDOM() {
- var _a;
- const iconNode = document.createElement('span');
- const iconName = typeof this.iconData === 'string'
- ? this.iconData
- : this.iconData.prefix + this.iconData.name;
- iconNode.style.color =
- (_a = this.plugin.getIconColor(this.path)) !== null && _a !== void 0 ? _a : this.plugin.getSettings().iconColor;
- iconNode.setAttribute('title', iconName);
- iconNode.classList.add('iconize-icon-in-link');
- if (typeof this.iconData === 'string') {
- iconNode.style.transform = 'translateY(0)';
- }
- let innerHTML = typeof this.iconData === 'string'
- ? this.iconData
- : this.iconData.svgElement;
- let fontSize = calculateFontTextSize();
- if (this.headerType) {
- fontSize = calculateHeaderSize(this.headerType);
- }
- if (emoji.isEmoji(innerHTML)) {
- innerHTML = emoji.parseEmoji(this.plugin.getSettings().emojiStyle, innerHTML, fontSize);
- }
- else {
- innerHTML = svg.setFontSize(innerHTML, fontSize);
- }
- iconNode.innerHTML = innerHTML;
- return iconNode;
- }
- ignoreEvent() {
- return true;
- }
- }
- const buildLinkDecorations = (view$1, plugin) => {
- const builder = new state.RangeSetBuilder();
- const mdView = view$1.state.field(obsidian.editorInfoField);
- for (const { from, to } of view$1.visibleRanges) {
- language.syntaxTree(view$1.state).iterate({
- from,
- to,
- enter: (node) => {
- const tokenProps = node.type.prop(language.tokenClassNodeProp);
- if (tokenProps) {
- const props = new Set(tokenProps.split(' '));
- const isLink = props.has('hmd-internal-link');
- const headerType = [
- 'header-1',
- 'header-2',
- 'header-3',
- 'header-4',
- 'header-5',
- 'header-6',
- ].find((header) => props.has(header));
- if (isLink) {
- let linkText = view$1.state.doc.sliceString(node.from, node.to);
- linkText = linkText.split('#')[0];
- const file = plugin.app.metadataCache.getFirstLinkpathDest(linkText, mdView.file.basename);
- if (file) {
- const possibleIcon = icon.getIconByPath(plugin, file.path);
- if (possibleIcon) {
- const iconDecoration = view.Decoration.widget({
- widget: new IconInLinkWidget(plugin, possibleIcon, file.path, headerType),
- });
- builder.add(node.from, node.from, iconDecoration);
- }
- }
- }
- }
- },
- });
- }
- return builder.finish();
- };
- const buildTextDecorations = (view$1, plugin) => {
- const ranges = [];
- const iconInfo = view$1.state.field(plugin.positionField);
- for (const { from, to } of view$1.visibleRanges) {
- iconInfo.between(from - 1, to + 1, (from, to, { iconId }) => {
- ranges.push([iconId, from, to]);
- });
- }
- return view.Decoration.set(ranges.map(([code, from, to]) => {
- const widget = new IconInTextWidget(plugin, code);
- widget.setPosition(from, to);
- if (view$1.state.field(obsidian.editorLivePreviewField)) {
- return view.Decoration.replace({
- widget,
- side: -1,
- }).range(from, to);
- }
- return view.Decoration.widget({
- widget,
- side: -1,
- }).range(to);
- }), true);
- };
- const buildIconInTextPlugin = (plugin) => {
- return view.ViewPlugin.fromClass(class IconPlugin {
- constructor(view) {
- this.plugin = plugin;
- this.decorations = buildTextDecorations(view, plugin);
- }
- update(update) {
- this.decorations = buildTextDecorations(update.view, this.plugin);
- }
- }, {
- decorations: (v) => v.decorations,
- provide: (plugin) => view.EditorView.atomicRanges.of((view$1) => {
- const value = view$1.plugin(plugin);
- return value ? value.decorations : view.Decoration.none;
- }),
- });
- };
- const buildIconInLinksPlugin = (plugin) => {
- return view.ViewPlugin.fromClass(class {
- constructor(view) {
- this.plugin = plugin;
- this.decorations = buildLinkDecorations(view, plugin);
- }
- destroy() { }
- update(update) {
- if (update.docChanged || update.viewportChanged) {
- this.decorations = buildLinkDecorations(update.view, this.plugin);
- }
- }
- }, {
- decorations: (v) => v.decorations,
- });
- };
- // TODO: Optimize the code to reduce the number of iterations and improve the
- // performance.
- function checkForSourceMode(plugin) {
- let isSourceMode = false;
- // Iterate over all leaves to check if any is in source mode
- plugin.app.workspace.iterateAllLeaves((leaf) => {
- var _a;
- if (!isSourceMode && leaf.view.getViewType() === 'markdown') {
- if ((_a = leaf.getViewState().state) === null || _a === void 0 ? void 0 : _a.source) {
- isSourceMode = true;
- }
- }
- });
- return isSourceMode;
- }
- class IconPosition extends state.RangeValue {
- constructor(text) {
- super();
- this.text = text;
- }
- get iconId() {
- return this.text;
- }
- eq(other) {
- return other instanceof IconPosition && other.text === this.text;
- }
- }
- /**
- * Builds a position field for the editor state. This field will track the
- * positions of the icons in the document.
- **/
- const buildPositionField = (plugin) => {
- /**
- * Checks the ranges of the icons in the document. If the range is not
- * excluded, the range is added to the range set. If the range is excluded,
- * the range is removed from the range set.
- * @param state EditorState to get the ranges from.
- * @param excludeFrom Number to exclude from the ranges.
- * @param excludeTo Number to exclude to the ranges.
- * @param updateRange Function callback to update the range.
- */
- const checkRanges = (state, excludeFrom, excludeTo, updateRange) => {
- const isSourceMode = checkForSourceMode(plugin);
- const text = state.doc.sliceString(0, state.doc.length);
- const identifier = plugin.getSettings().iconIdentifier;
- const regex = new RegExp(`(${identifier})((\\w{1,64}:\\d{17,18})|(\\w{1,64}))(${identifier})`, 'g');
- for (const { 0: rawCode, index: offset } of text.matchAll(regex)) {
- const iconName = rawCode.substring(identifier.length, rawCode.length - identifier.length);
- if (!icon.getIconByName(iconName)) {
- continue;
- }
- const from = offset;
- const to = offset + rawCode.length;
- if (!isNodeInRangeAccepted(state, from, to)) {
- continue;
- }
- if (offset < excludeFrom || offset > excludeTo) {
- updateRange(from, to, new IconPosition(iconName), isSourceMode);
- continue;
- }
- updateRange(from, to, new IconPosition(iconName), true);
- }
- for (const { 0: emojiName, index: offset } of text.matchAll(emoji.getRegex())) {
- if (!emoji.isEmoji(emojiName)) {
- continue;
- }
- const from = offset;
- const to = offset + emojiName.length;
- if (!isNodeInRangeAccepted(state, from, to)) {
- continue;
- }
- if (offset < excludeFrom || offset > excludeTo) {
- updateRange(from, to, new IconPosition(emojiName), isSourceMode);
- continue;
- }
- updateRange(from, to, new IconPosition(emojiName), true);
- }
- };
- const isNodeInRangeAccepted = (state, from, to) => {
- let isRangeAccepted = true;
- language.syntaxTree(state).iterate({
- from,
- to,
- enter: ({ type }) => {
- var _a;
- if (type.name === 'Document') {
- return;
- }
- const allowedNodeTypes = [
- 'header',
- 'strong',
- 'em',
- 'quote',
- 'link',
- 'list-1',
- 'list-2',
- 'list-3',
- 'highlight',
- 'footref',
- 'comment',
- 'link-alias',
- ];
- const excludedNodeTypes = [
- 'formatting',
- 'hmd-codeblock',
- 'inline-code',
- 'hr',
- ];
- const nodeProps = (_a = type.prop(language.tokenClassNodeProp)) !== null && _a !== void 0 ? _a : '';
- const s = new Set(nodeProps.split(' '));
- if (excludedNodeTypes.some((t) => s.has(t)) &&
- allowedNodeTypes.every((t) => !s.has(t))) {
- isRangeAccepted = false;
- }
- },
- });
- return isRangeAccepted;
- };
- return state.StateField.define({
- create: (state$1) => {
- const rangeSet = new state.RangeSetBuilder();
- const changedLines = [];
- checkRanges(state$1, -1, -1, (from, to, iconPosition) => {
- changedLines.push({ from, to, iconPosition });
- });
- changedLines.sort((a, b) => a.from - b.from);
- for (const { from, to, iconPosition } of changedLines) {
- rangeSet.add(from, to, iconPosition);
- }
- return rangeSet.finish();
- },
- update: (rangeSet, transaction) => {
- const newRanges = [];
- if (!transaction.docChanged) {
- if (transaction.selection) {
- const from = transaction.selection.ranges[0].from;
- const to = transaction.selection.ranges[0].to;
- const lineEnd = transaction.state.doc.lineAt(to).length;
- const lineStart = transaction.state.doc.lineAt(from).from;
- // Checks the ranges of the icons in the document except for the
- // excluded line start and end.
- checkRanges(transaction.state, lineStart, lineStart + lineEnd, (from, to, value, removed) => {
- rangeSet = rangeSet.update({
- filterFrom: from,
- filterTo: to,
- filter: () => false,
- });
- if (!removed) {
- newRanges.push(value.range(from, to));
- }
- });
- }
- else {
- checkRanges(transaction.state, -1, -1, (from, to, value, removed) => {
- rangeSet = rangeSet.update({
- filterFrom: from,
- filterTo: to,
- filter: () => false,
- });
- if (!removed) {
- newRanges.push(value.range(from, to));
- }
- });
- }
- newRanges.sort((a, b) => a.from - b.from);
- rangeSet = rangeSet.update({ add: newRanges });
- return rangeSet;
- }
- rangeSet = rangeSet.map(transaction.changes);
- const changedLines = [];
- transaction.changes.iterChangedRanges((_f, _t, from, to) => {
- changedLines.push([
- transaction.state.doc.lineAt(from).number,
- transaction.state.doc.lineAt(to).number,
- ]);
- });
- for (const [start, end] of changedLines) {
- const from = transaction.state.doc.line(start).from;
- const to = transaction.state.doc.line(end).to;
- rangeSet = rangeSet.update({
- filterFrom: from,
- filterTo: to,
- filter: () => false,
- });
- const lineEnd = transaction.state.doc.line(end).length;
- const lineStart = transaction.state.doc.line(end).from;
- // Checks the ranges of the icons in the document except for the excluded
- // line start and end.
- checkRanges(transaction.state, lineStart, lineStart + lineEnd, (from, to, value, removed) => {
- if (!removed) {
- newRanges.push(value.range(from, to));
- }
- });
- }
- newRanges.sort((a, b) => a.from - b.from);
- rangeSet = rangeSet.update({ add: newRanges });
- return rangeSet;
- },
- });
- };
- class ChangeColorModal extends obsidian.Modal {
- constructor(app, plugin, path) {
- var _a;
- super(app);
- this.plugin = plugin;
- this.path = path;
- this.usedColor = this.plugin.getIconColor(this.path);
- this.contentEl.style.display = 'block';
- this.modalEl.classList.add('iconize-custom-modal');
- this.titleEl.setText('Change color');
- const description = this.contentEl.createEl('p', {
- text: 'Select a color for this icon',
- cls: 'setting-item-description',
- });
- description.style.marginBottom = 'var(--size-2-2)';
- const colorContainer = this.contentEl.createDiv();
- colorContainer.style.display = 'flex';
- colorContainer.style.alignItems = 'center';
- colorContainer.style.justifyContent = 'space-between';
- const colorPicker = new obsidian.ColorComponent(colorContainer)
- .setValue((_a = this.usedColor) !== null && _a !== void 0 ? _a : '#000000')
- .onChange((value) => {
- this.usedColor = value;
- });
- const defaultColorButton = new obsidian.ButtonComponent(colorContainer);
- defaultColorButton.setTooltip('Set color to the default one');
- defaultColorButton.setButtonText('Reset');
- defaultColorButton.onClick(() => {
- colorPicker.setValue('#000000');
- this.usedColor = undefined;
- });
- // Save button.
- const button = new obsidian.ButtonComponent(this.contentEl);
- button.buttonEl.style.marginTop = 'var(--size-4-4)';
- button.buttonEl.style.float = 'right';
- button.setButtonText('Save Changes');
- button.onClick(() => __awaiter(this, void 0, void 0, function* () {
- var _a;
- new obsidian.Notice('Color of icon changed.');
- if (this.usedColor) {
- this.plugin.addIconColor(this.path, this.usedColor);
- }
- else {
- this.plugin.removeIconColor(this.path);
- }
- // Refresh the DOM.
- const iconNode = dom.getIconNodeFromPath(this.path);
- iconNode.style.color = (_a = this.usedColor) !== null && _a !== void 0 ? _a : null;
- const colorizedInnerHtml = svg.colorize(iconNode.innerHTML, this.usedColor);
- iconNode.innerHTML = colorizedInnerHtml;
- this.close();
- }));
- }
- onOpen() {
- super.onOpen();
- }
- onClose() {
- const { contentEl } = this;
- contentEl.empty();
- }
- }
- class EventEmitter {
- constructor() {
- this.listeners = {};
- }
- on(type, listener, priority = 0) {
- var _a, _b;
- var _c;
- (_a = (_c = this.listeners)[type]) !== null && _a !== void 0 ? _a : (_c[type] = []);
- (_b = this.listeners[type]) === null || _b === void 0 ? void 0 : _b.push({ listener, once: false, priority });
- this.sortListeners(type);
- }
- once(type, listener, priority = 0) {
- var _a, _b;
- var _c;
- (_a = (_c = this.listeners)[type]) !== null && _a !== void 0 ? _a : (_c[type] = []);
- (_b = this.listeners[type]) === null || _b === void 0 ? void 0 : _b.push({ listener, once: true, priority });
- this.sortListeners(type);
- }
- off(type, listener) {
- var _a;
- if (!this.listeners[type]) {
- return;
- }
- this.listeners[type] = (_a = this.listeners[type]) === null || _a === void 0 ? void 0 : _a.filter((entry) => entry.listener !== listener);
- }
- emit(type, payload) {
- const listeners = this.listeners[type];
- if (!listeners) {
- return;
- }
- const event = { payload };
- listeners.slice().forEach((entry) => {
- entry.listener(event);
- if (entry.once) {
- this.off(type, entry.listener);
- }
- });
- }
- sortListeners(type) {
- var _a;
- if (this.listeners[type]) {
- (_a = this.listeners[type]) === null || _a === void 0 ? void 0 : _a.sort((a, b) => b.priority - a.priority);
- }
- }
- }
- function getApi(plugin) {
- return {
- getEventEmitter: () => plugin.getEventEmitter(),
- getIconByName: (iconNameWithPrefix) => icon.getIconByName(iconNameWithPrefix),
- setIconForNode: (iconName, node, color) => dom.setIconForNode(plugin, iconName, node, { color }),
- saveIconToIconPack: (iconNameWithPrefix) => saveIconToIconPack(plugin, iconNameWithPrefix),
- removeIconFromIconPack: (iconNameWithPrefix) => removeIconFromIconPack(plugin, iconNameWithPrefix),
- getIconsFromIconPack: getIconsFromIconPack,
- getAllIconPacks: getAllIconPacks,
- doesElementHasIconNode: dom.doesElementHasIconNode,
- getIconFromElement: dom.getIconFromElement,
- removeIconInNode: dom.removeIconInNode,
- removeIconInPath: dom.removeIconInPath,
- util: {
- dom,
- svg,
- },
- version: {
- get current() {
- return plugin.manifest.version;
- },
- },
- };
- }
- class IconizePlugin extends obsidian.Plugin {
- constructor() {
- super(...arguments);
- this.registeredFileExplorers = new Set();
- this.modifiedInternalPlugins = [];
- this.positionField = buildPositionField(this);
- this.frontmatterCache = new Set();
- this.eventEmitter = new EventEmitter();
- this.api = getApi(this);
- }
- onload() {
- return __awaiter(this, void 0, void 0, function* () {
- console.log(`loading ${config.PLUGIN_NAME}`);
- yield this.loadIconFolderData();
- logger.toggleLogging(this.getSettings().debugMode);
- setPath(this.getSettings().iconPacksPath);
- if (this.getSettings().useInternalPlugins) {
- // Registers all modified internal plugins.
- // Only adds star plugin for obsidian under v0.12.6.
- if (!obsidian.requireApiVersion('0.12.6')) {
- this.modifiedInternalPlugins.push(new StarredInternalPlugin(this));
- }
- else if (obsidian.requireApiVersion('1.2.0')) {
- this.modifiedInternalPlugins.push(new BookmarkInternalPlugin(this));
- }
- this.modifiedInternalPlugins.push(new OutlineInternalPlugin(this));
- }
- yield createDefaultDirectory(this);
- yield this.checkRecentlyUsedIcons();
- yield migrate(this);
- const usedIconNames = icon.getAllWithPath(this).map((value) => value.icon);
- if (!this.doesUseCustomLucideIconPack()) {
- addLucideIconsPack(this);
- }
- yield loadUsedIcons(this, usedIconNames);
- this.app.workspace.onLayoutReady(() => this.handleChangeLayout());
- this.addCommand({
- id: 'iconize:set-icon-for-file',
- name: 'Set icon for file',
- hotkeys: [
- {
- modifiers: ['Mod', 'Shift'],
- key: 'j',
- },
- ],
- editorCallback: (editor) => __awaiter(this, void 0, void 0, function* () {
- var _a;
- const file = (_a = editor.editorComponent) === null || _a === void 0 ? void 0 : _a.file;
- if (!file) {
- logger.warn(`'editor.editorComponent?.file' is undefined for file: ${file}`);
- return;
- }
- const modal = new IconsPickerModal(this.app, this, file.path);
- modal.open();
- modal.onSelect = (iconName) => {
- IconCache.getInstance().set(file.path, {
- iconNameWithPrefix: iconName,
- });
- // Update icon in tab when setting is enabled.
- if (this.getSettings().iconInTabsEnabled) {
- const tabLeaves = iconTabs.getTabLeavesOfFilePath(this, file.path);
- for (const tabLeaf of tabLeaves) {
- iconTabs.update(this, iconName, tabLeaf.tabHeaderInnerIconEl);
- }
- }
- // Update icon in title when setting is enabled.
- if (this.getSettings().iconInTitleEnabled) {
- this.addIconInTitle(iconName);
- }
- };
- }),
- });
- this.registerEvent(
- // Registering file menu event for listening to file pinning and unpinning.
- this.app.workspace.on('file-menu', (menu, file) => {
- // I've researched other ways of doing this. However, there is no other way to listen to file pinning and unpinning.
- menu.onHide(() => {
- const path = file.path;
- if (this.getSettings().iconInTabsEnabled) {
- for (const openedFile of getAllOpenedFiles(this)) {
- if (openedFile.path === path) {
- const possibleIcon = IconCache.getInstance().get(path);
- if (!possibleIcon) {
- return;
- }
- const tabLeaves = iconTabs.getTabLeavesOfFilePath(this, file.path);
- for (const tabLeaf of tabLeaves) {
- // Add timeout to ensure that the default icon is already set.
- setTimeout(() => {
- iconTabs.add(this, file.path, tabLeaf.tabHeaderInnerIconEl);
- }, 5);
- }
- }
- }
- }
- });
- }));
- this.registerEvent(this.app.workspace.on('layout-change', () => this.handleChangeLayout()));
- this.registerEvent(this.app.workspace.on('file-menu', (menu, file) => {
- const addIconMenuItem = (item) => {
- item.setTitle('Change icon');
- item.setIcon('hashtag');
- item.onClick(() => {
- const modal = new IconsPickerModal(this.app, this, file.path);
- modal.open();
- modal.onSelect = (iconName) => {
- IconCache.getInstance().set(file.path, {
- iconNameWithPrefix: iconName,
- });
- // Update icon in tab when setting is enabled.
- if (this.getSettings().iconInTabsEnabled) {
- const tabLeaves = iconTabs.getTabLeavesOfFilePath(this, file.path);
- for (const tabLeaf of tabLeaves) {
- iconTabs.update(this, iconName, tabLeaf.tabHeaderInnerIconEl);
- }
- }
- // Update icon in title when setting is enabled.
- if (this.getSettings().iconInTitleEnabled) {
- this.addIconInTitle(iconName);
- }
- };
- });
- };
- const removeIconMenuItem = (item) => {
- item.setTitle('Remove icon');
- item.setIcon('trash');
- item.onClick(() => __awaiter(this, void 0, void 0, function* () {
- yield this.removeSingleIcon(file);
- }));
- };
- const changeColorOfIcon = (item) => {
- item.setTitle('Change color of icon');
- item.setIcon('palette');
- item.onClick(() => {
- const modal = new ChangeColorModal(this.app, this, file.path);
- modal.open();
- });
- };
- menu.addItem(addIconMenuItem);
- const filePathData = this.getData()[file.path];
- const hasNestedIcon = typeof filePathData === 'object' &&
- filePathData.iconName !== null;
- // Only add remove icon menu item when the file path exists in the data.
- // We do not want to show this menu item for e.g. custom rules.
- if (filePathData &&
- (typeof filePathData === 'string' || hasNestedIcon)) {
- const icon = typeof filePathData === 'string'
- ? filePathData
- : filePathData.iconName;
- if (!emoji.isEmoji(icon)) {
- menu.addItem(changeColorOfIcon);
- }
- menu.addItem(removeIconMenuItem);
- }
- }));
- // deleting event
- this.registerEvent(this.app.vault.on('delete', (file) => {
- const path = file.path;
- this.removeFolderIcon(path);
- }));
- // renaming event
- this.registerEvent(this.app.vault.on('rename', (file, oldPath) => {
- // Check if the file was moved and had an icon before.
- const dataPoint = this.data[oldPath];
- if (dataPoint && oldPath !== 'settings') {
- const iconNameWithPrefix = typeof dataPoint === 'object'
- ? dataPoint.iconName
- : dataPoint;
- dom.createIconNode(this, file.path, iconNameWithPrefix);
- }
- this.renameFolder(file.path, oldPath);
- }));
- if (this.getSettings().iconsInNotesEnabled) {
- this.registerMarkdownPostProcessor((el) => processIconInTextMarkdown(this, el));
- this.registerEditorSuggest(new SuggestionIcon(this.app, this));
- this.registerEditorExtension([
- this.positionField,
- buildIconInTextPlugin(this),
- ]);
- }
- if (this.getSettings().iconsInLinksEnabled) {
- this.registerMarkdownPostProcessor((el, ctx) => processIconInLinkMarkdown(this, el, ctx));
- this.registerEditorExtension([
- this.positionField,
- buildIconInLinksPlugin(this),
- ]);
- }
- this.addSettingTab(new IconFolderSettings(this.app, this));
- });
- }
- notifyPlugins() {
- this.modifiedInternalPlugins.forEach((internalPlugin) => {
- if (internalPlugin.enabled) {
- internalPlugin.onMount();
- }
- });
- }
- removeSingleIcon(file) {
- return __awaiter(this, void 0, void 0, function* () {
- this.removeFolderIcon(file.path);
- dom.removeIconInPath(file.path);
- IconCache.getInstance().invalidate(file.path);
- this.notifyPlugins();
- let didUpdate = false;
- // Refreshes the icon tab and title icon for custom rules.
- for (const rule of customRule.getSortedRules(this)) {
- const applicable = yield customRule.isApplicable(this, rule, file.path);
- if (applicable) {
- customRule.add(this, rule, file);
- this.addIconInTitle(rule.icon);
- const tabLeaves = iconTabs.getTabLeavesOfFilePath(this, file.path);
- for (const tabLeaf of tabLeaves) {
- iconTabs.add(this, file.path, tabLeaf.tabHeaderInnerIconEl, {
- iconName: rule.icon,
- });
- }
- didUpdate = true;
- break;
- }
- }
- // Only remove icon above titles and icon in tabs if no custom rule was found.
- if (!didUpdate) {
- // Refreshes icons above title and icons in tabs.
- for (const openedFile of getAllOpenedFiles(this)) {
- if (this.getSettings().iconInTitleEnabled) {
- titleIcon.remove(openedFile.leaf.view.inlineTitleEl);
- }
- if (this.getSettings().iconInTabsEnabled) {
- const leaf = openedFile.leaf;
- iconTabs.remove(leaf.tabHeaderInnerIconEl, {
- replaceWithDefaultIcon: true,
- });
- }
- }
- }
- });
- }
- handleChangeLayout() {
- // Transform data that are objects to single strings.
- const data = Object.entries(this.data);
- this.modifiedInternalPlugins.forEach((internalPlugin) => {
- if (internalPlugin.enabled) {
- internalPlugin.onMount();
- internalPlugin.register();
- }
- });
- icon.addAll(this, data, this.registeredFileExplorers, () => {
- // After initialization of the icon packs, checks the vault for missing icons and
- // adds them.
- initIconPacks(this).then(() => __awaiter(this, void 0, void 0, function* () {
- if (this.getSettings().iconsBackgroundCheckEnabled) {
- const data = Object.entries(this.data);
- yield icon.checkMissingIcons(this, data);
- resetPreloadedIcons();
- }
- this.eventEmitter.emit('allIconsLoaded');
- }));
- if (this.getSettings().iconInFrontmatterEnabled) {
- const activeFile = this.app.workspace.getActiveFile();
- if (activeFile) {
- this.frontmatterCache.add(activeFile.path);
- }
- }
- // Adds the title icon to the active leaf view.
- if (this.getSettings().iconInTitleEnabled) {
- for (const openedFile of getAllOpenedFiles(this)) {
- const iconName = icon.getByPath(this, openedFile.path);
- const activeView = openedFile.leaf.view;
- if (activeView instanceof obsidian.MarkdownView && iconName) {
- let possibleIcon = iconName;
- if (!emoji.isEmoji(iconName)) {
- const iconNextIdentifier = nextIdentifier(iconName);
- possibleIcon = getSvgFromLoadedIcon(iconName.substring(0, iconNextIdentifier), iconName.substring(iconNextIdentifier));
- }
- if (possibleIcon) {
- titleIcon.add(this, activeView.inlineTitleEl, possibleIcon, {
- fontSize: calculateInlineTitleSize(),
- });
- }
- }
- }
- }
- // Register rename event for adding icons with custom rules to the DOM
- // when file was moved to another directory.
- this.registerEvent(this.app.vault.on('rename', (file, oldPath) => __awaiter(this, void 0, void 0, function* () {
- const sortedRules = customRule.getSortedRules(this);
- // Removes possible icons from the renamed file.
- sortedRules.forEach((rule) => {
- if (customRule.doesMatchPath(rule, oldPath)) {
- dom.removeIconInPath(file.path);
- }
- });
- // Adds possible icons to the renamed file.
- sortedRules.forEach((rule) => {
- if (customRule.doesMatchPath(rule, oldPath)) {
- return;
- }
- customRule.add(this, rule, file, undefined);
- });
- // Updates icon tabs for the renamed file.
- for (const rule of customRule.getSortedRules(this)) {
- const applicable = yield customRule.isApplicable(this, rule, file.path);
- if (!applicable) {
- continue;
- }
- const openedFiles = getAllOpenedFiles(this);
- const openedFile = openedFiles.find((openedFile) => openedFile.path === file.path);
- if (openedFile) {
- const leaf = openedFile.leaf;
- iconTabs.update(this, rule.icon, leaf.tabHeaderInnerIconEl);
- }
- break;
- }
- })));
- // Register `layout-change` event for adding icons to tabs when moving a pane or
- // enabling reading mode.
- this.registerEvent(this.app.workspace.on('layout-change', () => {
- var _a, _b;
- if (this.getSettings().iconInTitleEnabled) {
- const activeView = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);
- if (activeView) {
- const file = activeView.file;
- const view = activeView.leaf.view.currentMode
- .view;
- const iconNameWithPrefix = icon.getByPath(this, file.path);
- if (!iconNameWithPrefix) {
- titleIcon.hide(view.inlineTitleEl);
- return;
- }
- let foundIcon = iconNameWithPrefix;
- if (!emoji.isEmoji(foundIcon)) {
- foundIcon = (_a = icon.getIconByName(iconNameWithPrefix)) === null || _a === void 0 ? void 0 : _a.svgElement;
- // Check for preloaded icons if no icon was found when the start up was faster
- // than the loading of the icons.
- if (!foundIcon && getPreloadedIcons().length > 0) {
- foundIcon = (_b = getPreloadedIcons().find((icon) => icon.prefix + icon.name === iconNameWithPrefix)) === null || _b === void 0 ? void 0 : _b.svgElement;
- }
- }
- if (foundIcon) {
- // Removes the node because the editor markdown content is being rerendered
- // when the content mode changes back to editing.
- titleIcon.remove(view.inlineTitleEl);
- titleIcon.add(this, view.inlineTitleEl, foundIcon, {
- fontSize: calculateInlineTitleSize(),
- });
- }
- }
- }
- if (!this.getSettings().iconInTabsEnabled) {
- return;
- }
- for (const openedFile of getAllOpenedFiles(this)) {
- const leaf = openedFile.leaf;
- const iconColor = this.getIconColor(leaf.view.file.path);
- iconTabs.add(this, openedFile.path, leaf.tabHeaderInnerIconEl, {
- iconColor,
- });
- }
- }));
- // Register `file-open` event for adding icon to title.
- this.registerEvent(this.app.workspace.on('file-open', (file) => {
- var _a, _b;
- if (!this.getSettings().iconInTitleEnabled) {
- return;
- }
- for (const openedFile of getAllOpenedFiles(this)) {
- if (!file || !openedFile || openedFile.path !== file.path) {
- continue;
- }
- const leaf = openedFile.leaf.view;
- const iconNameWithPrefix = icon.getByPath(this, file.path);
- if (!iconNameWithPrefix) {
- titleIcon.hide(leaf.inlineTitleEl);
- return;
- }
- let foundIcon = iconNameWithPrefix;
- if (!emoji.isEmoji(foundIcon)) {
- foundIcon = (_a = icon.getIconByName(iconNameWithPrefix)) === null || _a === void 0 ? void 0 : _a.svgElement;
- // Check for preloaded icons if no icon was found when the start up was faster
- // than the loading of the icons.
- if (!foundIcon && getPreloadedIcons().length > 0) {
- foundIcon = (_b = getPreloadedIcons().find((icon) => icon.prefix + icon.name === iconNameWithPrefix)) === null || _b === void 0 ? void 0 : _b.svgElement;
- }
- }
- if (foundIcon) {
- titleIcon.add(this, leaf.inlineTitleEl, foundIcon, {
- fontSize: calculateInlineTitleSize(),
- });
- }
- else {
- titleIcon.hide(leaf.inlineTitleEl);
- }
- }
- }));
- // Register event for frontmatter icon registration.
- this.registerEvent(this.app.metadataCache.on('resolve', (file) => __awaiter(this, void 0, void 0, function* () {
- if (!this.getSettings().iconInFrontmatterEnabled) {
- return;
- }
- const fileCache = this.app.metadataCache.getFileCache(file);
- const iconFrontmatterName = this.getSettings().iconInFrontmatterFieldName;
- const iconColorFrontmatterName = this.getSettings().iconColorInFrontmatterFieldName;
- if (fileCache === null || fileCache === void 0 ? void 0 : fileCache.frontmatter) {
- const { [iconFrontmatterName]: newIconName, [iconColorFrontmatterName]: newIconColor, } = fileCache.frontmatter;
- // If `icon` property is empty, we will remove it from the data and remove the icon.
- if (!newIconName) {
- if (this.frontmatterCache.has(file.path)) {
- yield this.removeSingleIcon(file);
- this.frontmatterCache.delete(file.path);
- }
- return;
- }
- if (typeof newIconName !== 'string') {
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Frontmatter property type \`icon\` has to be of type \`text\`.`);
- return;
- }
- if (newIconColor && typeof newIconColor !== 'string') {
- new obsidian.Notice(`[${config.PLUGIN_NAME}] Frontmatter property type \`iconColor\` has to be of type \`text\`.`);
- return;
- }
- let iconColor = newIconColor;
- if (isHexadecimal(iconColor)) {
- iconColor = stringToHex(iconColor);
- }
- const cachedIcon = IconCache.getInstance().get(file.path);
- if (newIconName === (cachedIcon === null || cachedIcon === void 0 ? void 0 : cachedIcon.iconNameWithPrefix) &&
- iconColor === (cachedIcon === null || cachedIcon === void 0 ? void 0 : cachedIcon.iconColor)) {
- return;
- }
- this.frontmatterCache.add(file.path);
- try {
- if (!emoji.isEmoji(newIconName)) {
- saveIconToIconPack(this, newIconName);
- }
- }
- catch (e) {
- logger.warn(`Something went wrong while saving icon to icon pack (error: ${e})`);
- new obsidian.Notice(e.message);
- return;
- }
- dom.createIconNode(this, file.path, newIconName, {
- color: iconColor,
- });
- this.addFolderIcon(file.path, newIconName);
- this.addIconColor(file.path, iconColor);
- IconCache.getInstance().set(file.path, {
- iconNameWithPrefix: newIconName,
- iconColor,
- });
- // Update icon in tab when setting is enabled.
- if (this.getSettings().iconInTabsEnabled) {
- const tabLeaves = iconTabs.getTabLeavesOfFilePath(this, file.path);
- for (const tabLeaf of tabLeaves) {
- iconTabs.update(this, newIconName, tabLeaf.tabHeaderInnerIconEl);
- }
- }
- // Update icon in title when setting is enabled.
- if (this.getSettings().iconInTitleEnabled) {
- this.addIconInTitle(newIconName);
- }
- }
- })));
- // Register active leaf change event for adding icon of file to tab.
- this.registerEvent(this.app.workspace.on('active-leaf-change', (leaf) => {
- if (!this.getSettings().iconInTabsEnabled) {
- return;
- }
- // TODO: Maybe change in the future to a more optimal solution.
- // Fixes a problem when the file was clicked twice in the same tab.
- // See https://github.com/FlorianWoelki/obsidian-iconize/issues/208.
- if (leaf.view.getViewType() === 'file-explorer') {
- for (const openedFile of getAllOpenedFiles(this)) {
- const leaf = openedFile.leaf;
- const iconColor = this.getIconColor(leaf.view.file.path);
- iconTabs.add(this, openedFile.path, leaf.tabHeaderInnerIconEl, {
- iconColor,
- });
- }
- return;
- }
- if (leaf.view.getViewType() !== 'markdown') {
- return;
- }
- const tabHeaderLeaf = leaf;
- if (tabHeaderLeaf.view.file) {
- const iconColor = this.getIconColor(tabHeaderLeaf.view.file.path);
- iconTabs.add(this, tabHeaderLeaf.view.file.path, tabHeaderLeaf.tabHeaderInnerIconEl, {
- iconColor,
- });
- }
- }));
- this.registerEvent(this.app.workspace.on('css-change', () => {
- for (const openedFile of getAllOpenedFiles(this)) {
- const activeView = openedFile.leaf.view;
- if (activeView instanceof obsidian.MarkdownView) {
- titleIcon.updateStyle(activeView.inlineTitleEl, {
- fontSize: calculateInlineTitleSize(),
- });
- }
- }
- }));
- });
- }
- addIconInTitle(iconName) {
- var _a;
- for (const openedFile of getAllOpenedFiles(this)) {
- const activeView = openedFile.leaf.view;
- if (activeView instanceof obsidian.MarkdownView) {
- let possibleIcon = iconName;
- if (!emoji.isEmoji(iconName)) {
- possibleIcon = (_a = icon.getIconByName(iconName)) === null || _a === void 0 ? void 0 : _a.svgElement;
- }
- if (possibleIcon) {
- titleIcon.add(this, activeView.inlineTitleEl, possibleIcon, {
- fontSize: calculateInlineTitleSize(),
- });
- }
- }
- }
- }
- onunload() {
- console.log('unloading obsidian-icon-folder');
- }
- renameFolder(newPath, oldPath) {
- if (!this.data[oldPath] || newPath === oldPath) {
- return;
- }
- Object.defineProperty(this.data, newPath, Object.getOwnPropertyDescriptor(this.data, oldPath));
- delete this.data[oldPath];
- this.saveIconFolderData();
- }
- addIconColor(path, iconColor) {
- const pathData = this.getData()[path];
- if (typeof pathData === 'string') {
- this.getData()[path] = {
- iconName: pathData,
- iconColor,
- };
- }
- else {
- pathData.iconColor = iconColor;
- }
- this.saveIconFolderData();
- }
- getIconColor(path) {
- const pathData = this.getData()[path];
- if (!pathData) {
- return undefined;
- }
- if (typeof pathData === 'string') {
- return undefined;
- }
- return pathData.iconColor;
- }
- removeIconColor(path) {
- const pathData = this.getData()[path];
- if (typeof pathData === 'string') {
- return;
- }
- const currentValue = pathData;
- this.getData()[path] = currentValue.iconName;
- this.saveIconFolderData();
- }
- removeFolderIcon(path) {
- if (!this.data[path]) {
- return;
- }
- // Saves the icon name with prefix to remove it from the icon pack directory later.
- const iconData = this.data[path];
- delete this.data[path];
- // Removes the icon from the icon pack directory if it is not used as an icon somewhere
- // else.
- if (iconData) {
- let iconNameWithPrefix = iconData;
- if (typeof iconData === 'object') {
- iconNameWithPrefix = iconData.iconName;
- }
- else {
- iconNameWithPrefix = iconData;
- }
- if (!emoji.isEmoji(iconNameWithPrefix)) {
- removeIconFromIconPack(this, iconNameWithPrefix);
- }
- }
- //this.addIconsToSearch();
- this.saveIconFolderData();
- }
- addFolderIcon(path, icon) {
- const iconName = getNormalizedName(typeof icon === 'object' ? icon.displayName : icon);
- this.data[path] = iconName;
- // Update recently used icons.
- if (!this.getSettings().recentlyUsedIcons.includes(iconName)) {
- if (this.getSettings().recentlyUsedIcons.length >=
- this.getSettings().recentlyUsedIconsSize) {
- this.getSettings().recentlyUsedIcons =
- this.getSettings().recentlyUsedIcons.slice(0, this.getSettings().recentlyUsedIconsSize - 1);
- }
- this.getSettings().recentlyUsedIcons.unshift(iconName);
- this.checkRecentlyUsedIcons();
- }
- //this.addIconsToSearch();
- this.saveIconFolderData();
- }
- getSettings() {
- return this.data.settings;
- }
- loadIconFolderData() {
- return __awaiter(this, void 0, void 0, function* () {
- const data = yield this.loadData();
- if (data) {
- Object.entries(DEFAULT_SETTINGS).forEach(([k, v]) => {
- if (data.settings[k] === undefined) {
- data.settings[k] = v;
- }
- });
- }
- this.data = Object.assign({ settings: Object.assign({}, DEFAULT_SETTINGS) }, {}, data);
- });
- }
- saveIconFolderData() {
- return __awaiter(this, void 0, void 0, function* () {
- yield this.saveData(this.data);
- });
- }
- checkRecentlyUsedIcons() {
- return __awaiter(this, void 0, void 0, function* () {
- if (this.getSettings().recentlyUsedIcons.length >
- this.getSettings().recentlyUsedIconsSize) {
- this.getSettings().recentlyUsedIcons =
- this.getSettings().recentlyUsedIcons.slice(0, this.getSettings().recentlyUsedIconsSize);
- yield this.saveIconFolderData();
- }
- });
- }
- getEventEmitter() {
- return this.eventEmitter;
- }
- getData() {
- return this.data;
- }
- getIconNameFromPath(path) {
- if (typeof this.getData()[path] === 'object') {
- return this.getData()[path].iconName;
- }
- return this.getData()[path];
- }
- getRegisteredFileExplorers() {
- return this.registeredFileExplorers;
- }
- doesUseCustomLucideIconPack() {
- return this.getSettings().lucideIconPackType === 'custom';
- }
- doesUseNativeLucideIconPack() {
- return this.getSettings().lucideIconPackType === 'native';
- }
- /**
- * Returns a possible data path by the given value. This function checks for
- * direct icon and custom rules.
- * @param value String that will be used to find the data path.
- * @returns String that is the data path or `undefined` if no data path was found.
- */
- getDataPathByValue(value) {
- return Object.entries(this.data).find(([k, v]) => {
- if (typeof v === 'string') {
- if (value === v) {
- return k;
- }
- }
- else if (typeof v === 'object') {
- // Check for custom rules.
- if (k === 'settings') {
- // `rules` are defined in the settings object.
- const rules = v.rules;
- return rules.find((rule) => rule.icon === value);
- }
- v = v;
- if (value === v.iconName) {
- return k;
- }
- }
- });
- }
- }
- module.exports = IconizePlugin;
- /* nosourcemap */
|