| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599 |
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.zip = {}));
- })(this, (function (exports) { 'use strict';
-
- const { Array, Object, String, Number, BigInt, Math, Date, Map, Set, Response, URL, Error, Uint8Array, Uint16Array, Uint32Array, DataView, Blob, Promise, TextEncoder, TextDecoder, document, crypto, btoa, TransformStream, ReadableStream, WritableStream, CompressionStream, DecompressionStream, navigator, Worker } = typeof globalThis !== 'undefined' ? globalThis : this || self;
-
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- const MAX_32_BITS = 0xffffffff;
- const MAX_16_BITS = 0xffff;
- const MAX_8_BITS = 0xff;
- const COMPRESSION_METHOD_DEFLATE = 0x08;
- const COMPRESSION_METHOD_DEFLATE_64 = 0x09;
- const COMPRESSION_METHOD_STORE = 0x00;
- const COMPRESSION_METHOD_AES = 0x63;
-
- const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
- const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
- const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
- const CENTRAL_FILE_HEADER_SIGNATURE = 0x02014b50;
- const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;
- const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 0x06064b50;
- const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE = 0x07064b50;
- const END_OF_CENTRAL_DIR_LENGTH = 22;
- const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH = 20;
- const ZIP64_END_OF_CENTRAL_DIR_LENGTH = 56;
- const ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH = END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LENGTH;
-
- const DATA_DESCRIPTOR_RECORD_LENGTH = 12;
- const DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH = 20;
- const DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH = 4;
-
- const EXTRAFIELD_TYPE_ZIP64 = 0x0001;
- const EXTRAFIELD_TYPE_AES = 0x9901;
- const EXTRAFIELD_TYPE_NTFS = 0x000a;
- const EXTRAFIELD_TYPE_NTFS_TAG1 = 0x0001;
- const EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP = 0x5455;
- const EXTRAFIELD_TYPE_UNICODE_PATH = 0x7075;
- const EXTRAFIELD_TYPE_UNICODE_COMMENT = 0x6375;
- const EXTRAFIELD_TYPE_USDZ = 0x1986;
- const EXTRAFIELD_TYPE_INFOZIP = 0x7875;
- const EXTRAFIELD_TYPE_UNIX = 0x7855;
-
- const BITFLAG_ENCRYPTED = 0b1;
- const BITFLAG_LEVEL = 0b0110;
- const BITFLAG_LEVEL_MAX_MASK = 0b010;
- const BITFLAG_LEVEL_FAST_MASK = 0b100;
- const BITFLAG_LEVEL_SUPER_FAST_MASK = 0b110;
- const BITFLAG_DATA_DESCRIPTOR = 0b1000;
- const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
- const FILE_ATTR_MSDOS_DIR_MASK = 0b10000;
- const FILE_ATTR_MSDOS_READONLY_MASK = 0x01;
- const FILE_ATTR_MSDOS_HIDDEN_MASK = 0x02;
- const FILE_ATTR_MSDOS_SYSTEM_MASK = 0x04;
- const FILE_ATTR_MSDOS_ARCHIVE_MASK = 0x20;
- const FILE_ATTR_UNIX_TYPE_MASK = 0o170000;
- const FILE_ATTR_UNIX_TYPE_DIR = 0o040000;
- const FILE_ATTR_UNIX_EXECUTABLE_MASK = 0o111;
- const FILE_ATTR_UNIX_DEFAULT_MASK = 0o644;
- const FILE_ATTR_UNIX_SETUID_MASK = 0o4000;
- const FILE_ATTR_UNIX_SETGID_MASK = 0o2000;
- const FILE_ATTR_UNIX_STICKY_MASK = 0o1000;
-
- const VERSION_DEFLATE = 0x14;
- const VERSION_ZIP64 = 0x2D;
- const VERSION_AES = 0x33;
-
- const DIRECTORY_SIGNATURE = "/";
-
- const HEADER_SIZE = 30;
- const HEADER_OFFSET_SIGNATURE = 10;
- const HEADER_OFFSET_COMPRESSED_SIZE = 14;
- const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18;
-
- const MAX_DATE = new Date(2107, 11, 31);
- const MIN_DATE = new Date(1980, 0, 1);
-
- const UNDEFINED_VALUE = undefined;
- const INFINITY_VALUE = Infinity;
- const UNDEFINED_TYPE = "undefined";
- const FUNCTION_TYPE = "function";
- const OBJECT_TYPE = "object";
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const MINIMUM_CHUNK_SIZE = 64;
- let maxWorkers = 2;
- try {
- if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
- maxWorkers = navigator.hardwareConcurrency;
- }
- } catch {
- // ignored
- }
- const DEFAULT_CONFIGURATION = {
- workerURI: "./core/web-worker-wasm.js",
- wasmURI: "./core/streams/zlib-wasm/zlib-streams.wasm",
- chunkSize: 64 * 1024,
- maxWorkers,
- terminateWorkerTimeout: 5000,
- useWebWorkers: true,
- useCompressionStream: true,
- CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
- DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
- };
-
- const config = Object.assign({}, DEFAULT_CONFIGURATION);
-
- function getConfiguration() {
- return config;
- }
-
- function getChunkSize(config) {
- return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
- }
-
- function configure(configuration) {
- const {
- baseURI,
- chunkSize,
- maxWorkers,
- terminateWorkerTimeout,
- useCompressionStream,
- useWebWorkers,
- CompressionStream,
- DecompressionStream,
- CompressionStreamZlib,
- DecompressionStreamZlib,
- workerURI,
- wasmURI
- } = configuration;
- setIfDefined("baseURI", baseURI);
- setIfDefined("wasmURI", wasmURI);
- setIfDefined("workerURI", workerURI);
- setIfDefined("chunkSize", chunkSize);
- setIfDefined("maxWorkers", maxWorkers);
- setIfDefined("terminateWorkerTimeout", terminateWorkerTimeout);
- setIfDefined("useCompressionStream", useCompressionStream);
- setIfDefined("useWebWorkers", useWebWorkers);
- setIfDefined("CompressionStream", CompressionStream);
- setIfDefined("DecompressionStream", DecompressionStream);
- setIfDefined("CompressionStreamZlib", CompressionStreamZlib);
- setIfDefined("DecompressionStreamZlib", DecompressionStreamZlib);
- }
-
- function setIfDefined(propertyName, propertyValue) {
- if (propertyValue !== UNDEFINED_VALUE) {
- config[propertyName] = propertyValue;
- }
- }
-
- const A="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function g$1(g){g({workerURI:g=>{const B="text/javascript",I=(g=>{g=(g=>{const B=(g=(g+"").replace(/[^A-Za-z0-9+/=]/g,"")).length,I=[];for(let C=0;B>C;C+=4){const B=A.indexOf(g[C])<<18|A.indexOf(g[C+1])<<12|(63&A.indexOf(g[C+2]))<<6|63&A.indexOf(g[C+3]);I.push(B>>16&255),"="!==g[C+2]&&I.push(B>>8&255),"="!==g[C+3]&&I.push(255&B);}return new Uint8Array(I)})(g);let B=new Uint8Array(1024),I=0;for(let A=0;A<g.length;){const E=g[A++];if(128&E){const Q=3+(127&E),Y=g[A++]<<8|g[A++],F=I-Y;C(I+Q);for(let A=0;Q>A;A++)B[I++]=B[F+A];}else {const Q=E;C(I+Q);for(let C=0;Q>C&&A<g.length;C++)B[I++]=g[A++];}}return (g=>{let B="";const I=g.length;let C=0;for(;I>C+2;C+=3){const I=g[C]<<16|g[C+1]<<8|g[C+2];B+=A[I>>18&63]+A[I>>12&63]+A[I>>6&63]+A[63&I];}const E=I-C;if(1===E){const I=g[C]<<16;B+=A[I>>18&63]+A[I>>12&63]+"==";}else if(2===E){const I=g[C]<<16|g[C+1]<<8;B+=A[I>>18&63]+A[I>>12&63]+A[I>>6&63]+"=";}return B})(new Uint8Array(B.buffer.slice(0,I)));function C(A){if(B.length<A){let g=2*B.length;for(;A>g;)g*=2;const C=new Uint8Array(g);C.set(B.subarray(0,I)),B=C;}}})("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");if(g){const A=atob(I),g=new Blob([A],{type:B});return URL.createObjectURL(g)}return "data:"+B+";base64,"+I}});}
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- const table$1 = [];
- for (let i = 0; i < 256; i++) {
- let t = i;
- for (let j = 0; j < 8; j++) {
- if (t & 1) {
- t = (t >>> 1) ^ 0xEDB88320;
- } else {
- t = t >>> 1;
- }
- }
- table$1[i] = t;
- }
-
- class Crc32 {
-
- constructor(crc) {
- this.crc = crc || -1;
- }
-
- append(data) {
- let crc = this.crc | 0;
- for (let offset = 0, length = data.length | 0; offset < length; offset++) {
- crc = (crc >>> 8) ^ table$1[(crc ^ data[offset]) & 0xFF];
- }
- this.crc = crc;
- }
-
- get() {
- return ~this.crc;
- }
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- class Crc32Stream extends TransformStream {
-
- constructor() {
- // deno-lint-ignore prefer-const
- let stream;
- const crc32 = new Crc32();
- super({
- transform(chunk, controller) {
- crc32.append(chunk);
- controller.enqueue(chunk);
- },
- flush() {
- const value = new Uint8Array(4);
- const dataView = new DataView(value.buffer);
- dataView.setUint32(0, crc32.get());
- stream.value = value;
- }
- });
- stream = this;
- }
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- function encodeText(value) {
- // deno-lint-ignore valid-typeof
- if (typeof TextEncoder == UNDEFINED_TYPE) {
- value = unescape(encodeURIComponent(value));
- const result = new Uint8Array(value.length);
- for (let i = 0; i < result.length; i++) {
- result[i] = value.charCodeAt(i);
- }
- return result;
- } else {
- return new TextEncoder().encode(value);
- }
- }
-
- // Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
-
- // deno-lint-ignore-file no-this-alias
-
- /*
- * SJCL is open. You can use, modify and redistribute it under a BSD
- * license or under the GNU GPL, version 2.0.
- */
-
- /** @fileOverview Javascript cryptography implementation.
- *
- * Crush to remove comments, shorten variable names and
- * generally reduce transmission size.
- *
- * @author Emily Stark
- * @author Mike Hamburg
- * @author Dan Boneh
- */
-
- /*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */
-
- /** @fileOverview Arrays of bits, encoded as arrays of Numbers.
- *
- * @author Emily Stark
- * @author Mike Hamburg
- * @author Dan Boneh
- */
-
- /**
- * Arrays of bits, encoded as arrays of Numbers.
- * @namespace
- * @description
- * <p>
- * These objects are the currency accepted by SJCL's crypto functions.
- * </p>
- *
- * <p>
- * Most of our crypto primitives operate on arrays of 4-byte words internally,
- * but many of them can take arguments that are not a multiple of 4 bytes.
- * This library encodes arrays of bits (whose size need not be a multiple of 8
- * bits) as arrays of 32-bit words. The bits are packed, big-endian, into an
- * array of words, 32 bits at a time. Since the words are double-precision
- * floating point numbers, they fit some extra data. We use this (in a private,
- * possibly-changing manner) to encode the number of bits actually present
- * in the last word of the array.
- * </p>
- *
- * <p>
- * Because bitwise ops clear this out-of-band data, these arrays can be passed
- * to ciphers like AES which want arrays of words.
- * </p>
- */
- const bitArray = {
- /**
- * Concatenate two bit arrays.
- * @param {bitArray} a1 The first array.
- * @param {bitArray} a2 The second array.
- * @return {bitArray} The concatenation of a1 and a2.
- */
- concat(a1, a2) {
- if (a1.length === 0 || a2.length === 0) {
- return a1.concat(a2);
- }
-
- const last = a1[a1.length - 1], shift = bitArray.getPartial(last);
- if (shift === 32) {
- return a1.concat(a2);
- } else {
- return bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1));
- }
- },
-
- /**
- * Find the length of an array of bits.
- * @param {bitArray} a The array.
- * @return {Number} The length of a, in bits.
- */
- bitLength(a) {
- const l = a.length;
- if (l === 0) {
- return 0;
- }
- const x = a[l - 1];
- return (l - 1) * 32 + bitArray.getPartial(x);
- },
-
- /**
- * Truncate an array.
- * @param {bitArray} a The array.
- * @param {Number} len The length to truncate to, in bits.
- * @return {bitArray} A new array, truncated to len bits.
- */
- clamp(a, len) {
- if (a.length * 32 < len) {
- return a;
- }
- a = a.slice(0, Math.ceil(len / 32));
- const l = a.length;
- len = len & 31;
- if (l > 0 && len) {
- a[l - 1] = bitArray.partial(len, a[l - 1] & 0x80000000 >> (len - 1), 1);
- }
- return a;
- },
-
- /**
- * Make a partial word for a bit array.
- * @param {Number} len The number of bits in the word.
- * @param {Number} x The bits.
- * @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side.
- * @return {Number} The partial word.
- */
- partial(len, x, _end) {
- if (len === 32) {
- return x;
- }
- return (_end ? x | 0 : x << (32 - len)) + len * 0x10000000000;
- },
-
- /**
- * Get the number of bits used by a partial word.
- * @param {Number} x The partial word.
- * @return {Number} The number of bits used by the partial word.
- */
- getPartial(x) {
- return Math.round(x / 0x10000000000) || 32;
- },
-
- /** Shift an array right.
- * @param {bitArray} a The array to shift.
- * @param {Number} shift The number of bits to shift.
- * @param {Number} [carry=0] A byte to carry in
- * @param {bitArray} [out=[]] An array to prepend to the output.
- * @private
- */
- _shiftRight(a, shift, carry, out) {
- if (out === undefined) {
- out = [];
- }
-
- for (; shift >= 32; shift -= 32) {
- out.push(carry);
- carry = 0;
- }
- if (shift === 0) {
- return out.concat(a);
- }
-
- for (let i = 0; i < a.length; i++) {
- out.push(carry | a[i] >>> shift);
- carry = a[i] << (32 - shift);
- }
- const last2 = a.length ? a[a.length - 1] : 0;
- const shift2 = bitArray.getPartial(last2);
- out.push(bitArray.partial(shift + shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(), 1));
- return out;
- }
- };
-
- /** @fileOverview Bit array codec implementations.
- *
- * @author Emily Stark
- * @author Mike Hamburg
- * @author Dan Boneh
- */
-
- /**
- * Arrays of bytes
- * @namespace
- */
- const codec = {
- bytes: {
- /** Convert from a bitArray to an array of bytes. */
- fromBits(arr) {
- const bl = bitArray.bitLength(arr);
- const byteLength = bl / 8;
- const out = new Uint8Array(byteLength);
- let tmp;
- for (let i = 0; i < byteLength; i++) {
- if ((i & 3) === 0) {
- tmp = arr[i / 4];
- }
- out[i] = tmp >>> 24;
- tmp <<= 8;
- }
- return out;
- },
- /** Convert from an array of bytes to a bitArray. */
- toBits(bytes) {
- const out = [];
- let i;
- let tmp = 0;
- for (i = 0; i < bytes.length; i++) {
- tmp = tmp << 8 | bytes[i];
- if ((i & 3) === 3) {
- out.push(tmp);
- tmp = 0;
- }
- }
- if (i & 3) {
- out.push(bitArray.partial(8 * (i & 3), tmp));
- }
- return out;
- }
- }
- };
-
- const hash = {};
-
- /**
- * Context for a SHA-1 operation in progress.
- * @constructor
- */
- hash.sha1 = class {
- constructor(hash) {
- const sha1 = this;
- /**
- * The hash's block size, in bits.
- * @constant
- */
- sha1.blockSize = 512;
- /**
- * The SHA-1 initialization vector.
- * @private
- */
- sha1._init = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
- /**
- * The SHA-1 hash key.
- * @private
- */
- sha1._key = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6];
- if (hash) {
- sha1._h = hash._h.slice(0);
- sha1._buffer = hash._buffer.slice(0);
- sha1._length = hash._length;
- } else {
- sha1.reset();
- }
- }
-
- /**
- * Reset the hash state.
- * @return this
- */
- reset() {
- const sha1 = this;
- sha1._h = sha1._init.slice(0);
- sha1._buffer = [];
- sha1._length = 0;
- return sha1;
- }
-
- /**
- * Input several words to the hash.
- * @param {bitArray|String} data the data to hash.
- * @return this
- */
- update(data) {
- const sha1 = this;
- if (typeof data === "string") {
- data = codec.utf8String.toBits(data);
- }
- const b = sha1._buffer = bitArray.concat(sha1._buffer, data);
- const ol = sha1._length;
- const nl = sha1._length = ol + bitArray.bitLength(data);
- if (nl > 9007199254740991) {
- throw new Error("Cannot hash more than 2^53 - 1 bits");
- }
- const c = new Uint32Array(b);
- let j = 0;
- for (let i = sha1.blockSize + ol - ((sha1.blockSize + ol) & (sha1.blockSize - 1)); i <= nl;
- i += sha1.blockSize) {
- sha1._block(c.subarray(16 * j, 16 * (j + 1)));
- j += 1;
- }
- b.splice(0, 16 * j);
- return sha1;
- }
-
- /**
- * Complete hashing and output the hash value.
- * @return {bitArray} The hash value, an array of 5 big-endian words. TODO
- */
- finalize() {
- const sha1 = this;
- let b = sha1._buffer;
- const h = sha1._h;
-
- // Round out and push the buffer
- b = bitArray.concat(b, [bitArray.partial(1, 1)]);
- // Round out the buffer to a multiple of 16 words, less the 2 length words.
- for (let i = b.length + 2; i & 15; i++) {
- b.push(0);
- }
-
- // append the length
- b.push(Math.floor(sha1._length / 0x100000000));
- b.push(sha1._length | 0);
-
- while (b.length) {
- sha1._block(b.splice(0, 16));
- }
-
- sha1.reset();
- return h;
- }
-
- /**
- * The SHA-1 logical functions f(0), f(1), ..., f(79).
- * @private
- */
- _f(t, b, c, d) {
- if (t <= 19) {
- return (b & c) | (~b & d);
- } else if (t <= 39) {
- return b ^ c ^ d;
- } else if (t <= 59) {
- return (b & c) | (b & d) | (c & d);
- } else if (t <= 79) {
- return b ^ c ^ d;
- }
- }
-
- /**
- * Circular left-shift operator.
- * @private
- */
- _S(n, x) {
- return (x << n) | (x >>> 32 - n);
- }
-
- /**
- * Perform one cycle of SHA-1.
- * @param {Uint32Array|bitArray} words one block of words.
- * @private
- */
- _block(words) {
- const sha1 = this;
- const h = sha1._h;
- // When words is passed to _block, it has 16 elements. SHA1 _block
- // function extends words with new elements (at the end there are 80 elements).
- // The problem is that if we use Uint32Array instead of Array,
- // the length of Uint32Array cannot be changed. Thus, we replace words with a
- // normal Array here.
- const w = Array(80); // do not use Uint32Array here as the instantiation is slower
- for (let j = 0; j < 16; j++) {
- w[j] = words[j];
- }
-
- let a = h[0];
- let b = h[1];
- let c = h[2];
- let d = h[3];
- let e = h[4];
-
- for (let t = 0; t <= 79; t++) {
- if (t >= 16) {
- w[t] = sha1._S(1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]);
- }
- const tmp = (sha1._S(5, a) + sha1._f(t, b, c, d) + e + w[t] +
- sha1._key[Math.floor(t / 20)]) | 0;
- e = d;
- d = c;
- c = sha1._S(30, b);
- b = a;
- a = tmp;
- }
-
- h[0] = (h[0] + a) | 0;
- h[1] = (h[1] + b) | 0;
- h[2] = (h[2] + c) | 0;
- h[3] = (h[3] + d) | 0;
- h[4] = (h[4] + e) | 0;
- }
- };
-
- /** @fileOverview Low-level AES implementation.
- *
- * This file contains a low-level implementation of AES, optimized for
- * size and for efficiency on several browsers. It is based on
- * OpenSSL's aes_core.c, a public-domain implementation by Vincent
- * Rijmen, Antoon Bosselaers and Paulo Barreto.
- *
- * An older version of this implementation is available in the public
- * domain, but this one is (c) Emily Stark, Mike Hamburg, Dan Boneh,
- * Stanford University 2008-2010 and BSD-licensed for liability
- * reasons.
- *
- * @author Emily Stark
- * @author Mike Hamburg
- * @author Dan Boneh
- */
-
- const cipher = {};
-
- /**
- * Schedule out an AES key for both encryption and decryption. This
- * is a low-level class. Use a cipher mode to do bulk encryption.
- *
- * @constructor
- * @param {Array} key The key as an array of 4, 6 or 8 words.
- */
- cipher.aes = class {
- constructor(key) {
- /**
- * The expanded S-box and inverse S-box tables. These will be computed
- * on the client so that we don't have to send them down the wire.
- *
- * There are two tables, _tables[0] is for encryption and
- * _tables[1] is for decryption.
- *
- * The first 4 sub-tables are the expanded S-box with MixColumns. The
- * last (_tables[01][4]) is the S-box itself.
- *
- * @private
- */
- const aes = this;
- aes._tables = [[[], [], [], [], []], [[], [], [], [], []]];
-
- if (!aes._tables[0][0][0]) {
- aes._precompute();
- }
-
- const sbox = aes._tables[0][4];
- const decTable = aes._tables[1];
- const keyLen = key.length;
-
- let i, encKey, decKey, rcon = 1;
-
- if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
- throw new Error("invalid aes key size");
- }
-
- aes._key = [encKey = key.slice(0), decKey = []];
-
- // schedule encryption keys
- for (i = keyLen; i < 4 * keyLen + 28; i++) {
- let tmp = encKey[i - 1];
-
- // apply sbox
- if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) {
- tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255];
-
- // shift rows and add rcon
- if (i % keyLen === 0) {
- tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24;
- rcon = rcon << 1 ^ (rcon >> 7) * 283;
- }
- }
-
- encKey[i] = encKey[i - keyLen] ^ tmp;
- }
-
- // schedule decryption keys
- for (let j = 0; i; j++, i--) {
- const tmp = encKey[j & 3 ? i : i - 4];
- if (i <= 4 || j < 4) {
- decKey[j] = tmp;
- } else {
- decKey[j] = decTable[0][sbox[tmp >>> 24]] ^
- decTable[1][sbox[tmp >> 16 & 255]] ^
- decTable[2][sbox[tmp >> 8 & 255]] ^
- decTable[3][sbox[tmp & 255]];
- }
- }
- }
- // public
- /* Something like this might appear here eventually
- name: "AES",
- blockSize: 4,
- keySizes: [4,6,8],
- */
-
- /**
- * Encrypt an array of 4 big-endian words.
- * @param {Array} data The plaintext.
- * @return {Array} The ciphertext.
- */
- encrypt(data) {
- return this._crypt(data, 0);
- }
-
- /**
- * Decrypt an array of 4 big-endian words.
- * @param {Array} data The ciphertext.
- * @return {Array} The plaintext.
- */
- decrypt(data) {
- return this._crypt(data, 1);
- }
-
- /**
- * Expand the S-box tables.
- *
- * @private
- */
- _precompute() {
- const encTable = this._tables[0];
- const decTable = this._tables[1];
- const sbox = encTable[4];
- const sboxInv = decTable[4];
- const d = [];
- const th = [];
- let xInv, x2, x4, x8;
-
- // Compute double and third tables
- for (let i = 0; i < 256; i++) {
- th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
- }
-
- for (let x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
- // Compute sbox
- let s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
- s = s >> 8 ^ s & 255 ^ 99;
- sbox[x] = s;
- sboxInv[s] = x;
-
- // Compute MixColumns
- x8 = d[x4 = d[x2 = d[x]]];
- let tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
- let tEnc = d[s] * 0x101 ^ s * 0x1010100;
-
- for (let i = 0; i < 4; i++) {
- encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
- decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
- }
- }
-
- // Compactify. Considerable speedup on Firefox.
- for (let i = 0; i < 5; i++) {
- encTable[i] = encTable[i].slice(0);
- decTable[i] = decTable[i].slice(0);
- }
- }
-
- /**
- * Encryption and decryption core.
- * @param {Array} input Four words to be encrypted or decrypted.
- * @param dir The direction, 0 for encrypt and 1 for decrypt.
- * @return {Array} The four encrypted or decrypted words.
- * @private
- */
- _crypt(input, dir) {
- if (input.length !== 4) {
- throw new Error("invalid aes block size");
- }
-
- const key = this._key[dir];
-
- const nInnerRounds = key.length / 4 - 2;
- const out = [0, 0, 0, 0];
- const table = this._tables[dir];
-
- // load up the tables
- const t0 = table[0];
- const t1 = table[1];
- const t2 = table[2];
- const t3 = table[3];
- const sbox = table[4];
-
- // state variables a,b,c,d are loaded with pre-whitened data
- let a = input[0] ^ key[0];
- let b = input[dir ? 3 : 1] ^ key[1];
- let c = input[2] ^ key[2];
- let d = input[dir ? 1 : 3] ^ key[3];
- let kIndex = 4;
- let a2, b2, c2;
-
- // Inner rounds. Cribbed from OpenSSL.
- for (let i = 0; i < nInnerRounds; i++) {
- a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex];
- b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1];
- c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2];
- d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3];
- kIndex += 4;
- a = a2; b = b2; c = c2;
- }
-
- // Last round.
- for (let i = 0; i < 4; i++) {
- out[dir ? 3 & -i : i] =
- sbox[a >>> 24] << 24 ^
- sbox[b >> 16 & 255] << 16 ^
- sbox[c >> 8 & 255] << 8 ^
- sbox[d & 255] ^
- key[kIndex++];
- a2 = a; a = b; b = c; c = d; d = a2;
- }
-
- return out;
- }
- };
-
- /**
- * Random values
- * @namespace
- */
- const random = {
- /**
- * Generate random words with pure js, cryptographically not as strong & safe as native implementation.
- * @param {TypedArray} typedArray The array to fill.
- * @return {TypedArray} The random values.
- */
- getRandomValues(typedArray) {
- const words = new Uint32Array(typedArray.buffer);
- const r = (m_w) => {
- let m_z = 0x3ade68b1;
- const mask = 0xffffffff;
- return function () {
- m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask;
- m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask;
- const result = ((((m_z << 0x10) + m_w) & mask) / 0x100000000) + .5;
- return result * (Math.random() > .5 ? 1 : -1);
- };
- };
- for (let i = 0, rcache; i < typedArray.length; i += 4) {
- const _r = r((rcache || Math.random()) * 0x100000000);
- rcache = _r() * 0x3ade67b7;
- words[i / 4] = (_r() * 0x100000000) | 0;
- }
- return typedArray;
- }
- };
-
- /** @fileOverview CTR mode implementation.
- *
- * Special thanks to Roy Nicholson for pointing out a bug in our
- * implementation.
- *
- * @author Emily Stark
- * @author Mike Hamburg
- * @author Dan Boneh
- */
-
- /** Brian Gladman's CTR Mode.
- * @constructor
- * @param {Object} _prf The aes instance to generate key.
- * @param {bitArray} _iv The iv for ctr mode, it must be 128 bits.
- */
-
- const mode = {};
-
- /**
- * Brian Gladman's CTR Mode.
- * @namespace
- */
- mode.ctrGladman = class {
- constructor(prf, iv) {
- this._prf = prf;
- this._initIv = iv;
- this._iv = iv;
- }
-
- reset() {
- this._iv = this._initIv;
- }
-
- /** Input some data to calculate.
- * @param {bitArray} data the data to process, it must be intergral multiple of 128 bits unless it's the last.
- */
- update(data) {
- return this.calculate(this._prf, data, this._iv);
- }
-
- incWord(word) {
- if (((word >> 24) & 0xff) === 0xff) { //overflow
- let b1 = (word >> 16) & 0xff;
- let b2 = (word >> 8) & 0xff;
- let b3 = word & 0xff;
-
- if (b1 === 0xff) { // overflow b1
- b1 = 0;
- if (b2 === 0xff) {
- b2 = 0;
- if (b3 === 0xff) {
- b3 = 0;
- } else {
- ++b3;
- }
- } else {
- ++b2;
- }
- } else {
- ++b1;
- }
-
- word = 0;
- word += (b1 << 16);
- word += (b2 << 8);
- word += b3;
- } else {
- word += (0x01 << 24);
- }
- return word;
- }
-
- incCounter(counter) {
- if ((counter[0] = this.incWord(counter[0])) === 0) {
- // encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8
- counter[1] = this.incWord(counter[1]);
- }
- }
-
- calculate(prf, data, iv) {
- let l;
- if (!(l = data.length)) {
- return [];
- }
- const bl = bitArray.bitLength(data);
- for (let i = 0; i < l; i += 4) {
- this.incCounter(iv);
- const e = prf.encrypt(iv);
- data[i] ^= e[0];
- data[i + 1] ^= e[1];
- data[i + 2] ^= e[2];
- data[i + 3] ^= e[3];
- }
- return bitArray.clamp(data, bl);
- }
- };
-
- const misc = {
- importKey(password) {
- return new misc.hmacSha1(codec.bytes.toBits(password));
- },
- pbkdf2(prf, salt, count, length) {
- count = count || 10000;
- if (length < 0 || count < 0) {
- throw new Error("invalid params to pbkdf2");
- }
- const byteLength = ((length >> 5) + 1) << 2;
- let u, ui, i, j, k;
- const arrayBuffer = new ArrayBuffer(byteLength);
- const out = new DataView(arrayBuffer);
- let outLength = 0;
- const b = bitArray;
- salt = codec.bytes.toBits(salt);
- for (k = 1; outLength < (byteLength || 1); k++) {
- u = ui = prf.encrypt(b.concat(salt, [k]));
- for (i = 1; i < count; i++) {
- ui = prf.encrypt(ui);
- for (j = 0; j < ui.length; j++) {
- u[j] ^= ui[j];
- }
- }
- for (i = 0; outLength < (byteLength || 1) && i < u.length; i++) {
- out.setInt32(outLength, u[i]);
- outLength += 4;
- }
- }
- return arrayBuffer.slice(0, length / 8);
- }
- };
-
- /** @fileOverview HMAC implementation.
- *
- * @author Emily Stark
- * @author Mike Hamburg
- * @author Dan Boneh
- */
-
- /** HMAC with the specified hash function.
- * @constructor
- * @param {bitArray} key the key for HMAC.
- * @param {Object} [Hash=hash.sha1] The hash function to use.
- */
- misc.hmacSha1 = class {
-
- constructor(key) {
- const hmac = this;
- const Hash = hmac._hash = hash.sha1;
- const exKey = [[], []];
- hmac._baseHash = [new Hash(), new Hash()];
- const bs = hmac._baseHash[0].blockSize / 32;
-
- if (key.length > bs) {
- key = new Hash().update(key).finalize();
- }
-
- for (let i = 0; i < bs; i++) {
- exKey[0][i] = key[i] ^ 0x36363636;
- exKey[1][i] = key[i] ^ 0x5C5C5C5C;
- }
-
- hmac._baseHash[0].update(exKey[0]);
- hmac._baseHash[1].update(exKey[1]);
- hmac._resultHash = new Hash(hmac._baseHash[0]);
- }
- reset() {
- const hmac = this;
- hmac._resultHash = new hmac._hash(hmac._baseHash[0]);
- hmac._updated = false;
- }
-
- update(data) {
- const hmac = this;
- hmac._updated = true;
- hmac._resultHash.update(data);
- }
-
- digest() {
- const hmac = this;
- const w = hmac._resultHash.finalize();
- const result = new (hmac._hash)(hmac._baseHash[1]).update(w).finalize();
-
- hmac.reset();
-
- return result;
- }
-
- encrypt(data) {
- if (!this._updated) {
- this.update(data);
- return this.digest(data);
- } else {
- throw new Error("encrypt on already updated hmac called!");
- }
- }
- };
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const GET_RANDOM_VALUES_SUPPORTED = typeof crypto != UNDEFINED_TYPE && typeof crypto.getRandomValues == FUNCTION_TYPE;
-
- const ERR_INVALID_PASSWORD = "Invalid password";
- const ERR_INVALID_SIGNATURE = "Invalid signature";
- const ERR_ABORT_CHECK_PASSWORD = "zipjs-abort-check-password";
-
- function getRandomValues(array) {
- if (GET_RANDOM_VALUES_SUPPORTED) {
- return crypto.getRandomValues(array);
- } else {
- return random.getRandomValues(array);
- }
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const BLOCK_LENGTH = 16;
- const RAW_FORMAT = "raw";
- const PBKDF2_ALGORITHM = { name: "PBKDF2" };
- const HASH_ALGORITHM = { name: "HMAC" };
- const HASH_FUNCTION = "SHA-1";
- const BASE_KEY_ALGORITHM = Object.assign({ hash: HASH_ALGORITHM }, PBKDF2_ALGORITHM);
- const DERIVED_BITS_ALGORITHM = Object.assign({ iterations: 1000, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM);
- const DERIVED_BITS_USAGE = ["deriveBits"];
- const SALT_LENGTH = [8, 12, 16];
- const KEY_LENGTH = [16, 24, 32];
- const SIGNATURE_LENGTH = 10;
- const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
- // deno-lint-ignore valid-typeof
- const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
- const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
- const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE;
- const codecBytes = codec.bytes;
- const Aes = cipher.aes;
- const CtrGladman = mode.ctrGladman;
- const HmacSha1 = misc.hmacSha1;
-
- let IMPORT_KEY_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE;
- let DERIVE_BITS_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.deriveBits == FUNCTION_TYPE;
-
- class AESDecryptionStream extends TransformStream {
-
- constructor({ password, rawPassword, signed, encryptionStrength, checkPasswordOnly }) {
- super({
- start() {
- Object.assign(this, {
- ready: new Promise(resolve => this.resolveReady = resolve),
- password: encodePassword(password, rawPassword),
- signed,
- strength: encryptionStrength - 1,
- pending: new Uint8Array()
- });
- },
- async transform(chunk, controller) {
- const aesCrypto = this;
- const {
- password,
- strength,
- resolveReady,
- ready
- } = aesCrypto;
- if (password) {
- await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] + 2));
- chunk = subarray(chunk, SALT_LENGTH[strength] + 2);
- if (checkPasswordOnly) {
- controller.error(new Error(ERR_ABORT_CHECK_PASSWORD));
- } else {
- resolveReady();
- }
- } else {
- await ready;
- }
- const output = new Uint8Array(chunk.length - SIGNATURE_LENGTH - ((chunk.length - SIGNATURE_LENGTH) % BLOCK_LENGTH));
- controller.enqueue(append(aesCrypto, chunk, output, 0, SIGNATURE_LENGTH, true));
- },
- async flush(controller) {
- const {
- signed,
- ctr,
- hmac,
- pending,
- ready
- } = this;
- if (hmac && ctr) {
- await ready;
- const chunkToDecrypt = subarray(pending, 0, pending.length - SIGNATURE_LENGTH);
- const originalSignature = subarray(pending, pending.length - SIGNATURE_LENGTH);
- let decryptedChunkArray = new Uint8Array();
- if (chunkToDecrypt.length) {
- const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
- hmac.update(encryptedChunk);
- const decryptedChunk = ctr.update(encryptedChunk);
- decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
- }
- if (signed) {
- const signature = subarray(fromBits(codecBytes, hmac.digest()), 0, SIGNATURE_LENGTH);
- for (let indexSignature = 0; indexSignature < SIGNATURE_LENGTH; indexSignature++) {
- if (signature[indexSignature] != originalSignature[indexSignature]) {
- throw new Error(ERR_INVALID_SIGNATURE);
- }
- }
- }
- controller.enqueue(decryptedChunkArray);
- }
- }
- });
- }
- }
-
- class AESEncryptionStream extends TransformStream {
-
- constructor({ password, rawPassword, encryptionStrength }) {
- // deno-lint-ignore prefer-const
- let stream;
- super({
- start() {
- Object.assign(this, {
- ready: new Promise(resolve => this.resolveReady = resolve),
- password: encodePassword(password, rawPassword),
- strength: encryptionStrength - 1,
- pending: new Uint8Array()
- });
- },
- async transform(chunk, controller) {
- const aesCrypto = this;
- const {
- password,
- strength,
- resolveReady,
- ready
- } = aesCrypto;
- let preamble = new Uint8Array();
- if (password) {
- preamble = await createEncryptionKeys(aesCrypto, strength, password);
- resolveReady();
- } else {
- await ready;
- }
- const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
- output.set(preamble, 0);
- controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
- },
- async flush(controller) {
- const {
- ctr,
- hmac,
- pending,
- ready
- } = this;
- if (hmac && ctr) {
- await ready;
- let encryptedChunkArray = new Uint8Array();
- if (pending.length) {
- const encryptedChunk = ctr.update(toBits(codecBytes, pending));
- hmac.update(encryptedChunk);
- encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
- }
- stream.signature = fromBits(codecBytes, hmac.digest()).slice(0, SIGNATURE_LENGTH);
- controller.enqueue(concat(encryptedChunkArray, stream.signature));
- }
- }
- });
- stream = this;
- }
- }
-
- function append(aesCrypto, input, output, paddingStart, paddingEnd, verifySignature) {
- const {
- ctr,
- hmac,
- pending
- } = aesCrypto;
- const inputLength = input.length - paddingEnd;
- if (pending.length) {
- input = concat(pending, input);
- output = expand(output, inputLength - (inputLength % BLOCK_LENGTH));
- }
- let offset;
- for (offset = 0; offset <= inputLength - BLOCK_LENGTH; offset += BLOCK_LENGTH) {
- const inputChunk = toBits(codecBytes, subarray(input, offset, offset + BLOCK_LENGTH));
- if (verifySignature) {
- hmac.update(inputChunk);
- }
- const outputChunk = ctr.update(inputChunk);
- if (!verifySignature) {
- hmac.update(outputChunk);
- }
- output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
- }
- aesCrypto.pending = subarray(input, offset);
- return output;
- }
-
- async function createDecryptionKeys(decrypt, strength, password, preamble) {
- const passwordVerificationKey = await createKeys$1(decrypt, strength, password, subarray(preamble, 0, SALT_LENGTH[strength]));
- const passwordVerification = subarray(preamble, SALT_LENGTH[strength]);
- if (passwordVerificationKey[0] != passwordVerification[0] || passwordVerificationKey[1] != passwordVerification[1]) {
- throw new Error(ERR_INVALID_PASSWORD);
- }
- }
-
- async function createEncryptionKeys(encrypt, strength, password) {
- const salt = getRandomValues(new Uint8Array(SALT_LENGTH[strength]));
- const passwordVerification = await createKeys$1(encrypt, strength, password, salt);
- return concat(salt, passwordVerification);
- }
-
- async function createKeys$1(aesCrypto, strength, password, salt) {
- aesCrypto.password = null;
- const baseKey = await importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
- const derivedBits = await deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, 8 * ((KEY_LENGTH[strength] * 2) + 2));
- const compositeKey = new Uint8Array(derivedBits);
- const key = toBits(codecBytes, subarray(compositeKey, 0, KEY_LENGTH[strength]));
- const authentication = toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[strength], KEY_LENGTH[strength] * 2));
- const passwordVerification = subarray(compositeKey, KEY_LENGTH[strength] * 2);
- Object.assign(aesCrypto, {
- keys: {
- key,
- authentication,
- passwordVerification
- },
- ctr: new CtrGladman(new Aes(key), Array.from(COUNTER_DEFAULT_VALUE)),
- hmac: new HmacSha1(authentication)
- });
- return passwordVerification;
- }
-
- async function importKey(format, password, algorithm, extractable, keyUsages) {
- if (IMPORT_KEY_SUPPORTED) {
- try {
- return await subtle.importKey(format, password, algorithm, extractable, keyUsages);
- } catch {
- IMPORT_KEY_SUPPORTED = false;
- return misc.importKey(password);
- }
- } else {
- return misc.importKey(password);
- }
- }
-
- async function deriveBits(algorithm, baseKey, length) {
- if (DERIVE_BITS_SUPPORTED) {
- try {
- return await subtle.deriveBits(algorithm, baseKey, length);
- } catch {
- DERIVE_BITS_SUPPORTED = false;
- return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
- }
- } else {
- return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
- }
- }
-
- function encodePassword(password, rawPassword) {
- if (rawPassword === UNDEFINED_VALUE) {
- return encodeText(password);
- } else {
- return rawPassword;
- }
- }
-
- function concat(leftArray, rightArray) {
- let array = leftArray;
- if (leftArray.length + rightArray.length) {
- array = new Uint8Array(leftArray.length + rightArray.length);
- array.set(leftArray, 0);
- array.set(rightArray, leftArray.length);
- }
- return array;
- }
-
- function expand(inputArray, length) {
- if (length && length > inputArray.length) {
- const array = inputArray;
- inputArray = new Uint8Array(length);
- inputArray.set(array, 0);
- }
- return inputArray;
- }
-
- function subarray(array, begin, end) {
- return array.subarray(begin, end);
- }
-
- function fromBits(codecBytes, chunk) {
- return codecBytes.fromBits(chunk);
- }
- function toBits(codecBytes, chunk) {
- return codecBytes.toBits(chunk);
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const HEADER_LENGTH = 12;
-
- class ZipCryptoDecryptionStream extends TransformStream {
-
- constructor({ password, passwordVerification, checkPasswordOnly }) {
- super({
- start() {
- Object.assign(this, {
- password,
- passwordVerification
- });
- createKeys(this, password);
- },
- transform(chunk, controller) {
- const zipCrypto = this;
- if (zipCrypto.password) {
- const decryptedHeader = decrypt(zipCrypto, chunk.subarray(0, HEADER_LENGTH));
- zipCrypto.password = null;
- if (decryptedHeader.at(-1) != zipCrypto.passwordVerification) {
- throw new Error(ERR_INVALID_PASSWORD);
- }
- chunk = chunk.subarray(HEADER_LENGTH);
- }
- if (checkPasswordOnly) {
- controller.error(new Error(ERR_ABORT_CHECK_PASSWORD));
- } else {
- controller.enqueue(decrypt(zipCrypto, chunk));
- }
- }
- });
- }
- }
-
- class ZipCryptoEncryptionStream extends TransformStream {
-
- constructor({ password, passwordVerification }) {
- super({
- start() {
- Object.assign(this, {
- password,
- passwordVerification
- });
- createKeys(this, password);
- },
- transform(chunk, controller) {
- const zipCrypto = this;
- let output;
- let offset;
- if (zipCrypto.password) {
- zipCrypto.password = null;
- const header = getRandomValues(new Uint8Array(HEADER_LENGTH));
- header[HEADER_LENGTH - 1] = zipCrypto.passwordVerification;
- output = new Uint8Array(chunk.length + header.length);
- output.set(encrypt(zipCrypto, header), 0);
- offset = HEADER_LENGTH;
- } else {
- output = new Uint8Array(chunk.length);
- offset = 0;
- }
- output.set(encrypt(zipCrypto, chunk), offset);
- controller.enqueue(output);
- }
- });
- }
- }
-
- function decrypt(target, input) {
- const output = new Uint8Array(input.length);
- for (let index = 0; index < input.length; index++) {
- output[index] = getByte(target) ^ input[index];
- updateKeys(target, output[index]);
- }
- return output;
- }
-
- function encrypt(target, input) {
- const output = new Uint8Array(input.length);
- for (let index = 0; index < input.length; index++) {
- output[index] = getByte(target) ^ input[index];
- updateKeys(target, input[index]);
- }
- return output;
- }
-
- function createKeys(target, password) {
- const keys = [0x12345678, 0x23456789, 0x34567890];
- Object.assign(target, {
- keys,
- crcKey0: new Crc32(keys[0]),
- crcKey2: new Crc32(keys[2])
- });
- for (let index = 0; index < password.length; index++) {
- updateKeys(target, password.charCodeAt(index));
- }
- }
-
- function updateKeys(target, byte) {
- let [key0, key1, key2] = target.keys;
- target.crcKey0.append([byte]);
- key0 = ~target.crcKey0.get();
- key1 = getInt32(Math.imul(getInt32(key1 + getInt8(key0)), 134775813) + 1);
- target.crcKey2.append([key1 >>> 24]);
- key2 = ~target.crcKey2.get();
- target.keys = [key0, key1, key2];
- }
-
- function getByte(target) {
- const temp = target.keys[2] | 2;
- return getInt8(Math.imul(temp, (temp ^ 1)) >>> 8);
- }
-
- function getInt8(number) {
- return number & 0xFF;
- }
-
- function getInt32(number) {
- return number & 0xFFFFFFFF;
- }
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
- const FORMAT_DEFLATE_RAW = "deflate-raw";
- const FORMAT_DEFLATE64_RAW = "deflate64-raw";
-
- class DeflateStream extends TransformStream {
-
- constructor(options, { chunkSize, CompressionStreamZlib, CompressionStream }) {
- super({});
- const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level } = options;
- const stream = this;
- let crc32Stream, encryptionStream;
- let readable = super.readable;
- if ((!encrypted || zipCrypto) && signed) {
- crc32Stream = new Crc32Stream();
- readable = pipeThrough(readable, crc32Stream);
- }
- if (compressed) {
- readable = pipeThroughCommpressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamZlib, CompressionStream);
- }
- if (encrypted) {
- if (zipCrypto) {
- readable = pipeThrough(readable, new ZipCryptoEncryptionStream(options));
- } else {
- encryptionStream = new AESEncryptionStream(options);
- readable = pipeThrough(readable, encryptionStream);
- }
- }
- setReadable(stream, readable, () => {
- let signature;
- if (encrypted && !zipCrypto) {
- signature = encryptionStream.signature;
- }
- if ((!encrypted || zipCrypto) && signed) {
- signature = new DataView(crc32Stream.value.buffer).getUint32(0);
- }
- stream.signature = signature;
- });
- }
- }
-
- class InflateStream extends TransformStream {
-
- constructor(options, { chunkSize, DecompressionStreamZlib, DecompressionStream }) {
- super({});
- const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream, deflate64 } = options;
- let crc32Stream, decryptionStream;
- let readable = super.readable;
- if (encrypted) {
- if (zipCrypto) {
- readable = pipeThrough(readable, new ZipCryptoDecryptionStream(options));
- } else {
- decryptionStream = new AESDecryptionStream(options);
- readable = pipeThrough(readable, decryptionStream);
- }
- }
- if (compressed) {
- readable = pipeThroughCommpressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamZlib, DecompressionStream);
- }
- if ((!encrypted || zipCrypto) && signed) {
- crc32Stream = new Crc32Stream();
- readable = pipeThrough(readable, crc32Stream);
- }
- setReadable(this, readable, () => {
- if ((!encrypted || zipCrypto) && signed) {
- const dataViewSignature = new DataView(crc32Stream.value.buffer);
- if (signature != dataViewSignature.getUint32(0, false)) {
- throw new Error(ERR_INVALID_SIGNATURE);
- }
- }
- });
- }
- }
-
- function setReadable(stream, readable, flush) {
- readable = pipeThrough(readable, new TransformStream({ flush }));
- Object.defineProperty(stream, "readable", {
- get() {
- return readable;
- }
- });
- }
-
- function pipeThroughCommpressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamZlib, CompressionStream) {
- const Stream = useCompressionStream && CompressionStreamNative ? CompressionStreamNative : CompressionStreamZlib || CompressionStream;
- const format = options.deflate64 ? FORMAT_DEFLATE64_RAW : FORMAT_DEFLATE_RAW;
- try {
- readable = pipeThrough(readable, new Stream(format, options));
- } catch (error) {
- if (useCompressionStream) {
- if (CompressionStreamZlib) {
- readable = pipeThrough(readable, new CompressionStreamZlib(format, options));
- } else if (CompressionStream) {
- readable = pipeThrough(readable, new CompressionStream(format, options));
- } else {
- throw error;
- }
- } else {
- throw error;
- }
- }
- return readable;
- }
-
- function pipeThrough(readable, transformStream) {
- return readable.pipeThrough(transformStream);
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const MESSAGE_EVENT_TYPE = "message";
- const MESSAGE_START = "start";
- const MESSAGE_PULL = "pull";
- const MESSAGE_DATA = "data";
- const MESSAGE_ACK_DATA = "ack";
- const MESSAGE_CLOSE = "close";
- const CODEC_DEFLATE = "deflate";
- const CODEC_INFLATE = "inflate";
-
- class CodecStream extends TransformStream {
-
- constructor(options, config) {
- super({});
- const codec = this;
- const { codecType } = options;
- let Stream;
- if (codecType.startsWith(CODEC_DEFLATE)) {
- Stream = DeflateStream;
- } else if (codecType.startsWith(CODEC_INFLATE)) {
- Stream = InflateStream;
- }
- codec.outputSize = 0;
- let inputSize = 0;
- const stream = new Stream(options, config);
- const readable = super.readable;
- const inputSizeStream = new TransformStream({
- transform(chunk, controller) {
- if (chunk && chunk.length) {
- inputSize += chunk.length;
- controller.enqueue(chunk);
- }
- },
- flush() {
- Object.assign(codec, {
- inputSize
- });
- }
- });
- const outputSizeStream = new TransformStream({
- transform(chunk, controller) {
- if (chunk && chunk.length) {
- controller.enqueue(chunk);
- codec.outputSize += chunk.length;
- if (options.outputSize !== UNDEFINED_VALUE && codec.outputSize > options.outputSize) {
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
- }
- }
- },
- flush() {
- const { signature } = stream;
- Object.assign(codec, {
- signature,
- inputSize
- });
- }
- });
- Object.defineProperty(codec, "readable", {
- get() {
- return readable.pipeThrough(inputSizeStream).pipeThrough(stream).pipeThrough(outputSizeStream);
- }
- });
- }
- }
-
- class ChunkStream extends TransformStream {
-
- constructor(chunkSize) {
- let pendingChunk;
- super({
- transform,
- flush(controller) {
- if (pendingChunk && pendingChunk.length) {
- controller.enqueue(pendingChunk);
- }
- }
- });
-
- function transform(chunk, controller) {
- if (pendingChunk) {
- const newChunk = new Uint8Array(pendingChunk.length + chunk.length);
- newChunk.set(pendingChunk);
- newChunk.set(chunk, pendingChunk.length);
- chunk = newChunk;
- pendingChunk = null;
- }
- if (chunk.length > chunkSize) {
- controller.enqueue(chunk.slice(0, chunkSize));
- transform(chunk.slice(chunkSize), controller);
- } else {
- pendingChunk = chunk;
- }
- }
- }
- }
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const MODULE_WORKER_OPTIONS = { type: "module" };
-
- let webWorkerSupported, webWorkerURI, webWorkerOptions;
- let transferStreamsSupported = true;
- try {
- transferStreamsSupported = typeof structuredClone == FUNCTION_TYPE && structuredClone(new DOMException("", "AbortError")).code !== UNDEFINED_VALUE;
- } catch {
- // ignored
- }
- let initModule = () => { };
-
- class CodecWorker {
-
- constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI }, onTaskFinished) {
- const { signal } = streamOptions;
- Object.assign(workerData, {
- busy: true,
- readable: readable
- .pipeThrough(new ChunkStream(config.chunkSize))
- .pipeThrough(new ProgressWatcherStream(streamOptions), { signal }),
- writable,
- options: Object.assign({}, options),
- workerURI,
- transferStreams,
- terminate() {
- return new Promise(resolve => {
- const { worker, busy } = workerData;
- if (worker) {
- if (busy) {
- workerData.resolveTerminated = resolve;
- } else {
- worker.terminate();
- resolve();
- }
- workerData.interface = null;
- } else {
- resolve();
- }
- });
- },
- onTaskFinished() {
- const { resolveTerminated } = workerData;
- if (resolveTerminated) {
- workerData.resolveTerminated = null;
- workerData.terminated = true;
- workerData.worker.terminate();
- resolveTerminated();
- }
- workerData.busy = false;
- onTaskFinished(workerData);
- }
- });
- if (webWorkerSupported === UNDEFINED_VALUE) {
- // deno-lint-ignore valid-typeof
- webWorkerSupported = typeof Worker != UNDEFINED_TYPE;
- }
- return (useWebWorkers && webWorkerSupported ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
- }
- }
-
- class ProgressWatcherStream extends TransformStream {
-
- constructor({ onstart, onprogress, size, onend }) {
- let chunkOffset = 0;
- super({
- async start() {
- if (onstart) {
- await callHandler(onstart, size);
- }
- },
- async transform(chunk, controller) {
- chunkOffset += chunk.length;
- if (onprogress) {
- await callHandler(onprogress, chunkOffset, size);
- }
- controller.enqueue(chunk);
- },
- async flush() {
- if (onend) {
- await callHandler(onend, chunkOffset);
- }
- }
- });
- }
- }
-
- async function callHandler(handler, ...parameters) {
- try {
- await handler(...parameters);
- } catch {
- // ignored
- }
- }
-
- function createWorkerInterface(workerData, config) {
- return {
- run: () => runWorker$1(workerData, config)
- };
- }
-
- function createWebWorkerInterface(workerData, config) {
- const { baseURI, chunkSize } = config;
- let { wasmURI } = config;
-
- if (!workerData.interface) {
- // deno-lint-ignore valid-typeof
- if (typeof wasmURI == FUNCTION_TYPE) {
- wasmURI = wasmURI();
- }
- let worker;
- try {
- worker = getWebWorker(workerData.workerURI, baseURI, workerData);
- } catch {
- webWorkerSupported = false;
- return createWorkerInterface(workerData, config);
- }
- Object.assign(workerData, {
- worker,
- interface: {
- run: () => runWebWorker(workerData, { chunkSize, wasmURI, baseURI })
- }
- });
- }
- return workerData.interface;
- }
-
- async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
- let codecStream;
- try {
- if (!options.useCompressionStream) {
- try {
- await initModule(config);
- } catch {
- options.useCompressionStream = true;
- }
- }
- codecStream = new CodecStream(options, config);
- await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true });
- const {
- signature,
- inputSize,
- outputSize
- } = codecStream;
- return {
- signature,
- inputSize,
- outputSize
- };
- } catch (error) {
- if (codecStream) {
- error.outputSize = codecStream.outputSize;
- }
- throw error;
- } finally {
- onTaskFinished();
- }
- }
-
- async function runWebWorker(workerData, config) {
- let resolveResult, rejectResult;
- const result = new Promise((resolve, reject) => {
- resolveResult = resolve;
- rejectResult = reject;
- });
- Object.assign(workerData, {
- reader: null,
- writer: null,
- resolveResult,
- rejectResult,
- result
- });
- const { readable, options } = workerData;
- const { writable, closed } = watchClosedStream(workerData.writable);
- const streamsTransferred = sendMessage({
- type: MESSAGE_START,
- options,
- config,
- readable,
- writable
- }, workerData);
- if (!streamsTransferred) {
- Object.assign(workerData, {
- reader: readable.getReader(),
- writer: writable.getWriter()
- });
- }
- const resultValue = await result;
- if (!streamsTransferred) {
- await writable.getWriter().close();
- }
- await closed;
- return resultValue;
- }
-
- function watchClosedStream(writableSource) {
- const { writable, readable } = new TransformStream();
- const closed = readable.pipeTo(writableSource, { preventClose: true });
- return { writable, closed };
- }
-
- function getWebWorker(url, baseURI, workerData, isModuleType, useBlobURI = true) {
- let worker, resolvedURI, resolvedOptions;
- if (webWorkerURI === UNDEFINED_VALUE) {
- // deno-lint-ignore valid-typeof
- const isFunctionURI = typeof url == FUNCTION_TYPE;
- if (isFunctionURI) {
- resolvedURI = url(useBlobURI);
- } else {
- resolvedURI = url;
- }
- const isDataURI = resolvedURI.startsWith("data:");
- const isBlobURI = resolvedURI.startsWith("blob:");
- if (isDataURI || isBlobURI) {
- if (isModuleType === UNDEFINED_VALUE) {
- isModuleType = false;
- }
- if (isModuleType) {
- resolvedOptions = MODULE_WORKER_OPTIONS;
- }
- try {
- worker = new Worker(resolvedURI, resolvedOptions);
- } catch (error) {
- if (isBlobURI) {
- try {
- URL.revokeObjectURL(resolvedURI);
- } catch {
- // ignored
- }
- }
- if (isFunctionURI && isBlobURI) {
- return getWebWorker(url, baseURI, workerData, isModuleType, false);
- } else if (!isModuleType) {
- return getWebWorker(url, baseURI, workerData, true, false);
- } else {
- throw error;
- }
- }
- } else {
- if (isModuleType === UNDEFINED_VALUE) {
- isModuleType = true;
- }
- if (isModuleType) {
- resolvedOptions = MODULE_WORKER_OPTIONS;
- }
- try {
- resolvedURI = new URL(resolvedURI, baseURI);
- } catch {
- // ignored
- }
- try {
- worker = new Worker(resolvedURI, resolvedOptions);
- } catch (error) {
- if (!isModuleType) {
- return getWebWorker(url, baseURI, workerData, false, useBlobURI);
- } else {
- throw error;
- }
- }
- }
- webWorkerURI = resolvedURI;
- webWorkerOptions = resolvedOptions;
- } else {
- worker = new Worker(webWorkerURI, webWorkerOptions);
- }
- worker.addEventListener(MESSAGE_EVENT_TYPE, event => onMessage(event, workerData));
- return worker;
- }
-
- function sendMessage(message, { worker, writer, onTaskFinished, transferStreams }) {
- try {
- const { value, readable, writable } = message;
- const transferables = [];
- if (value) {
- message.value = value;
- transferables.push(message.value.buffer);
- }
- if (transferStreams && transferStreamsSupported) {
- if (readable) {
- transferables.push(readable);
- }
- if (writable) {
- transferables.push(writable);
- }
- } else {
- message.readable = message.writable = null;
- }
- if (transferables.length) {
- try {
- worker.postMessage(message, transferables);
- return true;
- } catch {
- transferStreamsSupported = false;
- message.readable = message.writable = null;
- worker.postMessage(message);
- }
- } else {
- worker.postMessage(message);
- }
- } catch (error) {
- if (writer) {
- writer.releaseLock();
- }
- onTaskFinished();
- throw error;
- }
- }
-
- async function onMessage({ data }, workerData) {
- const { type, value, messageId, result, error } = data;
- const { reader, writer, resolveResult, rejectResult, onTaskFinished } = workerData;
- try {
- if (error) {
- const { message, stack, code, name, outputSize } = error;
- const responseError = new Error(message);
- Object.assign(responseError, { stack, code, name, outputSize });
- close(responseError);
- } else {
- if (type == MESSAGE_PULL) {
- const { value, done } = await reader.read();
- sendMessage({ type: MESSAGE_DATA, value, done, messageId }, workerData);
- }
- if (type == MESSAGE_DATA) {
- await writer.ready;
- await writer.write(new Uint8Array(value));
- sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
- }
- if (type == MESSAGE_CLOSE) {
- close(null, result);
- }
- }
- } catch (error) {
- sendMessage({ type: MESSAGE_CLOSE, messageId }, workerData);
- close(error);
- }
-
- function close(error, result) {
- if (error) {
- rejectResult(error);
- } else {
- resolveResult(result);
- }
- if (writer) {
- writer.releaseLock();
- }
- onTaskFinished();
- }
- }
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- let pool = [];
- const pendingRequests = [];
-
- let indexWorker = 0;
-
- async function runWorker(stream, workerOptions) {
- const { options, config } = workerOptions;
- const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options;
- const { workerURI, maxWorkers } = config;
- workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
- const streamCopy = !compressed && !signed && !encrypted && !workerOptions.transferStreams;
- workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
- workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
- options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
- return (await getWorker()).run();
-
- // deno-lint-ignore require-await
- async function getWorker() {
- const workerData = pool.find(workerData => !workerData.busy);
- if (workerData) {
- clearTerminateTimeout(workerData);
- return new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
- } else if (pool.length < maxWorkers) {
- const workerData = { indexWorker };
- indexWorker++;
- pool.push(workerData);
- return new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
- } else {
- return new Promise(resolve => pendingRequests.push({ resolve, stream, workerOptions }));
- }
- }
-
- function onTaskFinished(workerData) {
- if (pendingRequests.length) {
- const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
- resolve(new CodecWorker(workerData, stream, workerOptions, onTaskFinished));
- } else if (workerData.worker) {
- clearTerminateTimeout(workerData);
- terminateWorker(workerData, workerOptions);
- } else {
- pool = pool.filter(data => data != workerData);
- }
- }
- }
-
- function terminateWorker(workerData, workerOptions) {
- const { config } = workerOptions;
- const { terminateWorkerTimeout } = config;
- if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
- if (workerData.terminated) {
- workerData.terminated = false;
- } else {
- workerData.terminateTimeout = setTimeout(async () => {
- pool = pool.filter(data => data != workerData);
- try {
- await workerData.terminate();
- } catch {
- // ignored
- }
- }, terminateWorkerTimeout);
- }
- }
- }
-
- function clearTerminateTimeout(workerData) {
- const { terminateTimeout } = workerData;
- if (terminateTimeout) {
- clearTimeout(terminateTimeout);
- workerData.terminateTimeout = null;
- }
- }
-
- async function terminateWorkers() {
- await Promise.allSettled(pool.map(workerData => {
- clearTerminateTimeout(workerData);
- return workerData.terminate();
- }));
- }
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const ERR_HTTP_STATUS = "HTTP error ";
- const ERR_HTTP_RANGE = "HTTP Range not supported";
- const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
- const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
-
- const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
- const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
- const HTTP_HEADER_CONTENT_RANGE = "Content-Range";
- const HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges";
- const HTTP_HEADER_RANGE = "Range";
- const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
- const HTTP_METHOD_HEAD = "HEAD";
- const HTTP_METHOD_GET = "GET";
- const HTTP_RANGE_UNIT = "bytes";
- const DEFAULT_CHUNK_SIZE = 64 * 1024;
- const DEFAULT_BUFFER_SIZE = 256 * 1024;
-
- const PROPERTY_NAME_WRITABLE = "writable";
-
- class Stream {
-
- constructor() {
- this.size = 0;
- }
-
- init() {
- this.initialized = true;
- }
- }
-
- class Reader extends Stream {
-
- get readable() {
- const reader = this;
- const { chunkSize = DEFAULT_CHUNK_SIZE } = reader;
- const readable = new ReadableStream({
- start() {
- this.chunkOffset = 0;
- },
- async pull(controller) {
- const { offset = 0, size, diskNumberStart } = readable;
- const { chunkOffset } = this;
- const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
- const data = await readUint8Array(reader, offset + chunkOffset, dataSize, diskNumberStart);
- controller.enqueue(data);
- if ((chunkOffset + chunkSize > size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
- controller.close();
- } else {
- this.chunkOffset += chunkSize;
- }
- }
- });
- return readable;
- }
- }
-
- class Writer extends Stream {
-
- constructor() {
- super();
- const writer = this;
- const writable = new WritableStream({
- write(chunk) {
- if (!writer.initialized) {
- throw new Error(ERR_WRITER_NOT_INITIALIZED);
- }
- return writer.writeUint8Array(chunk);
- }
- });
- Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
- get() {
- return writable;
- }
- });
- }
-
- writeUint8Array() {
- // abstract
- }
- }
-
- class Data64URIReader extends Reader {
-
- constructor(dataURI) {
- super();
- let dataEnd = dataURI.length;
- while (dataURI.charAt(dataEnd - 1) == "=") {
- dataEnd--;
- }
- const dataStart = dataURI.indexOf(",") + 1;
- Object.assign(this, {
- dataURI,
- dataStart,
- size: Math.floor((dataEnd - dataStart) * 0.75)
- });
- }
-
- readUint8Array(offset, length) {
- const {
- dataStart,
- dataURI
- } = this;
- const dataArray = new Uint8Array(length);
- const start = Math.floor(offset / 3) * 4;
- const bytes = atob(dataURI.substring(start + dataStart, Math.ceil((offset + length) / 3) * 4 + dataStart));
- const delta = offset - Math.floor(start / 4) * 3;
- let effectiveLength = 0;
- for (let indexByte = delta; indexByte < delta + length && indexByte < bytes.length; indexByte++) {
- dataArray[indexByte - delta] = bytes.charCodeAt(indexByte);
- effectiveLength++;
- }
- if (effectiveLength < dataArray.length) {
- return dataArray.subarray(0, effectiveLength);
- } else {
- return dataArray;
- }
- }
- }
-
- class Data64URIWriter extends Writer {
-
- constructor(contentType) {
- super();
- Object.assign(this, {
- data: "data:" + (contentType || "") + ";base64,",
- pending: []
- });
- }
-
- writeUint8Array(array) {
- const writer = this;
- let indexArray = 0;
- let dataString = writer.pending;
- const delta = writer.pending.length;
- writer.pending = "";
- for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
- dataString += String.fromCharCode(array[indexArray]);
- }
- for (; indexArray < array.length; indexArray++) {
- writer.pending += String.fromCharCode(array[indexArray]);
- }
- if (dataString.length) {
- if (dataString.length > 2) {
- writer.data += btoa(dataString);
- } else {
- writer.pending += dataString;
- }
- }
- }
-
- getData() {
- return this.data + btoa(this.pending);
- }
- }
-
- class BlobReader extends Reader {
-
- constructor(blob) {
- super();
- Object.assign(this, {
- blob,
- size: blob.size
- });
- }
-
- async readUint8Array(offset, length) {
- const reader = this;
- const offsetEnd = offset + length;
- const blob = offset || offsetEnd < reader.size ? reader.blob.slice(offset, offsetEnd) : reader.blob;
- let arrayBuffer = await blob.arrayBuffer();
- if (arrayBuffer.byteLength > length) {
- arrayBuffer = arrayBuffer.slice(offset, offsetEnd);
- }
- return new Uint8Array(arrayBuffer);
- }
- }
-
- class BlobWriter extends Stream {
-
- constructor(contentType) {
- super();
- const writer = this;
- const transformStream = new TransformStream();
- const headers = [];
- if (contentType) {
- headers.push([HTTP_HEADER_CONTENT_TYPE, contentType]);
- }
- Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
- get() {
- return transformStream.writable;
- }
- });
- writer.blob = new Response(transformStream.readable, { headers }).blob();
- }
-
- getData() {
- return this.blob;
- }
- }
-
- class TextReader extends BlobReader {
-
- constructor(text) {
- super(new Blob([text], { type: CONTENT_TYPE_TEXT_PLAIN }));
- }
- }
-
- class TextWriter extends BlobWriter {
-
- constructor(encoding) {
- super(encoding);
- Object.assign(this, {
- encoding,
- utf8: !encoding || encoding.toLowerCase() == "utf-8"
- });
- }
-
- async getData() {
- const {
- encoding,
- utf8
- } = this;
- const blob = await super.getData();
- if (blob.text && utf8) {
- return blob.text();
- } else {
- const reader = new FileReader();
- return new Promise((resolve, reject) => {
- Object.assign(reader, {
- onload: ({ target }) => resolve(target.result),
- onerror: () => reject(reader.error)
- });
- reader.readAsText(blob, encoding);
- });
- }
- }
- }
-
- class FetchReader extends Reader {
-
- constructor(url, options) {
- super();
- createHttpReader(this, url, options);
- }
-
- async init() {
- await initHttpReader(this, sendFetchRequest, getFetchRequestData);
- super.init();
- }
-
- readUint8Array(index, length) {
- return readUint8ArrayHttpReader(this, index, length, sendFetchRequest, getFetchRequestData);
- }
- }
-
- class XHRReader extends Reader {
-
- constructor(url, options) {
- super();
- createHttpReader(this, url, options);
- }
-
- async init() {
- await initHttpReader(this, sendXMLHttpRequest, getXMLHttpRequestData);
- super.init();
- }
-
- readUint8Array(index, length) {
- return readUint8ArrayHttpReader(this, index, length, sendXMLHttpRequest, getXMLHttpRequestData);
- }
- }
-
- function createHttpReader(httpReader, url, options) {
- const {
- preventHeadRequest,
- useRangeHeader,
- forceRangeRequests,
- combineSizeEocd
- } = options;
- options = Object.assign({}, options);
- delete options.preventHeadRequest;
- delete options.useRangeHeader;
- delete options.forceRangeRequests;
- delete options.combineSizeEocd;
- delete options.useXHR;
- Object.assign(httpReader, {
- url,
- options,
- preventHeadRequest,
- useRangeHeader,
- forceRangeRequests,
- combineSizeEocd
- });
- }
-
- async function initHttpReader(httpReader, sendRequest, getRequestData) {
- const {
- url,
- preventHeadRequest,
- useRangeHeader,
- forceRangeRequests,
- combineSizeEocd
- } = httpReader;
- if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == "undefined" || preventHeadRequest)) {
- const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -END_OF_CENTRAL_DIR_LENGTH : undefined));
- const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
- if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
- throw new Error(ERR_HTTP_RANGE);
- } else {
- if (combineSizeEocd) {
- httpReader.eocdCache = new Uint8Array(await response.arrayBuffer());
- }
- let contentSize;
- const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
- if (contentRangeHeader) {
- const splitHeader = contentRangeHeader.trim().split(/\s*\/\s*/);
- if (splitHeader.length) {
- const headerValue = splitHeader[1];
- if (headerValue && headerValue != "*") {
- contentSize = Number(headerValue);
- }
- }
- }
- if (contentSize === UNDEFINED_VALUE) {
- await getContentLength(httpReader, sendRequest, getRequestData);
- } else {
- httpReader.size = contentSize;
- }
- }
- } else {
- await getContentLength(httpReader, sendRequest, getRequestData);
- }
- }
-
- async function readUint8ArrayHttpReader(httpReader, index, length, sendRequest, getRequestData) {
- const {
- useRangeHeader,
- forceRangeRequests,
- eocdCache,
- size,
- options
- } = httpReader;
- if (useRangeHeader || forceRangeRequests) {
- if (eocdCache && index == size - END_OF_CENTRAL_DIR_LENGTH && length == END_OF_CENTRAL_DIR_LENGTH) {
- return eocdCache;
- }
- if (index >= size || length === 0) {
- return new Uint8Array();
- } else {
- if (index + length > size) {
- length = size - index;
- }
- const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
- if (response.status != 206) {
- throw new Error(ERR_HTTP_RANGE);
- }
- return new Uint8Array(await response.arrayBuffer());
- }
- } else {
- const { data } = httpReader;
- if (!data) {
- await getRequestData(httpReader, options);
- }
- return new Uint8Array(httpReader.data.subarray(index, index + length));
- }
- }
-
- function getRangeHeaders(httpReader, index = 0, length = 1) {
- return Object.assign({}, getHeaders(httpReader), { [HTTP_HEADER_RANGE]: HTTP_RANGE_UNIT + "=" + (index < 0 ? index : index + "-" + (index + length - 1)) });
- }
-
- function getHeaders({ options }) {
- const { headers } = options;
- if (headers) {
- if (Symbol.iterator in headers) {
- return Object.fromEntries(headers);
- } else {
- return headers;
- }
- }
- }
-
- async function getFetchRequestData(httpReader) {
- await getRequestData(httpReader, sendFetchRequest);
- }
-
- async function getXMLHttpRequestData(httpReader) {
- await getRequestData(httpReader, sendXMLHttpRequest);
- }
-
- async function getRequestData(httpReader, sendRequest) {
- const response = await sendRequest(HTTP_METHOD_GET, httpReader, getHeaders(httpReader));
- httpReader.data = new Uint8Array(await response.arrayBuffer());
- if (!httpReader.size) {
- httpReader.size = httpReader.data.length;
- }
- }
-
- async function getContentLength(httpReader, sendRequest, getRequestData) {
- if (httpReader.preventHeadRequest) {
- await getRequestData(httpReader, httpReader.options);
- } else {
- const response = await sendRequest(HTTP_METHOD_HEAD, httpReader, getHeaders(httpReader));
- const contentLength = response.headers.get(HTTP_HEADER_CONTENT_LENGTH);
- if (contentLength) {
- httpReader.size = Number(contentLength);
- } else {
- await getRequestData(httpReader, httpReader.options);
- }
- }
- }
-
- async function sendFetchRequest(method, { options, url }, headers) {
- const response = await fetch(url, Object.assign({}, options, { method, headers }));
- if (response.status < 400) {
- return response;
- } else {
- throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
- }
- }
-
- function sendXMLHttpRequest(method, { url }, headers) {
- return new Promise((resolve, reject) => {
- const request = new XMLHttpRequest();
- request.addEventListener("load", () => {
- if (request.status < 400) {
- const headers = [];
- request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
- const splitHeader = header.trim().split(/\s*:\s*/);
- splitHeader[0] = splitHeader[0].trim().replace(/^[a-z]|-[a-z]/g, value => value.toUpperCase());
- headers.push(splitHeader);
- });
- resolve({
- status: request.status,
- arrayBuffer: () => request.response,
- headers: new Map(headers)
- });
- } else {
- reject(request.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (request.statusText || request.status)));
- }
- }, false);
- request.addEventListener("error", event => reject(event.detail ? event.detail.error : new Error("Network error")), false);
- request.open(method, url);
- if (headers) {
- for (const entry of Object.entries(headers)) {
- request.setRequestHeader(entry[0], entry[1]);
- }
- }
- request.responseType = "arraybuffer";
- request.send();
- });
- }
-
- class HttpReader extends Reader {
-
- constructor(url, options = {}) {
- super();
- Object.assign(this, {
- url,
- reader: options.useXHR ? new XHRReader(url, options) : new FetchReader(url, options)
- });
- }
-
- set size(value) {
- // ignored
- }
-
- get size() {
- return this.reader.size;
- }
-
- async init() {
- await this.reader.init();
- super.init();
- }
-
- readUint8Array(index, length) {
- return this.reader.readUint8Array(index, length);
- }
- }
-
- class HttpRangeReader extends HttpReader {
-
- constructor(url, options = {}) {
- options.useRangeHeader = true;
- super(url, options);
- }
- }
-
-
- class Uint8ArrayReader extends Reader {
-
- constructor(array) {
- super();
- array = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
- Object.assign(this, {
- array,
- size: array.length
- });
- }
-
- readUint8Array(index, length) {
- return this.array.slice(index, index + length);
- }
- }
-
- class Uint8ArrayWriter extends Writer {
-
- constructor(defaultBufferSize) {
- super();
- this.defaultBufferSize = defaultBufferSize || DEFAULT_BUFFER_SIZE;
- }
-
- init(initSize = 0) {
- Object.assign(this, {
- offset: 0,
- array: new Uint8Array(initSize > 0 ? initSize : this.defaultBufferSize)
- });
- super.init();
- }
-
- writeUint8Array(array) {
- const writer = this;
- const requiredLength = writer.offset + array.length;
- if (requiredLength > writer.array.length) {
- let newLength = writer.array.length ? writer.array.length * 2 : writer.defaultBufferSize;
- while (newLength < requiredLength) {
- newLength *= 2;
- }
- const previousArray = writer.array;
- writer.array = new Uint8Array(newLength);
- writer.array.set(previousArray);
- }
- writer.array.set(array, writer.offset);
- writer.offset += array.length;
- }
-
- getData() {
- if (this.offset === this.array.length) {
- return this.array;
- } else {
- return this.array.slice(0, this.offset);
- }
- }
- }
-
- class SplitDataReader extends Reader {
-
- constructor(readers) {
- super();
- this.readers = readers;
- }
-
- async init() {
- const reader = this;
- const { readers } = reader;
- reader.lastDiskNumber = 0;
- reader.lastDiskOffset = 0;
- await Promise.all(readers.map(async (diskReader, indexDiskReader) => {
- await diskReader.init();
- if (indexDiskReader != readers.length - 1) {
- reader.lastDiskOffset += diskReader.size;
- }
- reader.size += diskReader.size;
- }));
- super.init();
- }
-
- async readUint8Array(offset, length, diskNumber = 0) {
- const reader = this;
- const { readers } = this;
- let result;
- let currentDiskNumber = diskNumber;
- if (currentDiskNumber == -1) {
- currentDiskNumber = readers.length - 1;
- }
- let currentReaderOffset = offset;
- while (readers[currentDiskNumber] && currentReaderOffset >= readers[currentDiskNumber].size) {
- currentReaderOffset -= readers[currentDiskNumber].size;
- currentDiskNumber++;
- }
- const currentReader = readers[currentDiskNumber];
- if (currentReader) {
- const currentReaderSize = currentReader.size;
- if (currentReaderOffset + length <= currentReaderSize) {
- result = await readUint8Array(currentReader, currentReaderOffset, length);
- } else {
- const chunkLength = currentReaderSize - currentReaderOffset;
- result = new Uint8Array(length);
- const firstPart = await readUint8Array(currentReader, currentReaderOffset, chunkLength);
- result.set(firstPart, 0);
- const secondPart = await reader.readUint8Array(offset + chunkLength, length - chunkLength, diskNumber);
- result.set(secondPart, chunkLength);
- if (firstPart.length + secondPart.length < length) {
- result = result.subarray(0, firstPart.length + secondPart.length);
- }
- }
- } else {
- result = new Uint8Array();
- }
- reader.lastDiskNumber = Math.max(currentDiskNumber, reader.lastDiskNumber);
- return result;
- }
- }
-
- class SplitDataWriter extends Stream {
-
- constructor(writerGenerator, maxSize = 4294967295) {
- super();
- const writer = this;
- Object.assign(writer, {
- diskNumber: 0,
- diskOffset: 0,
- size: 0,
- maxSize,
- availableSize: maxSize
- });
- let diskSourceWriter, diskWritable, diskWriter;
- const writable = new WritableStream({
- async write(chunk) {
- const { availableSize } = writer;
- if (!diskWriter) {
- const { value, done } = await writerGenerator.next();
- if (done && !value) {
- throw new Error(ERR_ITERATOR_COMPLETED_TOO_SOON);
- } else {
- diskSourceWriter = value;
- diskSourceWriter.size = 0;
- if (diskSourceWriter.maxSize) {
- writer.maxSize = diskSourceWriter.maxSize;
- }
- writer.availableSize = writer.maxSize;
- await initStream(diskSourceWriter);
- diskWritable = value.writable;
- diskWriter = diskWritable.getWriter();
- }
- await this.write(chunk);
- } else if (chunk.length >= availableSize) {
- await writeChunk(chunk.subarray(0, availableSize));
- await closeDisk();
- writer.diskOffset += diskSourceWriter.size;
- writer.diskNumber++;
- diskWriter = null;
- await this.write(chunk.subarray(availableSize));
- } else {
- await writeChunk(chunk);
- }
- },
- async close() {
- await diskWriter.ready;
- await closeDisk();
- }
- });
- Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
- get() {
- return writable;
- }
- });
-
- async function writeChunk(chunk) {
- const chunkLength = chunk.length;
- if (chunkLength) {
- await diskWriter.ready;
- await diskWriter.write(chunk);
- diskSourceWriter.size += chunkLength;
- writer.size += chunkLength;
- writer.availableSize -= chunkLength;
- }
- }
-
- async function closeDisk() {
- await diskWriter.close();
- }
- }
- }
-
- class GenericReader {
-
- constructor(reader) {
- if (Array.isArray(reader)) {
- reader = new SplitDataReader(reader);
- }
- if (reader instanceof ReadableStream) {
- reader = {
- readable: reader
- };
- }
- return reader;
- }
- }
-
- class GenericWriter {
-
- constructor(writer) {
- if (writer.writable === UNDEFINED_VALUE && typeof writer.next == FUNCTION_TYPE) {
- writer = new SplitDataWriter(writer);
- }
- if (writer instanceof WritableStream) {
- writer = {
- writable: writer
- };
- }
- if (writer.size === UNDEFINED_VALUE) {
- writer.size = 0;
- }
- if (!(writer instanceof SplitDataWriter)) {
- Object.assign(writer, {
- diskNumber: 0,
- diskOffset: 0,
- availableSize: INFINITY_VALUE,
- maxSize: INFINITY_VALUE
- });
- }
- return writer;
- }
- }
-
- function isHttpFamily(url) {
- const { baseURI } = getConfiguration();
- const { protocol } = new URL(url, baseURI);
- return protocol == "http:" || protocol == "https:";
- }
-
- async function initStream(stream, initSize) {
- if (stream.init && !stream.initialized) {
- await stream.init(initSize);
- } else {
- return Promise.resolve();
- }
- }
-
- function readUint8Array(reader, offset, size, diskNumber) {
- return reader.readUint8Array(offset, size, diskNumber);
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- /* global TextDecoder */
-
- const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
- const VALID_CP437 = CP437.length == 256;
-
- function decodeCP437(stringValue) {
- if (VALID_CP437) {
- let result = "";
- for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
- result += CP437[stringValue[indexCharacter]];
- }
- return result;
- } else {
- return new TextDecoder().decode(stringValue);
- }
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- function decodeText(value, encoding) {
- if (encoding && encoding.trim().toLowerCase() == "cp437") {
- return decodeCP437(value);
- } else {
- return new TextDecoder(encoding).decode(value);
- }
- }
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- const PROPERTY_NAME_FILENAME = "filename";
- const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
- const PROPERTY_NAME_COMMENT = "comment";
- const PROPERTY_NAME_RAW_COMMENT = "rawComment";
- const PROPERTY_NAME_UNCOMPRESSED_SIZE = "uncompressedSize";
- const PROPERTY_NAME_COMPRESSED_SIZE = "compressedSize";
- const PROPERTY_NAME_OFFSET = "offset";
- const PROPERTY_NAME_DISK_NUMBER_START = "diskNumberStart";
- const PROPERTY_NAME_LAST_MODIFICATION_DATE = "lastModDate";
- const PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE = "rawLastModDate";
- const PROPERTY_NAME_LAST_ACCESS_DATE = "lastAccessDate";
- const PROPERTY_NAME_RAW_LAST_ACCESS_DATE = "rawLastAccessDate";
- const PROPERTY_NAME_CREATION_DATE = "creationDate";
- const PROPERTY_NAME_RAW_CREATION_DATE = "rawCreationDate";
- const PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES = "internalFileAttributes";
- const PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES = "externalFileAttributes";
- const PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW = "msdosAttributesRaw";
- const PROPERTY_NAME_MSDOS_ATTRIBUTES = "msdosAttributes";
- const PROPERTY_NAME_MS_DOS_COMPATIBLE = "msDosCompatible";
- const PROPERTY_NAME_ZIP64 = "zip64";
- const PROPERTY_NAME_ENCRYPTED = "encrypted";
- const PROPERTY_NAME_VERSION = "version";
- const PROPERTY_NAME_VERSION_MADE_BY = "versionMadeBy";
- const PROPERTY_NAME_ZIPCRYPTO = "zipCrypto";
- const PROPERTY_NAME_DIRECTORY = "directory";
- const PROPERTY_NAME_EXECUTABLE = "executable";
- const PROPERTY_NAME_COMPRESSION_METHOD = "compressionMethod";
- const PROPERTY_NAME_SIGNATURE = "signature";
- const PROPERTY_NAME_EXTRA_FIELD = "extraField";
- const PROPERTY_NAME_EXTRA_FIELD_INFOZIP = "extraFieldInfoZip";
- const PROPERTY_NAME_EXTRA_FIELD_UNIX = "extraFieldUnix";
- const PROPERTY_NAME_UID = "uid";
- const PROPERTY_NAME_GID = "gid";
- const PROPERTY_NAME_UNIX_MODE = "unixMode";
- const PROPERTY_NAME_SETUID = "setuid";
- const PROPERTY_NAME_SETGID = "setgid";
- const PROPERTY_NAME_STICKY = "sticky";
- const PROPERTY_NAME_BITFLAG = "bitFlag";
- const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
- const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
- const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
- const PROPERTY_NAME_EXTRA_FIELD_ZIP64 = "extraFieldZip64";
- const PROPERTY_NAME_EXTRA_FIELD_UNICODE_PATH = "extraFieldUnicodePath";
- const PROPERTY_NAME_EXTRA_FIELD_UNICODE_COMMENT = "extraFieldUnicodeComment";
- const PROPERTY_NAME_EXTRA_FIELD_AES = "extraFieldAES";
- const PROPERTY_NAME_EXTRA_FIELD_NTFS = "extraFieldNTFS";
- const PROPERTY_NAME_EXTRA_FIELD_EXTENDED_TIMESTAMP = "extraFieldExtendedTimestamp";
-
- const PROPERTY_NAMES = [
- PROPERTY_NAME_FILENAME,
- PROPERTY_NAME_RAW_FILENAME,
- PROPERTY_NAME_UNCOMPRESSED_SIZE,
- PROPERTY_NAME_COMPRESSED_SIZE,
- PROPERTY_NAME_LAST_MODIFICATION_DATE,
- PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE,
- PROPERTY_NAME_COMMENT,
- PROPERTY_NAME_RAW_COMMENT,
- PROPERTY_NAME_LAST_ACCESS_DATE,
- PROPERTY_NAME_CREATION_DATE,
- PROPERTY_NAME_RAW_CREATION_DATE,
- PROPERTY_NAME_OFFSET,
- PROPERTY_NAME_DISK_NUMBER_START,
- PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES,
- PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES,
- PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW,
- PROPERTY_NAME_MSDOS_ATTRIBUTES,
- PROPERTY_NAME_MS_DOS_COMPATIBLE,
- PROPERTY_NAME_ZIP64,
- PROPERTY_NAME_ENCRYPTED,
- PROPERTY_NAME_VERSION,
- PROPERTY_NAME_VERSION_MADE_BY,
- PROPERTY_NAME_ZIPCRYPTO,
- PROPERTY_NAME_DIRECTORY,
- PROPERTY_NAME_EXECUTABLE,
- PROPERTY_NAME_COMPRESSION_METHOD,
- PROPERTY_NAME_SIGNATURE,
- PROPERTY_NAME_EXTRA_FIELD,
- PROPERTY_NAME_EXTRA_FIELD_UNIX,
- PROPERTY_NAME_EXTRA_FIELD_INFOZIP,
- PROPERTY_NAME_UID,
- PROPERTY_NAME_GID,
- PROPERTY_NAME_UNIX_MODE,
- PROPERTY_NAME_SETUID,
- PROPERTY_NAME_SETGID,
- PROPERTY_NAME_STICKY,
- PROPERTY_NAME_BITFLAG,
- PROPERTY_NAME_FILENAME_UTF8,
- PROPERTY_NAME_COMMENT_UTF8,
- PROPERTY_NAME_RAW_EXTRA_FIELD,
- PROPERTY_NAME_EXTRA_FIELD_ZIP64,
- PROPERTY_NAME_EXTRA_FIELD_UNICODE_PATH,
- PROPERTY_NAME_EXTRA_FIELD_UNICODE_COMMENT,
- PROPERTY_NAME_EXTRA_FIELD_AES,
- PROPERTY_NAME_EXTRA_FIELD_NTFS,
- PROPERTY_NAME_EXTRA_FIELD_EXTENDED_TIMESTAMP
- ];
-
- class Entry {
-
- constructor(data) {
- PROPERTY_NAMES.forEach(name => this[name] = data[name]);
- }
-
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- const OPTION_FILENAME_ENCODING = "filenameEncoding";
- const OPTION_COMMENT_ENCODING = "commentEncoding";
- const OPTION_DECODE_TEXT = "decodeText";
- const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
- const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
- const OPTION_PASSWORD = "password";
- const OPTION_RAW_PASSWORD = "rawPassword";
- const OPTION_PASS_THROUGH = "passThrough";
- const OPTION_SIGNAL = "signal";
- const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
- const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
- const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
- const OPTION_CHECK_SIGNATURE = "checkSignature";
- const OPTION_USE_WEB_WORKERS = "useWebWorkers";
- const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
- const OPTION_TRANSFER_STREAMS = "transferStreams";
- const OPTION_PREVENT_CLOSE = "preventClose";
- const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
- const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
- const OPTION_KEEP_ORDER = "keepOrder";
- const OPTION_LEVEL = "level";
- const OPTION_BUFFERED_WRITE = "bufferedWrite";
- const OPTION_CREATE_TEMP_STREAM = "createTempStream";
- const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
- const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
- const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
- const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
- const OPTION_ENCODE_TEXT = "encodeText";
- const OPTION_OFFSET = "offset";
- const OPTION_USDZ = "usdz";
- const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const ERR_BAD_FORMAT = "File format is not recognized";
- const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
- const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
- const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
- const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
- const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
- const ERR_ENCRYPTED = "File contains encrypted entry";
- const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
- const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
- const ERR_SPLIT_ZIP_FILE = "Split zip file";
- const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
- const CHARSET_UTF8 = "utf-8";
- const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
- const CHARSET_CP437 = "cp437";
- const ZIP64_PROPERTIES = [
- [PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS],
- [PROPERTY_NAME_COMPRESSED_SIZE, MAX_32_BITS],
- [PROPERTY_NAME_OFFSET, MAX_32_BITS],
- [PROPERTY_NAME_DISK_NUMBER_START, MAX_16_BITS]
- ];
- const ZIP64_EXTRACTION = {
- [MAX_16_BITS]: {
- getValue: getUint32,
- bytes: 4
- },
- [MAX_32_BITS]: {
- getValue: getBigUint64,
- bytes: 8
- }
- };
-
- class ZipReader {
-
- constructor(reader, options = {}) {
- Object.assign(this, {
- reader: new GenericReader(reader),
- options,
- config: getConfiguration(),
- readRanges: []
- });
- }
-
- async* getEntriesGenerator(options = {}) {
- const zipReader = this;
- let { reader } = zipReader;
- const { config } = zipReader;
- await initStream(reader);
- if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
- reader = new BlobReader(await new Response(reader.readable).blob());
- await initStream(reader);
- }
- if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
- throw new Error(ERR_BAD_FORMAT);
- }
- reader.chunkSize = getChunkSize(config);
- const endOfDirectoryInfo = await seekSignature(reader, END_OF_CENTRAL_DIR_SIGNATURE, reader.size, END_OF_CENTRAL_DIR_LENGTH, MAX_16_BITS * 16);
- if (!endOfDirectoryInfo) {
- const signatureArray = await readUint8Array(reader, 0, 4);
- const signatureView = getDataView$1(signatureArray);
- if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
- throw new Error(ERR_SPLIT_ZIP_FILE);
- } else {
- throw new Error(ERR_EOCDR_NOT_FOUND);
- }
- }
- const endOfDirectoryView = getDataView$1(endOfDirectoryInfo);
- let directoryDataLength = getUint32(endOfDirectoryView, 12);
- let directoryDataOffset = getUint32(endOfDirectoryView, 16);
- const commentOffset = endOfDirectoryInfo.offset;
- const commentLength = getUint16(endOfDirectoryView, 20);
- const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
- let lastDiskNumber = getUint16(endOfDirectoryView, 4);
- const expectedLastDiskNumber = reader.lastDiskNumber || 0;
- let diskNumber = getUint16(endOfDirectoryView, 6);
- let filesLength = getUint16(endOfDirectoryView, 8);
- let prependedDataLength = 0;
- let startOffset = 0;
- if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS) {
- const endOfDirectoryLocatorArray = await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH);
- const endOfDirectoryLocatorView = getDataView$1(endOfDirectoryLocatorArray);
- if (getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
- directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8);
- let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
- let endOfDirectoryView = getDataView$1(endOfDirectoryArray);
- const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
- if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE && directoryDataOffset != expectedDirectoryDataOffset) {
- const originalDirectoryDataOffset = directoryDataOffset;
- directoryDataOffset = expectedDirectoryDataOffset;
- if (directoryDataOffset > originalDirectoryDataOffset) {
- prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
- }
- endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
- endOfDirectoryView = getDataView$1(endOfDirectoryArray);
- }
- if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
- throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
- }
- if (lastDiskNumber == MAX_16_BITS) {
- lastDiskNumber = getUint32(endOfDirectoryView, 16);
- }
- if (diskNumber == MAX_16_BITS) {
- diskNumber = getUint32(endOfDirectoryView, 20);
- }
- if (filesLength == MAX_16_BITS) {
- filesLength = getBigUint64(endOfDirectoryView, 32);
- }
- if (directoryDataLength == MAX_32_BITS) {
- directoryDataLength = getBigUint64(endOfDirectoryView, 40);
- }
- directoryDataOffset -= directoryDataLength;
- }
- }
- if (directoryDataOffset >= reader.size) {
- prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
- directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
- }
- if (expectedLastDiskNumber != lastDiskNumber) {
- throw new Error(ERR_SPLIT_ZIP_FILE);
- }
- if (directoryDataOffset < 0) {
- throw new Error(ERR_BAD_FORMAT);
- }
- let offset = 0;
- let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
- let directoryView = getDataView$1(directoryArray);
- if (directoryDataLength) {
- const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - directoryDataLength;
- if (getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE && directoryDataOffset != expectedDirectoryDataOffset) {
- const originalDirectoryDataOffset = directoryDataOffset;
- directoryDataOffset = expectedDirectoryDataOffset;
- if (directoryDataOffset > originalDirectoryDataOffset) {
- prependedDataLength += directoryDataOffset - originalDirectoryDataOffset;
- }
- directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
- directoryView = getDataView$1(directoryArray);
- }
- }
- const expectedDirectoryDataLength = endOfDirectoryInfo.offset - directoryDataOffset - (reader.lastDiskOffset || 0);
- if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0) {
- directoryDataLength = expectedDirectoryDataLength;
- directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
- directoryView = getDataView$1(directoryArray);
- }
- if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
- throw new Error(ERR_BAD_FORMAT);
- }
- const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
- const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
- for (let indexFile = 0; indexFile < filesLength; indexFile++) {
- const fileEntry = new ZipEntry$1(reader, config, zipReader.options);
- if (getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
- throw new Error(ERR_CENTRAL_DIRECTORY_NOT_FOUND);
- }
- readCommonHeader(fileEntry, directoryView, offset + 6);
- const languageEncodingFlag = Boolean(fileEntry.bitFlag.languageEncodingFlag);
- const filenameOffset = offset + 46;
- const extraFieldOffset = filenameOffset + fileEntry.filenameLength;
- const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
- const versionMadeBy = getUint16(directoryView, offset + 4);
- const msDosCompatible = versionMadeBy >> 8 == 0;
- const unixCompatible = versionMadeBy >> 8 == 3;
- const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
- const commentLength = getUint16(directoryView, offset + 32);
- const endOffset = commentOffset + commentLength;
- const rawComment = directoryArray.subarray(commentOffset, endOffset);
- const filenameUTF8 = languageEncodingFlag;
- const commentUTF8 = languageEncodingFlag;
- const externalFileAttributes = getUint32(directoryView, offset + 38);
- const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
- const msdosAttributes = {
- readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
- hidden: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_HIDDEN_MASK),
- system: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_SYSTEM_MASK),
- directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
- archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
- };
- const offsetFileEntry = getUint32(directoryView, offset + 42) + prependedDataLength;
- const decode = getOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
- const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
- const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
- let filename = decode(rawFilename, rawFilenameEncoding);
- if (filename === UNDEFINED_VALUE) {
- filename = decodeText(rawFilename, rawFilenameEncoding);
- }
- let comment = decode(rawComment, rawCommentEncoding);
- if (comment === UNDEFINED_VALUE) {
- comment = decodeText(rawComment, rawCommentEncoding);
- }
- Object.assign(fileEntry, {
- versionMadeBy,
- msDosCompatible,
- compressedSize: 0,
- uncompressedSize: 0,
- commentLength,
- offset: offsetFileEntry,
- diskNumberStart: getUint16(directoryView, offset + 34),
- internalFileAttributes: getUint16(directoryView, offset + 36),
- externalFileAttributes,
- msdosAttributesRaw,
- msdosAttributes,
- rawFilename,
- filenameUTF8,
- commentUTF8,
- rawExtraField: directoryArray.subarray(extraFieldOffset, commentOffset),
- rawComment,
- filename,
- comment
- });
- startOffset = Math.max(offsetFileEntry, startOffset);
- readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
- const unixExternalUpper = (fileEntry.externalFileAttributes >> 16) & MAX_16_BITS;
- if (fileEntry.unixMode === UNDEFINED_VALUE && (unixExternalUpper & (FILE_ATTR_UNIX_DEFAULT_MASK | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_TYPE_DIR)) != 0) {
- fileEntry.unixMode = unixExternalUpper;
- }
- const setuid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETUID_MASK);
- const setgid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETGID_MASK);
- const sticky = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_STICKY_MASK);
- const executable = (fileEntry.unixMode !== UNDEFINED_VALUE)
- ? ((fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)
- : (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0));
- const modeIsDir = fileEntry.unixMode !== UNDEFINED_VALUE && ((fileEntry.unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
- const upperIsDir = ((unixExternalUpper & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
- Object.assign(fileEntry, {
- setuid,
- setgid,
- sticky,
- unixExternalUpper,
- internalFileAttribute: fileEntry.internalFileAttributes,
- externalFileAttribute: fileEntry.externalFileAttributes,
- executable,
- directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || (filename.endsWith(DIRECTORY_SIGNATURE) && !fileEntry.uncompressedSize),
- zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
- });
- const entry = new Entry(fileEntry);
- entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader.readRanges, options);
- entry.arrayBuffer = async options => {
- const writer = new TransformStream();
- const [arrayBuffer] = await Promise.all([
- new Response(writer.readable).arrayBuffer(),
- fileEntry.getData(writer, entry, zipReader.readRanges, options)]);
- return arrayBuffer;
- };
- offset = endOffset;
- const { onprogress } = options;
- if (onprogress) {
- try {
- await onprogress(indexFile + 1, filesLength, new Entry(fileEntry));
- } catch {
- // ignored
- }
- }
- yield entry;
- }
- const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
- const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
- if (extractPrependedData) {
- zipReader.prependedData = startOffset > 0 ? await readUint8Array(reader, 0, startOffset) : new Uint8Array();
- }
- zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : new Uint8Array();
- if (extractAppendedData) {
- zipReader.appendedData = appendedDataOffset < reader.size ? await readUint8Array(reader, appendedDataOffset, reader.size - appendedDataOffset) : new Uint8Array();
- }
- return true;
- }
-
- async getEntries(options = {}) {
- const entries = [];
- for await (const entry of this.getEntriesGenerator(options)) {
- entries.push(entry);
- }
- return entries;
- }
-
- async close() {
- }
- }
-
- class ZipReaderStream {
-
- constructor(options = {}) {
- const { readable, writable } = new TransformStream();
- const gen = new ZipReader(readable, options).getEntriesGenerator();
- this.readable = new ReadableStream({
- async pull(controller) {
- const { done, value } = await gen.next();
- if (done)
- return controller.close();
- const chunk = {
- ...value,
- readable: (function () {
- const { readable, writable } = new TransformStream();
- if (value.getData) {
- value.getData(writable);
- return readable;
- }
- })()
- };
- delete chunk.getData;
- controller.enqueue(chunk);
- }
- });
- this.writable = writable;
- }
- }
-
- let ZipEntry$1 = class ZipEntry {
-
- constructor(reader, config, options) {
- Object.assign(this, {
- reader,
- config,
- options
- });
- }
-
- async getData(writer, fileEntry, readRanges, options = {}) {
- const zipEntry = this;
- const {
- reader,
- offset,
- diskNumberStart,
- extraFieldAES,
- extraFieldZip64,
- compressionMethod,
- config,
- bitFlag,
- signature,
- rawLastModDate,
- uncompressedSize,
- compressedSize
- } = zipEntry;
- const {
- dataDescriptor
- } = bitFlag;
- const localDirectory = fileEntry.localDirectory = {};
- const dataArray = await readUint8Array(reader, offset, HEADER_SIZE, diskNumberStart);
- const dataView = getDataView$1(dataArray);
- let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
- let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
- const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
- password = password && password.length && password;
- rawPassword = rawPassword && rawPassword.length && rawPassword;
- if (extraFieldAES) {
- if (extraFieldAES.originalCompressionMethod != COMPRESSION_METHOD_AES) {
- throw new Error(ERR_UNSUPPORTED_COMPRESSION);
- }
- }
- if ((compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64) && !passThrough) {
- throw new Error(ERR_UNSUPPORTED_COMPRESSION);
- }
- if (getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
- throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
- }
- readCommonHeader(localDirectory, dataView, 4);
- const {
- extraFieldLength,
- filenameLength,
- lastAccessDate,
- creationDate
- } = localDirectory;
- localDirectory.rawExtraField = extraFieldLength ?
- await readUint8Array(reader, offset + HEADER_SIZE + filenameLength, extraFieldLength, diskNumberStart) :
- new Uint8Array();
- readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
- Object.assign(fileEntry, { lastAccessDate, creationDate });
- const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
- const zipCrypto = encrypted && !extraFieldAES;
- if (!passThrough) {
- fileEntry.zipCrypto = zipCrypto;
- }
- if (encrypted) {
- if (!zipCrypto && extraFieldAES.strength === UNDEFINED_VALUE) {
- throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
- } else if (!password && !rawPassword) {
- throw new Error(ERR_ENCRYPTED);
- }
- }
- const dataOffset = offset + HEADER_SIZE + filenameLength + extraFieldLength;
- const size = compressedSize;
- const readable = reader.readable;
- Object.assign(readable, {
- diskNumberStart,
- offset: dataOffset,
- size
- });
- const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
- const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
- let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
- const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
- if (checkOverlappingEntryOnly) {
- checkOverlappingEntry = true;
- }
- const { onstart, onprogress, onend } = options;
- const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
- let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
- if (deflate64) {
- useCompressionStream = false;
- }
- const workerOptions = {
- options: {
- codecType: CODEC_INFLATE,
- password,
- rawPassword,
- zipCrypto,
- encryptionStrength: extraFieldAES && extraFieldAES.strength,
- signed: getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) && !passThrough,
- passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((signature >>> 24) & MAX_8_BITS)),
- outputSize: passThrough ? compressedSize : uncompressedSize,
- signature,
- compressed: compressionMethod != 0 && !passThrough,
- encrypted: zipEntry.encrypted && !passThrough,
- useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
- useCompressionStream,
- transferStreams: getOptionValue$1(zipEntry, options, OPTION_TRANSFER_STREAMS),
- deflate64,
- checkPasswordOnly
- },
- config,
- streamOptions: { signal, size, onstart, onprogress, onend }
- };
- if (checkOverlappingEntry) {
- await detectOverlappingEntry({
- reader,
- fileEntry,
- offset,
- diskNumberStart,
- signature,
- compressedSize,
- uncompressedSize,
- dataOffset,
- dataDescriptor: dataDescriptor || localDirectory.bitFlag.dataDescriptor,
- extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
- readRanges
- });
- }
- let writable;
- try {
- if (!checkOverlappingEntryOnly) {
- if (checkPasswordOnly) {
- writer = new WritableStream();
- }
- writer = new GenericWriter(writer);
- await initStream(writer, passThrough ? compressedSize : uncompressedSize);
- ({ writable } = writer);
- const { outputSize } = await runWorker({ readable, writable }, workerOptions);
- writer.size += outputSize;
- if (outputSize != (passThrough ? compressedSize : uncompressedSize)) {
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
- }
- }
- } catch (error) {
- if (error.outputSize !== UNDEFINED_VALUE) {
- writer.size += error.outputSize;
- }
- if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) {
- throw error;
- }
- } finally {
- const preventClose = getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
- if (!preventClose && writable && !writable.locked) {
- await writable.getWriter().close();
- }
- }
- return checkPasswordOnly || checkOverlappingEntryOnly ? UNDEFINED_VALUE : writer.getData ? writer.getData() : writable;
- }
- };
-
- function readCommonHeader(directory, dataView, offset) {
- const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
- const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
- const rawLastModDate = getUint32(dataView, offset + 6);
- Object.assign(directory, {
- encrypted,
- version: getUint16(dataView, offset),
- bitFlag: {
- level: (rawBitFlag & BITFLAG_LEVEL) >> 1,
- dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR,
- languageEncodingFlag: (rawBitFlag & BITFLAG_LANG_ENCODING_FLAG) == BITFLAG_LANG_ENCODING_FLAG
- },
- rawLastModDate,
- lastModDate: getDate(rawLastModDate),
- filenameLength: getUint16(dataView, offset + 22),
- extraFieldLength: getUint16(dataView, offset + 24)
- });
- }
-
- function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory) {
- const { rawExtraField } = directory;
- const extraField = directory.extraField = new Map();
- const rawExtraFieldView = getDataView$1(new Uint8Array(rawExtraField));
- let offsetExtraField = 0;
- try {
- while (offsetExtraField < rawExtraField.length) {
- const type = getUint16(rawExtraFieldView, offsetExtraField);
- const size = getUint16(rawExtraFieldView, offsetExtraField + 2);
- extraField.set(type, {
- type,
- data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size)
- });
- offsetExtraField += 4 + size;
- }
- } catch {
- // ignored
- }
- const compressionMethod = getUint16(dataView, offset + 4);
- Object.assign(directory, {
- signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
- compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
- uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
- });
- const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
- if (extraFieldZip64) {
- readExtraFieldZip64(extraFieldZip64, directory);
- directory.extraFieldZip64 = extraFieldZip64;
- }
- const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
- if (extraFieldUnicodePath) {
- readExtraFieldUnicode(extraFieldUnicodePath, PROPERTY_NAME_FILENAME, PROPERTY_NAME_RAW_FILENAME, directory, fileEntry);
- directory.extraFieldUnicodePath = extraFieldUnicodePath;
- }
- const extraFieldUnicodeComment = extraField.get(EXTRAFIELD_TYPE_UNICODE_COMMENT);
- if (extraFieldUnicodeComment) {
- readExtraFieldUnicode(extraFieldUnicodeComment, PROPERTY_NAME_COMMENT, PROPERTY_NAME_RAW_COMMENT, directory, fileEntry);
- directory.extraFieldUnicodeComment = extraFieldUnicodeComment;
- }
- const extraFieldAES = extraField.get(EXTRAFIELD_TYPE_AES);
- if (extraFieldAES) {
- readExtraFieldAES(extraFieldAES, directory, compressionMethod);
- directory.extraFieldAES = extraFieldAES;
- } else {
- directory.compressionMethod = compressionMethod;
- }
- const extraFieldNTFS = extraField.get(EXTRAFIELD_TYPE_NTFS);
- if (extraFieldNTFS) {
- readExtraFieldNTFS(extraFieldNTFS, directory);
- directory.extraFieldNTFS = extraFieldNTFS;
- }
- const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
- if (extraFieldUnix) {
- readExtraFieldUnix(extraFieldUnix, directory, false);
- directory.extraFieldUnix = extraFieldUnix;
- } else {
- const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
- if (extraFieldInfoZip) {
- readExtraFieldUnix(extraFieldInfoZip, directory, true);
- directory.extraFieldInfoZip = extraFieldInfoZip;
- }
- }
- const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
- if (extraFieldExtendedTimestamp) {
- readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory);
- directory.extraFieldExtendedTimestamp = extraFieldExtendedTimestamp;
- }
- const extraFieldUSDZ = extraField.get(EXTRAFIELD_TYPE_USDZ);
- if (extraFieldUSDZ) {
- directory.extraFieldUSDZ = extraFieldUSDZ;
- }
- }
-
- function readExtraFieldZip64(extraFieldZip64, directory) {
- directory.zip64 = true;
- const extraFieldView = getDataView$1(extraFieldZip64.data);
- const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
- for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
- const [propertyName, max] = missingProperties[indexMissingProperty];
- if (directory[propertyName] == max) {
- const extraction = ZIP64_EXTRACTION[max];
- directory[propertyName] = extraFieldZip64[propertyName] = extraction.getValue(extraFieldView, offset);
- offset += extraction.bytes;
- } else if (extraFieldZip64[propertyName]) {
- throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
- }
- }
- }
-
- function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) {
- const extraFieldView = getDataView$1(extraFieldUnicode.data);
- const crc32 = new Crc32();
- crc32.append(fileEntry[rawPropertyName]);
- const dataViewSignature = getDataView$1(new Uint8Array(4));
- dataViewSignature.setUint32(0, crc32.get(), true);
- const signature = getUint32(extraFieldView, 1);
- Object.assign(extraFieldUnicode, {
- version: getUint8(extraFieldView, 0),
- [propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
- valid: !fileEntry.bitFlag.languageEncodingFlag && signature == getUint32(dataViewSignature, 0)
- });
- if (extraFieldUnicode.valid) {
- directory[propertyName] = extraFieldUnicode[propertyName];
- directory[propertyName + PROPERTY_NAME_UTF8_SUFFIX] = true;
- }
- }
-
- function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
- const extraFieldView = getDataView$1(extraFieldAES.data);
- const strength = getUint8(extraFieldView, 4);
- Object.assign(extraFieldAES, {
- vendorVersion: getUint8(extraFieldView, 0),
- vendorId: getUint8(extraFieldView, 2),
- strength,
- originalCompressionMethod: compressionMethod,
- compressionMethod: getUint16(extraFieldView, 5)
- });
- directory.compressionMethod = extraFieldAES.compressionMethod;
- }
-
- function readExtraFieldNTFS(extraFieldNTFS, directory) {
- const extraFieldView = getDataView$1(extraFieldNTFS.data);
- let offsetExtraField = 4;
- let tag1Data;
- try {
- while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) {
- const tagValue = getUint16(extraFieldView, offsetExtraField);
- const attributeSize = getUint16(extraFieldView, offsetExtraField + 2);
- if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) {
- tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize);
- }
- offsetExtraField += 4 + attributeSize;
- }
- } catch {
- // ignored
- }
- try {
- if (tag1Data && tag1Data.length == 24) {
- const tag1View = getDataView$1(tag1Data);
- const rawLastModDate = tag1View.getBigUint64(0, true);
- const rawLastAccessDate = tag1View.getBigUint64(8, true);
- const rawCreationDate = tag1View.getBigUint64(16, true);
- Object.assign(extraFieldNTFS, {
- rawLastModDate,
- rawLastAccessDate,
- rawCreationDate
- });
- const lastModDate = getDateNTFS(rawLastModDate);
- const lastAccessDate = getDateNTFS(rawLastAccessDate);
- const creationDate = getDateNTFS(rawCreationDate);
- const extraFieldData = { lastModDate, lastAccessDate, creationDate };
- Object.assign(extraFieldNTFS, extraFieldData);
- Object.assign(directory, extraFieldData);
- }
- } catch {
- // ignored
- }
- }
-
- function readExtraFieldUnix(extraField, directory, isInfoZip) {
- try {
- const view = getDataView$1(new Uint8Array(extraField.data));
- let offset = 0;
- const version = getUint8(view, offset++);
- const uidSize = getUint8(view, offset++);
- const uidBytes = extraField.data.subarray(offset, offset + uidSize);
- offset += uidSize;
- const uid = unpackUnixId(uidBytes);
- const gidSize = getUint8(view, offset++);
- const gidBytes = extraField.data.subarray(offset, offset + gidSize);
- offset += gidSize;
- const gid = unpackUnixId(gidBytes);
- let unixMode = UNDEFINED_VALUE;
- if (!isInfoZip && offset + 2 <= extraField.data.length) {
- const base = extraField.data;
- const modeView = new DataView(base.buffer, base.byteOffset + offset, 2);
- unixMode = modeView.getUint16(0, true);
- }
- Object.assign(extraField, { version, uid, gid, unixMode });
- if (uid !== UNDEFINED_VALUE) {
- directory.uid = uid;
- }
- if (gid !== UNDEFINED_VALUE) {
- directory.gid = gid;
- }
- if (unixMode !== UNDEFINED_VALUE) {
- directory.unixMode = unixMode;
- }
- } catch {
- // ignored
- }
- }
-
- function unpackUnixId(bytes) {
- const buffer = new Uint8Array(4);
- buffer.set(bytes, 0);
- const view = new DataView(buffer.buffer, buffer.byteOffset, 4);
- return view.getUint32(0, true);
- }
-
- function readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory) {
- const extraFieldView = getDataView$1(extraFieldExtendedTimestamp.data);
- const flags = getUint8(extraFieldView, 0);
- const timeProperties = [];
- const timeRawProperties = [];
- if (localDirectory) {
- if ((flags & 0x1) == 0x1) {
- timeProperties.push(PROPERTY_NAME_LAST_MODIFICATION_DATE);
- timeRawProperties.push(PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
- }
- if ((flags & 0x2) == 0x2) {
- timeProperties.push(PROPERTY_NAME_LAST_ACCESS_DATE);
- timeRawProperties.push(PROPERTY_NAME_RAW_LAST_ACCESS_DATE);
- }
- if ((flags & 0x4) == 0x4) {
- timeProperties.push(PROPERTY_NAME_CREATION_DATE);
- timeRawProperties.push(PROPERTY_NAME_RAW_CREATION_DATE);
- }
- } else if (extraFieldExtendedTimestamp.data.length >= 5) {
- timeProperties.push(PROPERTY_NAME_LAST_MODIFICATION_DATE);
- timeRawProperties.push(PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
- }
- let offset = 1;
- timeProperties.forEach((propertyName, indexProperty) => {
- if (extraFieldExtendedTimestamp.data.length >= offset + 4) {
- const time = getUint32(extraFieldView, offset);
- directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date(time * 1000);
- const rawPropertyName = timeRawProperties[indexProperty];
- extraFieldExtendedTimestamp[rawPropertyName] = time;
- }
- offset += 4;
- });
- }
-
- async function detectOverlappingEntry({
- reader,
- fileEntry,
- offset,
- diskNumberStart,
- signature,
- compressedSize,
- uncompressedSize,
- dataOffset,
- dataDescriptor,
- extraFieldZip64,
- readRanges
- }) {
- let diskOffset = 0;
- if (diskNumberStart) {
- for (let indexReader = 0; indexReader < diskNumberStart; indexReader++) {
- const diskReader = reader.readers[indexReader];
- diskOffset += diskReader.size;
- }
- }
- let dataDescriptorLength = 0;
- if (dataDescriptor) {
- if (extraFieldZip64) {
- dataDescriptorLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH;
- } else {
- dataDescriptorLength = DATA_DESCRIPTOR_RECORD_LENGTH;
- }
- }
- if (dataDescriptorLength) {
- const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, diskNumberStart);
- const dataDescriptorSignature = getUint32(getDataView$1(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
- if (dataDescriptorSignature) {
- const readSignature = getUint32(getDataView$1(dataDescriptorArray), 4);
- let readCompressedSize;
- let readUncompressedSize;
- if (extraFieldZip64) {
- readCompressedSize = getBigUint64(getDataView$1(dataDescriptorArray), 8);
- readUncompressedSize = getBigUint64(getDataView$1(dataDescriptorArray), 16);
- } else {
- readCompressedSize = getUint32(getDataView$1(dataDescriptorArray), 8);
- readUncompressedSize = getUint32(getDataView$1(dataDescriptorArray), 12);
- }
- const matchSignature = (fileEntry.encrypted && !fileEntry.zipCrypto) || readSignature == signature;
- if (matchSignature &&
- readCompressedSize == compressedSize &&
- readUncompressedSize == uncompressedSize) {
- dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
- }
- }
- }
- const range = {
- start: diskOffset + offset,
- end: diskOffset + dataOffset + compressedSize + dataDescriptorLength,
- fileEntry
- };
- for (const otherRange of readRanges) {
- if (otherRange.fileEntry != fileEntry && range.start >= otherRange.start && range.start < otherRange.end) {
- const error = new Error(ERR_OVERLAPPING_ENTRY);
- error.overlappingEntry = otherRange.fileEntry;
- throw error;
- }
- }
- readRanges.push(range);
- }
-
- async function seekSignature(reader, signature, startOffset, minimumBytes, maximumLength) {
- const signatureArray = new Uint8Array(4);
- const signatureView = getDataView$1(signatureArray);
- setUint32$1(signatureView, 0, signature);
- const maximumBytes = minimumBytes + maximumLength;
- return (await seek(minimumBytes)) || await seek(Math.min(maximumBytes, startOffset));
-
- async function seek(length) {
- const offset = startOffset - length;
- const bytes = await readUint8Array(reader, offset, length);
- for (let indexByte = bytes.length - minimumBytes; indexByte >= 0; indexByte--) {
- if (bytes[indexByte] == signatureArray[0] && bytes[indexByte + 1] == signatureArray[1] &&
- bytes[indexByte + 2] == signatureArray[2] && bytes[indexByte + 3] == signatureArray[3]) {
- return {
- offset: offset + indexByte,
- buffer: bytes.slice(indexByte, indexByte + minimumBytes).buffer
- };
- }
- }
- }
- }
-
- function getOptionValue$1(zipReader, options, name) {
- return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
- }
-
- function getDate(timeRaw) {
- const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
- try {
- return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
- } catch {
- // ignored
- }
- }
-
- function getDateNTFS(timeRaw) {
- return new Date((Number((timeRaw / BigInt(10000)) - BigInt(11644473600000))));
- }
-
- function getUint8(view, offset) {
- return view.getUint8(offset);
- }
-
- function getUint16(view, offset) {
- return view.getUint16(offset, true);
- }
-
- function getUint32(view, offset) {
- return view.getUint32(offset, true);
- }
-
- function getBigUint64(view, offset) {
- return Number(view.getBigUint64(offset, true));
- }
-
- function setUint32$1(view, offset, value) {
- view.setUint32(offset, value, true);
- }
-
- function getDataView$1(array) {
- return new DataView(array.buffer);
- }
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const ERR_DUPLICATED_NAME = "File already exists";
- const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
- const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
- const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
- const ERR_INVALID_VERSION = "Version exceeds 65535";
- const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
- const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
- const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
- const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
- const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
- const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
- const ERR_INVALID_UID = "Invalid uid (must be integer 0..2^32-1)";
- const ERR_INVALID_GID = "Invalid gid (must be integer 0..2^32-1)";
- const ERR_INVALID_UNIX_MODE = "Invalid UNIX mode (must be integer 0..65535)";
- const ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = "Invalid unixExtraFieldType (must be 'infozip' or 'unix')";
- const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
- const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
-
- const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
- const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
- const UNIX_EXTRA_FIELD_TYPE = "unix";
-
- let workers = 0;
- const pendingEntries = [];
-
- class ZipWriter {
-
- constructor(writer, options = {}) {
- writer = new GenericWriter(writer);
- const addSplitZipSignature =
- writer.availableSize !== UNDEFINED_VALUE && writer.availableSize > 0 && writer.availableSize !== INFINITY_VALUE &&
- writer.maxSize !== UNDEFINED_VALUE && writer.maxSize > 0 && writer.maxSize !== INFINITY_VALUE;
- Object.assign(this, {
- writer,
- addSplitZipSignature,
- options,
- config: getConfiguration(),
- files: new Map(),
- filenames: new Set(),
- offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
- pendingEntriesSize: 0,
- pendingAddFileCalls: new Set(),
- bufferedWrites: 0
- });
- }
-
- async prependZip(reader) {
- if (this.filenames.size) {
- throw new Error(ERR_ZIP_NOT_EMPTY);
- }
- reader = new GenericReader(reader);
- const zipReader = new ZipReader(reader.readable);
- const entries = await zipReader.getEntries();
- await zipReader.close();
- await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
- this.writer.size = this.offset = reader.size;
- this.filenames = new Set(entries.map(entry => entry.filename));
- this.files = new Map(entries.map(entry => {
- const {
- version,
- compressionMethod,
- lastModDate,
- lastAccessDate,
- creationDate,
- rawFilename,
- bitFlag,
- encrypted,
- uncompressedSize,
- compressedSize,
- diskOffset,
- diskNumber,
- zip64
- } = entry;
- let {
- rawExtraFieldZip64,
- rawExtraFieldAES,
- rawExtraFieldExtendedTimestamp,
- rawExtraFieldNTFS,
- rawExtraFieldUnix,
- rawExtraField,
- } = entry;
- const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
- rawExtraFieldZip64 = rawExtraFieldZip64 || new Uint8Array();
- rawExtraFieldAES = rawExtraFieldAES || new Uint8Array();
- rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || new Uint8Array();
- rawExtraFieldNTFS = rawExtraFieldNTFS || new Uint8Array();
- rawExtraFieldUnix = entry.rawExtraFieldUnix || new Uint8Array();
- rawExtraField = rawExtraField || new Uint8Array();
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
- const zip64UncompressedSize = zip64 && uncompressedSize > MAX_32_BITS;
- const zip64CompressedSize = zip64 && compressedSize > MAX_32_BITS;
- const {
- headerArray,
- headerView
- } = getHeaderArrayData({
- version,
- bitFlag: getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod),
- compressionMethod,
- uncompressedSize,
- compressedSize,
- lastModDate,
- rawFilename,
- zip64CompressedSize,
- zip64UncompressedSize,
- extraFieldLength
- });
- Object.assign(entry, {
- zip64UncompressedSize,
- zip64CompressedSize,
- zip64Offset: zip64 && this.offset - diskOffset > MAX_32_BITS,
- zip64DiskNumberStart: zip64 && diskNumber > MAX_16_BITS,
- rawExtraFieldZip64,
- rawExtraFieldAES,
- rawExtraFieldExtendedTimestamp,
- rawExtraFieldNTFS,
- rawExtraFieldUnix,
- rawExtraField,
- extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
- extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
- headerArray,
- headerView
- });
- return [entry.filename, entry];
- }));
- }
-
- async add(name = "", reader, options = {}) {
- const zipWriter = this;
- const {
- pendingAddFileCalls,
- config
- } = zipWriter;
- if (workers < config.maxWorkers) {
- workers++;
- } else {
- await new Promise(resolve => pendingEntries.push(resolve));
- }
- let promiseAddFile;
- try {
- name = name.trim();
- if (zipWriter.filenames.has(name)) {
- throw new Error(ERR_DUPLICATED_NAME);
- }
- zipWriter.filenames.add(name);
- promiseAddFile = addFile(zipWriter, name, reader, options);
- pendingAddFileCalls.add(promiseAddFile);
- return await promiseAddFile;
- } catch (error) {
- zipWriter.filenames.delete(name);
- throw error;
- } finally {
- pendingAddFileCalls.delete(promiseAddFile);
- const pendingEntry = pendingEntries.shift();
- if (pendingEntry) {
- pendingEntry();
- } else {
- workers--;
- }
- }
- }
-
- remove(entry) {
- const { filenames, files } = this;
- if (typeof entry == "string") {
- entry = files.get(entry);
- }
- if (entry && entry.filename !== UNDEFINED_VALUE) {
- const { filename } = entry;
- if (filenames.has(filename) && files.has(filename)) {
- filenames.delete(filename);
- files.delete(filename);
- return true;
- }
- }
- return false;
- }
-
- async close(comment = new Uint8Array(), options = {}) {
- const zipWriter = this;
- const { pendingAddFileCalls, writer } = this;
- const { writable } = writer;
- while (pendingAddFileCalls.size) {
- await Promise.allSettled(Array.from(pendingAddFileCalls));
- }
- await closeFile(zipWriter, comment, options);
- const preventClose = getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
- if (!preventClose) {
- await writable.getWriter().close();
- }
- return writer.getData ? writer.getData() : writable;
- }
- }
-
- class ZipWriterStream {
-
- constructor(options = {}) {
- const { readable, writable } = new TransformStream();
- this.readable = readable;
- this.zipWriter = new ZipWriter(writable, options);
- }
-
- transform(path) {
- const { readable, writable } = new TransformStream({
- flush: () => { this.zipWriter.close(); }
- });
- this.zipWriter.add(path, readable);
- return { readable: this.readable, writable };
- }
-
- writable(path) {
- const { readable, writable } = new TransformStream();
- this.zipWriter.add(path, readable);
- return writable;
- }
-
- close(comment = UNDEFINED_VALUE, options = {}) {
- return this.zipWriter.close(comment, options);
- }
- }
-
- async function addFile(zipWriter, name, reader, options) {
- name = name.trim();
- let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
- let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
- const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
- const uid = getOptionValue(zipWriter, options, PROPERTY_NAME_UID);
- const gid = getOptionValue(zipWriter, options, PROPERTY_NAME_GID);
- let unixMode = getOptionValue(zipWriter, options, PROPERTY_NAME_UNIX_MODE);
- const unixExtraFieldType = getOptionValue(zipWriter, options, OPTION_UNIX_EXTRA_FIELD_TYPE);
- let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
- let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
- let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
- if (uid !== UNDEFINED_VALUE && (uid < 0 || uid > MAX_32_BITS)) {
- throw new Error(ERR_INVALID_UID);
- }
- if (gid !== UNDEFINED_VALUE && (gid < 0 || gid > MAX_32_BITS)) {
- throw new Error(ERR_INVALID_GID);
- }
- if (unixMode !== UNDEFINED_VALUE && (unixMode < 0 || unixMode > MAX_16_BITS)) {
- throw new Error(ERR_INVALID_UNIX_MODE);
- }
- if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
- throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
- }
- let msdosAttributesRaw = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
- let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
- const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
- const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
- if (hasUnixMetadata) {
- msDosCompatible = false;
- versionMadeBy = (versionMadeBy & MAX_16_BITS) | (3 << 8);
- } else if (hasMsDosProvided) {
- msDosCompatible = true;
- versionMadeBy = (versionMadeBy & MAX_8_BITS);
- }
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
- throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
- }
- if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
- throw new Error(ERR_INVALID_MSDOS_DATA);
- }
- if (versionMadeBy > MAX_16_BITS) {
- throw new Error(ERR_INVALID_VERSION);
- }
- let externalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES, 0);
- if (!options[PROPERTY_NAME_DIRECTORY] && name.endsWith(DIRECTORY_SIGNATURE)) {
- options[PROPERTY_NAME_DIRECTORY] = true;
- }
- const directory = getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
- if (directory) {
- if (!name.endsWith(DIRECTORY_SIGNATURE)) {
- name += DIRECTORY_SIGNATURE;
- }
- if (externalFileAttributes === 0) {
- externalFileAttributes = FILE_ATTR_MSDOS_DIR_MASK;
- if (!msDosCompatible) {
- externalFileAttributes |= (FILE_ATTR_UNIX_TYPE_DIR | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_DEFAULT_MASK) << 16;
- }
- }
- } else if (!msDosCompatible && externalFileAttributes === 0) {
- if (executable) {
- externalFileAttributes = (FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_DEFAULT_MASK) << 16;
- } else {
- externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
- }
- }
- let unixExternalUpper;
- if (!msDosCompatible) {
- unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
- unixMode = unixMode === UNDEFINED_VALUE ? unixExternalUpper : (unixMode & MAX_16_BITS);
- if (setuid) {
- unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
- } else {
- setuid = Boolean(unixMode & FILE_ATTR_UNIX_SETUID_MASK);
- }
- if (setgid) {
- unixMode |= FILE_ATTR_UNIX_SETGID_MASK;
- } else {
- setgid = Boolean(unixMode & FILE_ATTR_UNIX_SETGID_MASK);
- }
- if (sticky) {
- unixMode |= FILE_ATTR_UNIX_STICKY_MASK;
- } else {
- sticky = Boolean(unixMode & FILE_ATTR_UNIX_STICKY_MASK);
- }
- if (directory) {
- unixMode |= FILE_ATTR_UNIX_TYPE_DIR;
- }
- externalFileAttributes = ((unixMode & MAX_16_BITS) << 16) | (externalFileAttributes & MAX_8_BITS);
- }
- ({ msdosAttributesRaw, msdosAttributes } = normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes));
- if (hasMsDosProvided) {
- externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
- }
- const encode = getOptionValue(zipWriter, options, OPTION_ENCODE_TEXT, encodeText);
- let rawFilename = encode(name);
- if (rawFilename === UNDEFINED_VALUE) {
- rawFilename = encodeText(name);
- }
- if (getLength(rawFilename) > MAX_16_BITS) {
- throw new Error(ERR_INVALID_ENTRY_NAME);
- }
- const comment = options[PROPERTY_NAME_COMMENT] || "";
- let rawComment = encode(comment);
- if (rawComment === UNDEFINED_VALUE) {
- rawComment = encodeText(comment);
- }
- if (getLength(rawComment) > MAX_16_BITS) {
- throw new Error(ERR_INVALID_ENTRY_COMMENT);
- }
- const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION, VERSION_DEFLATE);
- if (version > MAX_16_BITS) {
- throw new Error(ERR_INVALID_VERSION);
- }
- const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
- const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
- const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
- const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
- const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
- let password, rawPassword;
- if (!passThrough) {
- password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
- rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
- }
- const encryptionStrength = getOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
- const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
- const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
- const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
- const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
- const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS, true);
- const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
- const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
- const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, false);
- const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
- const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
- const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
- let level = getOptionValue(zipWriter, options, OPTION_LEVEL);
- let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
- let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
- if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
- dataDescriptor = false;
- }
- if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
- dataDescriptor = true;
- }
- if (level !== UNDEFINED_VALUE && level != 6) {
- useCompressionStream = false;
- }
- if (!useCompressionStream && (zipWriter.config.CompressionStream === UNDEFINED_VALUE && zipWriter.config.CompressionStreamZlib === UNDEFINED_VALUE)) {
- level = 0;
- }
- let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
- if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(encryptionStrength >= 1 && encryptionStrength <= 3)) {
- throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
- }
- let rawExtraField = new Uint8Array();
- const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
- if (extraField) {
- let extraFieldSize = 0;
- let offset = 0;
- extraField.forEach(data => extraFieldSize += 4 + getLength(data));
- rawExtraField = new Uint8Array(extraFieldSize);
- extraField.forEach((data, type) => {
- if (type > MAX_16_BITS) {
- throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
- }
- if (getLength(data) > MAX_16_BITS) {
- throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
- }
- arraySet(rawExtraField, new Uint16Array([type]), offset);
- arraySet(rawExtraField, new Uint16Array([getLength(data)]), offset + 2);
- arraySet(rawExtraField, data, offset + 4);
- offset += 4 + getLength(data);
- });
- }
- let maximumCompressedSize = 0;
- let maximumEntrySize = 0;
- let uncompressedSize = 0;
- if (passThrough) {
- uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
- if (uncompressedSize === UNDEFINED_VALUE) {
- throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
- }
- }
- const zip64Enabled = zip64 === true;
- if (reader) {
- reader = new GenericReader(reader);
- await initStream(reader);
- if (!passThrough) {
- if (reader.size === UNDEFINED_VALUE) {
- dataDescriptor = true;
- if (zip64 || zip64 === UNDEFINED_VALUE) {
- zip64 = true;
- uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
- }
- } else {
- options.uncompressedSize = uncompressedSize = reader.size;
- maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
- }
- } else {
- options.uncompressedSize = uncompressedSize;
- maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
- }
- }
- const { diskOffset, diskNumber } = zipWriter.writer;
- const zip64UncompressedSize = zip64Enabled || uncompressedSize > MAX_32_BITS;
- const zip64CompressedSize = zip64Enabled || maximumCompressedSize > MAX_32_BITS;
- if (zip64UncompressedSize || zip64CompressedSize) {
- if (zip64 === false) {
- throw new Error(ERR_UNSUPPORTED_FORMAT);
- } else {
- zip64 = true;
- }
- }
- zip64 = zip64 || false;
- const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
- options = Object.assign({}, options, {
- rawFilename,
- rawComment,
- version,
- versionMadeBy,
- lastModDate,
- lastAccessDate,
- creationDate,
- rawExtraField,
- zip64,
- zip64UncompressedSize,
- zip64CompressedSize,
- password,
- rawPassword,
- level,
- useWebWorkers,
- transferStreams,
- encryptionStrength,
- extendedTimestamp,
- zipCrypto,
- bufferedWrite,
- createTempStream,
- keepOrder,
- useUnicodeFileNames,
- dataDescriptor,
- dataDescriptorSignature,
- signal,
- msDosCompatible,
- internalFileAttribute: internalFileAttributes,
- internalFileAttributes,
- externalFileAttribute: externalFileAttributes,
- externalFileAttributes,
- useCompressionStream,
- passThrough,
- encrypted: Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted),
- signature: options[PROPERTY_NAME_SIGNATURE],
- compressionMethod,
- uncompressedSize,
- offset: zipWriter.offset - diskOffset,
- diskNumberStart: diskNumber,
- uid,
- gid,
- setuid,
- setgid,
- sticky,
- unixMode,
- msdosAttributesRaw,
- msdosAttributes,
- unixExternalUpper
- });
- const headerInfo = getHeaderInfo(options);
- const dataDescriptorInfo = getDataDescriptorInfo(options);
- const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
- maximumEntrySize = metadataSize + maximumCompressedSize;
- if (zipWriter.options[OPTION_USDZ]) {
- maximumEntrySize += maximumEntrySize + 64;
- }
- zipWriter.pendingEntriesSize += maximumEntrySize;
- let fileEntry;
- try {
- fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
- } finally {
- zipWriter.pendingEntriesSize -= maximumEntrySize;
- }
- Object.assign(fileEntry, { name, comment, extraField });
- return new Entry(fileEntry);
- }
-
- async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
- const {
- files,
- writer
- } = zipWriter;
- const {
- keepOrder,
- dataDescriptor,
- signal
- } = options;
- const {
- headerInfo
- } = entryInfo;
- const usdz = zipWriter.options[OPTION_USDZ];
- const previousFileEntry = Array.from(files.values()).pop();
- let fileEntry = {};
- let bufferedWrite;
- let releaseLockWriter;
- let releaseLockCurrentFileEntry;
- let writingBufferedEntryData;
- let writingEntryData;
- let fileWriter;
- files.set(name, fileEntry);
- try {
- let lockPreviousFileEntry;
- if (keepOrder) {
- lockPreviousFileEntry = previousFileEntry && previousFileEntry.lock;
- requestLockCurrentFileEntry();
- }
- if ((options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) && !usdz) {
- if (options.createTempStream) {
- fileWriter = await options.createTempStream();
- } else {
- fileWriter = new TransformStream(UNDEFINED_VALUE, UNDEFINED_VALUE, { highWaterMark: INFINITY_VALUE });
- }
- fileWriter.size = 0;
- bufferedWrite = true;
- zipWriter.bufferedWrites++;
- await initStream(writer);
- } else {
- fileWriter = writer;
- await requestLockWriter();
- }
- await initStream(fileWriter);
- const { writable, diskOffset } = writer;
- if (zipWriter.addSplitZipSignature) {
- delete zipWriter.addSplitZipSignature;
- const signatureArray = new Uint8Array(4);
- const signatureArrayView = getDataView(signatureArray);
- setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
- await writeData(writer, signatureArray);
- zipWriter.offset += 4;
- }
- if (usdz) {
- appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
- }
- const {
- localHeaderView,
- localHeaderArray
- } = headerInfo;
- if (!bufferedWrite) {
- await lockPreviousFileEntry;
- await skipDiskIfNeeded(writable);
- }
- const { diskNumber } = writer;
- fileEntry.diskNumberStart = diskNumber;
- if (!bufferedWrite) {
- writingEntryData = true;
- await writeData(fileWriter, localHeaderArray);
- }
- fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, zipWriter.config, options);
- if (!bufferedWrite) {
- writingEntryData = false;
- }
- files.set(name, fileEntry);
- fileEntry.filename = name;
- if (bufferedWrite) {
- await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
- await requestLockWriter();
- writingBufferedEntryData = true;
- fileEntry.diskNumberStart = writer.diskNumber;
- fileEntry.offset = zipWriter.offset - writer.diskOffset;
- updateLocalHeader(fileEntry, localHeaderView, options);
- await skipDiskIfNeeded(writable);
- await writeData(writer, localHeaderArray);
- await fileWriter.readable.pipeTo(writable, { preventClose: true, preventAbort: true, signal });
- writer.size += fileWriter.size;
- writingBufferedEntryData = false;
- } else {
- fileEntry.offset = zipWriter.offset - diskOffset;
- }
- zipWriter.offset += fileEntry.size;
- return fileEntry;
- } catch (error) {
- if (writingBufferedEntryData || writingEntryData) {
- zipWriter.hasCorruptedEntries = true;
- if (error) {
- try {
- error.corruptedEntry = true;
- } catch {
- // ignored
- }
- }
- if (bufferedWrite) {
- zipWriter.offset += fileWriter.size;
- } else {
- zipWriter.offset = fileWriter.size;
- }
- }
- files.delete(name);
- throw error;
- } finally {
- if (bufferedWrite) {
- zipWriter.bufferedWrites--;
- }
- if (releaseLockCurrentFileEntry) {
- releaseLockCurrentFileEntry();
- }
- if (releaseLockWriter) {
- releaseLockWriter();
- }
- }
-
- function requestLockCurrentFileEntry() {
- fileEntry.lock = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
- }
-
- async function requestLockWriter() {
- zipWriter.writerLocked = true;
- const { lockWriter } = zipWriter;
- zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
- zipWriter.writerLocked = false;
- resolve();
- });
- await lockWriter;
- }
-
- async function skipDiskIfNeeded(writable) {
- if (getLength(headerInfo.localHeaderArray) > writer.availableSize) {
- writer.availableSize = 0;
- await writeData(writable, new Uint8Array());
- }
- }
- }
-
- async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryInfo, config, options) {
- const {
- headerInfo,
- dataDescriptorInfo,
- metadataSize
- } = entryInfo;
- const {
- headerArray,
- headerView,
- lastModDate,
- rawLastModDate,
- encrypted,
- compressed,
- version,
- compressionMethod,
- rawExtraFieldZip64,
- localExtraFieldZip64Length,
- rawExtraFieldExtendedTimestamp,
- extraFieldExtendedTimestampFlag,
- rawExtraFieldNTFS,
- rawExtraFieldUnix,
- rawExtraFieldAES,
- } = headerInfo;
- const { dataDescriptorArray } = dataDescriptorInfo;
- const {
- rawFilename,
- lastAccessDate,
- creationDate,
- password,
- rawPassword,
- level,
- zip64,
- zip64UncompressedSize,
- zip64CompressedSize,
- zipCrypto,
- dataDescriptor,
- directory,
- executable,
- versionMadeBy,
- rawComment,
- rawExtraField,
- useWebWorkers,
- transferStreams,
- onstart,
- onprogress,
- onend,
- signal,
- encryptionStrength,
- extendedTimestamp,
- msDosCompatible,
- internalFileAttributes,
- externalFileAttributes,
- uid,
- gid,
- unixMode,
- setuid,
- setgid,
- sticky,
- unixExternalUpper,
- msdosAttributesRaw,
- msdosAttributes,
- useCompressionStream,
- passThrough
- } = options;
- const fileEntry = {
- lock,
- versionMadeBy,
- zip64,
- directory: Boolean(directory),
- executable: Boolean(executable),
- filenameUTF8: true,
- rawFilename,
- commentUTF8: true,
- rawComment,
- rawExtraFieldZip64,
- localExtraFieldZip64Length,
- rawExtraFieldExtendedTimestamp,
- rawExtraFieldNTFS,
- rawExtraFieldUnix,
- rawExtraFieldAES,
- rawExtraField,
- extendedTimestamp,
- msDosCompatible,
- internalFileAttributes,
- externalFileAttributes,
- diskNumberStart,
- uid,
- gid,
- unixMode,
- setuid,
- setgid,
- sticky,
- unixExternalUpper,
- msdosAttributesRaw,
- msdosAttributes
- };
- let {
- signature,
- uncompressedSize
- } = options;
- let compressedSize = 0;
- if (!passThrough) {
- uncompressedSize = 0;
- }
- const { writable } = writer;
- if (reader) {
- reader.chunkSize = getChunkSize(config);
- const readable = reader.readable;
- const size = reader.size;
- const workerOptions = {
- options: {
- codecType: CODEC_DEFLATE,
- level,
- rawPassword,
- password,
- encryptionStrength,
- zipCrypto: encrypted && zipCrypto,
- passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
- signed: !passThrough,
- compressed: compressed && !passThrough,
- encrypted: encrypted && !passThrough,
- useWebWorkers,
- useCompressionStream,
- transferStreams
- },
- config,
- streamOptions: { signal, size, onstart, onprogress, onend }
- };
- try {
- const result = await runWorker({ readable, writable }, workerOptions);
- compressedSize = result.outputSize;
- writer.size += compressedSize;
- if (!passThrough) {
- uncompressedSize = result.inputSize;
- signature = result.signature;
- }
- } catch (error) {
- if (error.outputSize !== UNDEFINED_VALUE) {
- writer.size += error.outputSize;
- }
- throw error;
- }
-
- }
- setEntryInfo({
- signature,
- compressedSize,
- uncompressedSize,
- headerInfo,
- dataDescriptorInfo
- }, options);
- if (dataDescriptor) {
- await writeData(writer, dataDescriptorArray);
- }
- Object.assign(fileEntry, {
- uncompressedSize,
- compressedSize,
- lastModDate,
- rawLastModDate,
- creationDate,
- lastAccessDate,
- encrypted,
- zipCrypto,
- size: metadataSize + compressedSize,
- compressionMethod,
- version,
- headerArray,
- headerView,
- signature,
- extraFieldExtendedTimestampFlag,
- zip64UncompressedSize,
- zip64CompressedSize
- });
- return fileEntry;
- }
-
- function getHeaderInfo(options) {
- const {
- rawFilename,
- lastModDate,
- lastAccessDate,
- creationDate,
- level,
- zip64,
- zipCrypto,
- useUnicodeFileNames,
- dataDescriptor,
- directory,
- rawExtraField,
- encryptionStrength,
- extendedTimestamp,
- passThrough,
- encrypted,
- zip64UncompressedSize,
- zip64CompressedSize,
- uncompressedSize
- } = options;
- let { version, compressionMethod } = options;
- const compressed = !directory && (level > 0 || (level === UNDEFINED_VALUE && compressionMethod !== 0));
- let rawLocalExtraFieldZip64;
- const uncompressedFile = passThrough || !compressed;
- const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || ((!zip64UncompressedSize && !zip64CompressedSize) || uncompressedFile));
- if (zip64) {
- let rawLocalExtraFieldZip64Length = 4;
- if (zip64UncompressedSize) {
- rawLocalExtraFieldZip64Length += 8;
- }
- if (zip64CompressedSize) {
- rawLocalExtraFieldZip64Length += 8;
- }
- rawLocalExtraFieldZip64 = new Uint8Array(rawLocalExtraFieldZip64Length);
- const rawLocalExtraFieldZip64View = getDataView(rawLocalExtraFieldZip64);
- setUint16(rawLocalExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
- setUint16(rawLocalExtraFieldZip64View, 2, getLength(rawLocalExtraFieldZip64) - 4);
- if (zip64ExtraFieldComplete) {
- const rawLocalExtraFieldZip64View = getDataView(rawLocalExtraFieldZip64);
- let rawLocalExtraFieldZip64Offset = 4;
- if (zip64UncompressedSize) {
- setBigUint64(rawLocalExtraFieldZip64View, rawLocalExtraFieldZip64Offset, BigInt(uncompressedSize));
- rawLocalExtraFieldZip64Offset += 8;
- }
- if (zip64CompressedSize && uncompressedFile) {
- setBigUint64(rawLocalExtraFieldZip64View, rawLocalExtraFieldZip64Offset, BigInt(uncompressedSize));
- rawLocalExtraFieldZip64Offset += 8;
- }
- if (rawLocalExtraFieldZip64Offset == 4) {
- rawLocalExtraFieldZip64 = new Uint8Array();
- }
- }
- } else {
- rawLocalExtraFieldZip64 = new Uint8Array();
- }
- let rawExtraFieldAES;
- if (encrypted && !zipCrypto) {
- rawExtraFieldAES = new Uint8Array(getLength(EXTRAFIELD_DATA_AES) + 2);
- const extraFieldAESView = getDataView(rawExtraFieldAES);
- setUint16(extraFieldAESView, 0, EXTRAFIELD_TYPE_AES);
- arraySet(rawExtraFieldAES, EXTRAFIELD_DATA_AES, 2);
- setUint8(extraFieldAESView, 8, encryptionStrength);
- } else {
- rawExtraFieldAES = new Uint8Array();
- }
- let rawExtraFieldNTFS;
- let rawExtraFieldExtendedTimestamp;
- let extraFieldExtendedTimestampFlag;
- if (extendedTimestamp) {
- rawExtraFieldExtendedTimestamp = new Uint8Array(9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0));
- const extraFieldExtendedTimestampView = getDataView(rawExtraFieldExtendedTimestamp);
- setUint16(extraFieldExtendedTimestampView, 0, EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
- setUint16(extraFieldExtendedTimestampView, 2, getLength(rawExtraFieldExtendedTimestamp) - 4);
- extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
- setUint8(extraFieldExtendedTimestampView, 4, extraFieldExtendedTimestampFlag);
- let offset = 5;
- setUint32(extraFieldExtendedTimestampView, offset, Math.floor(lastModDate.getTime() / 1000));
- offset += 4;
- if (lastAccessDate) {
- setUint32(extraFieldExtendedTimestampView, offset, Math.floor(lastAccessDate.getTime() / 1000));
- offset += 4;
- }
- if (creationDate) {
- setUint32(extraFieldExtendedTimestampView, offset, Math.floor(creationDate.getTime() / 1000));
- }
- try {
- rawExtraFieldNTFS = new Uint8Array(36);
- const extraFieldNTFSView = getDataView(rawExtraFieldNTFS);
- const lastModTimeNTFS = getTimeNTFS(lastModDate);
- setUint16(extraFieldNTFSView, 0, EXTRAFIELD_TYPE_NTFS);
- setUint16(extraFieldNTFSView, 2, 32);
- setUint16(extraFieldNTFSView, 8, EXTRAFIELD_TYPE_NTFS_TAG1);
- setUint16(extraFieldNTFSView, 10, 24);
- setBigUint64(extraFieldNTFSView, 12, lastModTimeNTFS);
- setBigUint64(extraFieldNTFSView, 20, getTimeNTFS(lastAccessDate) || lastModTimeNTFS);
- setBigUint64(extraFieldNTFSView, 28, getTimeNTFS(creationDate) || lastModTimeNTFS);
- } catch {
- rawExtraFieldNTFS = new Uint8Array();
- }
- } else {
- rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array();
- }
- let rawExtraFieldUnix;
- try {
- const { uid, gid, unixMode, setuid, setgid, sticky, unixExtraFieldType } = options;
- if (unixExtraFieldType && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE)) {
- const uidBytes = packUnixId(uid);
- const gidBytes = packUnixId(gid);
- let modeArray = new Uint8Array();
- if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && unixMode !== UNDEFINED_VALUE) {
- let modeToWrite = unixMode & MAX_16_BITS;
- if (setuid) {
- modeToWrite |= FILE_ATTR_UNIX_SETUID_MASK;
- }
- if (setgid) {
- modeToWrite |= FILE_ATTR_UNIX_SETGID_MASK;
- }
- if (sticky) {
- modeToWrite |= FILE_ATTR_UNIX_STICKY_MASK;
- }
- modeArray = new Uint8Array(2);
- const modeDataView = new DataView(modeArray.buffer);
- modeDataView.setUint16(0, modeToWrite, true);
- }
- const payloadLength = 3 + uidBytes.length + gidBytes.length + modeArray.length;
- rawExtraFieldUnix = new Uint8Array(4 + payloadLength);
- const rawExtraFieldUnixView = getDataView(rawExtraFieldUnix);
- setUint16(rawExtraFieldUnixView, 0, unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE ? EXTRAFIELD_TYPE_INFOZIP : EXTRAFIELD_TYPE_UNIX);
- setUint16(rawExtraFieldUnixView, 2, payloadLength);
- setUint8(rawExtraFieldUnixView, 4, 1);
- setUint8(rawExtraFieldUnixView, 5, uidBytes.length);
- let offset = 6;
- arraySet(rawExtraFieldUnix, uidBytes, offset);
- offset += uidBytes.length;
- setUint8(rawExtraFieldUnixView, offset, gidBytes.length);
- offset++;
- arraySet(rawExtraFieldUnix, gidBytes, offset);
- offset += gidBytes.length;
- arraySet(rawExtraFieldUnix, modeArray, offset);
- } else {
- rawExtraFieldUnix = new Uint8Array();
- }
- } catch {
- rawExtraFieldUnix = new Uint8Array();
- }
- if (compressionMethod === UNDEFINED_VALUE) {
- compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
- }
- if (zip64) {
- version = version > VERSION_ZIP64 ? version : VERSION_ZIP64;
- }
- if (encrypted && !zipCrypto) {
- version = version > VERSION_AES ? version : VERSION_AES;
- rawExtraFieldAES[9] = compressionMethod;
- compressionMethod = COMPRESSION_METHOD_AES;
- }
- const localExtraFieldZip64Length = zip64ExtraFieldComplete ? getLength(rawLocalExtraFieldZip64) : 0;
- const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
- const {
- headerArray,
- headerView,
- rawLastModDate
- } = getHeaderArrayData({
- version,
- bitFlag: getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod),
- compressionMethod,
- uncompressedSize,
- lastModDate: lastModDate < MIN_DATE ? MIN_DATE : lastModDate > MAX_DATE ? MAX_DATE : lastModDate,
- rawFilename,
- zip64CompressedSize,
- zip64UncompressedSize,
- extraFieldLength
- });
- let localHeaderOffset = HEADER_SIZE;
- const localHeaderArray = new Uint8Array(localHeaderOffset + getLength(rawFilename) + extraFieldLength);
- const localHeaderView = getDataView(localHeaderArray);
- setUint32(localHeaderView, 0, LOCAL_FILE_HEADER_SIGNATURE);
- arraySet(localHeaderArray, headerArray, 4);
- arraySet(localHeaderArray, rawFilename, localHeaderOffset);
- localHeaderOffset += getLength(rawFilename);
- if (zip64ExtraFieldComplete) {
- arraySet(localHeaderArray, rawLocalExtraFieldZip64, localHeaderOffset);
- }
- localHeaderOffset += localExtraFieldZip64Length;
- arraySet(localHeaderArray, rawExtraFieldAES, localHeaderOffset);
- localHeaderOffset += getLength(rawExtraFieldAES);
- arraySet(localHeaderArray, rawExtraFieldExtendedTimestamp, localHeaderOffset);
- localHeaderOffset += getLength(rawExtraFieldExtendedTimestamp);
- arraySet(localHeaderArray, rawExtraFieldNTFS, localHeaderOffset);
- localHeaderOffset += getLength(rawExtraFieldNTFS);
- arraySet(localHeaderArray, rawExtraFieldUnix, localHeaderOffset);
- localHeaderOffset += getLength(rawExtraFieldUnix);
- arraySet(localHeaderArray, rawExtraField, localHeaderOffset);
- if (dataDescriptor) {
- setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + 4, 0);
- setUint32(localHeaderView, HEADER_OFFSET_UNCOMPRESSED_SIZE + 4, 0);
- }
- return {
- localHeaderArray,
- localHeaderView,
- headerArray,
- headerView,
- lastModDate,
- rawLastModDate,
- encrypted,
- compressed,
- version,
- compressionMethod,
- extraFieldExtendedTimestampFlag,
- rawExtraFieldZip64: new Uint8Array(),
- localExtraFieldZip64Length,
- rawExtraFieldExtendedTimestamp,
- rawExtraFieldNTFS,
- rawExtraFieldUnix,
- rawExtraFieldAES,
- extraFieldLength
- };
- }
-
- function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
- const { headerInfo } = entryInfo;
- let { localHeaderArray, extraFieldLength } = headerInfo;
- let localHeaderArrayView = getDataView(localHeaderArray);
- let extraBytesLength = 64 - ((zipWriterOffset + getLength(localHeaderArray)) % 64);
- if (extraBytesLength < 4) {
- extraBytesLength += 64;
- }
- const rawExtraFieldUSDZ = new Uint8Array(extraBytesLength);
- const extraFieldUSDZView = getDataView(rawExtraFieldUSDZ);
- setUint16(extraFieldUSDZView, 0, EXTRAFIELD_TYPE_USDZ);
- setUint16(extraFieldUSDZView, 2, extraBytesLength - 2);
- const previousLocalHeaderArray = localHeaderArray;
- headerInfo.localHeaderArray = localHeaderArray = new Uint8Array(getLength(previousLocalHeaderArray) + extraBytesLength);
- arraySet(localHeaderArray, previousLocalHeaderArray);
- arraySet(localHeaderArray, rawExtraFieldUSDZ, getLength(previousLocalHeaderArray));
- localHeaderArrayView = getDataView(localHeaderArray);
- setUint16(localHeaderArrayView, 28, extraFieldLength + extraBytesLength);
- entryInfo.metadataSize += extraBytesLength;
- }
-
- function packUnixId(id) {
- if (id === UNDEFINED_VALUE) {
- return new Uint8Array();
- } else {
- const dataArray = new Uint8Array(4);
- const dataView = getDataView(dataArray);
- dataView.setUint32(0, id, true);
- let length = 4;
- while (length > 1 && dataArray[length - 1] === 0) {
- length--;
- }
- return dataArray.subarray(0, length);
- }
- }
-
- function normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes) {
- if (msdosAttributesRaw !== UNDEFINED_VALUE) {
- msdosAttributesRaw = msdosAttributesRaw & MAX_8_BITS;
- } else if (msdosAttributes !== UNDEFINED_VALUE) {
- const { readOnly, hidden, system, directory: msdDir, archive } = msdosAttributes;
- let raw = 0;
- if (readOnly) raw |= FILE_ATTR_MSDOS_READONLY_MASK;
- if (hidden) raw |= FILE_ATTR_MSDOS_HIDDEN_MASK;
- if (system) raw |= FILE_ATTR_MSDOS_SYSTEM_MASK;
- if (msdDir) raw |= FILE_ATTR_MSDOS_DIR_MASK;
- if (archive) raw |= FILE_ATTR_MSDOS_ARCHIVE_MASK;
- msdosAttributesRaw = raw & MAX_8_BITS;
- }
- if (msdosAttributes === UNDEFINED_VALUE) {
- msdosAttributes = {
- readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
- hidden: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_HIDDEN_MASK),
- system: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_SYSTEM_MASK),
- directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
- archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
- };
- }
- return { msdosAttributesRaw, msdosAttributes };
- }
-
- function getDataDescriptorInfo({
- zip64,
- dataDescriptor,
- dataDescriptorSignature
- }) {
- let dataDescriptorArray = new Uint8Array();
- let dataDescriptorView, dataDescriptorOffset = 0;
- let dataDescriptorLength = zip64 ? DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH : DATA_DESCRIPTOR_RECORD_LENGTH;
- if (dataDescriptorSignature) {
- dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
- }
- if (dataDescriptor) {
- dataDescriptorArray = new Uint8Array(dataDescriptorLength);
- dataDescriptorView = getDataView(dataDescriptorArray);
- if (dataDescriptorSignature) {
- dataDescriptorOffset = DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
- setUint32(dataDescriptorView, 0, DATA_DESCRIPTOR_RECORD_SIGNATURE);
- }
- }
- return {
- dataDescriptorArray,
- dataDescriptorView,
- dataDescriptorOffset
- };
- }
-
- function setEntryInfo({
- signature,
- compressedSize,
- uncompressedSize,
- headerInfo,
- dataDescriptorInfo
- }, {
- zip64,
- zipCrypto,
- dataDescriptor
- }) {
- const {
- headerView,
- encrypted
- } = headerInfo;
- const {
- dataDescriptorView,
- dataDescriptorOffset
- } = dataDescriptorInfo;
- if ((!encrypted || zipCrypto) && signature !== UNDEFINED_VALUE) {
- setUint32(headerView, HEADER_OFFSET_SIGNATURE, signature);
- if (dataDescriptor) {
- setUint32(dataDescriptorView, dataDescriptorOffset, signature);
- }
- }
- if (zip64) {
- if (dataDescriptor) {
- setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
- setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
- }
- } else {
- setUint32(headerView, HEADER_OFFSET_COMPRESSED_SIZE, compressedSize);
- setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
- if (dataDescriptor) {
- setUint32(dataDescriptorView, dataDescriptorOffset + 4, compressedSize);
- setUint32(dataDescriptorView, dataDescriptorOffset + 8, uncompressedSize);
- }
- }
- }
-
- function updateLocalHeader({
- rawFilename,
- encrypted,
- zip64,
- localExtraFieldZip64Length,
- signature,
- compressedSize,
- uncompressedSize,
- zip64UncompressedSize,
- zip64CompressedSize
- }, localHeaderView, { dataDescriptor }) {
- if (!dataDescriptor) {
- if (!encrypted) {
- setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + 4, signature);
- }
- if (!zip64CompressedSize) {
- setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + 4, compressedSize);
- }
- if (!zip64UncompressedSize) {
- setUint32(localHeaderView, HEADER_OFFSET_UNCOMPRESSED_SIZE + 4, uncompressedSize);
- }
- }
- if (zip64 && localExtraFieldZip64Length) {
- let localHeaderOffset = HEADER_SIZE + getLength(rawFilename) + 4;
- if (zip64UncompressedSize) {
- setBigUint64(localHeaderView, localHeaderOffset, BigInt(uncompressedSize));
- localHeaderOffset += 8;
- }
- if (zip64CompressedSize) {
- setBigUint64(localHeaderView, localHeaderOffset, BigInt(compressedSize));
- localHeaderOffset += 8;
- }
- }
- }
-
-
- async function closeFile(zipWriter, comment, options) {
- const { files, writer } = zipWriter;
- const { diskOffset } = writer;
- let { diskNumber } = writer;
- let offset = 0;
- let directoryDataLength = 0;
- let directoryOffset = zipWriter.offset - diskOffset;
- let filesLength = files.size;
- for (const [, fileEntry] of files) {
- const {
- rawFilename,
- rawExtraFieldAES,
- rawComment,
- rawExtraFieldNTFS,
- rawExtraFieldUnix,
- rawExtraField,
- extendedTimestamp,
- extraFieldExtendedTimestampFlag,
- lastModDate,
- zip64UncompressedSize,
- zip64CompressedSize,
- uncompressedSize,
- compressedSize
- } = fileEntry;
- const zip64Offset = fileEntry.offset > MAX_32_BITS;
- const zip64DiskNumberStart = fileEntry.diskNumberStart > MAX_16_BITS;
- let rawExtraFieldZip64;
- if (zip64Offset || zip64DiskNumberStart || zip64UncompressedSize || zip64CompressedSize) {
- let length = 4;
- if (zip64UncompressedSize) length += 8;
- if (zip64CompressedSize) length += 8;
- if (zip64Offset) length += 8;
- if (zip64DiskNumberStart) length += 4;
- rawExtraFieldZip64 = new Uint8Array(length);
- const zip64View = getDataView(rawExtraFieldZip64);
- setUint16(zip64View, 0, EXTRAFIELD_TYPE_ZIP64);
- setUint16(zip64View, 2, length - 4);
- let zip64FieldOffset = 4;
- if (zip64UncompressedSize) { setBigUint64(zip64View, zip64FieldOffset, BigInt(uncompressedSize)); zip64FieldOffset += 8; }
- if (zip64CompressedSize) { setBigUint64(zip64View, zip64FieldOffset, BigInt(compressedSize)); zip64FieldOffset += 8; }
- if (zip64Offset) { setBigUint64(zip64View, zip64FieldOffset, BigInt(fileEntry.offset)); zip64FieldOffset += 8; }
- if (zip64DiskNumberStart) { setUint32(zip64View, zip64FieldOffset, fileEntry.diskNumberStart); }
- } else {
- rawExtraFieldZip64 = new Uint8Array();
- }
- fileEntry.rawExtraFieldZip64 = rawExtraFieldZip64;
- fileEntry.zip64Offset = zip64Offset;
- fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
- let rawExtraFieldTimestamp;
- if (extendedTimestamp) {
- rawExtraFieldTimestamp = new Uint8Array(9);
- const extraFieldExtendedTimestampView = getDataView(rawExtraFieldTimestamp);
- setUint16(extraFieldExtendedTimestampView, 0, EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
- setUint16(extraFieldExtendedTimestampView, 2, 5);
- setUint8(extraFieldExtendedTimestampView, 4, extraFieldExtendedTimestampFlag);
- setUint32(extraFieldExtendedTimestampView, 5, Math.floor(lastModDate.getTime() / 1000));
- } else {
- rawExtraFieldTimestamp = new Uint8Array();
- }
- fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
- directoryDataLength += 46 +
- getLength(
- rawFilename,
- rawComment,
- rawExtraFieldZip64,
- rawExtraFieldAES,
- rawExtraFieldNTFS,
- rawExtraFieldUnix,
- rawExtraFieldTimestamp,
- rawExtraField);
- }
- const directoryArray = new Uint8Array(directoryDataLength);
- const directoryView = getDataView(directoryArray);
- await initStream(writer);
- let directoryDiskOffset = 0;
- for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
- const {
- offset: fileEntryOffset,
- rawFilename,
- rawExtraFieldZip64,
- rawExtraFieldAES,
- rawExtraFieldExtendedTimestamp,
- rawExtraFieldNTFS,
- rawExtraFieldUnix,
- rawExtraField,
- rawComment,
- versionMadeBy,
- headerArray,
- headerView,
- zip64UncompressedSize,
- zip64CompressedSize,
- zip64DiskNumberStart,
- zip64Offset,
- internalFileAttributes,
- externalFileAttributes,
- diskNumberStart,
- uncompressedSize,
- compressedSize
- } = fileEntry;
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
- setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
- setUint16(directoryView, offset + 4, versionMadeBy);
- if (!zip64UncompressedSize) {
- setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
- }
- if (!zip64CompressedSize) {
- setUint32(headerView, HEADER_OFFSET_COMPRESSED_SIZE, compressedSize);
- }
- arraySet(directoryArray, headerArray, offset + 6);
- let directoryOffset = offset + HEADER_SIZE;
- setUint16(directoryView, directoryOffset, extraFieldLength);
- directoryOffset += 2;
- setUint16(directoryView, directoryOffset, getLength(rawComment));
- directoryOffset += 2;
- setUint16(directoryView, directoryOffset, zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
- directoryOffset += 2;
- setUint16(directoryView, directoryOffset, internalFileAttributes);
- directoryOffset += 2;
- if (externalFileAttributes) {
- setUint32(directoryView, directoryOffset, externalFileAttributes);
- }
- directoryOffset += 4;
- setUint32(directoryView, directoryOffset, zip64Offset ? MAX_32_BITS : fileEntryOffset);
- directoryOffset += 4;
- arraySet(directoryArray, rawFilename, directoryOffset);
- directoryOffset += getLength(rawFilename);
- arraySet(directoryArray, rawExtraFieldZip64, directoryOffset);
- directoryOffset += getLength(rawExtraFieldZip64);
- arraySet(directoryArray, rawExtraFieldAES, directoryOffset);
- directoryOffset += getLength(rawExtraFieldAES);
- arraySet(directoryArray, rawExtraFieldExtendedTimestamp, directoryOffset);
- directoryOffset += getLength(rawExtraFieldExtendedTimestamp);
- arraySet(directoryArray, rawExtraFieldNTFS, directoryOffset);
- directoryOffset += getLength(rawExtraFieldNTFS);
- arraySet(directoryArray, rawExtraFieldUnix, directoryOffset);
- directoryOffset += getLength(rawExtraFieldUnix);
- arraySet(directoryArray, rawExtraField, directoryOffset);
- directoryOffset += getLength(rawExtraField);
- arraySet(directoryArray, rawComment, directoryOffset);
- directoryOffset += getLength(rawComment);
- if (offset - directoryDiskOffset > writer.availableSize) {
- writer.availableSize = 0;
- await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
- directoryDiskOffset = offset;
- }
- offset = directoryOffset;
- if (options.onprogress) {
- try {
- await options.onprogress(indexFileEntry + 1, files.size, new Entry(fileEntry));
- } catch {
- // ignored
- }
- }
- }
- await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
- let lastDiskNumber = writer.diskNumber;
- const { availableSize } = writer;
- if (availableSize < END_OF_CENTRAL_DIR_LENGTH) {
- lastDiskNumber++;
- }
- let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
- if (directoryOffset > MAX_32_BITS || directoryDataLength > MAX_32_BITS || filesLength > MAX_16_BITS || lastDiskNumber > MAX_16_BITS) {
- if (zip64 === false) {
- throw new Error(ERR_UNSUPPORTED_FORMAT);
- } else {
- zip64 = true;
- }
- }
- const endOfdirectoryArray = new Uint8Array(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
- const endOfdirectoryView = getDataView(endOfdirectoryArray);
- offset = 0;
- if (zip64) {
- setUint32(endOfdirectoryView, 0, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
- setBigUint64(endOfdirectoryView, 4, BigInt(44));
- setUint16(endOfdirectoryView, 12, 45);
- setUint16(endOfdirectoryView, 14, 45);
- setUint32(endOfdirectoryView, 16, lastDiskNumber);
- setUint32(endOfdirectoryView, 20, diskNumber);
- setBigUint64(endOfdirectoryView, 24, BigInt(filesLength));
- setBigUint64(endOfdirectoryView, 32, BigInt(filesLength));
- setBigUint64(endOfdirectoryView, 40, BigInt(directoryDataLength));
- setBigUint64(endOfdirectoryView, 48, BigInt(directoryOffset));
- setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
- setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength));
- setUint32(endOfdirectoryView, 72, lastDiskNumber + 1);
- const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
- if (supportZip64SplitFile) {
- lastDiskNumber = MAX_16_BITS;
- diskNumber = MAX_16_BITS;
- }
- filesLength = MAX_16_BITS;
- directoryOffset = MAX_32_BITS;
- directoryDataLength = MAX_32_BITS;
- offset += ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
- }
- setUint32(endOfdirectoryView, offset, END_OF_CENTRAL_DIR_SIGNATURE);
- setUint16(endOfdirectoryView, offset + 4, lastDiskNumber);
- setUint16(endOfdirectoryView, offset + 6, diskNumber);
- setUint16(endOfdirectoryView, offset + 8, filesLength);
- setUint16(endOfdirectoryView, offset + 10, filesLength);
- setUint32(endOfdirectoryView, offset + 12, directoryDataLength);
- setUint32(endOfdirectoryView, offset + 16, directoryOffset);
- const commentLength = getLength(comment);
- if (commentLength) {
- if (commentLength <= MAX_16_BITS) {
- setUint16(endOfdirectoryView, offset + 20, commentLength);
- } else {
- throw new Error(ERR_INVALID_COMMENT);
- }
- }
- await writeData(writer, endOfdirectoryArray);
- if (commentLength) {
- await writeData(writer, comment);
- }
- }
-
- async function writeData(writer, array) {
- const { writable } = writer;
- const streamWriter = writable.getWriter();
- try {
- await streamWriter.ready;
- writer.size += getLength(array);
- await streamWriter.write(array);
- } finally {
- streamWriter.releaseLock();
- }
- }
-
- function getTimeNTFS(date) {
- if (date) {
- return ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
- }
- }
-
- function getOptionValue(zipWriter, options, name, defaultValue) {
- const result = options[name] === UNDEFINED_VALUE ? zipWriter.options[name] : options[name];
- return result === UNDEFINED_VALUE ? defaultValue : result;
- }
-
- function getMaximumCompressedSize(uncompressedSize) {
- return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
- }
-
- function setUint8(view, offset, value) {
- view.setUint8(offset, value);
- }
-
- function setUint16(view, offset, value) {
- view.setUint16(offset, value, true);
- }
-
- function setUint32(view, offset, value) {
- view.setUint32(offset, value, true);
- }
-
- function setBigUint64(view, offset, value) {
- view.setBigUint64(offset, value, true);
- }
-
- function arraySet(array, typedArray, offset) {
- array.set(typedArray, offset);
- }
-
- function getDataView(array) {
- return new DataView(array.buffer);
- }
-
- function getLength(...arrayLikes) {
- let result = 0;
- arrayLikes.forEach(arrayLike => arrayLike && (result += arrayLike.length));
- return result;
- }
-
- function getHeaderArrayData({
- version,
- bitFlag,
- compressionMethod,
- uncompressedSize,
- compressedSize,
- lastModDate,
- rawFilename,
- zip64CompressedSize,
- zip64UncompressedSize,
- extraFieldLength
- }) {
- const headerArray = new Uint8Array(HEADER_SIZE - 4);
- const headerView = getDataView(headerArray);
- setUint16(headerView, 0, version);
- setUint16(headerView, 2, bitFlag);
- setUint16(headerView, 4, compressionMethod);
- const dateArray = new Uint32Array(1);
- const dateView = getDataView(dateArray);
- setUint16(dateView, 0, (((lastModDate.getHours() << 6) | lastModDate.getMinutes()) << 5) | lastModDate.getSeconds() / 2);
- setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
- const rawLastModDate = dateArray[0];
- setUint32(headerView, 6, rawLastModDate);
- if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
- setUint32(headerView, HEADER_OFFSET_COMPRESSED_SIZE, zip64CompressedSize ? MAX_32_BITS : compressedSize);
- }
- if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
- setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
- }
- setUint16(headerView, 22, getLength(rawFilename));
- setUint16(headerView, 24, extraFieldLength);
- return {
- headerArray,
- headerView,
- rawLastModDate
- };
- }
-
- function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
- let bitFlag = 0;
- if (useUnicodeFileNames) {
- bitFlag = bitFlag | BITFLAG_LANG_ENCODING_FLAG;
- }
- if (dataDescriptor) {
- bitFlag = bitFlag | BITFLAG_DATA_DESCRIPTOR;
- }
- if (compressionMethod == COMPRESSION_METHOD_DEFLATE || compressionMethod == COMPRESSION_METHOD_DEFLATE_64) {
- if (level >= 0 && level <= 3) {
- bitFlag = bitFlag | BITFLAG_LEVEL_SUPER_FAST_MASK;
- }
- if (level > 3 && level <= 5) {
- bitFlag = bitFlag | BITFLAG_LEVEL_FAST_MASK;
- }
- if (level == 9) {
- bitFlag = bitFlag | BITFLAG_LEVEL_MAX_MASK;
- }
- }
- if (encrypted) {
- bitFlag = bitFlag | BITFLAG_ENCRYPTED;
- }
- return bitFlag;
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- function getMimeType$1() {
- return "application/octet-stream";
- }
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- try {
- configure({ baseURI: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('zip-fs-native.js', document.baseURI).href)) });
- } catch {
- // ignored
- }
-
- var{Uint8Array:x,Uint16Array:E,Int32Array:H,TransformStream:U,Math:N,Error:z,Array:v}=globalThis,Se=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],F=new x(0),qe=new E(0),de=[];for(let e=0;e<6;e++)de.push(e,0==e?8:4);de.push(0,1);var Ee=[];for(let e=0;e<14;e++)Ee.push(e,0==e?4:2);var ge=new E([0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576]),Te=new E([0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0]);function M(e,t,n,r,i){if(0==i)return;let f=e instanceof x?e:new x(e.buffer,e.byteOffset,e.byteLength),_=n instanceof x?n.subarray(r,r+i):new x(n.buffer,n.byteOffset+r,i);f.set(_,t);}function je(e,t,n){0!=n&&(e instanceof x?e:new x(e.buffer,e.byteOffset,e.byteLength)).fill(0,t,t+n);}function Ve(){return {next_in:F,next_in_index:0,avail_in:0,total_in:0,next_out:F,next_out_index:0,avail_out:0,total_out:0,msg:"",t:0,i:0,_:0,l:void 0}}function Je(e,t){let n=1<<t;return {o:e,u:new x(n),h:n,v:t,k:0,m:0,p:0,I:0}}function te(e){let t=[];for(let n=0;n<e.length;n+=2){let r=e[n],i=e[n+1];for(let e=0;e<i;e++)t.push(r);}return new E(t)}var ne=class{constructor(e,t){this.L=e,this.M=t,this.F=0;}},re=class{constructor(e,t,n,r,i){this.q=e,this.N=t,this.V=n,this.W=r,this.S=i;}};function g_(e){return V_[e<-6||e>2?9:2-e]||""}function Ae(e,t){try{e.msg=g_(t);}catch(n){e.msg="zlib error "+String(t)+" ("+n+")";}return t}function $e(e,t){let n=e>>>0,r=0;for(let e=0;e<t;e++)r=r<<1|1&n,n>>>=1;return r}function g(e,t){e.$[e.A++]=t;}function De(e,t){g(e,255&t),g(e,t>>>8&255);}function e_(e,t,n){let r=255&n,i=65535&t,f=e.U+e.D;return e.$[f]=255&i,e.$[f+1]=i>>>8&255,e.$[f+2]=r,e.D+=3,i=i-1&65535,e.C[__[r]+ie+1].Z++,e.T[T_(i)].Z++,e.D==e.B}function ye(e,t){let n=255&t,r=e.U+e.D;return e.$[r]=0,e.$[r+1]=0,e.$[r+2]=n,e.D+=3,e.C[n].Z++,e.D==e.B}function ve(e){return e.h-ae}function T_(e){return e<256?E_[e]:E_[256+(e>>7)]}function w_(e){let t=He+7,n=1<<t,r=(1<<t)-1,i=N.floor((t+I-1)/I),f=1<<8+He;return {...Je(e,15),o:e,R:42,G:0,O:void 0,P:32767,H:t,J:n,X:r,Y:i,j:new E(32768),K:new E(n),ee:f,$:new x(32768),te:0,ne:32768,A:0,re:0,ie:0,fe:0,_e:0,le:0,oe:-2,ue:0,ae:0,ce:0,se:0,he:0,de:0,we:0,be:0,ge:0,ve:0,ke:0,me:0,xe:0,ye:0,pe:new H(2*we+1),Ie:new x(2*we+1),ze:new E(be+1),D:0,B:0,Le:F,U:0,Ee:0,Me:0,Fe:8,qe:32768,Ne:0,Ve:0,We:0,C:new v(le).fill(0).map(()=>Q()),T:new v(2*me+1).fill(0).map(()=>Q()),Se:new v(2*oe+1).fill(0).map(()=>Q()),$e:S_(),Ae:S_(),Ue:S_()}}function A_(e){let t=[];for(let n=0;n<e.length;n+=2){let r=e[n],i=e[n+1],f=Q();f.Qe=r,f.De=i,t.push(f);}return t}function Q(){return {Z:0,Qe:0,Ze:0,De:0}}function S_(){return new ne([],mn(null,F,0,0,0))}function mn(e,t,n,r,i){return new re(e,t,n,r,i)}function J_(){let e=new v(288).fill(0);for(let t=0;t<=143;t++)e[t]=8;for(let t=144;t<=255;t++)e[t]=9;for(let t=256;t<=279;t++)e[t]=7;for(let t=280;t<=287;t++)e[t]=8;return e}function D_(e){let{code:t,length:n}=bn(e),r=new E(2*e.length),i=0;for(let f=0;f<e.length;f++){let e=n[f]||0,_=t[f]||0;r[i++]=e?$e(_,e):0,r[i++]=e;}return new E(r)}function Q_(e,t,n){let r=0;for(let n=0;n<e.length;n++){let i=t[n]?1<<t[n]:1,f=e[n]+i-1;f>r&&(r=f);}r<n&&(r=n);let i=new x(r+1);for(let n=0;n<=r;n++)for(let r=0;r<e.length;r++){let f=t[r]?1<<t[r]:1,_=e[r];if(n>=_&&n<=_+f-1){i[n]=r;break}}return i}function $_(e,t){let n=0;for(let r=0;r<e.length;r++){let i=t[r]?1<<t[r]:1,f=e[r]+i-1;f>n&&(n=f);}let r=new x(n+1);for(let i=0;i<=n;i++)for(let n=0;n<e.length;n++){let f=t[n]?1<<t[n]:1,_=e[n];if(i>=_&&i<=_+f-1){r[i]=n;break}}return r}function et(e){let t=new x(512),n=e.length-1;for(let r=0;r<256;r++)t[r]=r<=n?e[r]:e[n];for(let r=256;r<=n;r++){let n=r>>7;t[256+(n>255?255:n)]=e[r];}for(let e=257;e<512;e++)0==t[e]&&(t[e]=t[e-1]);return t}function bn(e){let t=N.max(...e),n=new v(t+1).fill(0);for(let t of e)t>0&&n[t]++;let r=new v(e.length).fill(0),i=new v(t+1).fill(0),f=0;for(let e=1;e<=t;e++)f=f+n[e-1]<<1,i[e]=f;for(let t=0;t<e.length;t++){let n=e[t];0!=n&&(r[t]=i[n]++);}return {code:r,length:e}}var He=8,I=3,_e=258,ae=_e+I+1,Ue=16,Be=_e,hn=29,ie=256,we=ie+1+hn,me=30,oe=19,le=2*we+1,be=15,_t=9,tt=255,nt=32,rt=4,ke=256,t_=16,n_=17,r_=18,at=0,y_=1,it=2,$=-1,V_=["need dictionary","stream end","","file error","stream error","data error","insufficient memory","buffer error",""],a_=te(de),i_=te(Ee),Ze=new E(19);Ze[16]=2,Ze[17]=3,Ze[18]=7;var sn=D_(J_()),xn=D_(new v(30).fill(5)),Fe=A_(sn),v_=A_(xn),__=Q_(Te,a_,_e),E_=et($_(ge,i_));function Pe(e){return e%65521>>>0}function he(e,t,n){if(void 0===t||void 0===n)return 1;let r=e>>>16&65535;if(e&=65535,1==n)return (e+=t[0])>=65521&&(e-=65521),r+=e,r>=65521&&(r-=65521),(r<<16|e)>>>0;if(n<16){for(let i=0;i<n;i++)r+=e+=t[i];return e>=65521&&(e-=65521),r=Pe(r),(r<<16|e)>>>0}for(;n>=5552;){n-=5552;let i=N.floor(347);do{for(let n=0;n<16;n++)r+=e+=t[n];t=t.subarray(16);}while(--i);e=Pe(e),r=Pe(r);}if(n){for(;n>=16;){n-=16;for(let n=0;n<16;n++)r+=e+=t[n];t=t.subarray(16);}for(let i=0;i<n;i++)r+=e+=t[i];e=Pe(e),r=Pe(r);}return (r<<16|e)>>>0}var pn=(()=>{let e=new v(256);for(let t=0;t<256;t++){let n=t;for(let e=0;e<8;e++)n=1&n?3988292384^n>>>1:n>>>1;e[t]=n>>>0;}return e})();function W(e=0,t,n){if(!t)return 0;void 0===n&&(n=t.length),n=N.min(n,t.length),e=~e>>>0;for(let r=0;r<n;r++)e=e>>>8^pn[255&(e^t[r])];return (4294967295^e)>>>0}function mt(e){16==e.I?(De(e,e.p),e.p=0,e.I=0):e.I>=8&&(g(e,e.p),e.p>>=8,e.I-=8);}function bt(e){e.I>8?De(e,e.p):e.I>0&&g(e,e.p),e.Ee=1+(e.I-1&7),e.p=0,e.I=0;}function Sn(e,t,n){let r,i,f=[],_=0;for(r=1;r<=be;r++)_=_+n[r-1]<<1,f[r]=_;for(i=0;i<=t;i++){let t=e[i].De;0!=t&&(e[i].Qe=$e(f[t]++,t));}}function L(e,t,n){e.I>Ue-n?(e.p=65535&(e.p|t<<e.I),De(e,e.p),e.p=t>>Ue-e.I&65535,e.I+=n-Ue):(e.p=65535&(e.p|t<<e.I),e.I+=n);}function ht(e){for(let t=0;t<e.C.length;t++)e.C[t].Z=0;for(let t=0;t<e.T.length;t++)e.T[t].Z=0;for(let t=0;t<e.Se.length;t++)e.Se[t].Z=0;e.C[ke].Z=1,e.ie=e.fe=0,e.D=e._e=0;}function st(e){if(e.C&&e.C.length>=le)for(let t=0;t<le;t++)e.C[t]=Q();else {e.C=[];for(let t=0;t<le;t++)e.C.push(Q());}if(e.T&&e.T.length>=2*me+1)for(let t=0;t<2*me+1;t++)e.T[t]=Q();else {e.T=[];for(let t=0;t<2*me+1;t++)e.T.push(Q());}if(e.Se&&e.Se.length>=2*oe+1)for(let t=0;t<2*oe+1;t++)e.Se[t]=Q();else {e.Se=[];for(let t=0;t<2*oe+1;t++)e.Se.push(Q());}e.$e=new ne(e.C,new re(Fe,a_,ie+1,we,be)),e.Ae=new ne(e.T,new re(v_,i_,0,me,be)),e.Ue=new ne(e.Se,new re(null,Ze,0,oe,7)),e.p=0,e.I=0,e.Ee=0,ht(e);}var se=1;function En(e,t,n){return n=e.pe[se],e.pe[se]=e.pe[e.Ve--],k_(e,t,se),n}function ft(e,t,n,r){return e[t].Z<e[n].Z||e[t].Z==e[n].Z&&r[t]<=r[n]}function k_(e,t,n){let r=e.pe[n],i=n<<1;for(;i<=e.Ve&&(i<e.Ve&&ft(t,e.pe[i+1],e.pe[i],e.Ie)&&i++,!ft(t,r,e.pe[i],e.Ie));)e.pe[n]=e.pe[i],n=i,i<<=1;e.pe[n]=r;}function gn(e,t){let n,r,i,f,_,l,o=t.L,u=t.F,a=t.M.q,c=t.M.N,s=t.M.V,h=t.M.S,d=0;for(f=0;f<=be;f++)e.ze[f]=0;for(o[e.pe[e.We]].De=0,n=e.We+1;n<le;n++)r=e.pe[n],f=o[o[r].Ze].De+1,f>h&&(f=h,d++),o[r].De=f,!(r>u)&&(e.ze[f]++,_=0,r>=s&&(_=c[r-s]),l=o[r].Z,e.ie+=l*(f+_),a&&(e.fe+=l*(a[r].De+_)));if(0!=d){do{for(f=h-1;0==e.ze[f];)f--;e.ze[f]--,e.ze[f+1]+=2,e.ze[h]--,d-=2;}while(d>0);for(f=h;0!=f;f--)for(r=e.ze[f];0!=r;)i=e.pe[--n],!(i>u)&&(o[i].De!=f&&(e.ie+=(f-o[i].De)*o[i].Z,o[i].De=f),r--);}}function I_(e,t){let n,r,i,f=t.L,_=t.M.q,l=t.M.W,o=-1;for(e.Ve=0,e.We=le,n=0;n<l;n++)0!=f[n].Z?(e.pe[++e.Ve]=o=n,e.Ie[n]=0):f[n].De=0;for(;e.Ve<2;)i=e.pe[++e.Ve]=o<2?++o:0,f[i].Z=1,e.Ie[i]=0,e.ie--,_&&(e.fe-=_[i].De);for(t.F=o,n=N.floor(e.Ve/2);n>=1;n--)k_(e,f,n);i=l;do{n=En(e,f,n),r=e.pe[se],e.pe[--e.We]=n,e.pe[--e.We]=r,f[i].Z=f[n].Z+f[r].Z,e.Ie[i]=(e.Ie[n]>=e.Ie[r]?e.Ie[n]:e.Ie[r])+1,f[n].Ze=f[r].Ze=i,e.pe[se]=i++,k_(e,f,se);}while(e.Ve>=2);e.pe[--e.We]=e.pe[se],gn(e,t),Sn(f,t.F,e.ze);}function ut(e,t,n){let r,i,f=-1,_=t[0].De,l=0,o=7,u=4;for(0==_&&(o=138,u=3),t[n+1].De=65535,r=0;r<=n;r++)i=_,_=t[r+1].De,!(++l<o&&i==_)&&(l<u?e.Se[i].Z+=l:0!=i?(i!=f&&e.Se[i].Z++,e.Se[t_].Z++):l<=10?e.Se[n_].Z++:e.Se[r_].Z++,l=0,f=i,0==_?(o=138,u=3):i==_?(o=6,u=3):(o=7,u=4));}function ct(e,t,n){let r,i=-1,f=t[0].De,_=0,l=7,o=4;0==f&&(l=138,o=3);for(let u=0;u<=n;u++)if(r=f,f=t[u+1].De,!(++_<l&&r==f)){if(_<o)do{L(e,e.Se[r].Qe,e.Se[r].De);}while(0!=--_);else 0!=r?(r!=i&&(L(e,e.Se[r].Qe,e.Se[r].De),_--),L(e,e.Se[t_].Qe,e.Se[t_].De),L(e,_-3,2)):_<=10?(L(e,e.Se[n_].Qe,e.Se[n_].De),L(e,_-3,3)):(L(e,e.Se[r_].Qe,e.Se[r_].De),L(e,_-11,7));_=0,i=r,0==f?(l=138,o=3):r==f?(l=6,o=3):(l=7,o=4);}}function Tn(e){let t;for(ut(e,e.C,e.$e.F),ut(e,e.T,e.Ae.F),I_(e,e.Ue),t=oe-1;t>=3&&0==e.Se[Se[t]].De;t--);return e.ie+=3*(t+1)+5+5+4,t}function wn(e,t,n,r){let i;for(L(e,t-257,5),L(e,n-1,5),L(e,r-4,4),i=0;i<r;i++)L(e,e.Se[Se[i]].De,3);ct(e,e.C,t-1),ct(e,e.T,n-1);}function Me(e,t,n,r,i=0){L(e,(at<<1)+r,3),bt(e),De(e,n),De(e,~n),n&&t&&M(e.$,e.A,t,i,n),e.A+=n;}function xt(e){mt(e);}function pt(e){L(e,y_<<1,3),L(e,Fe[ke].Qe,Fe[ke].De),mt(e);}function dt(e,t,n){let r,i,f,_,l=0;if(0!=e.D)do{r=255&e.Le[l],r+=(255&e.Le[l+1])<<8,i=e.Le[l+2],l+=3,0==r?L(e,t[i].Qe,t[i].De):(f=__[i],L(e,t[f+ie+1].Qe,t[f+ie+1].De),_=a_[f],0!=_&&(i-=Te[f],L(e,i,_)),r--,f=T_(r),L(e,n[f].Qe,n[f].De),_=i_[f],0!=_&&(r-=ge[f],L(e,r,_)));}while(l<e.D);L(e,t[ke].Qe,t[ke].De);}function An(e){let t,n=4093624447;for(t=0;t<=31;t++,n>>=1)if(1&n&&0!=e.C[t].Z)return 0;if(0!=e.C[9].Z||0!=e.C[10].Z||0!=e.C[13].Z)return 1;for(t=32;t<ie;t++)if(0!=e.C[t].Z)return 1;return 0}function St(e,t,n,r,i=0){let f,_,l=0;e.ge>0?(2==e.o.t&&(e.o.t=An(e)),I_(e,e.$e),I_(e,e.Ae),l=Tn(e),f=e.ie+3+7>>3,_=e.fe+3+7>>3,(_<=f||4==e.ve)&&(f=_)):f=_=n+5,n+4<=f&&t?Me(e,t,n,r,i):_==f?(L(e,(y_<<1)+r,3),dt(e,Fe,v_)):(L(e,(it<<1)+r,3),wn(e,e.$e.F+1,e.Ae.F+1,l+1),dt(e,e.C,e.T)),ht(e),r&&bt(e);}function wt(){let e=Ve();return e.l=w_(e),e}var Xe=[{Ce:It,Te:0,Be:0,Re:0,Ge:0},{Ce:z_,Te:4,Be:4,Re:8,Ge:4},{Ce:z_,Te:5,Be:5,Re:16,Ge:8},{Ce:z_,Te:6,Be:16,Re:32,Ge:32},{Ce:Re,Te:4,Be:4,Re:16,Ge:16},{Ce:Re,Te:16,Be:8,Re:16,Ge:32},{Ce:Re,Te:16,Be:16,Re:32,Ge:128},{Ce:Re,Te:32,Be:32,Re:128,Ge:256},{Ce:Re,Te:128,Be:128,Re:256,Ge:1024},{Ce:Re,Te:258,Be:258,Re:258,Ge:4096}];function Et(e){return 2*e-(e>4?9:0)}function f_(e,t,n){return ((t<<e.Y^n)&e.X)>>>0}function u_(e,t){e.be=f_(e,e.be,e.u[t+(I-1)]);let n=e.j[t&e.P]=e.K[e.be];return e.K[e.be]=t,n}function At(e){e.K[e.J-1]=0,je(e.K,0,(e.J-1)*e.K.BYTES_PER_ELEMENT);}function Nn(e){let t,n,r=e.h;for(t=e.J;t>0;)t--,n=e.K[t],e.K[t]=n>=r?n-r:0;for(t=r;t>0;)t--,n=e.j[t],e.j[t]=n>=r?n-r:0;}function C_(e,t,n,r){let i=e.avail_in;return i>r&&(i=r),0==i?0:(e.avail_in-=i,M(t,n,e.next_in,e.next_in_index,i),1==e.l.G?e.i=he(e.i,new x(t.buffer,t.byteOffset+n,i),i):2==e.l.G&&(e.i=W(e.i,new x(t.buffer,t.byteOffset+n,i),i)),e.next_in_index+=i,e.total_in+=i,i)}function c_(e){let t,n,r=e.h;do{if(n=e.qe-e.ce-e.ae,0==n&&0==e.ae&&0==e.ce?n=r:-1==n&&n--,e.ae>=r+ve(e)&&(M(e.u,0,e.u,r,r-n),e.Ne-=r,e.ae-=r,e.ue-=r,e.le>e.ae&&(e.le=e.ae),Nn(e),n+=r),0==e.o.avail_in)break;if(t=C_(e.o,e.u,e.ae+e.ce,n),e.ce+=t,e.ce+e.le>=I){let t=e.ae-e.le;for(e.be=e.u[t],e.be=f_(e,e.be,e.u[t+1]);e.le&&(e.be=f_(e,e.be,e.u[t+I-1]),e.j[t&e.P]=e.K[e.be],e.K[e.be]=t,t++,e.le--,!(e.ce+e.le<I)););}}while(e.ce<ae&&0!=e.o.avail_in);if(e.k<e.qe){let t,n=e.ae+e.ce;e.k<n?(t=e.qe-n,t>Be&&(t=Be),je(e.u,n,t),e.k=n+t):e.k<n+Be&&(t=n+Be-e.k,t>e.qe-e.k&&(t=e.qe-e.k),je(e.u,e.k,t),e.k+=t);}}function Dt(e,t,n=8,r=15,i=He,f=0){let _=1;if(!e)return -2;if(e.msg="",-1==t&&(t=6),r<0){if(_=0,r<-15)return -2;r=-r;}else r>15&&(_=2,r-=16);if(i<1||i>_t||8!=n||r<8||r>15||t<0||t>9||f<0||f>4||8==r&&1!=_)return -2;8==r&&(r=9);let l=w_(e);return l?(e.l=l,l.o=e,l.R=42,l.G=_,l.O=void 0,l.v=r,l.h=1<<l.v,l.P=l.h-1,l.H=i+7,l.J=1<<l.H,l.X=l.J-1,l.Y=(l.H+I-1)/I,l.u=new x(2*l.h),l.j=new E(l.h),l.K=new E(l.J),l.k=0,l.ee=1<<i+6,l.$=new x(l.ee*rt),l.ne=4*l.ee,l.u&&l.j&&l.K&&l.$?(l.Le=l.$.subarray(l.ee),l.U=l.te+l.ee,l.B=3*(l.ee-1),l.ge=t,l.ve=f,l.Fe=n,Cn(e)):(l.R=666,e.msg=g_(-4),B_(e),-4)):-4}function U_(e){if(null==e)return true;let t=e.l;return !t||t.o!=e||42!=t.R&&57!=t.R&&69!=t.R&&73!=t.R&&91!=t.R&&103!=t.R&&113!=t.R&&666!=t.R}function Rn(e){let t;return U_(e)?-2:(e.total_in=e.total_out=0,e.msg="",e.t=2,t=e.l,t.A=0,t.re=t.te,t.G<0&&(t.G=-t.G),t.R=2==t.G?57:42,e.i=2==t.G?W(0):he(0),t.oe=-2,st(t),0)}function zn(e){e.qe=2*e.h,At(e),e.ye=Xe[e.ge].Te,e.ke=Xe[e.ge].Be,e.me=Xe[e.ge].Re,e.xe=Xe[e.ge].Ge,e.ae=0,e.ue=0,e.ce=0,e.le=0,e.se=e.he=I-1,e.we=0,e.be=0;}function Cn(e){let t=Rn(e);return 0==t&&zn(e.l),t}function Ye(e,t){g(e,t>>8),g(e,255&t);}function q(e){let t,n=e.l;xt(n),t=n.A,t>e.avail_out&&(t=e.avail_out),0!=t&&(M(e.next_out,e.next_out_index,n.$,n.re,t),e.next_out_index+=t,n.re+=t,e.total_out+=t,e.avail_out-=t,n.A-=t,0==n.A&&(n.re=n.te));}function Ie(e,t){let n=e.l;n.O&&n.O.Oe&&(e.i=W(e.i,new x(n.$.buffer,n.te+t,n.A-t),n.A-t));}function yt(e,t){let n,r=e.l;if(U_(e)||t>5||t<0)return Ae(e,-2);if(!e.next_out||0!=e.avail_in&&!e.next_in||666==r.R&&4!=t)return Ae(e,-2);if(0==e.avail_out)return Ae(e,-5);if(n=r.oe,r.oe=t,0!=r.A){if(q(e),0==e.avail_out)return r.oe=$,0}else if(0==e.avail_in&&Et(t)<=Et(n)&&4!=t)return Ae(e,-5);if(666==r.R&&0!=e.avail_in)return Ae(e,-5);if(42==r.R&&0==r.G&&(r.R=113),42==r.R){let t,n=8+(r.v-8<<4)<<8;if(t=r.ve>=2||r.ge<2?0:r.ge<6?1:6==r.ge?2:3,n|=t<<6,0!=r.ae&&(n|=nt),n+=31-n%31,Ye(r,n),0!=r.ae&&(Ye(r,e.i>>16),Ye(r,65535&e.i)),e.i=1,r.R=113,q(e),0!=r.A)return r.oe=$,0}if(57==r.R)if(e.i=W(0),g(r,31),g(r,139),g(r,8),r.O)g(r,(r.O.Pe?1:0)+(r.O.Oe?2:0)+(null==r.O.He?0:4)+(null==r.O.Je?0:8)+(null==r.O.Xe?0:16)),g(r,255&r.O.Ye),g(r,r.O.Ye>>>8&255),g(r,r.O.Ye>>>16&255),g(r,r.O.Ye>>>24&255),g(r,9==r.ge?2:r.ve>=2||r.ge<2?4:0),g(r,255&r.O.je),null!=r.O.He&&(g(r,255&r.O.Ke),g(r,r.O.Ke>>>8&255)),r.O.Oe&&(e.i=W(e.i,r.$,r.A)),r.Me=0,r.R=69;else if(g(r,0),g(r,0),g(r,0),g(r,0),g(r,0),g(r,9==r.ge?2:r.ve>=2||r.ge<2?4:0),g(r,tt),r.R=113,q(e),0!=r.A)return r.oe=$,0;if(69==r.R){if(r.O&&null!=r.O.He){let t=r.A,n=(65535&r.O.Ke)-r.Me;for(;r.A+n>r.ne;){let i=r.ne-r.A;if(M(r.$,r.A,r.O.He,r.Me,i),r.A=r.ne,Ie(e,t),r.Me+=i,q(e),0!=r.A)return r.oe=$,0;t=0,n-=i;}M(r.$,r.A,r.O.He,r.Me,n),r.A+=n,Ie(e,t),r.Me=0;}r.R=73;}if(73==r.R){if(r.O&&r.O.Je&&r.O.Je.length){let t,n=r.A;do{if(r.A==r.ne){if(Ie(e,n),q(e),0!=r.A)return r.oe=$,0;n=0;}t=r.O.Je[r.Me++],g(r,t);}while(0!=t);Ie(e,n),r.Me=0;}r.R=91;}if(91==r.R){if(r.O&&r.O.Xe&&r.O.Xe.length){let t,n=r.A;do{if(r.A==r.ne){if(Ie(e,n),q(e),0!=r.A)return r.oe=$,0;n=0;}t=r.O.Xe[r.Me++],g(r,t);}while(0!=t);Ie(e,n);}r.R=103;}if(103==r.R){if(r.O&&r.O.Oe){if(r.A+2>r.ne&&(q(e),0!=r.A))return r.oe=$,0;g(r,255&e.i),g(r,e.i>>>8&255),e.i=W(0);}if(r.R=113,q(e),0!=r.A)return r.oe=$,0}if(0!=e.avail_in||0!=r.ce||0!=t&&666!=r.R){let n=0==r.ge?It(r,t):2==r.ve?On(r,t):3==r.ve?Ln(r,t):Xe[r.ge].Ce(r,t);if((2==n||3==n)&&(r.R=666),0==n||2==n)return 0==e.avail_out&&(r.oe=$),0;if(1==n&&(1==t?pt(r):5!=t&&(Me(r,null,0,0),3==t&&(At(r),0==r.ce&&(r.ae=0,r.ue=0,r.le=0))),q(e),0==e.avail_out))return r.oe=$,0}return 4!=t?0:r.G<=0?1:(2==r.G?(g(r,255&e.i),g(r,e.i>>>8&255),g(r,e.i>>>16&255),g(r,e.i>>>24&255),g(r,255&e.total_in),g(r,e.total_in>>>8&255),g(r,e.total_in>>>16&255),g(r,e.total_in>>>24&255)):(Ye(r,e.i>>>16&65535),Ye(r,65535&e.i)),q(e),r.G>0&&(r.G=-r.G),0!=r.A?0:1)}function B_(e){if(U_(e))return -2;let t=e.l,n=t.R;return t.u=F,t.j=qe,t.K=qe,t.$=F,t.Le=F,t.pe=new H(0),t.Ie=F,t.ze=qe,t.C.length=0,t.T.length=0,t.Se.length=0,t.O=void 0,t.te=0,t.re=0,t.U=0,113==n?-3:0}function vt(e,t){let n,r,i=e.xe,f=e.ae,_=e.he,l=e.me,o=e.ae>ve(e)?e.ae-ve(e):0,u=e.j,a=e.P,c=e.u[f],s=e.u[f+1],h=e.u[f+_-1],d=e.u[f+_];e.he>=e.ke&&(i>>=2),l>e.ce&&(l=e.ce);do{if(n=t,e.u[n+_]!=d||e.u[n+_-1]!=h||e.u[n]!=c||e.u[n+1]!=s)continue;let i=N.min(_e,e.ce),o=2;for(;o<i&&e.u[f+o]==e.u[n+o];)o++;if(r=o,r>_){if(e.Ne=t,_=r,r>=l)break;h=e.u[f+_-1],d=e.u[f+_];}}while((t=u[t&a])>o&&0!=--i);return _<=e.ce?_:e.ce}function kt(e,t){St(e,e.u,e.ae-e.ue,t,e.ue),e.ue=e.ae,q(e.o);}function V(e,t){return kt(e,t?1:0),0==e.o.avail_out?t?2:0:null}var gt=65535;function Ne(e,t){return e<t?e:t}function It(e,t){let n,r,i,f=Ne(e.ne-5,e.h),_=0,l=e.o.avail_in;do{if(n=gt,i=e.I+42>>3,e.o.avail_out<i||(i=e.o.avail_out-i,r=e.ae-e.ue,n>r+e.o.avail_in&&(n=r+e.o.avail_in),n>i&&(n=i),n<f&&(0==n&&4!=t||0==t||n!=r+e.o.avail_in)))break;_=4==t&&n==r+e.o.avail_in?1:0,Me(e,null,0,_),e.$[e.A-4]=n,e.$[e.A-3]=n>>8,e.$[e.A-2]=~n,e.$[e.A-1]=~n>>8,q(e.o),r&&(r>n&&(r=n),M(e.o.next_out,e.o.next_out_index,e.u,e.ue,r),e.o.next_out_index+=r,e.o.avail_out-=r,e.o.total_out+=r,e.ue+=r,n-=r),n&&(C_(e.o,e.o.next_out,e.o.next_out_index,n),e.o.next_out_index+=n,e.o.avail_out-=n,e.o.total_out+=n);}while(0==_);if(l-=e.o.avail_in,l){if(l>=e.h){e._e=2;let t=e.o.next_in_index-e.h;M(e.u,0,e.o.next_in,t,e.h),e.ae=e.h,e.le=e.ae;}else e.qe-e.ae<=l&&(e.ae-=e.h,M(e.u,0,e.u,e.h,e.ae),e._e<2&&e._e++,e.le>e.ae&&(e.le=e.ae)),M(e.u,e.ae,e.o.next_in,e.o.next_in_index-l,l),e.ae+=l,e.le+=Ne(l,e.h-e.le);e.ue=e.ae;}return e.k<e.ae&&(e.k=e.ae),_?(e.Ee=8,3):0!=t&&4!=t&&0==e.o.avail_in&&e.ae==e.ue?1:(i=e.qe-e.ae,e.o.avail_in>i&&e.ue>=e.h&&(e.ue-=e.h,e.ae-=e.h,M(e.u,0,e.u,e.h,e.ae),e._e<2&&e._e++,i+=e.h,e.le>e.ae&&(e.le=e.ae)),i>e.o.avail_in&&(i=e.o.avail_in),i&&(C_(e.o,e.u,e.ae,i),e.ae+=i,e.le+=Ne(i,e.h-e.le)),e.k<e.ae&&(e.k=e.ae),i=e.I+42>>3,i=Ne(e.ne-i,gt),f=Ne(i,e.h),r=e.ae-e.ue,(r>=f||(r||4==t)&&0!=t&&0==e.o.avail_in&&r<=i)&&(n=Ne(r,i),_=4==t&&0==e.o.avail_in&&n==r?1:0,Me(e,e.u,n,_,e.ue),e.ue+=n,q(e.o)),_&&(e.Ee=8),_?2:0)}function z_(e,t){let n,r=false;for(;;){if(e.ce<ae){if(c_(e),e.ce<ae&&0==t)return 0;if(0==e.ce)break}if(n=0,e.ce>=I&&(n=u_(e,e.ae)),0!=n&&e.ae-n<=ve(e)&&(e.se=vt(e,n)),e.se>=I)if(e.ae,e.Ne,e.se,r=e_(e,e.ae-e.Ne,e.se-I),e.ce-=e.se,e.se<=e.ye&&e.ce>=I){e.se--;do{e.ae++,n=u_(e,e.ae);}while(0!=--e.se);e.ae++;}else e.ae+=e.se,e.se=0,e.be=e.u[e.ae],e.be=f_(e,e.be,e.u[e.ae+1]);else r=ye(e,e.u[e.ae]),e.ce--,e.ae++;if(r){let t=V(e,false);if(null!=t)return t}}if(e.le=e.ae<I-1?e.ae:I-1,4==t){return V(e,true)??3}if(e.D){let t=V(e,false);if(null!=t)return t}return 1}function Re(e,t){let n,r=false;for(;;){if(e.ce<ae){if(c_(e),e.ce<ae&&0==t)return 0;if(0==e.ce)break}if(n=0,e.ce>=I&&(n=u_(e,e.ae)),e.he=e.se,e.de=e.Ne,e.se=I-1,0!=n&&e.he<e.ye&&e.ae-n<=ve(e)&&(e.se=vt(e,n),e.se<=5&&1==e.ve&&(e.se=I-1)),e.he>=I&&e.se<=e.he){let t=e.ae+e.ce-I;e.ae,e.de,e.he,r=e_(e,e.ae-1-e.de,e.he-I),e.ce-=e.he-1,e.he-=2;do{++e.ae<=t&&(n=u_(e,e.ae));}while(0!=--e.he);if(e.we=0,e.se=I-1,e.ae++,r){let t=V(e,false);if(null!=t)return t}}else if(e.we){if(r=ye(e,e.u[e.ae-1]),r&&kt(e,0),e.ae++,e.ce--,0==e.o.avail_out)return 0}else e.we=1,e.ae++,e.ce--;}if(e.we&&(r=ye(e,e.u[e.ae-1]),e.we=0),e.le=e.ae<I-1?e.ae:I-1,4==t){return V(e,true)??3}if(e.D){let t=V(e,false);if(null!=t)return t}return 1}function Ln(e,t){let n,r,i,f;for(;;){if(e.ce<=_e){if(c_(e),e.ce<=_e&&0==t)return 0;if(0==e.ce)break}if(e.se=0,e.ce>=I&&e.ae>0&&(i=e.ae-1,r=e.u[i],r==++i&&r==++i&&r==++i)){f=e.ae+_e;do{}while(r==++i&&r==++i&&r==++i&&r==++i&&r==++i&&r==++i&&r==++i&&r==++i&&i<f);e.se=_e-(f-i),e.se>e.ce&&(e.se=e.ce);}if(e.se>=I?(e.ae,e.ae,e.se,n=e_(e,1,e.se-I),e.ce-=e.se,e.ae+=e.se,e.se=0):(n=ye(e,e.u[e.ae]),e.ce--,e.ae++),n){let t=V(e,false);if(null!=t)return t}}if(e.le=0,4==t){return V(e,true)??3}if(e.D){let t=V(e,false);if(null!=t)return t}return 1}function On(e,t){let n=false;for(;;){if(0==e.ce&&(c_(e),0==e.ce)){if(0==t)return 0;break}if(e.se=0,n=ye(e,e.u[e.ae]),e.ce--,e.ae++,n){let t=V(e,false);if(null!=t)return t}}if(e.le=0,4==t){return V(e,true)??3}if(e.D){let t=V(e,false);if(null!=t)return t}return 1}var ue=852,d_=592,m_=594,Nt=ge.map(e=>e+1),Rt=Te.subarray(0,-1).map(e=>e+3),zt=[16,1,73,1,200,1],Ct=Ee.map(Wt),Lt=Ee.map(Gt);Ct.push(64,2),Lt.push(142,2);var Ot=de.map(Wt),Ht=de.map(Gt);Ot.push(...zt),Ht.push(...zt);var Ut=new E([...Rt,258,0,0]),Bt=new E([...Rt,3,0,0]),Zt=te(Ot),Ft=te(Ht),Pt=new E([...Nt,0,0]),Mt=new E([...Nt,32769,49153]),Yt=te(Ct),Xt=te(Lt);function Wt(e,t){return t%2?e:e+16}function Gt(e,t){return t%2?e:e+128}function qt(e,t){let n,r=e.l,i=e.next_in_index,f=e.next_out_index,_=e.next_in,l=e.next_out,o=r.u,u=r.p>>>0,a=r.I>>>0,c=r.et,s=r.tt,h=(1<<r.nt)-1,d=(1<<r.rt)-1,w=r.h>>>0,b=r.k>>>0,g=r.m>>>0,v=r.it,k=f-(t-e.avail_out),m=f+(e.avail_out-257),x=i+(e.avail_in-5),y=0,p=0,I=0,z=0;e:do{for(;a<15;){if(!(i<_.length))break e;u+=_[i++]<<a,a+=8;}n=c[u&h];t:for(;;){if(I=n.ft,u>>>=I,a-=I,I=n._t,0==I){l[f++]=n.lt;break}if(16&I){if(y=n.lt,I&=15,I){for(;a<I;){if(!(i<_.length)){r.ot=16200;break e}u+=_[i++]<<a,a+=8;}y+=u&(1<<I)-1,u>>>=I,a-=I;}for(;a<15;){if(!(i<_.length)){r.ot=16200;break e}u+=_[i++]<<a,a+=8;}n=s[u&d];n:for(;;){if(I=n.ft,u>>>=I,a-=I,I=n._t,16&I){if(p=n.lt,I&=15,I){for(;a<I;){if(!(i<_.length)){r.ot=16200;break e}u+=_[i++]<<a,a+=8;}p+=u&(1<<I)-1,u>>>=I,a-=I;}let t=y,c=f-k;if(p>c){let n=p-c;if(n>b&&v){e.msg="invalid distance too far back",r.ot=16209;break e}if(0==g){if(z=w-n,!(n<t)){for(let e=0;e<t;++e)l[f++]=o[z++];continue e}for(let e=0;e<n;++e)l[f++]=o[z++];t-=n,z=f-p;}else if(g<n){z=w+g-n;let e=n-g;if(!(e<t)){for(let e=0;e<t;++e)l[f++]=o[z++];continue e}for(let t=0;t<e;++t)l[f++]=o[z++];if(t-=e,z=0,g<t){for(let e=0;e<g;++e)l[f++]=o[z++];t-=g,z=f-p;}}else {if(z=g-n,!(n<t)){for(let e=0;e<t;++e)l[f++]=o[z++];continue e}for(let e=0;e<n;++e)l[f++]=o[z++];t-=n,z=f-p;}for(;t>2;)l[f++]=l[z++],l[f++]=l[z++],l[f++]=l[z++],t-=3;t&&(l[f++]=l[z++],t>1&&(l[f++]=l[z++]));}else {for(z=f-p;t>2;)l[f++]=l[z++],l[f++]=l[z++],l[f++]=l[z++],t-=3;t&&(l[f++]=l[z++],t>1&&(l[f++]=l[z++]));}break}if(64&I){e.msg="invalid distance code",r.ot=16209;break e}n=s[n.lt+(u&(1<<I)-1)];continue n}break}if(64&I){if(32&I){r.ot=16191;break e}e.msg="invalid literal/length code",r.ot=16209;break e}n=c[n.lt+(u&(1<<I)-1)];continue t}}while(i<x&&f<m);let L=a>>3;i-=L,a-=L<<3,u&=(1<<a)-1,e.next_in_index=i,e.next_out_index=f,e.avail_in=i<x?x-i+5:5-(i-x),e.avail_out=f<m?m-f+257:257-(f-m),r.p=u>>>0,r.I=a>>>0;}function Z_(e,t){let n=[],r=t?ue+m_:ue+d_;return {...Je(e,0),o:e,ot:16180,ut:false,G:0,ct:false,st:0,ht:0,dt:0,wt:0,u:F,bt:0,gt:0,He:0,et:n,tt:n,nt:0,rt:0,vt:0,kt:0,xt:0,yt:0,It:n,zt:new E(320),Lt:new E(288),Et:new v(r).fill(null).map(()=>pe()),Mt:0,it:true,Ft:0,qt:0,Nt:t}}function pe(e=0,t=0,n=0){return {_t:e,ft:t,lt:n}}function F_(e=1){return {_t:64,ft:e,lt:0}}function jt(e=0){return {_t:96,ft:e,lt:0}}function P_(e){return (255&e)<<24|(e>>8&255)<<16|(e>>16&255)<<8|e>>24&255}var Le=15,Un={Nt:false,Vt:Ut,Wt:Zt,St:Pt,$t:Yt,At:20,Ut:257,Qt:0,Dt:d_,Zt:false,Ct:true},Bn={Nt:true,Vt:Bt,Wt:Ft,St:Mt,$t:Xt,At:19,Ut:256,Qt:-1,Dt:m_,Zt:true,Ct:false};function Oe(e,t,n,r,i,f,_,l){let o,u,a,c,s,h,d,w,b,g,v,k,m,x,y,p,I,z,L,M=new E(Le+1),F=new E(Le+1),q=l?Bn:Un;for(o=0;o<=Le;o++)M[o]=0;for(u=0;u<n;u++)M[t[u]]++;for(s=i.Tt,c=Le;c>=1&&0==M[c];c--);if(s>c&&(s=c),0==c)return q.Ct?(y=F_(1),r.Tt[0]=y,r.Tt[1]=y,i.Tt=1,0):-1;for(a=1;a<c&&0==M[a];a++);for(s<a&&(s=a),w=1,o=1;o<=Le;o++)if(w<<=1,w-=M[o],w<0)return -1;if(w>0&&(0==e||1!=c))return -1;for(F[1]=0,o=1;o<Le;o++)F[o+1]=F[o]+M[o];for(u=0;u<n;u++)0!=t[u]&&(f[F[t[u]]++]=u);switch(e){case 0:I=z=f,L=q.At;break;case 1:I=q.Vt,z=q.Wt,L=q.Ut;break;default:I=q.St,z=q.$t,L=q.Qt;}if(g=0,u=0,o=a,p=_.Tt,h=s,d=0,m=-1,b=1<<s,x=b-1,1==e&&(q.Zt?b>=ue:b>ue)||2==e&&(q.Zt?b>=q.Dt:b>q.Dt))return 1;for(;;){y=Zn(f,u,o,d,e,I,z,L,q.Nt),v=1<<o-d,k=1<<h,a=k;do{k-=v;let e=(g>>d)+k;r.Tt[p+e]={...y};}while(0!=k);for(v=1<<o-1;g&v;)v>>=1;if(0!=v?(g&=v-1,g+=v):g=0,u++,0==--M[o]){if(o==c)break;o=t[f[u]];}if(o>s&&(g&x)!=m){for(0==d&&(d=s),p+=1<<h,h=o-d,w=1<<h;h+d<c&&(w-=M[h+d],!(w<=0));)h++,w<<=1;if(b+=1<<h,1==e&&(q.Zt?b>=ue:b>ue)||2==e&&(q.Zt?b>=q.Dt:b>q.Dt))return 1;m=g&x,r.Tt[_.Tt+m]={_t:h,ft:s,lt:p-_.Tt};}}if(0!=g)for(y=F_(o-d);0!=g;){for(0!=d&&(g&x)!=m&&(d=0,o=s,p=_.Tt,h=s,y.ft=o),r.Tt[p+(g>>d)]={...y},v=1<<o-1;g&v;)v>>=1;0!=v?(g&=v-1,g+=v):g=0;}return _.Tt+=b,i.Tt=s,0}function Zn(e,t,n,r,i,f,_,l,o){let u;if(o?e[t]<l:e[t]+1<l)u=pe(0,n-r,e[t]);else if(o?e[t]>l:e[t]>=l)if(o&&1==i){let i=e[t]-257;u=pe(_[i],n-r,f[i]);}else {let i=o?e[t]:e[t]-l;u=pe(_[i],n-r,f[i]);}else u=jt(n-r);return u}var Qt,$t,Vt=new v(544),Jt=true;function en(e){let t=Ve();return t.l=Z_(t,!!e),t}function Ge(e){let t;return !(e&&(t=e.l,!(!t||t.o!=e||t.Nt&&(t.ot<16191||t.ot>16209)||!t.Nt&&(t.ot<16180||t.ot>16211))))}function Xn(e){let t;return Ge(e)?-2:(t=e.l,e.total_in=e.total_out=t.wt=0,e.msg="",t.G&&(e.i=1&t.G),t.ot=t.Nt?16191:16180,t.ut=false,t.ct=false,t.st=-1,t.ht=t.Nt?65536:32768,delete t.O,t.p=0,t.I=0,t.et=t.Et,t.tt=t.Et,t.It=t.Et,t.it=true,t.Ft=-1,0)}function Wn(e){let t;return Ge(e)?-2:(t=e.l,t.h=0,t.k=0,t.m=0,Xn(e))}function Gn(e,t){let n,r,i;if(Ge(e))return -2;if(r=e.l,r.Nt?(t=-16,i=16):i=15,t<0){if(t<-i)return -2;n=0,t=-t;}else n=5+(t>>4),!r.Nt&&t<48&&(t&=15);return t&&(t<8||t>i)?-2:(r.u.length>0&&r.v!=t&&(r.u=F),r.G=n,r.v=t,Wn(e))}function _n(e,t){let n,r;if(!e)return -2;e.msg="";let i=!!e.l.Nt;return r=Z_(e,i),i&&(t=-16),e.l=r,r.o=e,r.ot=r.Nt?16191:16180,n=Gn(e,t),n}function Kn(e){let t={Tt:0};if(Jt){let n,r,i;for(n=0;n<144;)e.zt[n++]=8;for(;n<256;)e.zt[n++]=9;for(;n<280;)e.zt[n++]=7;for(;n<288;)e.zt[n++]=8;for(let e=0;e<544;e++)Vt[e]=pe();i=Vt,Qt=i,r=9;let f={Tt:i},_={Tt:r},l={Tt:0};for(Oe(1,e.zt,288,f,_,e.Lt,l,e.Nt),i=f.Tt,r=_.Tt,e.Mt=l.Tt,n=0;n<32;)e.zt[n++]=5;r=5;let o=l.Tt,u={Tt:i},a={Tt:r};t.Tt=o,Oe(2,e.zt,32,u,a,e.Lt,t,e.Nt),$t=i.slice(o),Jt=false;}e.et=Qt,e.nt=9,e.tt=$t,e.rt=5,e.Mt=t.Tt;}function qn(e,t,n){let r=e.l;if(!(r.u&&0!=r.u.length||(r.u=new x(1<<r.v),r.u)))return 1;if(0==r.h&&(r.h=1<<r.v,r.m=0,r.k=0),n>=r.h)M(r.u,0,t,t.length-r.h,r.h),r.m=0,r.k=r.h;else {let e=r.h-r.m;e>n&&(e=n),M(r.u,r.m,t,t.length-n,e),(n-=e)?(M(r.u,0,t,t.length-n,n),r.m=n,r.k=r.h):(r.m+=e,r.m==r.h&&(r.m=0),r.k<r.h&&(r.k+=e));}return 0}var h_=class extends z{constructor(){super("Need more input");}};function tn(e,t){let n,r,i,f,_,l,o,u,a,c,s,h,d,w,b,g,v,k=new x(4);if(Ge(e)||!e.next_out||!e.next_in&&0!=e.avail_in)return -2;l=0,u=0,o=0,a=0,r=F,i=0,f=F,_=0,n=e.l,16191==n.ot&&(n.ot=16192),z(),c=l,s=o,v=0;try{for(;;)switch(n.ot){case 16180:if(0==n.G){n.ot=16192;break}if(N(16),2&n.G&&35615==u){0==n.v&&(n.v=15),n.dt=W(0),n.dt=p(n.dt,u),E(),n.ot=16181;break}if(n.O&&(n.O.Bt=-1),!(1&n.G)||((V(8)<<8)+(u>>8))%31){e.msg="incorrect header check",n.ot=16209;break}if(8!=V(4)){e.msg="unknown compression method",n.ot=16209;break}if(S(4),g=V(4)+8,0==n.v&&(n.v=g),g>15||g>n.v){e.msg="invalid window size",n.ot=16209;break}n.ht=1<<g,n.st=0,e.i=n.dt=he(0),n.ot=512&u?16189:16191,E();break;case 16181:if(N(16),n.st=u,8!=(255&n.st)){e.msg="unknown compression method",n.ot=16209;break}if(57344&n.st){e.msg="unknown header flags set",n.ot=16209;break}n.O&&(n.O.Pe=u>>8&1),512&n.st&&4&n.G&&(n.dt=p(n.dt,u)),E(),n.ot=16182;case 16182:N(32),n.O&&(n.O.Ye=u),512&n.st&&4&n.G&&(n.dt=I(n.dt,u)),E(),n.ot=16183;case 16183:N(16),n.O&&(n.O.Rt=255&u,n.O.je=u>>8),512&n.st&&4&n.G&&(n.dt=p(n.dt,u)),E(),n.ot=16184;case 16184:1024&n.st?(N(16),n.bt=u,n.O&&(n.O.Ke=u),512&n.st&&4&n.G&&(n.dt=p(n.dt,u)),E()):n.O&&(n.O.He=F),n.ot=16185;case 16185:if(1024&n.st&&(h=n.bt,h>l&&(h=l),h&&(n.O&&n.O.He&&n.O.Gt&&(g=n.O.Ke-n.bt)<n.O.Gt&&M(n.O.He,g,r,i,h),512&n.st&&4&n.G&&(n.dt=W(n.dt,r.subarray(i,i+h),h)),l-=h,i+=h,n.bt-=h),n.bt))return m();n.bt=0,n.ot=16186;case 16186:if(2048&n.st){if(0==l)return m();h=0;do{g=r[i+h++],n.O&&n.O.Ot&&n.bt<n.O.Ot&&(n.O.Je[n.bt++]=g);}while(g&&h<l);if(512&n.st&&4&n.G&&(n.dt=W(n.dt,r.subarray(i,i+h),h)),l-=h,i+=h,g)return m()}else n.O&&(n.O.Je=F);n.bt=0,n.ot=16187;case 16187:if(4096&n.st){if(0==l)return m();h=0;do{g=r[i+h++],n.O&&n.O.Pt&&n.bt<n.O.Pt&&(n.O.Xe[n.bt++]=g);}while(g&&h<l);if(512&n.st&&4&n.G&&(n.dt=W(n.dt,r.subarray(i,i+h),h)),l-=h,i+=h,g)return m()}else n.O&&(n.O.Xe=F);n.ot=16188;case 16188:if(512&n.st){if(N(16),4&n.G&&u!=(65535&n.dt)){e.msg="header crc mismatch",n.ot=16209;break}E();}n.O&&(n.O.Oe=n.st>>9&1,n.O.Bt=1),e.i=n.dt=W(0),n.ot=16191;break;case 16189:N(32),e.i=n.dt=P_(u),E(),n.ot=16190;case 16190:if(!n.ct)return L(),2;e.i=n.dt=he(0),n.ot=16191;case 16191:if(5==t||6==t)return m();case 16192:if(n.ut){$(),n.ot=16206;break}switch(N(3),n.ut=!!V(1),S(1),V(2)){case 0:n.ot=16193;break;case 1:if(Kn(n),n.ot=16199,6==t)return S(2),m();break;case 2:n.ot=16196;break;case 3:e.msg="invalid block type",n.ot=16209;}S(2);break;case 16193:if($(),N(32),(65535&u)!=(u>>>16^65535)){e.msg="invalid stored block lengths",n.ot=16209;break}if(n.bt=65535&u,E(),n.ot=16194,6==t)return m();case 16194:n.ot=16195;case 16195:if(h=n.bt,h){if(h>l&&(h=l),h>o&&(h=o),0==h)return m();M(f,_,r,i,h),l-=h,i+=h,o-=h,_+=h,n.bt-=h;break}n.ot=16191;break;case 16196:if(N(14),n.kt=V(5)+257,S(5),n.xt=V(5)+1,S(5),n.vt=V(4)+4,S(4),n.kt>286||!n.Nt&&n.xt>30){e.msg=n.Nt?"too many length":"too many length or distance symbols",n.ot=16209;break}n.yt=0,n.ot=16197;case 16197:for(;n.yt<n.vt;)N(3),n.zt[Se[n.yt++]]=V(3),S(3);for(;n.yt<19;)n.zt[Se[n.yt++]]=0;n.It=n.Et,n.et=n.tt=n.It,n.nt=7;let c={Tt:n.It},k={Tt:n.nt},x={Tt:0};if(v=Oe(0,n.zt,19,c,k,n.Lt,x,n.Nt),n.It=c.Tt,n.nt=k.Tt,v){e.msg="invalid code lengths set",n.ot=16209;break}n.yt=0,n.ot=16198;case 16198:for(;n.yt<n.kt+n.xt;){for(;w=n.et[V(n.nt)],!(w.ft<=a);)q();if(w.lt<16)S(w.ft),n.zt[n.yt++]=w.lt;else {if(16==w.lt){if(N(w.ft+2),S(w.ft),0==n.yt){e.msg="invalid bit length repeat",n.ot=16209;break}g=n.zt[n.yt-1],h=3+V(2),S(2);}else 17==w.lt?(N(w.ft+3),S(w.ft),g=0,h=3+V(3),S(3)):(N(w.ft+7),S(w.ft),g=0,h=11+V(7),S(7));if(n.yt+h>n.kt+n.xt){e.msg="invalid bit length repeat",n.ot=16209;break}for(;h--;)n.zt[n.yt++]=g;}}if(16209==n.ot)break;if(0==n.zt[256]){e.msg="invalid code -- missing end-of-block",n.ot=16209;break}n.It=n.Et,n.nt=9;let A={Tt:n.It},U={Tt:n.nt},Q={Tt:0};v=Oe(1,n.zt,n.kt,A,U,n.Lt,Q,n.Nt),n.It=A.Tt,n.nt=U.Tt;let D=Q.Tt;if(n.et=n.It.slice(0,D),v){e.msg="invalid literal/lengths set",n.ot=16209;break}n.rt=6;let Z=n.zt.subarray(n.kt,n.kt+n.xt),C={Tt:n.It},T={Tt:n.rt},B={Tt:D};if(v=Oe(2,Z,n.xt,C,T,n.Lt,B,n.Nt),n.It=C.Tt,n.rt=T.Tt,n.tt=n.It.slice(D),v){e.msg="invalid distances set",n.ot=16209;break}if(n.ot=16199,6==t)return m();case 16199:n.ot=16200;case 16200:if(!n.Nt&&l>=6&&o>=258){L(),qt(e,s),z(),16191==n.ot&&(n.Ft=-1);break}for(n.Ft=0;w=n.et[V(n.nt)],!(w.ft<=a);)q();if(w._t&&!(240&w._t)){for(b=w;w=n.et[b.lt+(V(b.ft+b._t)>>b.ft)],!(b.ft+w.ft<=a);)q();S(b.ft),n.Ft+=b.ft;}if(S(w.ft),n.Ft+=w.ft,n.bt=w.lt,0==w._t){n.ot=16205;break}if(32&w._t){n.Ft=-1,n.ot=16191;break}if(64&w._t){e.msg="invalid literal/length code",n.ot=16209;break}n.He=15&w._t,n.ot=16201;case 16201:n.He&&(N(n.He),n.bt+=V(n.He),S(n.He),n.Ft+=n.He),n.qt=n.bt,n.ot=16202;case 16202:for(;w=n.tt[V(n.rt)],!(w.ft<=a);)q();if(!(240&w._t)){for(b=w;w=n.tt[b.lt+(V(b.ft+b._t)>>b.ft)],!(b.ft+w.ft<=a);)q();S(b.ft),n.Ft+=b.ft;}if(S(w.ft),n.Ft+=w.ft,64&w._t){e.msg="invalid distance code",n.ot=16209;break}n.gt=w.lt,n.He=15&w._t,n.ot=16203;case 16203:n.He&&(N(n.He),n.gt+=V(n.He),S(n.He),n.Ft+=n.He),n.ot=16204;case 16204:if(0==o)return m();if(h=s-o,n.gt>h){if(h=n.gt-h,h>n.k&&n.it){e.msg="invalid distance too far back",n.ot=16209;break}h>n.m?(h-=n.m,d=n.h-h):d=n.m-h,h>n.bt&&(h=n.bt),h>o&&(h=o);for(let e=0;e<h;++e)f[_]=255&n.u[d],++_,++d;}else {d=_-n.gt,h=n.bt,h>o&&(h=o);for(let e=0;e<h;++e)f[_]=f[d],++_,++d;}h>o&&(h=o),o-=h,n.bt-=h,0==n.bt&&(n.ot=16200);break;case 16205:if(0==o)return m();f[_++]=n.bt,o--,n.ot=16200;break;case 16206:if(n.G){if(N(32),s-=o,e.total_out+=s,n.wt+=s,4&n.G&&s){let t=f.subarray(_-s,_);e.i=n.dt=y(n.dt,t,s);}if(s=o,4&n.G&&(n.st?u:P_(u)>>>0)!=n.dt){e.msg="incorrect data check",n.ot=16209;break}E();}n.ot=16207;case 16207:if(n.G&&n.st){if(N(32),4&n.G&&u!=(4294967295&n.wt)){e.msg="incorrect length check",n.ot=16209;break}E();}n.ot=16208;case 16208:return v=1,m();case 16209:return v=-3,m();case 16210:return -4;default:return -2}}catch(e){if(e instanceof h_)return m();throw e}function m(){if(L(),n.h||s!=e.avail_out&&n.ot<16209&&(n.Nt?n.ot<16208:n.ot<16206)||4!=t){let t=s-e.avail_out;if(qn(e,e.next_out.subarray(e.next_out_index-t,e.next_out_index),t))return n.ot=16210,-4}return c-=e.avail_in,s-=e.avail_out,e.total_in+=c,e.total_out+=s,n.wt+=s,4&n.G&&s&&(e.i=n.dt=y(n.dt,e.next_out.subarray(e.next_out_index-s,e.next_out_index),s)),e.t=n.I+(n.ut?64:0)+(16191==n.ot?128:0)+(16199==n.ot||16194==n.ot?256:0),(0==c&&0==s&&0==v||4==t&&0==v)&&(v=-5),v}function y(e,t,r){return n.st?W(e,t,r):he(e,t,r)}function p(e,t){return k[0]=255&t,k[1]=t>>>8&255,W(e,k,2)>>>0}function I(e,t){return k[0]=255&t,k[1]=t>>>8&255,k[2]=t>>>16&255,k[3]=t>>>24&255,W(e,k,4)>>>0}function z(){f=e.next_out,_=e.next_out_index,o=e.avail_out,r=e.next_in,i=e.next_in_index,l=e.avail_in,u=n.p,a=n.I;}function L(){e.next_out=f,e.next_out_index=_,e.avail_out=o,e.next_in=r,e.next_in_index=i,e.avail_in=l,n.p=u,n.I=a;}function E(){u=0,a=0;}function q(){if(0==l)throw new h_;l--,u+=(255&r[i])<<a,i++,u>>>=0,a+=8;}function N(e){for(;a<e;)q();}function V(e){return u&(1<<e)-1}function S(e){u>>>=e,a-=e;}function $(){u>>>=7&a,a-=7&a;}}function nn(e){return Ge(e)?-2:0}var M_=65536,jn=32768,Y_=class{constructor(e=16,t=M_){this.Ht=[],this.Jt=e;for(let n=0;n<N.min(e,4);n++)this.Ht.push(new x(t));}acquire(e=M_){for(let t=this.Ht.length-1;t>=0;t--){let n=this.Ht[t];if(n.length>=e)return this.Ht.splice(t,1),n}return new x(e)}release(e){this.Ht.length<this.Jt&&this.Ht.push(e);}};function rn(e){let t=new Y_(32,M_),n=null;function r(e){try{t.release(e);}catch{}}return new U({start(){},transform(i,f){if(!n){let t=e.Xt(),r=e.Yt(t);if(0!=r&&0!=r)throw new z("init failed: "+r);n={o:t};}let _=n.o,l=0;for(;l<i.length;){let n=N.min(i.length-l,jn),o=i.subarray(l,l+n);for(_.next_in=o,_.next_in_index=0,_.avail_in=o.length;_.avail_in>0;){let n=t.acquire(),i=false;try{_.next_out=n,_.next_out_index=0,_.avail_out=n.length;let r=e.jt(_,0),l=n.length-_.avail_out;if(l>0){let e=!1,r={Kt:n.subarray(0,l),release:()=>{e||(e=!0,t.release(n));}};i=!0,f.enqueue(r);}if(0!=r&&1!=r)throw new z("process error: "+r)}finally{i||r(n);}}l+=n;}},flush(i){if(!n)return;let f=n.o;for(;;){let n=t.acquire(),_=false;try{f.next_out=n,f.next_out_index=0,f.avail_out=n.length;let r=e.jt(f,4),l=n.length-f.avail_out;if(l>0){let e=!1,r={Kt:n.subarray(0,l),release:()=>{e||(e=!0,t.release(n));}};_=!0,i.enqueue(r);}if(1==r)break;if(0!=r)throw new z("finalization error: "+r)}finally{_||r(n);}}let _=e.en(f);if(0!=_&&0!=_)throw new z("end failed: "+_)}})}function an(){return new U({start(){},transform(e,t){try{t.enqueue(e.Kt.slice(0));}finally{e.release();}},flush(){}})}function Vn(e="deflate",t){let n="gzip"==e?31:"deflate-raw"==e?-15:15,r=t&&"number"==typeof t.level?t.level:-1;return rn({Xt:()=>wt(),Yt:e=>Dt(e,r,8,n,8,0),jt:yt,en:B_})}function Jn(e="deflate"){let t="gzip"==e?31:"deflate-raw"==e?-15:15;return rn({Xt:()=>en("deflate64-raw"==e),Yt:e=>_n(e,t),jt:tn,en:nn})}var s_=class{constructor(e="deflate",t){let n=Vn(e,t);this.writable=n.writable,this.readable=n.readable.pipeThrough(an());}},x_=class{constructor(e="deflate"){let t=Jn(e);this.writable=t.writable,this.readable=t.readable.pipeThrough(an());}};
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- configure({
- workerURI: "./core/web-worker-native.js",
- wasmURI: null,
- CompressionStreamZlib: s_,
- DecompressionStreamZlib: x_
- });
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- class ZipEntry {
-
- constructor(fs, name, params, parent) {
- const zipEntry = this;
- if (fs.root && parent && parent.getChildByName(name)) {
- throw new Error("Entry filename already exists");
- }
- if (!params) {
- params = {};
- }
- Object.assign(zipEntry, {
- fs,
- name,
- data: params.data,
- options: params.options,
- id: fs.entries.length,
- parent,
- children: [],
- uncompressedSize: params.uncompressedSize || 0,
- passThrough: params.passThrough
- });
- fs.entries.push(zipEntry);
- if (parent) {
- zipEntry.parent.children.push(zipEntry);
- }
- }
-
- moveTo(target) {
- // deprecated
- const zipEntry = this;
- zipEntry.fs.move(zipEntry, target);
- }
-
- getFullname() {
- return this.getRelativeName();
- }
-
- getRelativeName(ancestor = this.fs.root) {
- const zipEntry = this;
- let relativeName = zipEntry.name;
- let entry = zipEntry.parent;
- while (entry && entry != ancestor) {
- relativeName = (entry.name ? entry.name + "/" : "") + relativeName;
- entry = entry.parent;
- }
- return relativeName;
- }
-
- isDescendantOf(ancestor) {
- let entry = this.parent;
- while (entry && entry.id != ancestor.id) {
- entry = entry.parent;
- }
- return Boolean(entry);
- }
-
- rename(name) {
- const parent = this.parent;
- if (parent && parent.getChildByName(name)) {
- throw new Error("Entry filename already exists");
- } else {
- this.name = name;
- }
- }
- }
-
- class ZipFileEntry extends ZipEntry {
-
- constructor(fs, name, params, parent) {
- super(fs, name, params, parent);
- const zipEntry = this;
- zipEntry.Reader = params.Reader;
- zipEntry.Writer = params.Writer;
- if (params.getData) {
- zipEntry.getData = params.getData;
- }
- }
-
- clone() {
- return new ZipFileEntry(this.fs, this.name, this);
- }
-
- async getData(writer, options = {}) {
- const zipEntry = this;
- if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data)) {
- return zipEntry.data;
- } else {
- const reader = zipEntry.reader = new zipEntry.Reader(zipEntry.data, options);
- const uncompressedSize = zipEntry.data ? zipEntry.data.uncompressedSize : reader.size;
- await Promise.all([initStream(reader), initStream(writer, uncompressedSize)]);
- const { readable } = reader;
- zipEntry.uncompressedSize = reader.size;
- await readable.pipeTo(writer.writable);
- return writer.getData ? writer.getData() : writer.writable;
- }
- }
-
- isPasswordProtected() {
- return this.data.encrypted;
- }
-
- async checkPassword(password, options = {}) {
- const zipEntry = this;
- if (zipEntry.isPasswordProtected()) {
- options.password = password;
- options.checkPasswordOnly = true;
- try {
- await zipEntry.data.getData(null, options);
- return true;
- } catch (error) {
- if (error.message == ERR_INVALID_PASSWORD) {
- return false;
- } else {
- throw error;
- }
- }
- } else {
- return true;
- }
- }
-
- getText(encoding, options) {
- return this.getData(new TextWriter(encoding), options);
- }
-
- getBlob(mimeType, options) {
- return this.getData(new BlobWriter(mimeType), options);
- }
-
- getData64URI(mimeType, options) {
- return this.getData(new Data64URIWriter(mimeType), options);
- }
-
- getUint8Array(options) {
- return this.getData(new Uint8ArrayWriter(), options);
- }
-
- getWritable(writable = new WritableStream(), options) {
- return this.getData({ writable }, options);
- }
-
- getArrayBuffer(options) {
- return this.data.arrayBuffer(options);
- }
-
- replaceBlob(blob) {
- Object.assign(this, {
- data: blob,
- Reader: BlobReader,
- Writer: BlobWriter,
- reader: null
- });
- }
-
- replaceText(text) {
- Object.assign(this, {
- data: text,
- Reader: TextReader,
- Writer: TextWriter,
- reader: null
- });
- }
-
- replaceData64URI(dataURI) {
- Object.assign(this, {
- data: dataURI,
- Reader: Data64URIReader,
- Writer: Data64URIWriter,
- reader: null
- });
- }
-
- replaceUint8Array(array) {
- Object.assign(this, {
- data: array,
- Reader: Uint8ArrayReader,
- Writer: Uint8ArrayWriter,
- reader: null
- });
- }
-
- replaceReadable(readable) {
- Object.assign(this, {
- data: null,
- Reader: function () { return { readable }; },
- Writer: null,
- reader: null
- });
- }
- }
-
- class ZipDirectoryEntry extends ZipEntry {
-
- constructor(fs, name, params, parent) {
- super(fs, name, params, parent);
- this.directory = true;
- }
-
- clone(deepClone) {
- const zipEntry = this;
- const clonedEntry = new ZipDirectoryEntry(zipEntry.fs, zipEntry.name);
- if (deepClone) {
- clonedEntry.children = zipEntry.children.map(child => {
- const childClone = child.clone(deepClone);
- childClone.parent = clonedEntry;
- return childClone;
- });
- }
- return clonedEntry;
- }
-
- addDirectory(name, options) {
- return addChild(this, name, { options }, true);
- }
-
- addText(name, text, options = {}) {
- return addChild(this, name, {
- data: text,
- Reader: TextReader,
- Writer: TextWriter,
- options,
- uncompressedSize: text.length
- });
- }
-
- addBlob(name, blob, options = {}) {
- return addChild(this, name, {
- data: blob,
- Reader: BlobReader,
- Writer: BlobWriter,
- options,
- uncompressedSize: blob.size
- });
- }
-
- addData64URI(name, dataURI, options = {}) {
- let dataEnd = dataURI.length;
- while (dataURI.charAt(dataEnd - 1) == "=") {
- dataEnd--;
- }
- const dataStart = dataURI.indexOf(",") + 1;
- return addChild(this, name, {
- data: dataURI,
- Reader: Data64URIReader,
- Writer: Data64URIWriter,
- options,
- uncompressedSize: Math.floor((dataEnd - dataStart) * 0.75)
- });
- }
-
- addUint8Array(name, array, options = {}) {
- return addChild(this, name, {
- data: array,
- Reader: Uint8ArrayReader,
- Writer: Uint8ArrayWriter,
- options,
- uncompressedSize: array.length
- });
- }
-
- addHttpContent(name, url, options = {}) {
- return addChild(this, name, {
- data: url,
- Reader: class extends HttpReader {
- constructor(url) {
- super(url, options);
- }
- },
- options
- });
- }
-
- addReadable(name, readable, options = {}) {
- return addChild(this, name, {
- Reader: function () { return { readable }; },
- options
- });
- }
-
- addFileSystemEntry(fileSystemEntry, options = {}) {
- return addFileSystemHandle(this, fileSystemEntry, options);
- }
-
- addFileSystemHandle(handle, options = {}) {
- return addFileSystemHandle(this, handle, options);
- }
-
- addFile(file, options = {}) {
- if (!options.lastModDate) {
- options.lastModDate = new Date(file.lastModified);
- }
- return addChild(this, file.name, {
- data: file,
- Reader: function () {
- const readable = file.stream();
- const size = file.size;
- return { readable, size };
- },
- options,
- uncompressedSize: file.size
- });
- }
-
- addData(name, params) {
- return addChild(this, name, params);
- }
-
- importBlob(blob, options) {
- return this.importZip(new BlobReader(blob), options);
- }
-
- importData64URI(dataURI, options) {
- return this.importZip(new Data64URIReader(dataURI), options);
- }
-
- importUint8Array(array, options) {
- return this.importZip(new Uint8ArrayReader(array), options);
- }
-
- importHttpContent(url, options) {
- return this.importZip(new HttpReader(url, options), options);
- }
-
- importReadable(readable, options) {
- return this.importZip({ readable }, options);
- }
-
- exportBlob(options = {}) {
- return this.exportZip(new BlobWriter(options.mimeType || "application/zip"), options);
- }
-
- exportData64URI(options = {}) {
- return this.exportZip(new Data64URIWriter(options.mimeType || "application/zip"), options);
- }
-
- exportUint8Array(options = {}) {
- return this.exportZip(new Uint8ArrayWriter(), options);
- }
-
- async exportWritable(writable = new WritableStream(), options = {}) {
- await this.exportZip({ writable }, options);
- return writable;
- }
-
- async importZip(reader, options = {}) {
- await initStream(reader);
- const zipReader = new ZipReader(reader, options);
- const importedEntries = [];
- const entries = await zipReader.getEntries();
- for (const entry of entries) {
- let parent = this;
- try {
- const path = entry.filename.split("/");
- const name = path.pop();
- path.forEach((pathPart, pathIndex) => {
- const previousParent = parent;
- parent = parent.getChildByName(pathPart);
- if (!parent) {
- parent = new ZipDirectoryEntry(this.fs, pathPart, { data: pathIndex == path.length - 1 ? entry : null }, previousParent);
- importedEntries.push(parent);
- }
- });
- if (!entry.directory) {
- importedEntries.push(addChild(parent, name, {
- data: entry,
- Reader: getZipBlobReader(Object.assign({}, options)),
- uncompressedSize: entry.uncompressedSize,
- passThrough: options.passThrough
- }));
- }
- } catch (error) {
- try {
- error.cause = {
- entry
- };
- } catch {
- // ignored
- }
- throw error;
- }
- }
- return importedEntries;
- }
-
- async exportZip(writer, options) {
- const zipEntry = this;
- if (options.bufferedWrite === UNDEFINED_VALUE) {
- options.bufferedWrite = true;
- }
- await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
- const zipWriter = new ZipWriter(writer, options);
- await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], "uncompressedSize"), options);
- await zipWriter.close();
- return writer.getData ? writer.getData() : writer.writable;
- }
-
- getChildByName(name) {
- const children = this.children;
- for (let childIndex = 0; childIndex < children.length; childIndex++) {
- const child = children[childIndex];
- if (child.name == name) {
- return child;
- }
- }
- }
-
- isPasswordProtected() {
- const children = this.children;
- for (let childIndex = 0; childIndex < children.length; childIndex++) {
- const child = children[childIndex];
- if (child.isPasswordProtected()) {
- return true;
- }
- }
- return false;
- }
-
- async checkPassword(password, options = {}) {
- const children = this.children;
- const result = await Promise.all(children.map(child => child.checkPassword(password, options)));
- return !result.includes(false);
- }
- }
-
-
- class FS {
-
- constructor() {
- resetFS(this);
- }
-
- get children() {
- return this.root.children;
- }
-
- remove(entry) {
- detach(entry);
- this.entries[entry.id] = null;
- }
-
- move(entry, destination) {
- if (entry == this.root) {
- throw new Error("Root directory cannot be moved");
- } else {
- if (destination.directory) {
- if (!destination.isDescendantOf(entry)) {
- if (entry != destination) {
- if (destination.getChildByName(entry.name)) {
- throw new Error("Entry filename already exists");
- }
- detach(entry);
- entry.parent = destination;
- destination.children.push(entry);
- }
- } else {
- throw new Error("Entry is a ancestor of target entry");
- }
- } else {
- throw new Error("Target entry is not a directory");
- }
- }
- }
-
- find(fullname) {
- const path = fullname.split("/");
- let node = this.root;
- for (let index = 0; node && index < path.length; index++) {
- node = node.getChildByName(path[index]);
- }
- return node;
- }
-
- getById(id) {
- return this.entries[id];
- }
-
- getChildByName(name) {
- return this.root.getChildByName(name);
- }
-
- addDirectory(name, options) {
- return this.root.addDirectory(name, options);
- }
-
- addText(name, text, options) {
- return this.root.addText(name, text, options);
- }
-
- addBlob(name, blob, options) {
- return this.root.addBlob(name, blob, options);
- }
-
- addData64URI(name, dataURI, options) {
- return this.root.addData64URI(name, dataURI, options);
- }
-
- addUint8Array(name, array, options) {
- return this.root.addUint8Array(name, array, options);
- }
-
- addHttpContent(name, url, options) {
- return this.root.addHttpContent(name, url, options);
- }
-
- addReadable(name, readable, options) {
- return this.root.addReadable(name, readable, options);
- }
-
- addFileSystemEntry(fileSystemEntry, options) {
- return this.root.addFileSystemEntry(fileSystemEntry, options);
- }
-
- addFileSystemHandle(handle, options) {
- return this.root.addFileSystemHandle(handle, options);
- }
-
- addFile(file, options) {
- return this.root.addFile(file, options);
- }
-
- addData(name, params) {
- return this.root.addData(name, params);
- }
-
- importBlob(blob, options) {
- resetFS(this);
- return this.root.importBlob(blob, options);
- }
-
- importData64URI(dataURI, options) {
- resetFS(this);
- return this.root.importData64URI(dataURI, options);
- }
-
- importUint8Array(array, options) {
- resetFS(this);
- return this.root.importUint8Array(array, options);
- }
-
- importHttpContent(url, options) {
- resetFS(this);
- return this.root.importHttpContent(url, options);
- }
-
- importReadable(readable, options) {
- resetFS(this);
- return this.root.importReadable(readable, options);
- }
-
- importZip(reader, options) {
- return this.root.importZip(reader, options);
- }
-
- exportBlob(options) {
- return this.root.exportBlob(options);
- }
-
- exportData64URI(options) {
- return this.root.exportData64URI(options);
- }
-
- exportUint8Array(options) {
- return this.root.exportUint8Array(options);
- }
-
- exportWritable(writable, options) {
- return this.root.exportWritable(writable, options);
- }
-
- isPasswordProtected() {
- return this.root.isPasswordProtected();
- }
-
- checkPassword(password, options) {
- return this.root.checkPassword(password, options);
- }
- }
-
- const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
-
- function getTotalSize(entries, propertyName) {
- let size = 0;
- entries.forEach(process);
- return size;
-
- function process(entry) {
- size += entry[propertyName];
- if (entry.children) {
- entry.children.forEach(process);
- }
- }
- }
-
- function getZipBlobReader(options) {
- return class extends Reader {
-
- constructor(entry, options = {}) {
- super();
- this.entry = entry;
- this.options = options;
- }
-
- async init() {
- const zipBlobReader = this;
- zipBlobReader.size = zipBlobReader.entry.uncompressedSize;
- const data = await zipBlobReader.entry.getData(new BlobWriter(), Object.assign({}, zipBlobReader.options, options));
- zipBlobReader.data = data;
- zipBlobReader.blobReader = new BlobReader(data);
- super.init();
- }
-
- readUint8Array(index, length) {
- return this.blobReader.readUint8Array(index, length);
- }
- };
- }
-
- async function initReaders(entry, options) {
- if (entry.children.length) {
- await Promise.all(entry.children.map(async child => {
- if (child.directory) {
- await initReaders(child, options);
- } else {
- const reader = child.reader = new child.Reader(child.data, options);
- try {
- await initStream(reader);
- } catch (error) {
- try {
- error.entryId = child.id;
- error.cause = {
- entry: child
- };
- } catch {
- // ignored
- }
- throw error;
- }
- child.uncompressedSize = reader.size;
- }
- }));
- }
- }
-
- function detach(entry) {
- if (entry.parent) {
- const children = entry.parent.children;
- children.forEach((child, index) => {
- if (child.id == entry.id) {
- children.splice(index, 1);
- }
- });
- }
- }
-
- async function exportZip(zipWriter, entry, totalSize, options) {
- const selectedEntry = entry;
- const entryOffsets = new Map();
- await process(zipWriter, entry);
-
- async function process(zipWriter, entry) {
- await exportChild();
-
- async function exportChild() {
- if (options.bufferedWrite) {
- await Promise.allSettled(entry.children.map(processChild));
- } else {
- for (const child of entry.children) {
- await processChild(child);
- }
- }
- }
-
- async function processChild(child) {
- const name = options.relativePath ? child.getRelativeName(selectedEntry) : child.getFullname();
- const childOptions = child.options || {};
- let zipEntryOptions = {};
- if (child.data instanceof Entry) {
- const {
- externalFileAttributes,
- versionMadeBy,
- comment,
- lastModDate,
- creationDate,
- lastAccessDate,
- uncompressedSize,
- encrypted,
- zipCrypto,
- signature,
- compressionMethod,
- extraFieldAES
- } = child.data;
- zipEntryOptions = {
- externalFileAttributes,
- versionMadeBy,
- comment,
- lastModDate,
- creationDate,
- lastAccessDate
- };
- if (child.passThrough) {
- let level, encryptionStrength;
- if (compressionMethod === 0) {
- level = 0;
- }
- if (extraFieldAES) {
- encryptionStrength = extraFieldAES.strength;
- }
- zipEntryOptions = Object.assign(zipEntryOptions, {
- passThrough: true,
- encrypted,
- zipCrypto,
- signature,
- uncompressedSize,
- level,
- encryptionStrength,
- compressionMethod
- });
- }
- }
- await zipWriter.add(name, child.reader, Object.assign({}, options, zipEntryOptions, childOptions, {
- directory: child.directory,
- onprogress: async indexProgress => {
- if (options.onprogress) {
- entryOffsets.set(name, indexProgress);
- try {
- await options.onprogress(Array.from(entryOffsets.values()).reduce((previousValue, currentValue) => previousValue + currentValue), totalSize);
- } catch {
- // ignored
- }
- }
- }
- }));
- await process(zipWriter, child);
- }
- }
- }
-
- function addFileSystemHandle(zipEntry, handle, options) {
- return addFile(zipEntry, handle, []);
-
- async function addFile(parentEntry, handle, addedEntries) {
- if (handle) {
- try {
- if (handle.isFile || handle.isDirectory) {
- handle = await transformToFileSystemhandle(handle);
- }
- if (handle.kind == "file") {
- const file = await handle.getFile();
- addedEntries.push(
- parentEntry.addData(file.name, {
- Reader: function () {
- const readable = file.stream();
- const size = file.size;
- return { readable, size };
- },
- options: Object.assign({}, { lastModDate: new Date(file.lastModified) }, options),
- uncompressedSize: file.size
- })
- );
- } else if (handle.kind == "directory") {
- const directoryEntry = parentEntry.addDirectory(handle.name);
- addedEntries.push(directoryEntry);
- for await (const childHandle of handle.values()) {
- await addFile(directoryEntry, childHandle, addedEntries);
- }
- }
- } catch (error) {
- const message = error.message + (handle ? " (" + handle.name + ")" : "");
- throw new Error(message);
- }
- }
- return addedEntries;
- }
- }
-
- async function transformToFileSystemhandle(entry) {
- const handle = {
- name: entry.name
- };
- if (entry.isFile) {
- handle.kind = "file";
- handle.getFile = () =>
- new Promise((resolve, reject) => entry.file(resolve, reject));
- }
- if (entry.isDirectory) {
- handle.kind = "directory";
- const handles = await transformToFileSystemhandles(entry);
- handle.values = () => handles;
- }
- return handle;
- }
-
- async function transformToFileSystemhandles(entry) {
- const entries = [];
- function readEntries(directoryReader, resolve, reject) {
- directoryReader.readEntries(async (entriesPart) => {
- if (!entriesPart.length) {
- resolve(entries);
- } else {
- for (const entry of entriesPart) {
- entries.push(await transformToFileSystemhandle(entry));
- }
- readEntries(directoryReader, resolve, reject);
- }
- }, reject);
- }
- await new Promise((resolve, reject) =>
- readEntries(entry.createReader(), resolve, reject)
- );
- return {
- [Symbol.iterator]() {
- let entryIndex = 0;
- return {
- next() {
- const result = {
- value: entries[entryIndex],
- done: entryIndex == entries.length
- };
- entryIndex++;
- return result;
- }
- };
- }
- };
- }
-
- function resetFS(fs) {
- fs.entries = [];
- fs.root = new ZipDirectoryEntry(fs);
- }
-
- function addChild(parent, name, params, directory) {
- if (parent.directory) {
- return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
- } else {
- throw new Error("Parent entry is not a directory");
- }
- }
-
- /*
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- const table = {
- "application": {
- "andrew-inset": "ez",
- "annodex": "anx",
- "atom+xml": "atom",
- "atomcat+xml": "atomcat",
- "atomserv+xml": "atomsrv",
- "bbolin": "lin",
- "cu-seeme": "cu",
- "davmount+xml": "davmount",
- "dsptype": "tsp",
- "ecmascript": [
- "es",
- "ecma"
- ],
- "futuresplash": "spl",
- "hta": "hta",
- "java-archive": "jar",
- "java-serialized-object": "ser",
- "java-vm": "class",
- "m3g": "m3g",
- "mac-binhex40": "hqx",
- "mathematica": [
- "nb",
- "ma",
- "mb"
- ],
- "msaccess": "mdb",
- "msword": [
- "doc",
- "dot",
- "wiz"
- ],
- "mxf": "mxf",
- "oda": "oda",
- "ogg": "ogx",
- "pdf": "pdf",
- "pgp-keys": "key",
- "pgp-signature": [
- "asc",
- "sig"
- ],
- "pics-rules": "prf",
- "postscript": [
- "ps",
- "ai",
- "eps",
- "epsi",
- "epsf",
- "eps2",
- "eps3"
- ],
- "rar": "rar",
- "rdf+xml": "rdf",
- "rss+xml": "rss",
- "rtf": "rtf",
- "xhtml+xml": [
- "xhtml",
- "xht"
- ],
- "xml": [
- "xml",
- "xsl",
- "xsd",
- "xpdl"
- ],
- "xspf+xml": "xspf",
- "zip": "zip",
- "vnd.android.package-archive": "apk",
- "vnd.cinderella": "cdy",
- "vnd.google-earth.kml+xml": "kml",
- "vnd.google-earth.kmz": "kmz",
- "vnd.mozilla.xul+xml": "xul",
- "vnd.ms-excel": [
- "xls",
- "xlb",
- "xlt",
- "xlm",
- "xla",
- "xlc",
- "xlw"
- ],
- "vnd.ms-pki.seccat": "cat",
- "vnd.ms-pki.stl": "stl",
- "vnd.ms-powerpoint": [
- "ppt",
- "pps",
- "pot",
- "ppa",
- "pwz"
- ],
- "vnd.oasis.opendocument.chart": "odc",
- "vnd.oasis.opendocument.database": "odb",
- "vnd.oasis.opendocument.formula": "odf",
- "vnd.oasis.opendocument.graphics": "odg",
- "vnd.oasis.opendocument.graphics-template": "otg",
- "vnd.oasis.opendocument.image": "odi",
- "vnd.oasis.opendocument.presentation": "odp",
- "vnd.oasis.opendocument.presentation-template": "otp",
- "vnd.oasis.opendocument.spreadsheet": "ods",
- "vnd.oasis.opendocument.spreadsheet-template": "ots",
- "vnd.oasis.opendocument.text": "odt",
- "vnd.oasis.opendocument.text-master": [
- "odm",
- "otm"
- ],
- "vnd.oasis.opendocument.text-template": "ott",
- "vnd.oasis.opendocument.text-web": "oth",
- "vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
- "vnd.openxmlformats-officedocument.spreadsheetml.template": "xltx",
- "vnd.openxmlformats-officedocument.presentationml.presentation": "pptx",
- "vnd.openxmlformats-officedocument.presentationml.slideshow": "ppsx",
- "vnd.openxmlformats-officedocument.presentationml.template": "potx",
- "vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
- "vnd.openxmlformats-officedocument.wordprocessingml.template": "dotx",
- "vnd.smaf": "mmf",
- "vnd.stardivision.calc": "sdc",
- "vnd.stardivision.chart": "sds",
- "vnd.stardivision.draw": "sda",
- "vnd.stardivision.impress": "sdd",
- "vnd.stardivision.math": [
- "sdf",
- "smf"
- ],
- "vnd.stardivision.writer": [
- "sdw",
- "vor"
- ],
- "vnd.stardivision.writer-global": "sgl",
- "vnd.sun.xml.calc": "sxc",
- "vnd.sun.xml.calc.template": "stc",
- "vnd.sun.xml.draw": "sxd",
- "vnd.sun.xml.draw.template": "std",
- "vnd.sun.xml.impress": "sxi",
- "vnd.sun.xml.impress.template": "sti",
- "vnd.sun.xml.math": "sxm",
- "vnd.sun.xml.writer": "sxw",
- "vnd.sun.xml.writer.global": "sxg",
- "vnd.sun.xml.writer.template": "stw",
- "vnd.symbian.install": [
- "sis",
- "sisx"
- ],
- "vnd.visio": [
- "vsd",
- "vst",
- "vss",
- "vsw",
- "vsdx",
- "vssx",
- "vstx",
- "vssm",
- "vstm"
- ],
- "vnd.wap.wbxml": "wbxml",
- "vnd.wap.wmlc": "wmlc",
- "vnd.wap.wmlscriptc": "wmlsc",
- "vnd.wordperfect": "wpd",
- "vnd.wordperfect5.1": "wp5",
- "x-123": "wk",
- "x-7z-compressed": "7z",
- "x-abiword": "abw",
- "x-apple-diskimage": "dmg",
- "x-bcpio": "bcpio",
- "x-bittorrent": "torrent",
- "x-cbr": [
- "cbr",
- "cba",
- "cbt",
- "cb7"
- ],
- "x-cbz": "cbz",
- "x-cdf": [
- "cdf",
- "cda"
- ],
- "x-cdlink": "vcd",
- "x-chess-pgn": "pgn",
- "x-cpio": "cpio",
- "x-csh": "csh",
- "x-director": [
- "dir",
- "dxr",
- "cst",
- "cct",
- "cxt",
- "w3d",
- "fgd",
- "swa"
- ],
- "x-dms": "dms",
- "x-doom": "wad",
- "x-dvi": "dvi",
- "x-httpd-eruby": "rhtml",
- "x-font": "pcf.Z",
- "x-freemind": "mm",
- "x-gnumeric": "gnumeric",
- "x-go-sgf": "sgf",
- "x-graphing-calculator": "gcf",
- "x-gtar": [
- "gtar",
- "taz"
- ],
- "x-hdf": "hdf",
- "x-httpd-php": [
- "phtml",
- "pht",
- "php"
- ],
- "x-httpd-php-source": "phps",
- "x-httpd-php3": "php3",
- "x-httpd-php3-preprocessed": "php3p",
- "x-httpd-php4": "php4",
- "x-httpd-php5": "php5",
- "x-ica": "ica",
- "x-info": "info",
- "x-internet-signup": [
- "ins",
- "isp"
- ],
- "x-iphone": "iii",
- "x-iso9660-image": "iso",
- "x-java-jnlp-file": "jnlp",
- "x-jmol": "jmz",
- "x-killustrator": "kil",
- "x-latex": "latex",
- "x-lyx": "lyx",
- "x-lzx": "lzx",
- "x-maker": [
- "frm",
- "fb",
- "fbdoc"
- ],
- "x-ms-wmd": "wmd",
- "x-msdos-program": [
- "com",
- "exe",
- "bat",
- "dll"
- ],
- "x-netcdf": [
- "nc"
- ],
- "x-ns-proxy-autoconfig": [
- "pac",
- "dat"
- ],
- "x-nwc": "nwc",
- "x-object": "o",
- "x-oz-application": "oza",
- "x-pkcs7-certreqresp": "p7r",
- "x-python-code": [
- "pyc",
- "pyo"
- ],
- "x-qgis": [
- "qgs",
- "shp",
- "shx"
- ],
- "x-quicktimeplayer": "qtl",
- "x-redhat-package-manager": [
- "rpm",
- "rpa"
- ],
- "x-ruby": "rb",
- "x-sh": "sh",
- "x-shar": "shar",
- "x-shockwave-flash": [
- "swf",
- "swfl"
- ],
- "x-silverlight": "scr",
- "x-stuffit": "sit",
- "x-sv4cpio": "sv4cpio",
- "x-sv4crc": "sv4crc",
- "x-tar": "tar",
- "x-tex-gf": "gf",
- "x-tex-pk": "pk",
- "x-texinfo": [
- "texinfo",
- "texi"
- ],
- "x-trash": [
- "~",
- "%",
- "bak",
- "old",
- "sik"
- ],
- "x-ustar": "ustar",
- "x-wais-source": "src",
- "x-wingz": "wz",
- "x-x509-ca-cert": [
- "crt",
- "der",
- "cer"
- ],
- "x-xcf": "xcf",
- "x-xfig": "fig",
- "x-xpinstall": "xpi",
- "applixware": "aw",
- "atomsvc+xml": "atomsvc",
- "ccxml+xml": "ccxml",
- "cdmi-capability": "cdmia",
- "cdmi-container": "cdmic",
- "cdmi-domain": "cdmid",
- "cdmi-object": "cdmio",
- "cdmi-queue": "cdmiq",
- "docbook+xml": "dbk",
- "dssc+der": "dssc",
- "dssc+xml": "xdssc",
- "emma+xml": "emma",
- "epub+zip": "epub",
- "exi": "exi",
- "font-tdpfr": "pfr",
- "gml+xml": "gml",
- "gpx+xml": "gpx",
- "gxf": "gxf",
- "hyperstudio": "stk",
- "inkml+xml": [
- "ink",
- "inkml"
- ],
- "ipfix": "ipfix",
- "jsonml+json": "jsonml",
- "lost+xml": "lostxml",
- "mads+xml": "mads",
- "marc": "mrc",
- "marcxml+xml": "mrcx",
- "mathml+xml": [
- "mathml",
- "mml"
- ],
- "mbox": "mbox",
- "mediaservercontrol+xml": "mscml",
- "metalink+xml": "metalink",
- "metalink4+xml": "meta4",
- "mets+xml": "mets",
- "mods+xml": "mods",
- "mp21": [
- "m21",
- "mp21"
- ],
- "mp4": "mp4s",
- "oebps-package+xml": "opf",
- "omdoc+xml": "omdoc",
- "onenote": [
- "onetoc",
- "onetoc2",
- "onetmp",
- "onepkg"
- ],
- "oxps": "oxps",
- "patch-ops-error+xml": "xer",
- "pgp-encrypted": "pgp",
- "pkcs10": "p10",
- "pkcs7-mime": [
- "p7m",
- "p7c"
- ],
- "pkcs7-signature": "p7s",
- "pkcs8": "p8",
- "pkix-attr-cert": "ac",
- "pkix-crl": "crl",
- "pkix-pkipath": "pkipath",
- "pkixcmp": "pki",
- "pls+xml": "pls",
- "prs.cww": "cww",
- "pskc+xml": "pskcxml",
- "reginfo+xml": "rif",
- "relax-ng-compact-syntax": "rnc",
- "resource-lists+xml": "rl",
- "resource-lists-diff+xml": "rld",
- "rls-services+xml": "rs",
- "rpki-ghostbusters": "gbr",
- "rpki-manifest": "mft",
- "rpki-roa": "roa",
- "rsd+xml": "rsd",
- "sbml+xml": "sbml",
- "scvp-cv-request": "scq",
- "scvp-cv-response": "scs",
- "scvp-vp-request": "spq",
- "scvp-vp-response": "spp",
- "sdp": "sdp",
- "set-payment-initiation": "setpay",
- "set-registration-initiation": "setreg",
- "shf+xml": "shf",
- "sparql-query": "rq",
- "sparql-results+xml": "srx",
- "srgs": "gram",
- "srgs+xml": "grxml",
- "sru+xml": "sru",
- "ssdl+xml": "ssdl",
- "ssml+xml": "ssml",
- "tei+xml": [
- "tei",
- "teicorpus"
- ],
- "thraud+xml": "tfi",
- "timestamped-data": "tsd",
- "vnd.3gpp.pic-bw-large": "plb",
- "vnd.3gpp.pic-bw-small": "psb",
- "vnd.3gpp.pic-bw-var": "pvb",
- "vnd.3gpp2.tcap": "tcap",
- "vnd.3m.post-it-notes": "pwn",
- "vnd.accpac.simply.aso": "aso",
- "vnd.accpac.simply.imp": "imp",
- "vnd.acucobol": "acu",
- "vnd.acucorp": [
- "atc",
- "acutc"
- ],
- "vnd.adobe.air-application-installer-package+zip": "air",
- "vnd.adobe.formscentral.fcdt": "fcdt",
- "vnd.adobe.fxp": [
- "fxp",
- "fxpl"
- ],
- "vnd.adobe.xdp+xml": "xdp",
- "vnd.adobe.xfdf": "xfdf",
- "vnd.ahead.space": "ahead",
- "vnd.airzip.filesecure.azf": "azf",
- "vnd.airzip.filesecure.azs": "azs",
- "vnd.amazon.ebook": "azw",
- "vnd.americandynamics.acc": "acc",
- "vnd.amiga.ami": "ami",
- "vnd.anser-web-certificate-issue-initiation": "cii",
- "vnd.anser-web-funds-transfer-initiation": "fti",
- "vnd.antix.game-component": "atx",
- "vnd.apple.installer+xml": "mpkg",
- "vnd.apple.mpegurl": "m3u8",
- "vnd.aristanetworks.swi": "swi",
- "vnd.astraea-software.iota": "iota",
- "vnd.audiograph": "aep",
- "vnd.blueice.multipass": "mpm",
- "vnd.bmi": "bmi",
- "vnd.businessobjects": "rep",
- "vnd.chemdraw+xml": "cdxml",
- "vnd.chipnuts.karaoke-mmd": "mmd",
- "vnd.claymore": "cla",
- "vnd.cloanto.rp9": "rp9",
- "vnd.clonk.c4group": [
- "c4g",
- "c4d",
- "c4f",
- "c4p",
- "c4u"
- ],
- "vnd.cluetrust.cartomobile-config": "c11amc",
- "vnd.cluetrust.cartomobile-config-pkg": "c11amz",
- "vnd.commonspace": "csp",
- "vnd.contact.cmsg": "cdbcmsg",
- "vnd.cosmocaller": "cmc",
- "vnd.crick.clicker": "clkx",
- "vnd.crick.clicker.keyboard": "clkk",
- "vnd.crick.clicker.palette": "clkp",
- "vnd.crick.clicker.template": "clkt",
- "vnd.crick.clicker.wordbank": "clkw",
- "vnd.criticaltools.wbs+xml": "wbs",
- "vnd.ctc-posml": "pml",
- "vnd.cups-ppd": "ppd",
- "vnd.curl.car": "car",
- "vnd.curl.pcurl": "pcurl",
- "vnd.dart": "dart",
- "vnd.data-vision.rdz": "rdz",
- "vnd.dece.data": [
- "uvf",
- "uvvf",
- "uvd",
- "uvvd"
- ],
- "vnd.dece.ttml+xml": [
- "uvt",
- "uvvt"
- ],
- "vnd.dece.unspecified": [
- "uvx",
- "uvvx"
- ],
- "vnd.dece.zip": [
- "uvz",
- "uvvz"
- ],
- "vnd.denovo.fcselayout-link": "fe_launch",
- "vnd.dna": "dna",
- "vnd.dolby.mlp": "mlp",
- "vnd.dpgraph": "dpg",
- "vnd.dreamfactory": "dfac",
- "vnd.ds-keypoint": "kpxx",
- "vnd.dvb.ait": "ait",
- "vnd.dvb.service": "svc",
- "vnd.dynageo": "geo",
- "vnd.ecowin.chart": "mag",
- "vnd.enliven": "nml",
- "vnd.epson.esf": "esf",
- "vnd.epson.msf": "msf",
- "vnd.epson.quickanime": "qam",
- "vnd.epson.salt": "slt",
- "vnd.epson.ssf": "ssf",
- "vnd.eszigno3+xml": [
- "es3",
- "et3"
- ],
- "vnd.ezpix-album": "ez2",
- "vnd.ezpix-package": "ez3",
- "vnd.fdf": "fdf",
- "vnd.fdsn.mseed": "mseed",
- "vnd.fdsn.seed": [
- "seed",
- "dataless"
- ],
- "vnd.flographit": "gph",
- "vnd.fluxtime.clip": "ftc",
- "vnd.framemaker": [
- "fm",
- "frame",
- "maker",
- "book"
- ],
- "vnd.frogans.fnc": "fnc",
- "vnd.frogans.ltf": "ltf",
- "vnd.fsc.weblaunch": "fsc",
- "vnd.fujitsu.oasys": "oas",
- "vnd.fujitsu.oasys2": "oa2",
- "vnd.fujitsu.oasys3": "oa3",
- "vnd.fujitsu.oasysgp": "fg5",
- "vnd.fujitsu.oasysprs": "bh2",
- "vnd.fujixerox.ddd": "ddd",
- "vnd.fujixerox.docuworks": "xdw",
- "vnd.fujixerox.docuworks.binder": "xbd",
- "vnd.fuzzysheet": "fzs",
- "vnd.genomatix.tuxedo": "txd",
- "vnd.geogebra.file": "ggb",
- "vnd.geogebra.tool": "ggt",
- "vnd.geometry-explorer": [
- "gex",
- "gre"
- ],
- "vnd.geonext": "gxt",
- "vnd.geoplan": "g2w",
- "vnd.geospace": "g3w",
- "vnd.gmx": "gmx",
- "vnd.grafeq": [
- "gqf",
- "gqs"
- ],
- "vnd.groove-account": "gac",
- "vnd.groove-help": "ghf",
- "vnd.groove-identity-message": "gim",
- "vnd.groove-injector": "grv",
- "vnd.groove-tool-message": "gtm",
- "vnd.groove-tool-template": "tpl",
- "vnd.groove-vcard": "vcg",
- "vnd.hal+xml": "hal",
- "vnd.handheld-entertainment+xml": "zmm",
- "vnd.hbci": "hbci",
- "vnd.hhe.lesson-player": "les",
- "vnd.hp-hpgl": "hpgl",
- "vnd.hp-hpid": "hpid",
- "vnd.hp-hps": "hps",
- "vnd.hp-jlyt": "jlt",
- "vnd.hp-pcl": "pcl",
- "vnd.hp-pclxl": "pclxl",
- "vnd.hydrostatix.sof-data": "sfd-hdstx",
- "vnd.ibm.minipay": "mpy",
- "vnd.ibm.modcap": [
- "afp",
- "listafp",
- "list3820"
- ],
- "vnd.ibm.rights-management": "irm",
- "vnd.ibm.secure-container": "sc",
- "vnd.iccprofile": [
- "icc",
- "icm"
- ],
- "vnd.igloader": "igl",
- "vnd.immervision-ivp": "ivp",
- "vnd.immervision-ivu": "ivu",
- "vnd.insors.igm": "igm",
- "vnd.intercon.formnet": [
- "xpw",
- "xpx"
- ],
- "vnd.intergeo": "i2g",
- "vnd.intu.qbo": "qbo",
- "vnd.intu.qfx": "qfx",
- "vnd.ipunplugged.rcprofile": "rcprofile",
- "vnd.irepository.package+xml": "irp",
- "vnd.is-xpr": "xpr",
- "vnd.isac.fcs": "fcs",
- "vnd.jam": "jam",
- "vnd.jcp.javame.midlet-rms": "rms",
- "vnd.jisp": "jisp",
- "vnd.joost.joda-archive": "joda",
- "vnd.kahootz": [
- "ktz",
- "ktr"
- ],
- "vnd.kde.karbon": "karbon",
- "vnd.kde.kchart": "chrt",
- "vnd.kde.kformula": "kfo",
- "vnd.kde.kivio": "flw",
- "vnd.kde.kontour": "kon",
- "vnd.kde.kpresenter": [
- "kpr",
- "kpt"
- ],
- "vnd.kde.kspread": "ksp",
- "vnd.kde.kword": [
- "kwd",
- "kwt"
- ],
- "vnd.kenameaapp": "htke",
- "vnd.kidspiration": "kia",
- "vnd.kinar": [
- "kne",
- "knp"
- ],
- "vnd.koan": [
- "skp",
- "skd",
- "skt",
- "skm"
- ],
- "vnd.kodak-descriptor": "sse",
- "vnd.las.las+xml": "lasxml",
- "vnd.llamagraphics.life-balance.desktop": "lbd",
- "vnd.llamagraphics.life-balance.exchange+xml": "lbe",
- "vnd.lotus-1-2-3": "123",
- "vnd.lotus-approach": "apr",
- "vnd.lotus-freelance": "pre",
- "vnd.lotus-notes": "nsf",
- "vnd.lotus-organizer": "org",
- "vnd.lotus-screencam": "scm",
- "vnd.lotus-wordpro": "lwp",
- "vnd.macports.portpkg": "portpkg",
- "vnd.mcd": "mcd",
- "vnd.medcalcdata": "mc1",
- "vnd.mediastation.cdkey": "cdkey",
- "vnd.mfer": "mwf",
- "vnd.mfmp": "mfm",
- "vnd.micrografx.flo": "flo",
- "vnd.micrografx.igx": "igx",
- "vnd.mif": "mif",
- "vnd.mobius.daf": "daf",
- "vnd.mobius.dis": "dis",
- "vnd.mobius.mbk": "mbk",
- "vnd.mobius.mqy": "mqy",
- "vnd.mobius.msl": "msl",
- "vnd.mobius.plc": "plc",
- "vnd.mobius.txf": "txf",
- "vnd.mophun.application": "mpn",
- "vnd.mophun.certificate": "mpc",
- "vnd.ms-artgalry": "cil",
- "vnd.ms-cab-compressed": "cab",
- "vnd.ms-excel.addin.macroenabled.12": "xlam",
- "vnd.ms-excel.sheet.binary.macroenabled.12": "xlsb",
- "vnd.ms-excel.sheet.macroenabled.12": "xlsm",
- "vnd.ms-excel.template.macroenabled.12": "xltm",
- "vnd.ms-fontobject": "eot",
- "vnd.ms-htmlhelp": "chm",
- "vnd.ms-ims": "ims",
- "vnd.ms-lrm": "lrm",
- "vnd.ms-officetheme": "thmx",
- "vnd.ms-powerpoint.addin.macroenabled.12": "ppam",
- "vnd.ms-powerpoint.presentation.macroenabled.12": "pptm",
- "vnd.ms-powerpoint.slide.macroenabled.12": "sldm",
- "vnd.ms-powerpoint.slideshow.macroenabled.12": "ppsm",
- "vnd.ms-powerpoint.template.macroenabled.12": "potm",
- "vnd.ms-project": [
- "mpp",
- "mpt"
- ],
- "vnd.ms-word.document.macroenabled.12": "docm",
- "vnd.ms-word.template.macroenabled.12": "dotm",
- "vnd.ms-works": [
- "wps",
- "wks",
- "wcm",
- "wdb"
- ],
- "vnd.ms-wpl": "wpl",
- "vnd.ms-xpsdocument": "xps",
- "vnd.mseq": "mseq",
- "vnd.musician": "mus",
- "vnd.muvee.style": "msty",
- "vnd.mynfc": "taglet",
- "vnd.neurolanguage.nlu": "nlu",
- "vnd.nitf": [
- "ntf",
- "nitf"
- ],
- "vnd.noblenet-directory": "nnd",
- "vnd.noblenet-sealer": "nns",
- "vnd.noblenet-web": "nnw",
- "vnd.nokia.n-gage.data": "ngdat",
- "vnd.nokia.n-gage.symbian.install": "n-gage",
- "vnd.nokia.radio-preset": "rpst",
- "vnd.nokia.radio-presets": "rpss",
- "vnd.novadigm.edm": "edm",
- "vnd.novadigm.edx": "edx",
- "vnd.novadigm.ext": "ext",
- "vnd.oasis.opendocument.chart-template": "otc",
- "vnd.oasis.opendocument.formula-template": "odft",
- "vnd.oasis.opendocument.image-template": "oti",
- "vnd.olpc-sugar": "xo",
- "vnd.oma.dd2+xml": "dd2",
- "vnd.openofficeorg.extension": "oxt",
- "vnd.openxmlformats-officedocument.presentationml.slide": "sldx",
- "vnd.osgeo.mapguide.package": "mgp",
- "vnd.osgi.dp": "dp",
- "vnd.osgi.subsystem": "esa",
- "vnd.palm": [
- "pdb",
- "pqa",
- "oprc"
- ],
- "vnd.pawaafile": "paw",
- "vnd.pg.format": "str",
- "vnd.pg.osasli": "ei6",
- "vnd.picsel": "efif",
- "vnd.pmi.widget": "wg",
- "vnd.pocketlearn": "plf",
- "vnd.powerbuilder6": "pbd",
- "vnd.previewsystems.box": "box",
- "vnd.proteus.magazine": "mgz",
- "vnd.publishare-delta-tree": "qps",
- "vnd.pvi.ptid1": "ptid",
- "vnd.quark.quarkxpress": [
- "qxd",
- "qxt",
- "qwd",
- "qwt",
- "qxl",
- "qxb"
- ],
- "vnd.realvnc.bed": "bed",
- "vnd.recordare.musicxml": "mxl",
- "vnd.recordare.musicxml+xml": "musicxml",
- "vnd.rig.cryptonote": "cryptonote",
- "vnd.rn-realmedia": "rm",
- "vnd.rn-realmedia-vbr": "rmvb",
- "vnd.route66.link66+xml": "link66",
- "vnd.sailingtracker.track": "st",
- "vnd.seemail": "see",
- "vnd.sema": "sema",
- "vnd.semd": "semd",
- "vnd.semf": "semf",
- "vnd.shana.informed.formdata": "ifm",
- "vnd.shana.informed.formtemplate": "itp",
- "vnd.shana.informed.interchange": "iif",
- "vnd.shana.informed.package": "ipk",
- "vnd.simtech-mindmapper": [
- "twd",
- "twds"
- ],
- "vnd.smart.teacher": "teacher",
- "vnd.solent.sdkm+xml": [
- "sdkm",
- "sdkd"
- ],
- "vnd.spotfire.dxp": "dxp",
- "vnd.spotfire.sfs": "sfs",
- "vnd.stepmania.package": "smzip",
- "vnd.stepmania.stepchart": "sm",
- "vnd.sus-calendar": [
- "sus",
- "susp"
- ],
- "vnd.svd": "svd",
- "vnd.syncml+xml": "xsm",
- "vnd.syncml.dm+wbxml": "bdm",
- "vnd.syncml.dm+xml": "xdm",
- "vnd.tao.intent-module-archive": "tao",
- "vnd.tcpdump.pcap": [
- "pcap",
- "cap",
- "dmp"
- ],
- "vnd.tmobile-livetv": "tmo",
- "vnd.trid.tpt": "tpt",
- "vnd.triscape.mxs": "mxs",
- "vnd.trueapp": "tra",
- "vnd.ufdl": [
- "ufd",
- "ufdl"
- ],
- "vnd.uiq.theme": "utz",
- "vnd.umajin": "umj",
- "vnd.unity": "unityweb",
- "vnd.uoml+xml": "uoml",
- "vnd.vcx": "vcx",
- "vnd.visionary": "vis",
- "vnd.vsf": "vsf",
- "vnd.webturbo": "wtb",
- "vnd.wolfram.player": "nbp",
- "vnd.wqd": "wqd",
- "vnd.wt.stf": "stf",
- "vnd.xara": "xar",
- "vnd.xfdl": "xfdl",
- "vnd.yamaha.hv-dic": "hvd",
- "vnd.yamaha.hv-script": "hvs",
- "vnd.yamaha.hv-voice": "hvp",
- "vnd.yamaha.openscoreformat": "osf",
- "vnd.yamaha.openscoreformat.osfpvg+xml": "osfpvg",
- "vnd.yamaha.smaf-audio": "saf",
- "vnd.yamaha.smaf-phrase": "spf",
- "vnd.yellowriver-custom-menu": "cmp",
- "vnd.zul": [
- "zir",
- "zirz"
- ],
- "vnd.zzazz.deck+xml": "zaz",
- "voicexml+xml": "vxml",
- "widget": "wgt",
- "winhlp": "hlp",
- "wsdl+xml": "wsdl",
- "wspolicy+xml": "wspolicy",
- "x-ace-compressed": "ace",
- "x-authorware-bin": [
- "aab",
- "x32",
- "u32",
- "vox"
- ],
- "x-authorware-map": "aam",
- "x-authorware-seg": "aas",
- "x-blorb": [
- "blb",
- "blorb"
- ],
- "x-bzip": "bz",
- "x-bzip2": [
- "bz2",
- "boz"
- ],
- "x-cfs-compressed": "cfs",
- "x-chat": "chat",
- "x-conference": "nsc",
- "x-dgc-compressed": "dgc",
- "x-dtbncx+xml": "ncx",
- "x-dtbook+xml": "dtb",
- "x-dtbresource+xml": "res",
- "x-eva": "eva",
- "x-font-bdf": "bdf",
- "x-font-ghostscript": "gsf",
- "x-font-linux-psf": "psf",
- "x-font-pcf": "pcf",
- "x-font-snf": "snf",
- "x-font-ttf": [
- "ttf",
- "ttc"
- ],
- "x-font-type1": [
- "pfa",
- "pfb",
- "pfm",
- "afm"
- ],
- "x-freearc": "arc",
- "x-gca-compressed": "gca",
- "x-glulx": "ulx",
- "x-gramps-xml": "gramps",
- "x-install-instructions": "install",
- "x-lzh-compressed": [
- "lzh",
- "lha"
- ],
- "x-mie": "mie",
- "x-mobipocket-ebook": [
- "prc",
- "mobi"
- ],
- "x-ms-application": "application",
- "x-ms-shortcut": "lnk",
- "x-ms-xbap": "xbap",
- "x-msbinder": "obd",
- "x-mscardfile": "crd",
- "x-msclip": "clp",
- "application/x-ms-installer": "msi",
- "x-msmediaview": [
- "mvb",
- "m13",
- "m14"
- ],
- "x-msmetafile": [
- "wmf",
- "wmz",
- "emf",
- "emz"
- ],
- "x-msmoney": "mny",
- "x-mspublisher": "pub",
- "x-msschedule": "scd",
- "x-msterminal": "trm",
- "x-mswrite": "wri",
- "x-nzb": "nzb",
- "x-pkcs12": [
- "p12",
- "pfx"
- ],
- "x-pkcs7-certificates": [
- "p7b",
- "spc"
- ],
- "x-research-info-systems": "ris",
- "x-silverlight-app": "xap",
- "x-sql": "sql",
- "x-stuffitx": "sitx",
- "x-subrip": "srt",
- "x-t3vm-image": "t3",
- "x-tex-tfm": "tfm",
- "x-tgif": "obj",
- "x-xliff+xml": "xlf",
- "x-xz": "xz",
- "x-zmachine": [
- "z1",
- "z2",
- "z3",
- "z4",
- "z5",
- "z6",
- "z7",
- "z8"
- ],
- "xaml+xml": "xaml",
- "xcap-diff+xml": "xdf",
- "xenc+xml": "xenc",
- "xml-dtd": "dtd",
- "xop+xml": "xop",
- "xproc+xml": "xpl",
- "xslt+xml": "xslt",
- "xv+xml": [
- "mxml",
- "xhvml",
- "xvml",
- "xvm"
- ],
- "yang": "yang",
- "yin+xml": "yin",
- "envoy": "evy",
- "fractals": "fif",
- "internet-property-stream": "acx",
- "olescript": "axs",
- "vnd.ms-outlook": "msg",
- "vnd.ms-pkicertstore": "sst",
- "x-compress": "z",
- "x-perfmon": [
- "pma",
- "pmc",
- "pmr",
- "pmw"
- ],
- "ynd.ms-pkipko": "pko",
- "gzip": [
- "gz",
- "tgz"
- ],
- "smil+xml": [
- "smi",
- "smil"
- ],
- "vnd.debian.binary-package": [
- "deb",
- "udeb"
- ],
- "vnd.hzn-3d-crossword": "x3d",
- "vnd.sqlite3": [
- "db",
- "sqlite",
- "sqlite3",
- "db-wal",
- "sqlite-wal",
- "db-shm",
- "sqlite-shm"
- ],
- "vnd.wap.sic": "sic",
- "vnd.wap.slc": "slc",
- "x-krita": [
- "kra",
- "krz"
- ],
- "x-perl": [
- "pm",
- "pl"
- ],
- "yaml": [
- "yaml",
- "yml"
- ]
- },
- "audio": {
- "amr": "amr",
- "amr-wb": "awb",
- "annodex": "axa",
- "basic": [
- "au",
- "snd"
- ],
- "flac": "flac",
- "midi": [
- "mid",
- "midi",
- "kar",
- "rmi"
- ],
- "mpeg": [
- "mpga",
- "mpega",
- "mp3",
- "m4a",
- "mp2a",
- "m2a",
- "m3a"
- ],
- "mpegurl": "m3u",
- "ogg": [
- "oga",
- "ogg",
- "spx"
- ],
- "prs.sid": "sid",
- "x-aiff": "aifc",
- "x-gsm": "gsm",
- "x-ms-wma": "wma",
- "x-ms-wax": "wax",
- "x-pn-realaudio": "ram",
- "x-realaudio": "ra",
- "x-sd2": "sd2",
- "adpcm": "adp",
- "mp4": "mp4a",
- "s3m": "s3m",
- "silk": "sil",
- "vnd.dece.audio": [
- "uva",
- "uvva"
- ],
- "vnd.digital-winds": "eol",
- "vnd.dra": "dra",
- "vnd.dts": "dts",
- "vnd.dts.hd": "dtshd",
- "vnd.lucent.voice": "lvp",
- "vnd.ms-playready.media.pya": "pya",
- "vnd.nuera.ecelp4800": "ecelp4800",
- "vnd.nuera.ecelp7470": "ecelp7470",
- "vnd.nuera.ecelp9600": "ecelp9600",
- "vnd.rip": "rip",
- "webm": "weba",
- "x-caf": "caf",
- "x-matroska": "mka",
- "x-pn-realaudio-plugin": "rmp",
- "xm": "xm",
- "aac": "aac",
- "aiff": [
- "aiff",
- "aif",
- "aff"
- ],
- "opus": "opus",
- "wav": "wav"
- },
- "chemical": {
- "x-alchemy": "alc",
- "x-cache": [
- "cac",
- "cache"
- ],
- "x-cache-csf": "csf",
- "x-cactvs-binary": [
- "cbin",
- "cascii",
- "ctab"
- ],
- "x-cdx": "cdx",
- "x-chem3d": "c3d",
- "x-cif": "cif",
- "x-cmdf": "cmdf",
- "x-cml": "cml",
- "x-compass": "cpa",
- "x-crossfire": "bsd",
- "x-csml": [
- "csml",
- "csm"
- ],
- "x-ctx": "ctx",
- "x-cxf": [
- "cxf",
- "cef"
- ],
- "x-embl-dl-nucleotide": [
- "emb",
- "embl"
- ],
- "x-gamess-input": [
- "inp",
- "gam",
- "gamin"
- ],
- "x-gaussian-checkpoint": [
- "fch",
- "fchk"
- ],
- "x-gaussian-cube": "cub",
- "x-gaussian-input": [
- "gau",
- "gjc",
- "gjf"
- ],
- "x-gaussian-log": "gal",
- "x-gcg8-sequence": "gcg",
- "x-genbank": "gen",
- "x-hin": "hin",
- "x-isostar": [
- "istr",
- "ist"
- ],
- "x-jcamp-dx": [
- "jdx",
- "dx"
- ],
- "x-kinemage": "kin",
- "x-macmolecule": "mcm",
- "x-macromodel-input": "mmod",
- "x-mdl-molfile": "mol",
- "x-mdl-rdfile": "rd",
- "x-mdl-rxnfile": "rxn",
- "x-mdl-sdfile": "sd",
- "x-mdl-tgf": "tgf",
- "x-mmcif": "mcif",
- "x-mol2": "mol2",
- "x-molconn-Z": "b",
- "x-mopac-graph": "gpt",
- "x-mopac-input": [
- "mop",
- "mopcrt",
- "zmt"
- ],
- "x-mopac-out": "moo",
- "x-ncbi-asn1": "asn",
- "x-ncbi-asn1-ascii": [
- "prt",
- "ent"
- ],
- "x-ncbi-asn1-binary": "val",
- "x-rosdal": "ros",
- "x-swissprot": "sw",
- "x-vamas-iso14976": "vms",
- "x-vmd": "vmd",
- "x-xtel": "xtel",
- "x-xyz": "xyz"
- },
- "font": {
- "otf": "otf",
- "woff": "woff",
- "woff2": "woff2"
- },
- "image": {
- "gif": "gif",
- "ief": "ief",
- "jpeg": [
- "jpeg",
- "jpg",
- "jpe",
- "jfif",
- "jfif-tbnl",
- "jif"
- ],
- "pcx": "pcx",
- "png": "png",
- "svg+xml": [
- "svg",
- "svgz"
- ],
- "tiff": [
- "tiff",
- "tif"
- ],
- "vnd.djvu": [
- "djvu",
- "djv"
- ],
- "vnd.wap.wbmp": "wbmp",
- "x-canon-cr2": "cr2",
- "x-canon-crw": "crw",
- "x-cmu-raster": "ras",
- "x-coreldraw": "cdr",
- "x-coreldrawpattern": "pat",
- "x-coreldrawtemplate": "cdt",
- "x-corelphotopaint": "cpt",
- "x-epson-erf": "erf",
- "x-icon": "ico",
- "x-jg": "art",
- "x-jng": "jng",
- "x-nikon-nef": "nef",
- "x-olympus-orf": "orf",
- "x-portable-anymap": "pnm",
- "x-portable-bitmap": "pbm",
- "x-portable-graymap": "pgm",
- "x-portable-pixmap": "ppm",
- "x-rgb": "rgb",
- "x-xbitmap": "xbm",
- "x-xpixmap": "xpm",
- "x-xwindowdump": "xwd",
- "bmp": "bmp",
- "cgm": "cgm",
- "g3fax": "g3",
- "ktx": "ktx",
- "prs.btif": "btif",
- "sgi": "sgi",
- "vnd.dece.graphic": [
- "uvi",
- "uvvi",
- "uvg",
- "uvvg"
- ],
- "vnd.dwg": "dwg",
- "vnd.dxf": "dxf",
- "vnd.fastbidsheet": "fbs",
- "vnd.fpx": "fpx",
- "vnd.fst": "fst",
- "vnd.fujixerox.edmics-mmr": "mmr",
- "vnd.fujixerox.edmics-rlc": "rlc",
- "vnd.ms-modi": "mdi",
- "vnd.ms-photo": "wdp",
- "vnd.net-fpx": "npx",
- "vnd.xiff": "xif",
- "webp": "webp",
- "x-3ds": "3ds",
- "x-cmx": "cmx",
- "x-freehand": [
- "fh",
- "fhc",
- "fh4",
- "fh5",
- "fh7"
- ],
- "x-pict": [
- "pic",
- "pct"
- ],
- "x-tga": "tga",
- "cis-cod": "cod",
- "avif": "avifs",
- "heic": [
- "heif",
- "heic"
- ],
- "pjpeg": [
- "pjpg"
- ],
- "vnd.adobe.photoshop": "psd",
- "x-adobe-dng": "dng",
- "x-fuji-raf": "raf",
- "x-icns": "icns",
- "x-kodak-dcr": "dcr",
- "x-kodak-k25": "k25",
- "x-kodak-kdc": "kdc",
- "x-minolta-mrw": "mrw",
- "x-panasonic-raw": [
- "raw",
- "rw2",
- "rwl"
- ],
- "x-pentax-pef": [
- "pef",
- "ptx"
- ],
- "x-sigma-x3f": "x3f",
- "x-sony-arw": "arw",
- "x-sony-sr2": "sr2",
- "x-sony-srf": "srf"
- },
- "message": {
- "rfc822": [
- "eml",
- "mime",
- "mht",
- "mhtml",
- "nws"
- ]
- },
- "model": {
- "iges": [
- "igs",
- "iges"
- ],
- "mesh": [
- "msh",
- "mesh",
- "silo"
- ],
- "vrml": [
- "wrl",
- "vrml"
- ],
- "x3d+vrml": [
- "x3dv",
- "x3dvz"
- ],
- "x3d+xml": "x3dz",
- "x3d+binary": [
- "x3db",
- "x3dbz"
- ],
- "vnd.collada+xml": "dae",
- "vnd.dwf": "dwf",
- "vnd.gdl": "gdl",
- "vnd.gtw": "gtw",
- "vnd.mts": "mts",
- "vnd.usdz+zip": "usdz",
- "vnd.vtu": "vtu"
- },
- "text": {
- "cache-manifest": [
- "manifest",
- "appcache"
- ],
- "calendar": [
- "ics",
- "icz",
- "ifb"
- ],
- "css": "css",
- "csv": "csv",
- "h323": "323",
- "html": [
- "html",
- "htm",
- "shtml",
- "stm"
- ],
- "iuls": "uls",
- "plain": [
- "txt",
- "text",
- "brf",
- "conf",
- "def",
- "list",
- "log",
- "in",
- "bas",
- "diff",
- "ksh"
- ],
- "richtext": "rtx",
- "scriptlet": [
- "sct",
- "wsc"
- ],
- "texmacs": "tm",
- "tab-separated-values": "tsv",
- "vnd.sun.j2me.app-descriptor": "jad",
- "vnd.wap.wml": "wml",
- "vnd.wap.wmlscript": "wmls",
- "x-bibtex": "bib",
- "x-boo": "boo",
- "x-c++hdr": [
- "h++",
- "hpp",
- "hxx",
- "hh"
- ],
- "x-c++src": [
- "c++",
- "cpp",
- "cxx",
- "cc"
- ],
- "x-component": "htc",
- "x-dsrc": "d",
- "x-diff": "patch",
- "x-haskell": "hs",
- "x-java": "java",
- "x-literate-haskell": "lhs",
- "x-moc": "moc",
- "x-pascal": [
- "p",
- "pas",
- "pp",
- "inc"
- ],
- "x-pcs-gcd": "gcd",
- "x-python": "py",
- "x-scala": "scala",
- "x-setext": "etx",
- "x-tcl": [
- "tcl",
- "tk"
- ],
- "x-tex": [
- "tex",
- "ltx",
- "sty",
- "cls"
- ],
- "x-vcalendar": "vcs",
- "x-vcard": "vcf",
- "n3": "n3",
- "prs.lines.tag": "dsc",
- "sgml": [
- "sgml",
- "sgm"
- ],
- "troff": [
- "t",
- "tr",
- "roff",
- "man",
- "me",
- "ms"
- ],
- "turtle": "ttl",
- "uri-list": [
- "uri",
- "uris",
- "urls"
- ],
- "vcard": "vcard",
- "vnd.curl": "curl",
- "vnd.curl.dcurl": "dcurl",
- "vnd.curl.scurl": "scurl",
- "vnd.curl.mcurl": "mcurl",
- "vnd.dvb.subtitle": "sub",
- "vnd.fly": "fly",
- "vnd.fmi.flexstor": "flx",
- "vnd.graphviz": "gv",
- "vnd.in3d.3dml": "3dml",
- "vnd.in3d.spot": "spot",
- "x-asm": [
- "s",
- "asm"
- ],
- "x-c": [
- "c",
- "h",
- "dic"
- ],
- "x-fortran": [
- "f",
- "for",
- "f77",
- "f90"
- ],
- "x-opml": "opml",
- "x-nfo": "nfo",
- "x-sfv": "sfv",
- "x-uuencode": "uu",
- "webviewhtml": "htt",
- "javascript": "js",
- "json": "json",
- "markdown": [
- "md",
- "markdown",
- "mdown",
- "markdn"
- ],
- "vnd.wap.si": "si",
- "vnd.wap.sl": "sl"
- },
- "video": {
- "avif": "avif",
- "3gpp": "3gp",
- "annodex": "axv",
- "dl": "dl",
- "dv": [
- "dif",
- "dv"
- ],
- "fli": "fli",
- "gl": "gl",
- "mpeg": [
- "mpeg",
- "mpg",
- "mpe",
- "m1v",
- "m2v",
- "mp2",
- "mpa",
- "mpv2"
- ],
- "mp4": [
- "mp4",
- "mp4v",
- "mpg4"
- ],
- "quicktime": [
- "qt",
- "mov"
- ],
- "ogg": "ogv",
- "vnd.mpegurl": [
- "mxu",
- "m4u"
- ],
- "x-flv": "flv",
- "x-la-asf": [
- "lsf",
- "lsx"
- ],
- "x-mng": "mng",
- "x-ms-asf": [
- "asf",
- "asx",
- "asr"
- ],
- "x-ms-wm": "wm",
- "x-ms-wmv": "wmv",
- "x-ms-wmx": "wmx",
- "x-ms-wvx": "wvx",
- "x-msvideo": "avi",
- "x-sgi-movie": "movie",
- "x-matroska": [
- "mpv",
- "mkv",
- "mk3d",
- "mks"
- ],
- "3gpp2": "3g2",
- "h261": "h261",
- "h263": "h263",
- "h264": "h264",
- "jpeg": "jpgv",
- "jpm": [
- "jpm",
- "jpgm"
- ],
- "mj2": [
- "mj2",
- "mjp2"
- ],
- "vnd.dece.hd": [
- "uvh",
- "uvvh"
- ],
- "vnd.dece.mobile": [
- "uvm",
- "uvvm"
- ],
- "vnd.dece.pd": [
- "uvp",
- "uvvp"
- ],
- "vnd.dece.sd": [
- "uvs",
- "uvvs"
- ],
- "vnd.dece.video": [
- "uvv",
- "uvvv"
- ],
- "vnd.dvb.file": "dvb",
- "vnd.fvt": "fvt",
- "vnd.ms-playready.media.pyv": "pyv",
- "vnd.uvvu.mp4": [
- "uvu",
- "uvvu"
- ],
- "vnd.vivo": "viv",
- "webm": "webm",
- "x-f4v": "f4v",
- "x-m4v": "m4v",
- "x-ms-vob": "vob",
- "x-smv": "smv",
- "mp2t": "ts"
- },
- "x-conference": {
- "x-cooltalk": "ice"
- },
- "x-world": {
- "x-vrml": [
- "vrm",
- "flr",
- "wrz",
- "xaf",
- "xof"
- ]
- }
- };
-
- const mimeTypes = (() => {
- const mimeTypes = {};
- for (const type of Object.keys(table)) {
- for (const subtype of Object.keys(table[type])) {
- const value = table[type][subtype];
- if (typeof value == "string") {
- mimeTypes[value] = type + "/" + subtype;
- } else {
- for (let indexMimeType = 0; indexMimeType < value.length; indexMimeType++) {
- mimeTypes[value[indexMimeType]] = type + "/" + subtype;
- }
- }
- }
- }
- return mimeTypes;
- })();
-
- function getMimeType(filename) {
- return filename && mimeTypes[filename.split(".").pop().toLowerCase()] || getMimeType$1();
- }
-
- /*
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- g$1(configure);
-
- exports.BlobReader = BlobReader;
- exports.BlobWriter = BlobWriter;
- exports.Data64URIReader = Data64URIReader;
- exports.Data64URIWriter = Data64URIWriter;
- exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
- exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
- exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
- exports.ERR_ENCRYPTED = ERR_ENCRYPTED;
- exports.ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND;
- exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
- exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
- exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
- exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
- exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
- exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
- exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
- exports.ERR_INVALID_EXTRAFIELD_DATA = ERR_INVALID_EXTRAFIELD_DATA;
- exports.ERR_INVALID_EXTRAFIELD_TYPE = ERR_INVALID_EXTRAFIELD_TYPE;
- exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
- exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
- exports.ERR_INVALID_UNCOMPRESSED_SIZE = ERR_INVALID_UNCOMPRESSED_SIZE;
- exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
- exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
- exports.ERR_OVERLAPPING_ENTRY = ERR_OVERLAPPING_ENTRY;
- exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
- exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
- exports.ERR_UNSUPPORTED_COMPRESSION = ERR_UNSUPPORTED_COMPRESSION;
- exports.ERR_UNSUPPORTED_ENCRYPTION = ERR_UNSUPPORTED_ENCRYPTION;
- exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
- exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
- exports.HttpRangeReader = HttpRangeReader;
- exports.HttpReader = HttpReader;
- exports.Reader = Reader;
- exports.SplitDataReader = SplitDataReader;
- exports.SplitDataWriter = SplitDataWriter;
- exports.TextReader = TextReader;
- exports.TextWriter = TextWriter;
- exports.Uint8ArrayReader = Uint8ArrayReader;
- exports.Uint8ArrayWriter = Uint8ArrayWriter;
- exports.Writer = Writer;
- exports.ZipReader = ZipReader;
- exports.ZipReaderStream = ZipReaderStream;
- exports.ZipWriter = ZipWriter;
- exports.ZipWriterStream = ZipWriterStream;
- exports.configure = configure;
- exports.fs = fs;
- exports.getMimeType = getMimeType;
- exports.terminateWorkers = terminateWorkers;
-
- }));
|