@prose-reader/streamer 1.319.0 → 1.320.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"createArchiveFromEntries-CNz716dm.js","names":[],"sources":["../package.json","../src/report.ts","../src/archives/printTree.ts","../src/archives/createArchive.ts","../src/utils/sortByTitleComparator.ts","../src/utils/uri.ts","../src/archives/createArchiveFromEntries.ts"],"sourcesContent":["{\n \"name\": \"@prose-reader/streamer\",\n \"version\": \"1.318.0\",\n \"type\": \"module\",\n \"main\": \"./dist/index/index.cjs\",\n \"module\": \"./dist/index/index.js\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index/index.js\",\n \"require\": \"./dist/index/index.cjs\"\n },\n \"./archives/createArchiveFromJszip\": {\n \"types\": \"./dist/archives/createArchiveFromJszip.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromJszip/index.js\",\n \"require\": \"./dist/archives/createArchiveFromJszip/index.cjs\"\n },\n \"./archives/createArchiveFromLibArchive\": {\n \"types\": \"./dist/archives/createArchiveFromLibArchive.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromLibArchive/index.js\",\n \"require\": \"./dist/archives/createArchiveFromLibArchive/index.cjs\"\n },\n \"./archives/createArchiveFromUnzipper\": {\n \"types\": \"./dist/archives/createArchiveFromUnzipper.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromUnzipper/index.js\",\n \"require\": \"./dist/archives/createArchiveFromUnzipper/index.cjs\"\n },\n \"./archives/createArchiveFromNodeUnrarJs\": {\n \"types\": \"./dist/archives/createArchiveFromNodeUnrarJs.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromNodeUnrarJs/index.js\",\n \"require\": \"./dist/archives/createArchiveFromNodeUnrarJs/index.cjs\"\n },\n \"./archives/createArchiveFromZipJs\": {\n \"types\": \"./dist/archives/createArchiveFromZipJs.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromZipJs/index.js\",\n \"require\": \"./dist/archives/createArchiveFromZipJs/index.cjs\"\n }\n },\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"files\": [\n \"/dist\"\n ],\n \"scripts\": {\n \"start\": \"vite build --watch --mode development\",\n \"build\": \"tsc && vite build\",\n \"test\": \"vitest run --coverage\",\n \"tsc\": \"tsc\",\n \"test:watch\": \"vitest watch\"\n },\n \"dependencies\": {\n \"@prose-reader/archive-parser\": \"^1.318.0\",\n \"@prose-reader/shared\": \"^1.318.0\",\n \"xmldoc\": \"^2.0.0\"\n },\n \"peerDependencies\": {\n \"@zip.js/zip.js\": \"^2.8.26\",\n \"buffer\": \"^6.0.3\",\n \"jszip\": \"^3.10.0\",\n \"libarchive.js\": \"^2.0.2\",\n \"node-unrar-js\": \"^2.0.2\",\n \"rxjs\": \"*\",\n \"unzipper\": \"^0.12.3\"\n },\n \"peerDependenciesMeta\": {\n \"@zip.js/zip.js\": {\n \"optional\": true\n },\n \"jszip\": {\n \"optional\": true\n },\n \"unzipper\": {\n \"optional\": true\n },\n \"libarchive.js\": {\n \"optional\": true\n },\n \"node-unrar-js\": {\n \"optional\": true\n }\n },\n \"gitHead\": \"4601e14dcacf50b2295cb343582a7ef2c7e1eedc\",\n \"devDependencies\": {\n \"@types/unzipper\": \"^0.10.11\",\n \"@zip.js/zip.js\": \"^2.8.26\",\n \"buffer\": \"^6.0.3\",\n \"isomorphic-fetch\": \"^3.0.0\",\n \"jszip\": \"^3.10.0\",\n \"libarchive.js\": \"^2.0.2\",\n \"node-unrar-js\": \"^2.0.2\",\n \"unzipper\": \"^0.12.3\"\n }\n}\n","import { Report as SharedReport } from \"@prose-reader/shared\"\nimport { name } from \"../package.json\"\n\nexport const Report = SharedReport.namespace(name, false, {\n color: \"#ffae42\",\n})\n","interface TreeNode {\n [key: string]: TreeNode\n}\n\nexport const printTree = (paths: string[]): string => {\n // Split and collect all parts for tree reconstruction\n const tree: TreeNode = {}\n for (const path of paths) {\n const parts = path.split(\"/\")\n let node = tree\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n if (part === undefined) continue\n if (!node[part]) {\n node[part] = {}\n }\n node = node[part]\n }\n }\n\n // Recursively build the tree string\n const render = (node: TreeNode, indent = \"\"): string => {\n return Object.keys(node)\n .sort()\n .map((key, i, arr) => {\n const isLast = i === arr.length - 1\n const prefix = indent + (isLast ? \"└── \" : \"├── \")\n const nextIndent = indent + (isLast ? \" \" : \"│ \")\n const value = node[key]\n if (value && Object.keys(value).length > 0) {\n return `${prefix}${key}/\\n${render(value, nextIndent)}`\n }\n return `${prefix}${key}`\n })\n .join(\"\\n\")\n }\n\n return render(tree)\n}\n","import { Report } from \"../report\"\nimport { printTree } from \"./printTree\"\nimport type { Archive, ArchiveRecord } from \"./types\"\n\ntype ArchiveInit = Omit<Archive, \"recordsByUri\">\n\n/**\n * Builds an {@link Archive} from its records and derives the `recordsByUri`\n * lookup index once, so consumers resolve records in O(1) on the hot path\n * instead of scanning {@link Archive.records}. Duplicate URIs keep the first\n * record, matching the previous `Array.prototype.find` semantics.\n */\nexport const createArchive = ({ records, ...rest }: ArchiveInit): Archive => {\n const recordsByUri = new Map<string, ArchiveRecord>()\n\n for (const record of records) {\n if (!recordsByUri.has(record.uri)) {\n recordsByUri.set(record.uri, record)\n }\n }\n\n const archive: Archive = {\n ...rest,\n records,\n recordsByUri,\n }\n\n Report.log(\"Generated archive\", archive)\n\n if (process.env.NODE_ENV === \"development\") {\n if (Report.isEnabled()) {\n const folderStructureStr = printTree(records.map((record) => record.uri))\n Report.groupCollapsed(...Report.getGroupArgs(\"Archive folder structure\"))\n Report.log(`\\n${folderStructureStr}`)\n Report.groupEnd()\n }\n }\n\n return archive\n}\n","export const sortByTitleComparator = (a: string, b: string) => {\n const alist = a.split(/(\\d+)/)\n const blist = b.split(/(\\d+)/)\n\n for (let i = 0, len = alist.length; i < len; i++) {\n if (alist[i] !== blist[i]) {\n if (alist[i]?.match(/\\d/)) {\n return +(alist[i] || ``) - +(blist[i] || ``)\n }\n return (alist[i] || ``).localeCompare(blist[i] || ``)\n }\n }\n\n return 1\n}\n","export const removeTrailingSlash = (uri: string) =>\n uri.endsWith(\"/\") ? uri.slice(0, -1) : uri\n\nexport const getUriBasename = (uri: string) => {\n const trimmed = removeTrailingSlash(uri)\n\n return trimmed.substring(trimmed.lastIndexOf(`/`) + 1) || trimmed\n}\n\nexport const getUriBasePath = (uri: string) => {\n const lastSlashIndex = uri.lastIndexOf(\"/\")\n\n return lastSlashIndex >= 0 ? uri.substring(0, lastSlashIndex) : \"\"\n}\n","import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { createArchive } from \"./createArchive\"\nimport type { Archive, ArchiveRecord, FileRecord } from \"./types\"\n\n/**\n * Normalized view of a source entry, shared by every `createArchiveFrom*`\n * creator that enumerates a flat list of records. A source only has to provide\n * each entry's `uri`, whether it is a directory, and (for files) its `size`\n * plus content accessors; everything else (basename derivation, mime\n * detection, ordering, the `recordsByUri` index) is handled centrally here.\n */\nexport type ArchiveEntry =\n | { dir: true; uri: string }\n | ({ dir: false; uri: string; size: number } & Pick<\n FileRecord,\n \"blob\" | \"arrayBuffer\"\n >)\n\nexport type CreateArchiveFromEntriesOptions = {\n orderByAlpha?: boolean\n name?: string\n encodingFormat?: string\n close: () => Promise<void>\n}\n\n/**\n * Builds an {@link Archive} from an arbitrary source list. `toEntry` is invoked\n * once per item, and the resulting records are sorted in place when\n * `orderByAlpha` is set — there is no intermediate array, so construction stays\n * a single map plus an optional sort regardless of the source.\n */\nexport const createArchiveFromEntries = <Item>(\n items: Item[],\n toEntry: (item: Item) => ArchiveEntry,\n {\n orderByAlpha,\n name,\n encodingFormat,\n close,\n }: CreateArchiveFromEntriesOptions,\n): Archive => {\n const records = items.map((item): ArchiveRecord => {\n const entry = toEntry(item)\n const basename = getUriBasename(entry.uri)\n\n if (entry.dir) {\n return { dir: true, basename, uri: entry.uri }\n }\n\n return {\n dir: false,\n basename,\n uri: entry.uri,\n encodingFormat: detectMimeTypeFromName(entry.uri),\n size: entry.size,\n blob: entry.blob,\n arrayBuffer: entry.arrayBuffer,\n }\n })\n\n if (orderByAlpha) {\n records.sort((a, b) => sortByTitleComparator(a.uri, b.uri))\n }\n\n return createArchive({ filename: name, encodingFormat, records, close })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createArchiveFromEntries-CNz716dm.js","names":[],"sources":["../package.json","../src/report.ts","../src/archives/printTree.ts","../src/archives/createArchive.ts","../src/utils/sortByTitleComparator.ts","../src/utils/uri.ts","../src/archives/createArchiveFromEntries.ts"],"sourcesContent":["{\n \"name\": \"@prose-reader/streamer\",\n \"version\": \"1.319.0\",\n \"type\": \"module\",\n \"main\": \"./dist/index/index.cjs\",\n \"module\": \"./dist/index/index.js\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index/index.js\",\n \"require\": \"./dist/index/index.cjs\"\n },\n \"./archives/createArchiveFromJszip\": {\n \"types\": \"./dist/archives/createArchiveFromJszip.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromJszip/index.js\",\n \"require\": \"./dist/archives/createArchiveFromJszip/index.cjs\"\n },\n \"./archives/createArchiveFromLibArchive\": {\n \"types\": \"./dist/archives/createArchiveFromLibArchive.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromLibArchive/index.js\",\n \"require\": \"./dist/archives/createArchiveFromLibArchive/index.cjs\"\n },\n \"./archives/createArchiveFromUnzipper\": {\n \"types\": \"./dist/archives/createArchiveFromUnzipper.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromUnzipper/index.js\",\n \"require\": \"./dist/archives/createArchiveFromUnzipper/index.cjs\"\n },\n \"./archives/createArchiveFromNodeUnrarJs\": {\n \"types\": \"./dist/archives/createArchiveFromNodeUnrarJs.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromNodeUnrarJs/index.js\",\n \"require\": \"./dist/archives/createArchiveFromNodeUnrarJs/index.cjs\"\n },\n \"./archives/createArchiveFromZipJs\": {\n \"types\": \"./dist/archives/createArchiveFromZipJs.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromZipJs/index.js\",\n \"require\": \"./dist/archives/createArchiveFromZipJs/index.cjs\"\n }\n },\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"files\": [\n \"/dist\"\n ],\n \"scripts\": {\n \"start\": \"vite build --watch --mode development\",\n \"build\": \"tsc && vite build\",\n \"test\": \"vitest run --coverage\",\n \"tsc\": \"tsc\",\n \"test:watch\": \"vitest watch\"\n },\n \"dependencies\": {\n \"@prose-reader/archive-reader\": \"^1.319.0\",\n \"@prose-reader/shared\": \"^1.319.0\",\n \"xmldoc\": \"^2.0.0\"\n },\n \"peerDependencies\": {\n \"@zip.js/zip.js\": \"^2.8.26\",\n \"buffer\": \"^6.0.3\",\n \"jszip\": \"^3.10.0\",\n \"libarchive.js\": \"^2.0.2\",\n \"node-unrar-js\": \"^2.0.2\",\n \"rxjs\": \"*\",\n \"unzipper\": \"^0.12.3\"\n },\n \"peerDependenciesMeta\": {\n \"@zip.js/zip.js\": {\n \"optional\": true\n },\n \"jszip\": {\n \"optional\": true\n },\n \"unzipper\": {\n \"optional\": true\n },\n \"libarchive.js\": {\n \"optional\": true\n },\n \"node-unrar-js\": {\n \"optional\": true\n }\n },\n \"gitHead\": \"4601e14dcacf50b2295cb343582a7ef2c7e1eedc\",\n \"devDependencies\": {\n \"@types/unzipper\": \"^0.10.11\",\n \"@zip.js/zip.js\": \"^2.8.26\",\n \"buffer\": \"^6.0.3\",\n \"isomorphic-fetch\": \"^3.0.0\",\n \"jszip\": \"^3.10.0\",\n \"libarchive.js\": \"^2.0.2\",\n \"node-unrar-js\": \"^2.0.2\",\n \"unzipper\": \"^0.12.3\"\n }\n}\n","import { Report as SharedReport } from \"@prose-reader/shared\"\nimport { name } from \"../package.json\"\n\nexport const Report = SharedReport.namespace(name, false, {\n color: \"#ffae42\",\n})\n","interface TreeNode {\n [key: string]: TreeNode\n}\n\nexport const printTree = (paths: string[]): string => {\n // Split and collect all parts for tree reconstruction\n const tree: TreeNode = {}\n for (const path of paths) {\n const parts = path.split(\"/\")\n let node = tree\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n if (part === undefined) continue\n if (!node[part]) {\n node[part] = {}\n }\n node = node[part]\n }\n }\n\n // Recursively build the tree string\n const render = (node: TreeNode, indent = \"\"): string => {\n return Object.keys(node)\n .sort()\n .map((key, i, arr) => {\n const isLast = i === arr.length - 1\n const prefix = indent + (isLast ? \"└── \" : \"├── \")\n const nextIndent = indent + (isLast ? \" \" : \"│ \")\n const value = node[key]\n if (value && Object.keys(value).length > 0) {\n return `${prefix}${key}/\\n${render(value, nextIndent)}`\n }\n return `${prefix}${key}`\n })\n .join(\"\\n\")\n }\n\n return render(tree)\n}\n","import { Report } from \"../report\"\nimport { printTree } from \"./printTree\"\nimport type { Archive, ArchiveRecord } from \"./types\"\n\ntype ArchiveInit = Omit<Archive, \"recordsByUri\">\n\n/**\n * Builds an {@link Archive} from its records and derives the `recordsByUri`\n * lookup index once, so consumers resolve records in O(1) on the hot path\n * instead of scanning {@link Archive.records}. Duplicate URIs keep the first\n * record, matching the previous `Array.prototype.find` semantics.\n */\nexport const createArchive = ({ records, ...rest }: ArchiveInit): Archive => {\n const recordsByUri = new Map<string, ArchiveRecord>()\n\n for (const record of records) {\n if (!recordsByUri.has(record.uri)) {\n recordsByUri.set(record.uri, record)\n }\n }\n\n const archive: Archive = {\n ...rest,\n records,\n recordsByUri,\n }\n\n Report.log(\"Generated archive\", archive)\n\n if (process.env.NODE_ENV === \"development\") {\n if (Report.isEnabled()) {\n const folderStructureStr = printTree(records.map((record) => record.uri))\n Report.groupCollapsed(...Report.getGroupArgs(\"Archive folder structure\"))\n Report.log(`\\n${folderStructureStr}`)\n Report.groupEnd()\n }\n }\n\n return archive\n}\n","export const sortByTitleComparator = (a: string, b: string) => {\n const alist = a.split(/(\\d+)/)\n const blist = b.split(/(\\d+)/)\n\n for (let i = 0, len = alist.length; i < len; i++) {\n if (alist[i] !== blist[i]) {\n if (alist[i]?.match(/\\d/)) {\n return +(alist[i] || ``) - +(blist[i] || ``)\n }\n return (alist[i] || ``).localeCompare(blist[i] || ``)\n }\n }\n\n return 1\n}\n","export const removeTrailingSlash = (uri: string) =>\n uri.endsWith(\"/\") ? uri.slice(0, -1) : uri\n\nexport const getUriBasename = (uri: string) => {\n const trimmed = removeTrailingSlash(uri)\n\n return trimmed.substring(trimmed.lastIndexOf(`/`) + 1) || trimmed\n}\n\nexport const getUriBasePath = (uri: string) => {\n const lastSlashIndex = uri.lastIndexOf(\"/\")\n\n return lastSlashIndex >= 0 ? uri.substring(0, lastSlashIndex) : \"\"\n}\n","import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { createArchive } from \"./createArchive\"\nimport type { Archive, ArchiveRecord, FileRecord } from \"./types\"\n\n/**\n * Normalized view of a source entry, shared by every `createArchiveFrom*`\n * creator that enumerates a flat list of records. A source only has to provide\n * each entry's `uri`, whether it is a directory, and (for files) its `size`\n * plus content accessors; everything else (basename derivation, mime\n * detection, ordering, the `recordsByUri` index) is handled centrally here.\n */\nexport type ArchiveEntry =\n | { dir: true; uri: string }\n | ({ dir: false; uri: string; size: number } & Pick<\n FileRecord,\n \"blob\" | \"arrayBuffer\"\n >)\n\nexport type CreateArchiveFromEntriesOptions = {\n orderByAlpha?: boolean\n name?: string\n encodingFormat?: string\n close: () => Promise<void>\n}\n\n/**\n * Builds an {@link Archive} from an arbitrary source list. `toEntry` is invoked\n * once per item, and the resulting records are sorted in place when\n * `orderByAlpha` is set — there is no intermediate array, so construction stays\n * a single map plus an optional sort regardless of the source.\n */\nexport const createArchiveFromEntries = <Item>(\n items: Item[],\n toEntry: (item: Item) => ArchiveEntry,\n {\n orderByAlpha,\n name,\n encodingFormat,\n close,\n }: CreateArchiveFromEntriesOptions,\n): Archive => {\n const records = items.map((item): ArchiveRecord => {\n const entry = toEntry(item)\n const basename = getUriBasename(entry.uri)\n\n if (entry.dir) {\n return { dir: true, basename, uri: entry.uri }\n }\n\n return {\n dir: false,\n basename,\n uri: entry.uri,\n encodingFormat: detectMimeTypeFromName(entry.uri),\n size: entry.size,\n blob: entry.blob,\n arrayBuffer: entry.arrayBuffer,\n }\n })\n\n if (orderByAlpha) {\n records.sort((a, b) => sortByTitleComparator(a.uri, b.uri))\n }\n\n return createArchive({ filename: name, encodingFormat, records, close })\n}\n"],"mappings":";;;ACGA,IAAa,IAAS,EAAa,UAAU,0BAAM,IAAO,EACxD,OAAO,UACT,CAAC,GCDY,KAAa,MAA4B;CAEpD,IAAM,IAAiB,CAAC;CACxB,KAAK,IAAM,KAAQ,GAAO;EACxB,IAAM,IAAQ,EAAK,MAAM,GAAG,GACxB,IAAO;EACX,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAAK;GACrC,IAAM,IAAO,EAAM;GACf,MAAS,KAAA,MACR,EAAK,OACR,EAAK,KAAQ,CAAC,IAEhB,IAAO,EAAK;EACd;CACF;CAGA,IAAM,KAAU,GAAgB,IAAS,OAChC,OAAO,KAAK,CAAI,CAAC,CACrB,KAAK,CAAC,CACN,KAAK,GAAK,GAAG,MAAQ;EACpB,IAAM,IAAS,MAAM,EAAI,SAAS,GAC5B,IAAS,KAAU,IAAS,SAAS,SACrC,IAAa,KAAU,IAAS,SAAS,SACzC,IAAQ,EAAK;EAInB,OAHI,KAAS,OAAO,KAAK,CAAK,CAAC,CAAC,SAAS,IAChC,GAAG,IAAS,EAAI,KAAK,EAAO,GAAO,CAAU,MAE/C,GAAG,IAAS;CACrB,CAAC,CAAC,CACD,KAAK,IAAI;CAGd,OAAO,EAAO,CAAI;AACpB,GC1Ba,KAAiB,EAAE,YAAS,GAAG,QAAiC;CAC3E,IAAM,oBAAe,IAAI,IAA2B;CAEpD,KAAK,IAAM,KAAU,GACnB,AAAK,EAAa,IAAI,EAAO,GAAG,KAC9B,EAAa,IAAI,EAAO,KAAK,CAAM;CAIvC,IAAM,IAAmB;EACvB,GAAG;EACH;EACA;CACF;CAIA,IAFA,EAAO,IAAI,qBAAqB,CAAO,GAEvC,QAAA,IAAA,aAA6B,iBACvB,EAAO,UAAU,GAAG;EACtB,IAAM,IAAqB,EAAU,EAAQ,KAAK,MAAW,EAAO,GAAG,CAAC;EAGxE,AAFA,EAAO,eAAe,GAAG,EAAO,aAAa,0BAA0B,CAAC,GACxE,EAAO,IAAI,KAAK,GAAoB,GACpC,EAAO,SAAS;CAClB;CAGF,OAAO;AACT,GCvCa,KAAyB,GAAW,MAAc;CAC7D,IAAM,IAAQ,EAAE,MAAM,OAAO,GACvB,IAAQ,EAAE,MAAM,OAAO;CAE7B,KAAK,IAAI,IAAI,GAAG,IAAM,EAAM,QAAQ,IAAI,GAAK,KAC3C,IAAI,EAAM,OAAO,EAAM,IAIrB,OAHI,EAAM,EAAE,EAAE,MAAM,IAAI,KACb,EAAM,MAAM,MAAM,EAAE,EAAM,MAAM,OAEnC,EAAM,MAAM,GAAA,CAAI,cAAc,EAAM,MAAM,EAAE;CAIxD,OAAO;AACT,GCda,KAAuB,MAClC,EAAI,SAAS,GAAG,IAAI,EAAI,MAAM,GAAG,EAAE,IAAI,GAE5B,KAAkB,MAAgB;CAC7C,IAAM,IAAU,EAAoB,CAAG;CAEvC,OAAO,EAAQ,UAAU,EAAQ,YAAY,GAAG,IAAI,CAAC,KAAK;AAC5D,GAEa,KAAkB,MAAgB;CAC7C,IAAM,IAAiB,EAAI,YAAY,GAAG;CAE1C,OAAO,KAAkB,IAAI,EAAI,UAAU,GAAG,CAAc,IAAI;AAClE,GCoBa,KACX,GACA,GACA,EACE,iBACA,SACA,mBACA,eAEU;CACZ,IAAM,IAAU,EAAM,KAAK,MAAwB;EACjD,IAAM,IAAQ,EAAQ,CAAI,GACpB,IAAW,EAAe,EAAM,GAAG;EAMzC,OAJI,EAAM,MACD;GAAE,KAAK;GAAM;GAAU,KAAK,EAAM;EAAI,IAGxC;GACL,KAAK;GACL;GACA,KAAK,EAAM;GACX,gBAAgB,EAAuB,EAAM,GAAG;GAChD,MAAM,EAAM;GACZ,MAAM,EAAM;GACZ,aAAa,EAAM;EACrB;CACF,CAAC;CAMD,OAJI,KACF,EAAQ,MAAM,GAAG,MAAM,EAAsB,EAAE,KAAK,EAAE,GAAG,CAAC,GAGrD,EAAc;EAAE,UAAU;EAAM;EAAgB;EAAS;CAAM,CAAC;AACzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"createArchiveFromEntries-DL9Q2cPL.cjs","names":[],"sources":["../package.json","../src/report.ts","../src/archives/printTree.ts","../src/archives/createArchive.ts","../src/utils/sortByTitleComparator.ts","../src/utils/uri.ts","../src/archives/createArchiveFromEntries.ts"],"sourcesContent":["{\n \"name\": \"@prose-reader/streamer\",\n \"version\": \"1.318.0\",\n \"type\": \"module\",\n \"main\": \"./dist/index/index.cjs\",\n \"module\": \"./dist/index/index.js\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index/index.js\",\n \"require\": \"./dist/index/index.cjs\"\n },\n \"./archives/createArchiveFromJszip\": {\n \"types\": \"./dist/archives/createArchiveFromJszip.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromJszip/index.js\",\n \"require\": \"./dist/archives/createArchiveFromJszip/index.cjs\"\n },\n \"./archives/createArchiveFromLibArchive\": {\n \"types\": \"./dist/archives/createArchiveFromLibArchive.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromLibArchive/index.js\",\n \"require\": \"./dist/archives/createArchiveFromLibArchive/index.cjs\"\n },\n \"./archives/createArchiveFromUnzipper\": {\n \"types\": \"./dist/archives/createArchiveFromUnzipper.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromUnzipper/index.js\",\n \"require\": \"./dist/archives/createArchiveFromUnzipper/index.cjs\"\n },\n \"./archives/createArchiveFromNodeUnrarJs\": {\n \"types\": \"./dist/archives/createArchiveFromNodeUnrarJs.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromNodeUnrarJs/index.js\",\n \"require\": \"./dist/archives/createArchiveFromNodeUnrarJs/index.cjs\"\n },\n \"./archives/createArchiveFromZipJs\": {\n \"types\": \"./dist/archives/createArchiveFromZipJs.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromZipJs/index.js\",\n \"require\": \"./dist/archives/createArchiveFromZipJs/index.cjs\"\n }\n },\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"files\": [\n \"/dist\"\n ],\n \"scripts\": {\n \"start\": \"vite build --watch --mode development\",\n \"build\": \"tsc && vite build\",\n \"test\": \"vitest run --coverage\",\n \"tsc\": \"tsc\",\n \"test:watch\": \"vitest watch\"\n },\n \"dependencies\": {\n \"@prose-reader/archive-parser\": \"^1.318.0\",\n \"@prose-reader/shared\": \"^1.318.0\",\n \"xmldoc\": \"^2.0.0\"\n },\n \"peerDependencies\": {\n \"@zip.js/zip.js\": \"^2.8.26\",\n \"buffer\": \"^6.0.3\",\n \"jszip\": \"^3.10.0\",\n \"libarchive.js\": \"^2.0.2\",\n \"node-unrar-js\": \"^2.0.2\",\n \"rxjs\": \"*\",\n \"unzipper\": \"^0.12.3\"\n },\n \"peerDependenciesMeta\": {\n \"@zip.js/zip.js\": {\n \"optional\": true\n },\n \"jszip\": {\n \"optional\": true\n },\n \"unzipper\": {\n \"optional\": true\n },\n \"libarchive.js\": {\n \"optional\": true\n },\n \"node-unrar-js\": {\n \"optional\": true\n }\n },\n \"gitHead\": \"4601e14dcacf50b2295cb343582a7ef2c7e1eedc\",\n \"devDependencies\": {\n \"@types/unzipper\": \"^0.10.11\",\n \"@zip.js/zip.js\": \"^2.8.26\",\n \"buffer\": \"^6.0.3\",\n \"isomorphic-fetch\": \"^3.0.0\",\n \"jszip\": \"^3.10.0\",\n \"libarchive.js\": \"^2.0.2\",\n \"node-unrar-js\": \"^2.0.2\",\n \"unzipper\": \"^0.12.3\"\n }\n}\n","import { Report as SharedReport } from \"@prose-reader/shared\"\nimport { name } from \"../package.json\"\n\nexport const Report = SharedReport.namespace(name, false, {\n color: \"#ffae42\",\n})\n","interface TreeNode {\n [key: string]: TreeNode\n}\n\nexport const printTree = (paths: string[]): string => {\n // Split and collect all parts for tree reconstruction\n const tree: TreeNode = {}\n for (const path of paths) {\n const parts = path.split(\"/\")\n let node = tree\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n if (part === undefined) continue\n if (!node[part]) {\n node[part] = {}\n }\n node = node[part]\n }\n }\n\n // Recursively build the tree string\n const render = (node: TreeNode, indent = \"\"): string => {\n return Object.keys(node)\n .sort()\n .map((key, i, arr) => {\n const isLast = i === arr.length - 1\n const prefix = indent + (isLast ? \"└── \" : \"├── \")\n const nextIndent = indent + (isLast ? \" \" : \"│ \")\n const value = node[key]\n if (value && Object.keys(value).length > 0) {\n return `${prefix}${key}/\\n${render(value, nextIndent)}`\n }\n return `${prefix}${key}`\n })\n .join(\"\\n\")\n }\n\n return render(tree)\n}\n","import { Report } from \"../report\"\nimport { printTree } from \"./printTree\"\nimport type { Archive, ArchiveRecord } from \"./types\"\n\ntype ArchiveInit = Omit<Archive, \"recordsByUri\">\n\n/**\n * Builds an {@link Archive} from its records and derives the `recordsByUri`\n * lookup index once, so consumers resolve records in O(1) on the hot path\n * instead of scanning {@link Archive.records}. Duplicate URIs keep the first\n * record, matching the previous `Array.prototype.find` semantics.\n */\nexport const createArchive = ({ records, ...rest }: ArchiveInit): Archive => {\n const recordsByUri = new Map<string, ArchiveRecord>()\n\n for (const record of records) {\n if (!recordsByUri.has(record.uri)) {\n recordsByUri.set(record.uri, record)\n }\n }\n\n const archive: Archive = {\n ...rest,\n records,\n recordsByUri,\n }\n\n Report.log(\"Generated archive\", archive)\n\n if (process.env.NODE_ENV === \"development\") {\n if (Report.isEnabled()) {\n const folderStructureStr = printTree(records.map((record) => record.uri))\n Report.groupCollapsed(...Report.getGroupArgs(\"Archive folder structure\"))\n Report.log(`\\n${folderStructureStr}`)\n Report.groupEnd()\n }\n }\n\n return archive\n}\n","export const sortByTitleComparator = (a: string, b: string) => {\n const alist = a.split(/(\\d+)/)\n const blist = b.split(/(\\d+)/)\n\n for (let i = 0, len = alist.length; i < len; i++) {\n if (alist[i] !== blist[i]) {\n if (alist[i]?.match(/\\d/)) {\n return +(alist[i] || ``) - +(blist[i] || ``)\n }\n return (alist[i] || ``).localeCompare(blist[i] || ``)\n }\n }\n\n return 1\n}\n","export const removeTrailingSlash = (uri: string) =>\n uri.endsWith(\"/\") ? uri.slice(0, -1) : uri\n\nexport const getUriBasename = (uri: string) => {\n const trimmed = removeTrailingSlash(uri)\n\n return trimmed.substring(trimmed.lastIndexOf(`/`) + 1) || trimmed\n}\n\nexport const getUriBasePath = (uri: string) => {\n const lastSlashIndex = uri.lastIndexOf(\"/\")\n\n return lastSlashIndex >= 0 ? uri.substring(0, lastSlashIndex) : \"\"\n}\n","import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { createArchive } from \"./createArchive\"\nimport type { Archive, ArchiveRecord, FileRecord } from \"./types\"\n\n/**\n * Normalized view of a source entry, shared by every `createArchiveFrom*`\n * creator that enumerates a flat list of records. A source only has to provide\n * each entry's `uri`, whether it is a directory, and (for files) its `size`\n * plus content accessors; everything else (basename derivation, mime\n * detection, ordering, the `recordsByUri` index) is handled centrally here.\n */\nexport type ArchiveEntry =\n | { dir: true; uri: string }\n | ({ dir: false; uri: string; size: number } & Pick<\n FileRecord,\n \"blob\" | \"arrayBuffer\"\n >)\n\nexport type CreateArchiveFromEntriesOptions = {\n orderByAlpha?: boolean\n name?: string\n encodingFormat?: string\n close: () => Promise<void>\n}\n\n/**\n * Builds an {@link Archive} from an arbitrary source list. `toEntry` is invoked\n * once per item, and the resulting records are sorted in place when\n * `orderByAlpha` is set — there is no intermediate array, so construction stays\n * a single map plus an optional sort regardless of the source.\n */\nexport const createArchiveFromEntries = <Item>(\n items: Item[],\n toEntry: (item: Item) => ArchiveEntry,\n {\n orderByAlpha,\n name,\n encodingFormat,\n close,\n }: CreateArchiveFromEntriesOptions,\n): Archive => {\n const records = items.map((item): ArchiveRecord => {\n const entry = toEntry(item)\n const basename = getUriBasename(entry.uri)\n\n if (entry.dir) {\n return { dir: true, basename, uri: entry.uri }\n }\n\n return {\n dir: false,\n basename,\n uri: entry.uri,\n encodingFormat: detectMimeTypeFromName(entry.uri),\n size: entry.size,\n blob: entry.blob,\n arrayBuffer: entry.arrayBuffer,\n }\n })\n\n if (orderByAlpha) {\n records.sort((a, b) => sortByTitleComparator(a.uri, b.uri))\n }\n\n return createArchive({ filename: name, encodingFormat, records, close })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createArchiveFromEntries-DL9Q2cPL.cjs","names":[],"sources":["../package.json","../src/report.ts","../src/archives/printTree.ts","../src/archives/createArchive.ts","../src/utils/sortByTitleComparator.ts","../src/utils/uri.ts","../src/archives/createArchiveFromEntries.ts"],"sourcesContent":["{\n \"name\": \"@prose-reader/streamer\",\n \"version\": \"1.319.0\",\n \"type\": \"module\",\n \"main\": \"./dist/index/index.cjs\",\n \"module\": \"./dist/index/index.js\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index/index.js\",\n \"require\": \"./dist/index/index.cjs\"\n },\n \"./archives/createArchiveFromJszip\": {\n \"types\": \"./dist/archives/createArchiveFromJszip.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromJszip/index.js\",\n \"require\": \"./dist/archives/createArchiveFromJszip/index.cjs\"\n },\n \"./archives/createArchiveFromLibArchive\": {\n \"types\": \"./dist/archives/createArchiveFromLibArchive.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromLibArchive/index.js\",\n \"require\": \"./dist/archives/createArchiveFromLibArchive/index.cjs\"\n },\n \"./archives/createArchiveFromUnzipper\": {\n \"types\": \"./dist/archives/createArchiveFromUnzipper.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromUnzipper/index.js\",\n \"require\": \"./dist/archives/createArchiveFromUnzipper/index.cjs\"\n },\n \"./archives/createArchiveFromNodeUnrarJs\": {\n \"types\": \"./dist/archives/createArchiveFromNodeUnrarJs.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromNodeUnrarJs/index.js\",\n \"require\": \"./dist/archives/createArchiveFromNodeUnrarJs/index.cjs\"\n },\n \"./archives/createArchiveFromZipJs\": {\n \"types\": \"./dist/archives/createArchiveFromZipJs.d.ts\",\n \"import\": \"./dist/archives/createArchiveFromZipJs/index.js\",\n \"require\": \"./dist/archives/createArchiveFromZipJs/index.cjs\"\n }\n },\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"files\": [\n \"/dist\"\n ],\n \"scripts\": {\n \"start\": \"vite build --watch --mode development\",\n \"build\": \"tsc && vite build\",\n \"test\": \"vitest run --coverage\",\n \"tsc\": \"tsc\",\n \"test:watch\": \"vitest watch\"\n },\n \"dependencies\": {\n \"@prose-reader/archive-reader\": \"^1.319.0\",\n \"@prose-reader/shared\": \"^1.319.0\",\n \"xmldoc\": \"^2.0.0\"\n },\n \"peerDependencies\": {\n \"@zip.js/zip.js\": \"^2.8.26\",\n \"buffer\": \"^6.0.3\",\n \"jszip\": \"^3.10.0\",\n \"libarchive.js\": \"^2.0.2\",\n \"node-unrar-js\": \"^2.0.2\",\n \"rxjs\": \"*\",\n \"unzipper\": \"^0.12.3\"\n },\n \"peerDependenciesMeta\": {\n \"@zip.js/zip.js\": {\n \"optional\": true\n },\n \"jszip\": {\n \"optional\": true\n },\n \"unzipper\": {\n \"optional\": true\n },\n \"libarchive.js\": {\n \"optional\": true\n },\n \"node-unrar-js\": {\n \"optional\": true\n }\n },\n \"gitHead\": \"4601e14dcacf50b2295cb343582a7ef2c7e1eedc\",\n \"devDependencies\": {\n \"@types/unzipper\": \"^0.10.11\",\n \"@zip.js/zip.js\": \"^2.8.26\",\n \"buffer\": \"^6.0.3\",\n \"isomorphic-fetch\": \"^3.0.0\",\n \"jszip\": \"^3.10.0\",\n \"libarchive.js\": \"^2.0.2\",\n \"node-unrar-js\": \"^2.0.2\",\n \"unzipper\": \"^0.12.3\"\n }\n}\n","import { Report as SharedReport } from \"@prose-reader/shared\"\nimport { name } from \"../package.json\"\n\nexport const Report = SharedReport.namespace(name, false, {\n color: \"#ffae42\",\n})\n","interface TreeNode {\n [key: string]: TreeNode\n}\n\nexport const printTree = (paths: string[]): string => {\n // Split and collect all parts for tree reconstruction\n const tree: TreeNode = {}\n for (const path of paths) {\n const parts = path.split(\"/\")\n let node = tree\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n if (part === undefined) continue\n if (!node[part]) {\n node[part] = {}\n }\n node = node[part]\n }\n }\n\n // Recursively build the tree string\n const render = (node: TreeNode, indent = \"\"): string => {\n return Object.keys(node)\n .sort()\n .map((key, i, arr) => {\n const isLast = i === arr.length - 1\n const prefix = indent + (isLast ? \"└── \" : \"├── \")\n const nextIndent = indent + (isLast ? \" \" : \"│ \")\n const value = node[key]\n if (value && Object.keys(value).length > 0) {\n return `${prefix}${key}/\\n${render(value, nextIndent)}`\n }\n return `${prefix}${key}`\n })\n .join(\"\\n\")\n }\n\n return render(tree)\n}\n","import { Report } from \"../report\"\nimport { printTree } from \"./printTree\"\nimport type { Archive, ArchiveRecord } from \"./types\"\n\ntype ArchiveInit = Omit<Archive, \"recordsByUri\">\n\n/**\n * Builds an {@link Archive} from its records and derives the `recordsByUri`\n * lookup index once, so consumers resolve records in O(1) on the hot path\n * instead of scanning {@link Archive.records}. Duplicate URIs keep the first\n * record, matching the previous `Array.prototype.find` semantics.\n */\nexport const createArchive = ({ records, ...rest }: ArchiveInit): Archive => {\n const recordsByUri = new Map<string, ArchiveRecord>()\n\n for (const record of records) {\n if (!recordsByUri.has(record.uri)) {\n recordsByUri.set(record.uri, record)\n }\n }\n\n const archive: Archive = {\n ...rest,\n records,\n recordsByUri,\n }\n\n Report.log(\"Generated archive\", archive)\n\n if (process.env.NODE_ENV === \"development\") {\n if (Report.isEnabled()) {\n const folderStructureStr = printTree(records.map((record) => record.uri))\n Report.groupCollapsed(...Report.getGroupArgs(\"Archive folder structure\"))\n Report.log(`\\n${folderStructureStr}`)\n Report.groupEnd()\n }\n }\n\n return archive\n}\n","export const sortByTitleComparator = (a: string, b: string) => {\n const alist = a.split(/(\\d+)/)\n const blist = b.split(/(\\d+)/)\n\n for (let i = 0, len = alist.length; i < len; i++) {\n if (alist[i] !== blist[i]) {\n if (alist[i]?.match(/\\d/)) {\n return +(alist[i] || ``) - +(blist[i] || ``)\n }\n return (alist[i] || ``).localeCompare(blist[i] || ``)\n }\n }\n\n return 1\n}\n","export const removeTrailingSlash = (uri: string) =>\n uri.endsWith(\"/\") ? uri.slice(0, -1) : uri\n\nexport const getUriBasename = (uri: string) => {\n const trimmed = removeTrailingSlash(uri)\n\n return trimmed.substring(trimmed.lastIndexOf(`/`) + 1) || trimmed\n}\n\nexport const getUriBasePath = (uri: string) => {\n const lastSlashIndex = uri.lastIndexOf(\"/\")\n\n return lastSlashIndex >= 0 ? uri.substring(0, lastSlashIndex) : \"\"\n}\n","import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { createArchive } from \"./createArchive\"\nimport type { Archive, ArchiveRecord, FileRecord } from \"./types\"\n\n/**\n * Normalized view of a source entry, shared by every `createArchiveFrom*`\n * creator that enumerates a flat list of records. A source only has to provide\n * each entry's `uri`, whether it is a directory, and (for files) its `size`\n * plus content accessors; everything else (basename derivation, mime\n * detection, ordering, the `recordsByUri` index) is handled centrally here.\n */\nexport type ArchiveEntry =\n | { dir: true; uri: string }\n | ({ dir: false; uri: string; size: number } & Pick<\n FileRecord,\n \"blob\" | \"arrayBuffer\"\n >)\n\nexport type CreateArchiveFromEntriesOptions = {\n orderByAlpha?: boolean\n name?: string\n encodingFormat?: string\n close: () => Promise<void>\n}\n\n/**\n * Builds an {@link Archive} from an arbitrary source list. `toEntry` is invoked\n * once per item, and the resulting records are sorted in place when\n * `orderByAlpha` is set — there is no intermediate array, so construction stays\n * a single map plus an optional sort regardless of the source.\n */\nexport const createArchiveFromEntries = <Item>(\n items: Item[],\n toEntry: (item: Item) => ArchiveEntry,\n {\n orderByAlpha,\n name,\n encodingFormat,\n close,\n }: CreateArchiveFromEntriesOptions,\n): Archive => {\n const records = items.map((item): ArchiveRecord => {\n const entry = toEntry(item)\n const basename = getUriBasename(entry.uri)\n\n if (entry.dir) {\n return { dir: true, basename, uri: entry.uri }\n }\n\n return {\n dir: false,\n basename,\n uri: entry.uri,\n encodingFormat: detectMimeTypeFromName(entry.uri),\n size: entry.size,\n blob: entry.blob,\n arrayBuffer: entry.arrayBuffer,\n }\n })\n\n if (orderByAlpha) {\n records.sort((a, b) => sortByTitleComparator(a.uri, b.uri))\n }\n\n return createArchive({ filename: name, encodingFormat, records, close })\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { OpfMetadata } from '@prose-reader/archive-parser';
1
+ import { OpfMetadata } from '@prose-reader/archive-reader';
2
2
  import { Archive } from '../archives/types';
3
3
  export type ArchiveOpfParsed = {
4
4
  opf: OpfMetadata;
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../createArchiveFromEntries-DL9Q2cPL.cjs"),t=require("../fileAccessors-DWVChFUB.cjs");let n=require("@prose-reader/shared"),r=require("@prose-reader/archive-parser"),i=require("xmldoc"),a=require("rxjs");var o=async(r,i={})=>e.t(r,e=>e.isDir?{dir:!0,uri:e.name}:{dir:!1,uri:e.name,size:e.size,...t.t(e.data,(0,n.detectMimeTypeFromName)(e.name)??``)},{...i,close:()=>Promise.resolve()}),s=async(n,{mimeType:r,direction:i}={mimeType:`text/plain`})=>{let a=`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../createArchiveFromEntries-DL9Q2cPL.cjs"),t=require("../fileAccessors-DWVChFUB.cjs");let n=require("@prose-reader/shared"),r=require("@prose-reader/archive-reader"),i=require("xmldoc"),a=require("rxjs");var o=async(r,i={})=>e.t(r,e=>e.isDir?{dir:!0,uri:e.name}:{dir:!1,uri:e.name,size:e.size,...t.t(e.data,(0,n.detectMimeTypeFromName)(e.name)??``)},{...i,close:()=>Promise.resolve()}),s=async(n,{mimeType:r,direction:i}={mimeType:`text/plain`})=>{let a=`
2
2
  <?xml version="1.0" encoding="UTF-8"?>
3
3
  <package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="ja" prefix="rendition: http://www.idpf.org/vocab/rendition/#"
4
4
  unique-identifier="ootuya-id">
@@ -28,5 +28,5 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
28
28
  `)}
29
29
  </spine>
30
30
  </package>
31
- `,c=r.map(r=>({dir:!1,basename:e.r(r),encodingFormat:(0,n.detectMimeTypeFromName)(r),uri:r,size:0,...t.n(async()=>(await fetch(r)).blob())}));return e.o({records:[{dir:!1,basename:`content.opf`,uri:`content.opf`,size:0,...t.n(async()=>new Blob([s]))},...c],close:()=>Promise.resolve()})},v=e=>!e.dir,y=e=>e.dir,b=(e,t)=>{let n=e.recordsByUri.get(t);return n&&v(n)?n:void 0},x=r.COMIC_INFO_FILENAME.toLowerCase(),S=e=>e.records.find(e=>v(e)&&e.basename.toLowerCase()===x),C=async e=>new TextDecoder().decode(await e.arrayBuffer()),te=({enableReport:t}={})=>{e.s.enable(!!t)},w=e=>{let t=e.records.filter(e=>!e.dir).find(e=>e.uri.endsWith(`.opf`));return{data:t,basePath:t?.uri.substring(0,t.uri.lastIndexOf(`/`))||``}};async function T(e){let{data:t,basePath:n}=w(e)||{};if(!(!t||t.dir))return{opf:(0,r.parseOpf)(await C(t)),basePath:n}}var E=r.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME.toLowerCase(),D=({archive:e})=>async t=>{let n=e.records.find(e=>!e.dir&&e.basename.toLowerCase()===E);if(!n||n.dir)return t;let i=await C(n);try{let{renditionLayout:e}=(0,r.resolveArchiveMetadata)((0,r.parseAppleDisplayOptionsXml)(i));return{...t,renditionLayout:t.renditionLayout??e}}catch(e){return console.error(`Unable to parse ${r.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME} for content\n`,i),console.error(e),t}},ne=r.COMIC_INFO_FILENAME.toLowerCase(),re=({archive:e})=>async t=>{let n=S(e);if(!n)return t;let i={...t,spineItems:t.spineItems.filter(e=>!e.id.toLowerCase().endsWith(ne)).map((e,t,n)=>({...e,progressionWeight:1/n.length}))},a=await C(n);try{let e=(0,r.resolveArchiveMetadata)((0,r.parseComicInfo)(a));return{...i,readingDirection:e.readingDirection??i.readingDirection}}catch(e){return console.error(`Unable to parse ${r.COMIC_INFO_FILENAME} for content\n`,a),console.error(e),i}},ie=({baseUrl:e=``,resourcePath:t})=>{if(!e&&/^https?:\/\//.test(t))return encodeURI(t);let n=e?`${e}${e.endsWith(`/`)?``:`/`}`:`file://`;return encodeURI(`${n}${t}`)},ae=({archive:e,baseUrl:t})=>async()=>{let n=e.records.filter(e=>!e.dir),r=_(),i=n.map(e=>({file:e,id:r(e.uri)}));return{filename:e.filename??``,title:e.records.find(({dir:e})=>e)?.basename.replace(/\/$/,``)||e.filename||``,renditionLayout:void 0,renditionSpread:`auto`,readingDirection:void 0,spineItems:i.filter(({file:e})=>!e.basename.endsWith(`.db`)).map(({file:e,id:r},i)=>({id:r,index:i,href:ie({baseUrl:t,resourcePath:e.uri}),renditionLayout:void 0,progressionWeight:1/n.length,pageSpreadLeft:void 0,pageSpreadRight:void 0,mediaType:e.encodingFormat})),items:i.map(({file:e,id:n})=>({id:n,href:encodeURI(`${t}${e.uri}`)}))}},O=async({archive:e,archiveOpf:t})=>{if(!t)return[];let{opf:n,basePath:r}=t,{spineRows:i}=n;return e.records.filter(e=>i.find(t=>r?`${r}/${t.href}`===e.uri:`${t.href}`===e.uri))},k=(e,t,n)=>{let{basePath:r}=w(t)||{};return e.map(e=>{let t=e.href,i=n?.(t)??``;return{href:r?`${i}${r}/${t}`:`${i}${t}`,id:e.id,mediaType:e.mediaType}})},oe=e=>{let t=e?.trim();return t===`scrolled-continuous`||t===`scrolled-doc`||t===`paginated`||t===`auto`?t:`auto`},se=e=>{let t=e?.trim();if(t===`none`||t===`landscape`||t===`portrait`||t===`both`||t===`auto`)return t},ce=e=>{let t=e?.trim();if(t===`cover`||t===`title-page`||t===`copyright-page`||t===`text`)return t},A=({archive:t,baseUrl:n,archiveOpf:i})=>async a=>{if(!i)return a;let{opf:o,basePath:s}=i,c=(0,r.resolveArchiveMetadata)(o);e.s.groupCollapsed(...e.s.getGroupArgs(`OPF parsed`)),e.s.log(`opf`,o),e.s.groupEnd();let l=o.renditionLayoutMeta?.trim(),u=l===`reflowable`||l===`pre-paginated`?l:c.renditionLayout,d=o.title?.trim()||t.records.find(({dir:e})=>e)?.basename||``,f=c.readingDirection??a.readingDirection,p=(await O({archive:t,archiveOpf:i})).filter(v).reduce((e,t)=>t.size+e,0),m=o.guide,h=[];for(let e of m){let t=ce(e.type);t!==void 0&&h.push({href:e.href,title:e.title,type:t})}return{filename:t.filename??``,renditionLayout:u,renditionFlow:oe(o.renditionFlowMeta),renditionSpread:se(o.renditionSpreadMeta),title:d,readingDirection:f,spineItems:o.spineRows.map((e,r)=>{let i=b(t,s?`${s}/${e.href}`:e.href),a=i?i.size:0,c=n||(/^https?:\/\//.test(e.href)?``:`file://`);return{id:e.id,index:r,href:e.href.startsWith(`https://`)?e.href:s?`${c}${s}/${e.href}`:`${c}${e.href}`,renditionLayout:e.renditionLayout??u,...e.renditionFlow===void 0?{}:{renditionFlow:e.renditionFlow},progressionWeight:p>0?a/p:1/o.spineRows.length,pageSpreadLeft:e.pageSpreadLeft,pageSpreadRight:e.pageSpreadRight,mediaType:e.mediaType}}),items:k(o.manifestItems,t,e=>/^https?:\/\//.test(e)?``:n||`file://`),guide:h.length>0?h:void 0}},j=e=>{let t=e.descendantWithPath(`head`)?.childrenNamed(`meta`).find(e=>e.attr.name===`viewport`);return!!(t&&t.attr.name===`viewport`)},M=e=>e.reduce(async(e,t)=>{if(!await e||!(0,n.isXmlBasedMimeType)({mimeType:v(t)?t.encodingFormat:void 0,uri:t.uri}))return!1;let r=t.dir?null:await C(t);return r?j(new i.XmlDocument(r)):!1},Promise.resolve(!0)),N=({archive:e,archiveOpf:t})=>async n=>n.renditionLayout===`reflowable`&&n.spineItems.every(e=>e.renditionLayout===`reflowable`)&&await M(await O({archive:e,archiveOpf:t}))?{...n,spineItems:n.spineItems.map(e=>({...e,renditionLayout:`pre-paginated`})),renditionLayout:`pre-paginated`}:n,P=()=>e=>({...e,readingDirection:e.readingDirection??`ltr`}),F=async e=>{let t;return await Promise.all(e.records.map(async e=>{if(e.dir||!e.uri.endsWith(r.KOBO_DISPLAY_OPTIONS_FILENAME))return;let n=await C(e);try{let{renditionLayout:e}=(0,r.parseKoboXml)(n);e&&(t=e)}catch(e){console.error(`Unable to parse ${r.KOBO_DISPLAY_OPTIONS_FILENAME} for content\n`,n),console.error(e)}})),{kind:`kobo`,...t===void 0?{}:{renditionLayout:t}}},I=({archive:e})=>async t=>{let{renditionLayout:n}=(0,r.resolveArchiveMetadata)(await F(e));return{...t,renditionLayout:t.renditionLayout??n}},L=e=>e.toLowerCase().endsWith(`.opf`),R=e=>e.records.some(e=>!e.dir&&(L(e.basename)||L(e.uri))),z=({archive:e})=>async t=>R(e)?t:{...t,spineItems:t.spineItems.map(t=>{let r=e.records.find(e=>decodeURI(t.href).endsWith(e.uri)),i=(0,n.parseContentType)((r&&v(r)?r.encodingFormat:void 0)??``)||(0,n.detectMimeTypeFromName)(r?.basename??``);return{...t,renditionLayout:i&&(0,n.isMediaContentMimeType)(i)?`pre-paginated`:t.renditionLayout}})},B=e=>e?e.children.map(e=>e instanceof i.XmlTextNode?e.text:e instanceof i.XmlElement?B(e):``).join(``).trim():``,V=e=>(0,r.tokenizeXmlSpaceSeparatedList)(e.properties).includes(`nav`),H=(e,{basePath:t,baseUrl:r})=>{let i={contents:[],path:``,href:``,title:``},a=e.childNamed(`span`)||e.childNamed(`a`);i.title=(a?.attr.title||a?.val.trim()||B(a))??``;let o=a?.name;o!==`a`&&(a=e.descendantWithPath(`${o}.a`),a&&(o=a.name.toLowerCase())),o===`a`&&a?.attr.href&&(i.path=(0,n.urlJoin)(t,a.attr.href),i.href=(0,n.urlJoin)(r,t,a.attr.href));let s=e.childNamed(`ol`);if(s){let e=s.childrenNamed(`li`);e&&e.length>0&&(i.contents=e.map(e=>H(e,{basePath:t,baseUrl:r})))}return i},U=(e,{basePath:t,baseUrl:n})=>{let r=[],i;return e.descendantWithPath(`body.nav.ol`)?i=e.descendantWithPath(`body.nav.ol`)?.children:e.descendantWithPath(`body.section.nav.ol`)&&(i=e.descendantWithPath(`body.section.nav.ol`)?.children),i&&i.length>0&&i.filter(e=>e.name===`li`).forEach(e=>{r.push(H(e,{basePath:t,baseUrl:n}))}),r},W=async(t,n,{baseUrl:r})=>{let a=t.manifestItems.find(V);if(a?.href){let t=n.records.find(e=>e.uri.endsWith(a.href));if(t&&!t.dir)return U(new i.XmlDocument(await C(t)),{basePath:e.n(t.uri),baseUrl:r})}},G=(e,{opfBasePath:t,baseUrl:r,prefix:i})=>{let a=e?.childNamed(`${i}content`)?.attr.src||``,o={title:e?.descendantWithPath(`${i}navLabel.${i}text`)?.val||``,path:(0,n.urlJoin)(t,a),href:(0,n.urlJoin)(r,t,a),contents:[]},s=e.childrenNamed(`${i}navPoint`);return s&&s.length>0&&(o.contents=s.map(e=>G(e,{opfBasePath:t,baseUrl:r,prefix:i}))),o},le=(e,{opfBasePath:t,baseUrl:n})=>{let r=[],i=e.name,a=``;return i.indexOf(`:`)!==-1&&(a=`${i.split(`:`)[0]}:`),e.childNamed(`${a}navMap`)?.childrenNamed(`${a}navPoint`).forEach(e=>{r.push(G(e,{opfBasePath:t,baseUrl:n,prefix:a}))}),r},ue=async({opf:e,opfBasePath:t,baseUrl:n,archive:r})=>{let a=e.spineTocIdref;if(a){let o=e.manifestItems.find(e=>e.id===a);if(o){let e=`${t}${t===``?``:`/`}${o.href}`,a=r.records.find(t=>t.uri.endsWith(e));if(a&&!a.dir)return le(new i.XmlDocument(await C(a)),{opfBasePath:t,baseUrl:n})}}},de=async(e,t,{baseUrl:n})=>{let{basePath:r}=w(t)||{},i=await W(e,t,{baseUrl:n});if(i)return i;let a=await ue({opf:e,opfBasePath:r??``,archive:t,baseUrl:n});if(a)return a},fe=e=>e.replace(/\.[^.]+$/,``).replace(/[_-]/g,` `).replace(/\s+/g,` `).trim(),pe=(e,t)=>{if(e.spineItems.length!==0&&e.spineItems.every(e=>((0,n.parseContentType)(e.mediaType??``)||(0,n.detectMimeTypeFromName)(e.href))?.startsWith(`audio/`)))return e.spineItems.map(e=>{let n=t.records.find(t=>!t.dir&&decodeURI(e.href).endsWith(t.uri));return{title:fe(n?.basename??e.href),href:e.href,path:n?.uri??e.href,contents:[]}})},me=(t,{baseUrl:r})=>{let i=[...t.records].sort((t,n)=>e.a(t.uri,n.uri)),a=(e,t,n,r,i)=>{let o=e.find(e=>e.title===t),[s,...c]=n;return o?s?[...e.filter(e=>e!==o),{...o,contents:[...o.contents,...a(o.contents,s,c,r,i)]}]:o.path.split(`/`).length>i.split(`/`).length?[...e.filter(e=>e!==o),{...o,path:i,href:r}]:e:s?[...e,{contents:a([],s,c,r,i),href:r,path:i,title:t}]:[...e,{contents:[],href:r,path:i,title:t}]};return i.reduce((e,t)=>{if(t.dir)return e;let[i,...o]=t.uri.split(`/`).slice(0,-1);if(!i)return e;let s=(0,n.urlJoin)(r,encodeURI(t.uri)).replace(/\/$/,``),c=t.uri.replace(/\/$/,``);return a(e,i,o,s,c)},[])},he=async(e,t,{baseUrl:n,archiveOpf:r})=>{if(r)return await de(r.opf,e,{baseUrl:n})||[];let i=pe(t,e);if(i)return i;let a=me(e,{baseUrl:n});if(a.length!==0)return a},ge=({archive:e,baseUrl:t,archiveOpf:n})=>async r=>{if(r.nav)return r;let i=await he(e,r,{baseUrl:t,archiveOpf:n});return i?{...r,nav:{toc:i}}:r},_e=e=>e?e.endsWith(`/`)?e:`${e}/`:``,K=async(t,{baseUrl:n=``,hooks:r={}}={})=>{e.s.log(`Generating manifest from archive`,t);let i=await T(t),a=_e(n),o=e=>(e??[]).map(e=>e({archive:t,baseUrl:a})),s=[A({archive:t,baseUrl:a,archiveOpf:i}),re({archive:t,baseUrl:a}),D({archive:t,baseUrl:a}),z({archive:t,baseUrl:a}),...o(r.content)],c=o(r.spine),l=[N({archive:t,baseUrl:a,archiveOpf:i}),I({archive:t,baseUrl:a}),...o(r.presentation)],u=[ge({archive:t,baseUrl:a,archiveOpf:i}),...o(r.navigation)],d=[...s,...c,...l,...u,P()];try{let n=ae({archive:t,baseUrl:a})(),r=await d.reduce(async(e,t)=>await t(await e),n);if(e.s.log(`Generated manifest`,r),process.env.NODE_ENV===`development`&&e.s.isEnabled()){let t=JSON.stringify(r,null,2);e.s.groupCollapsed(...e.s.getGroupArgs(`Generated manifest`)),e.s.log(`\n${t}`),e.s.groupEnd()}return r}catch(t){throw e.s.error(t),t}},ve=e=>{let t=e.descendantWithPath(`head`)?.childrenNamed(`meta`).find(e=>e.attr.name===`calibre:cover`);return!!(t&&t.attr.name===`calibre:cover`)},ye=e=>e.descendantWithPath(`body`)?.descendantWithPath(`div`)?.childrenNamed(`svg`)?.find(e=>e.attr.width===`100%`&&e.attr.preserveAspectRatio===`none`),be=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(r?.basename.endsWith(`.xhtml`)){let e=new i.XmlDocument(typeof n.body==`string`?n.body:await C(r));if(ve(e)){let t=ye(e);return t&&delete t.attr.preserveAspectRatio,{...n,body:e?.toString()}}}return n},xe=({archive:e,resourcePath:t})=>async n=>be({archive:e,resourcePath:t})(n),Se=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(r?.basename.endsWith(`.css`)){let e=(typeof n.body==`string`?n.body:await C(r)).replaceAll(`-webkit-writing-mode`,`writing-mode`);return{...n,body:e}}return n},Ce=async(e,t)=>{let n=await T(e);if(n){let{opf:r}=n,i=k(r.manifestItems,e,()=>``).find(e=>t.endsWith(e.href))?.mediaType;if(i)return{mediaType:i}}return{mediaType:we(t)}},we=e=>{if(e.endsWith(`.css`))return`text/css; charset=UTF-8`;if(e.endsWith(`.jpg`))return`image/jpg`;if(e.endsWith(`.xhtml`))return`application/xhtml+xml`;if(e.endsWith(`.mp4`))return`video/mp4`;if(e.endsWith(`.svg`))return`image/svg+xml`},Te=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(!r)return n;let i=await Ce(e,t);return{...n,params:{...n.params,...r?.encodingFormat&&{contentType:r.encodingFormat},...i.mediaType&&{contentType:i.mediaType}}}},q=`div.span.p.a.li.ul.ol.h1.h2.h3.h4.h5.h6.table.tr.td.th.thead.tbody.tfoot.section.article.header.footer.nav.aside.main.figure.figcaption.blockquote.pre.code.form.textarea.select.option.button.label.fieldset.legend.caption.dl.dt.dd.iframe.video.audio.canvas.script.style`.split(`.`),Ee=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(r?.basename.endsWith(`.xhtml`)){let e=typeof n.body==`string`?n.body:await C(r);if(!RegExp(`<(${q.join(`|`)})[\\s/>]`,`i`).test(e))return n;let t=RegExp(`<(${q.join(`|`)})(\\s[^>]*)?\\s*/>`,`gi`),i=e.replace(t,(e,t,n=``)=>`<${t} ${n.trim()}></${t}>`);return{...n,body:i}}return n},J=async(t,n,{hooks:r=[]}={})=>{let i={params:{}},a=[...r.map(e=>e({archive:t,resourcePath:n})),Te({archive:t,resourcePath:n}),Ee({archive:t,resourcePath:n}),Se({archive:t,resourcePath:n}),xe({archive:t,resourcePath:n})];try{let r=await a.reduce(async(e,t)=>await t(await e),Promise.resolve(i));if(e.s.log(`Generated resource`,n,r),r.body!==void 0)return r;let o=b(t,n);if(!o)throw Error(`no file found for resourcePath:${n}`);return{...r,body:await o.blob()}}catch(t){throw e.s.error(t),t}},De=class{constructor(e){this.cleanArchiveAfter=e,this.state$=new a.BehaviorSubject({status:`idle`,locks:0})}update(e){this.state$.next({...this.state$.getValue(),...e})}get locks$(){return this.state$.pipe((0,a.map)(({locks:e})=>e))}get state(){return this.state$.getValue()}get isUnlocked$(){return this.locks$.pipe((0,a.map)(e=>e<=0),(0,a.distinctUntilChanged)(),(0,a.shareReplay)())}get overTTL$(){return this.isUnlocked$.pipe((0,a.switchMap)(e=>e?this.cleanArchiveAfter===1/0?a.NEVER:(0,a.timer)(this.cleanArchiveAfter):a.NEVER))}},Oe=({getArchive:t,cleanArchiveAfter:n=300*1e3})=>{let r=new a.Subject,i=new a.Subject,o=new a.Subject,s={};return r.pipe((0,a.mergeMap)(n=>{let r=s[n];if(r?.state.status!==`idle`)return a.EMPTY;let i=!1,c=t=>{e.s.debug(`Cleaning up archive with key: ${t}`);let n=s[t];delete s[t],i||=(n?.state.archive?.close(),!0)};r.update({status:`loading`});let l=r.locks$,u=r.isUnlocked$,d=l.pipe((0,a.pairwise)(),(0,a.filter)(([e,t])=>t>e),(0,a.startWith)(!0));return(0,a.from)(t(n)).pipe((0,a.tap)(e=>{r.update({archive:e,status:`success`})}),(0,a.catchError)(e=>(c(n),r.update({status:`error`,error:e}),a.EMPTY)),(0,a.switchMap)(()=>(0,a.merge)(d.pipe((0,a.switchMap)(()=>o),(0,a.switchMap)(()=>u),(0,a.filter)(e=>e)),r.overTTL$).pipe((0,a.first)(),(0,a.tap)(()=>{c(n)}))))}),(0,a.takeUntil)(i)).subscribe(),{access:e=>{let t=!1,i=s[e]??new De(n);s[e]=i,i.update({locks:i.state.locks+1});let o=()=>{t||(t=!0,i.update({locks:i.state.locks-1}))};return r.next(e),(0,a.merge)(i.state$.pipe((0,a.map)(({archive:e})=>e),(0,a.filter)(e=>!!e)),i.state$.pipe((0,a.tap)(({error:e})=>{if(e)throw e}),(0,a.ignoreElements)())).pipe((0,a.first)(),(0,a.map)(e=>({archive:e,release:o})),(0,a.catchError)(e=>{throw o(),e}))},purge:()=>{o.next()},_archives:s}},Y=e=>e?/^\d+$/.test(e)?{valid:!0,value:Number.parseInt(e,10)}:{valid:!1,value:void 0}:{valid:!0,value:void 0},ke=e=>{if(!e.toLowerCase().startsWith(`bytes=`))return{kind:`missing`};let t=e.slice(6).trim();if(!t)return{kind:`invalid`};if(t.includes(`,`))return{kind:`multi`};let n=/^(\d*)-(\d*)$/.exec(t);if(!n)return{kind:`invalid`};let[,r=``,i=``]=n,a=Y(r.trim()),o=Y(i.trim());return!a.valid||!o.valid?{kind:`invalid`}:{kind:`single`,start:a.value,end:o.value}},Ae=e=>{if(e instanceof Blob)return{size:e.size,slice:(t,n)=>{let r=e.slice(t,n);return{content:r,length:r.size}}};let t=new TextEncoder().encode(e);return{size:t.byteLength,slice:(e,n)=>{let r=t.slice(e,n);return{content:r,length:r.byteLength}}}},X=({body:e,contentType:t,rangeHeader:n})=>{let r=new Headers;if(t&&r.set(`Content-Type`,t),r.set(`Accept-Ranges`,`bytes`),!n)return e instanceof Blob&&r.set(`Content-Length`,String(e.size)),new Response(e,{status:200,headers:r});let i=ke(n);if(i.kind===`missing`||i.kind===`multi`)return e instanceof Blob&&r.set(`Content-Length`,String(e.size)),new Response(e,{status:200,headers:r});let a=Ae(e),o=a.size;if(i.kind===`invalid`)return new Response(null,{status:416,headers:{"Content-Range":`bytes */${o}`}});let s=i.start,c=i.end;if(s===void 0&&c===void 0||(s===void 0?(s=Math.max(0,o-Math.min(c??0,o)),c=o-1):(c===void 0||c>=o)&&(c=o-1),s<0||c<0||s>=o||c>=o||s>c))return new Response(null,{status:416,headers:{"Content-Range":`bytes */${o}`}});let l=a.slice(s,c+1);return r.set(`Content-Length`,String(l.length)),r.set(`Content-Range`,`bytes ${s}-${c}/${o}`),new Response(l.content,{status:206,headers:r})},Z=`file://`,je=/^https?:\/\//,Me=e=>{try{return decodeURIComponent(e)}catch{return e}},Q=e=>e.startsWith(Z)?e.slice(Z.length):e,Ne=e=>{let t=Q(e);return je.test(t)?t:Q(Me(t))},$=class{constructor({hooks:e,onError:t,onManifestSuccess:n,...r}){this.onError=e=>(console.error(e),new Response(String(e),{status:500})),this.archiveLoader=Oe(r),this.hooks=e??{},this.onManifestSuccess=n??(({manifest:e})=>Promise.resolve(e)),this.onError=t??this.onError}prune(){this.archiveLoader.purge()}accessArchive(e){return this.lastAccessedKey!==void 0&&this.lastAccessedKey!==e&&this.archiveLoader.purge(),this.lastAccessedKey=e,this.archiveLoader.access(e)}accessArchiveWithoutLock(e){return this.accessArchive(e).pipe((0,a.map)(({archive:e,release:t})=>(t(),e)))}withArchiveResponse({key:e,getResponse:t}){return(0,a.lastValueFrom)(this.accessArchive(e).pipe((0,a.mergeMap)(({archive:e,release:n})=>(0,a.from)(t(e)).pipe((0,a.finalize)(()=>{n()}))),(0,a.catchError)(e=>(0,a.of)(this.onError(e)))))}fetchManifest({key:e,baseUrl:t}){return this.withArchiveResponse({key:e,getResponse:e=>(0,a.from)(K(e,{baseUrl:t,hooks:this.hooks.manifest})).pipe((0,a.switchMap)(t=>(0,a.from)(this.onManifestSuccess({manifest:t,archive:e}))),(0,a.map)(e=>new Response(JSON.stringify(e),{status:200})))})}fetchResource({key:e,resourcePath:t,request:n}){return this.withArchiveResponse({key:e,getResponse:e=>(0,a.from)(J(e,Ne(t),{hooks:this.hooks.resource})).pipe((0,a.map)(e=>X({body:e.body??``,contentType:e.params.contentType,rangeHeader:n?.headers.get(`range`)})))})}},Pe=class extends ${constructor({getUriInfo:e,...t}){super(t),this.getUriInfo=e,this.fetchEventListener=this.fetchEventListener.bind(this)}fetchEventListener(t){try{let n=this.getUriInfo(t);if(!n)return;let r=e.i(n.baseUrl),i=t.request.url.substring(r.length+1),[a=``]=i.split(`/`),o=e.i(i.substring(a.length+1));i.endsWith(`/manifest`)?t.respondWith(this.fetchManifest({key:a,baseUrl:`${r}/${a}/`})):t.respondWith(this.fetchResource({key:a,resourcePath:o,request:t.request}))}catch(e){t.respondWith(new Response(String(e),{status:500}))}}};exports.ServiceWorkerStreamer=Pe,exports.Streamer=$,exports.arrayBufferFileAccessors=t.t,exports.blobFileAccessors=t.n,exports.configure=te,exports.createArchive=e.o,exports.createArchiveFromArrayBufferList=o,exports.createArchiveFromEntries=e.t,exports.createArchiveFromText=s,exports.createArchiveFromUrls=ee,exports.createUniqueXmlSafeId=g,exports.createXmlSafeId=h,exports.createXmlSafeIdFactory=_,exports.generateManifestFromArchive=K,exports.generateResourceFromArchive=J,exports.getArchiveFileRecordByUri=b,exports.getArchiveHasComicInfo=S,exports.getArchiveOpfInfo=w,exports.getUriBasePath=e.n,exports.getUriBasename=e.r,exports.isDirectoryRecord=y,exports.isFileRecord=v,exports.readRecordAsText=C,exports.removeTrailingSlash=e.i,exports.sortByTitleComparator=e.a;
31
+ `,c=r.map(r=>({dir:!1,basename:e.r(r),encodingFormat:(0,n.detectMimeTypeFromName)(r),uri:r,size:0,...t.n(async()=>(await fetch(r)).blob())}));return e.o({records:[{dir:!1,basename:`content.opf`,uri:`content.opf`,size:0,...t.n(async()=>new Blob([s]))},...c],close:()=>Promise.resolve()})},v=e=>!e.dir,y=e=>e.dir,b=(e,t)=>{let n=e.recordsByUri.get(t);return n&&v(n)?n:void 0},te=r.COMIC_INFO_FILENAME.toLowerCase(),x=e=>e.records.find(e=>v(e)&&e.basename.toLowerCase()===te),S=async e=>new TextDecoder().decode(await e.arrayBuffer()),ne=({enableReport:t}={})=>{e.s.enable(!!t)},C=e=>{let t=e.records.filter(e=>!e.dir).find(e=>e.uri.endsWith(`.opf`));return{data:t,basePath:t?.uri.substring(0,t.uri.lastIndexOf(`/`))||``}};async function w(e){let{data:t,basePath:n}=C(e)||{};if(!(!t||t.dir))return{opf:(0,r.parseOpf)(await S(t)),basePath:n}}var T=r.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME.toLowerCase(),E=({archive:e})=>async t=>{let n=e.records.find(e=>!e.dir&&e.basename.toLowerCase()===T);if(!n||n.dir)return t;let i=await S(n);try{let{renditionLayout:e}=(0,r.resolveArchiveMetadata)((0,r.parseAppleDisplayOptionsXml)(i));return{...t,renditionLayout:t.renditionLayout??e}}catch(e){return console.error(`Unable to parse ${r.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME} for content\n`,i),console.error(e),t}},D=r.COMIC_INFO_FILENAME.toLowerCase(),re=({archive:e})=>async t=>{let n=x(e);if(!n)return t;let i={...t,spineItems:t.spineItems.filter(e=>!e.id.toLowerCase().endsWith(D)).map((e,t,n)=>({...e,progressionWeight:1/n.length}))},a=await S(n);try{let e=(0,r.resolveArchiveMetadata)((0,r.parseComicInfo)(a));return{...i,readingDirection:e.readingDirection??i.readingDirection}}catch(e){return console.error(`Unable to parse ${r.COMIC_INFO_FILENAME} for content\n`,a),console.error(e),i}},O=({baseUrl:e=``,resourcePath:t})=>{if(!e&&/^https?:\/\//.test(t))return encodeURI(t);let n=e?`${e}${e.endsWith(`/`)?``:`/`}`:`file://`;return encodeURI(`${n}${t}`)},ie=({archive:e,baseUrl:t})=>async()=>{let n=e.records.filter(e=>!e.dir),r=_(),i=n.map(e=>({file:e,id:r(e.uri)}));return{filename:e.filename??``,title:e.records.find(({dir:e})=>e)?.basename.replace(/\/$/,``)||e.filename||``,renditionLayout:void 0,renditionSpread:`auto`,readingDirection:void 0,spineItems:i.filter(({file:e})=>!e.basename.endsWith(`.db`)).map(({file:e,id:r},i)=>({id:r,index:i,href:O({baseUrl:t,resourcePath:e.uri}),renditionLayout:void 0,progressionWeight:1/n.length,pageSpreadLeft:void 0,pageSpreadRight:void 0,mediaType:e.encodingFormat})),items:i.map(({file:e,id:n})=>({id:n,href:encodeURI(`${t}${e.uri}`)}))}},k=async({archive:e,archiveOpf:t})=>{if(!t)return[];let{opf:n,basePath:r}=t,{spineRows:i}=n;return e.records.filter(e=>i.find(t=>r?`${r}/${t.href}`===e.uri:`${t.href}`===e.uri))},A=(e,t,n)=>{let{basePath:r}=C(t)||{};return e.map(e=>{let t=e.href,i=n?.(t)??``;return{href:r?`${i}${r}/${t}`:`${i}${t}`,id:e.id,mediaType:e.mediaType}})},ae=e=>{let t=e?.trim();return t===`scrolled-continuous`||t===`scrolled-doc`||t===`paginated`||t===`auto`?t:`auto`},oe=e=>{let t=e?.trim();if(t===`none`||t===`landscape`||t===`portrait`||t===`both`||t===`auto`)return t},se=e=>{let t=e?.trim();if(t===`cover`||t===`title-page`||t===`copyright-page`||t===`text`)return t},ce=({archive:t,baseUrl:n,archiveOpf:i})=>async a=>{if(!i)return a;let{opf:o,basePath:s}=i,c=(0,r.resolveArchiveMetadata)(o);e.s.groupCollapsed(...e.s.getGroupArgs(`OPF parsed`)),e.s.log(`opf`,o),e.s.groupEnd();let l=o.renditionLayoutMeta?.trim(),u=l===`reflowable`||l===`pre-paginated`?l:c.renditionLayout,d=o.title?.trim()||t.records.find(({dir:e})=>e)?.basename||``,f=c.readingDirection??a.readingDirection,p=(await k({archive:t,archiveOpf:i})).filter(v).reduce((e,t)=>t.size+e,0),m=o.guide,h=[];for(let e of m){let t=se(e.type);t!==void 0&&h.push({href:e.href,title:e.title,type:t})}return{filename:t.filename??``,renditionLayout:u,renditionFlow:ae(o.renditionFlowMeta),renditionSpread:oe(o.renditionSpreadMeta),title:d,readingDirection:f,spineItems:o.spineRows.map((e,r)=>{let i=b(t,s?`${s}/${e.href}`:e.href),a=i?i.size:0,c=n||(/^https?:\/\//.test(e.href)?``:`file://`);return{id:e.id,index:r,href:e.href.startsWith(`https://`)?e.href:s?`${c}${s}/${e.href}`:`${c}${e.href}`,renditionLayout:e.renditionLayout??u,...e.renditionFlow===void 0?{}:{renditionFlow:e.renditionFlow},progressionWeight:p>0?a/p:1/o.spineRows.length,pageSpreadLeft:e.pageSpreadLeft,pageSpreadRight:e.pageSpreadRight,mediaType:e.mediaType}}),items:A(o.manifestItems,t,e=>/^https?:\/\//.test(e)?``:n||`file://`),guide:h.length>0?h:void 0}},j=e=>{let t=e.descendantWithPath(`head`)?.childrenNamed(`meta`).find(e=>e.attr.name===`viewport`);return!!(t&&t.attr.name===`viewport`)},M=e=>e.reduce(async(e,t)=>{if(!await e||!(0,n.isXmlBasedMimeType)({mimeType:v(t)?t.encodingFormat:void 0,uri:t.uri}))return!1;let r=t.dir?null:await S(t);return r?j(new i.XmlDocument(r)):!1},Promise.resolve(!0)),N=({archive:e,archiveOpf:t})=>async n=>n.renditionLayout===`reflowable`&&n.spineItems.every(e=>e.renditionLayout===`reflowable`)&&await M(await k({archive:e,archiveOpf:t}))?{...n,spineItems:n.spineItems.map(e=>({...e,renditionLayout:`pre-paginated`})),renditionLayout:`pre-paginated`}:n,P=()=>e=>({...e,readingDirection:e.readingDirection??`ltr`}),F=async e=>{let t;return await Promise.all(e.records.map(async e=>{if(e.dir||!e.uri.endsWith(r.KOBO_DISPLAY_OPTIONS_FILENAME))return;let n=await S(e);try{let{renditionLayout:e}=(0,r.parseKoboXml)(n);e&&(t=e)}catch(e){console.error(`Unable to parse ${r.KOBO_DISPLAY_OPTIONS_FILENAME} for content\n`,n),console.error(e)}})),{kind:`kobo`,...t===void 0?{}:{renditionLayout:t}}},I=({archive:e})=>async t=>{let{renditionLayout:n}=(0,r.resolveArchiveMetadata)(await F(e));return{...t,renditionLayout:t.renditionLayout??n}},L=e=>e.toLowerCase().endsWith(`.opf`),R=e=>e.records.some(e=>!e.dir&&(L(e.basename)||L(e.uri))),z=({archive:e})=>async t=>R(e)?t:{...t,spineItems:t.spineItems.map(t=>{let r=e.records.find(e=>decodeURI(t.href).endsWith(e.uri)),i=(0,n.parseContentType)((r&&v(r)?r.encodingFormat:void 0)??``)||(0,n.detectMimeTypeFromName)(r?.basename??``);return{...t,renditionLayout:i&&(0,n.isMediaContentMimeType)(i)?`pre-paginated`:t.renditionLayout}})},B=e=>e?e.children.map(e=>e instanceof i.XmlTextNode?e.text:e instanceof i.XmlElement?B(e):``).join(``).trim():``,V=e=>(0,r.tokenizeXmlSpaceSeparatedList)(e.properties).includes(`nav`),H=(e,{basePath:t,baseUrl:r})=>{let i={contents:[],path:``,href:``,title:``},a=e.childNamed(`span`)||e.childNamed(`a`);i.title=(a?.attr.title||a?.val.trim()||B(a))??``;let o=a?.name;o!==`a`&&(a=e.descendantWithPath(`${o}.a`),a&&(o=a.name.toLowerCase())),o===`a`&&a?.attr.href&&(i.path=(0,n.urlJoin)(t,a.attr.href),i.href=(0,n.urlJoin)(r,t,a.attr.href));let s=e.childNamed(`ol`);if(s){let e=s.childrenNamed(`li`);e&&e.length>0&&(i.contents=e.map(e=>H(e,{basePath:t,baseUrl:r})))}return i},U=(e,{basePath:t,baseUrl:n})=>{let r=[],i;return e.descendantWithPath(`body.nav.ol`)?i=e.descendantWithPath(`body.nav.ol`)?.children:e.descendantWithPath(`body.section.nav.ol`)&&(i=e.descendantWithPath(`body.section.nav.ol`)?.children),i&&i.length>0&&i.filter(e=>e.name===`li`).forEach(e=>{r.push(H(e,{basePath:t,baseUrl:n}))}),r},W=async(t,n,{baseUrl:r})=>{let a=t.manifestItems.find(V);if(a?.href){let t=n.records.find(e=>e.uri.endsWith(a.href));if(t&&!t.dir)return U(new i.XmlDocument(await S(t)),{basePath:e.n(t.uri),baseUrl:r})}},G=(e,{opfBasePath:t,baseUrl:r,prefix:i})=>{let a=e?.childNamed(`${i}content`)?.attr.src||``,o={title:e?.descendantWithPath(`${i}navLabel.${i}text`)?.val||``,path:(0,n.urlJoin)(t,a),href:(0,n.urlJoin)(r,t,a),contents:[]},s=e.childrenNamed(`${i}navPoint`);return s&&s.length>0&&(o.contents=s.map(e=>G(e,{opfBasePath:t,baseUrl:r,prefix:i}))),o},le=(e,{opfBasePath:t,baseUrl:n})=>{let r=[],i=e.name,a=``;return i.indexOf(`:`)!==-1&&(a=`${i.split(`:`)[0]}:`),e.childNamed(`${a}navMap`)?.childrenNamed(`${a}navPoint`).forEach(e=>{r.push(G(e,{opfBasePath:t,baseUrl:n,prefix:a}))}),r},ue=async({opf:e,opfBasePath:t,baseUrl:n,archive:r})=>{let a=e.spineTocIdref;if(a){let o=e.manifestItems.find(e=>e.id===a);if(o){let e=`${t}${t===``?``:`/`}${o.href}`,a=r.records.find(t=>t.uri.endsWith(e));if(a&&!a.dir)return le(new i.XmlDocument(await S(a)),{opfBasePath:t,baseUrl:n})}}},de=async(e,t,{baseUrl:n})=>{let{basePath:r}=C(t)||{},i=await W(e,t,{baseUrl:n});if(i)return i;let a=await ue({opf:e,opfBasePath:r??``,archive:t,baseUrl:n});if(a)return a},fe=e=>e.replace(/\.[^.]+$/,``).replace(/[_-]/g,` `).replace(/\s+/g,` `).trim(),pe=(e,t)=>{if(e.spineItems.length!==0&&e.spineItems.every(e=>((0,n.parseContentType)(e.mediaType??``)||(0,n.detectMimeTypeFromName)(e.href))?.startsWith(`audio/`)))return e.spineItems.map(e=>{let n=t.records.find(t=>!t.dir&&decodeURI(e.href).endsWith(t.uri));return{title:fe(n?.basename??e.href),href:e.href,path:n?.uri??e.href,contents:[]}})},me=(t,{baseUrl:r})=>{let i=[...t.records].sort((t,n)=>e.a(t.uri,n.uri)),a=(e,t,n,r,i)=>{let o=e.find(e=>e.title===t),[s,...c]=n;return o?s?[...e.filter(e=>e!==o),{...o,contents:[...o.contents,...a(o.contents,s,c,r,i)]}]:o.path.split(`/`).length>i.split(`/`).length?[...e.filter(e=>e!==o),{...o,path:i,href:r}]:e:s?[...e,{contents:a([],s,c,r,i),href:r,path:i,title:t}]:[...e,{contents:[],href:r,path:i,title:t}]};return i.reduce((e,t)=>{if(t.dir)return e;let[i,...o]=t.uri.split(`/`).slice(0,-1);if(!i)return e;let s=(0,n.urlJoin)(r,encodeURI(t.uri)).replace(/\/$/,``),c=t.uri.replace(/\/$/,``);return a(e,i,o,s,c)},[])},he=async(e,t,{baseUrl:n,archiveOpf:r})=>{if(r)return await de(r.opf,e,{baseUrl:n})||[];let i=pe(t,e);if(i)return i;let a=me(e,{baseUrl:n});if(a.length!==0)return a},ge=({archive:e,baseUrl:t,archiveOpf:n})=>async r=>{if(r.nav)return r;let i=await he(e,r,{baseUrl:t,archiveOpf:n});return i?{...r,nav:{toc:i}}:r},_e=e=>e?e.endsWith(`/`)?e:`${e}/`:``,K=async(t,{baseUrl:n=``,hooks:r={}}={})=>{e.s.log(`Generating manifest from archive`,t);let i=await w(t),a=_e(n),o=e=>(e??[]).map(e=>e({archive:t,baseUrl:a})),s=[ce({archive:t,baseUrl:a,archiveOpf:i}),re({archive:t,baseUrl:a}),E({archive:t,baseUrl:a}),z({archive:t,baseUrl:a}),...o(r.content)],c=o(r.spine),l=[N({archive:t,baseUrl:a,archiveOpf:i}),I({archive:t,baseUrl:a}),...o(r.presentation)],u=[ge({archive:t,baseUrl:a,archiveOpf:i}),...o(r.navigation)],d=[...s,...c,...l,...u,P()];try{let n=ie({archive:t,baseUrl:a})(),r=await d.reduce(async(e,t)=>await t(await e),n);if(e.s.log(`Generated manifest`,r),process.env.NODE_ENV===`development`&&e.s.isEnabled()){let t=JSON.stringify(r,null,2);e.s.groupCollapsed(...e.s.getGroupArgs(`Generated manifest`)),e.s.log(`\n${t}`),e.s.groupEnd()}return r}catch(t){throw e.s.error(t),t}},ve=e=>{let t=e.descendantWithPath(`head`)?.childrenNamed(`meta`).find(e=>e.attr.name===`calibre:cover`);return!!(t&&t.attr.name===`calibre:cover`)},ye=e=>e.descendantWithPath(`body`)?.descendantWithPath(`div`)?.childrenNamed(`svg`)?.find(e=>e.attr.width===`100%`&&e.attr.preserveAspectRatio===`none`),be=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(r?.basename.endsWith(`.xhtml`)){let e=new i.XmlDocument(typeof n.body==`string`?n.body:await S(r));if(ve(e)){let t=ye(e);return t&&delete t.attr.preserveAspectRatio,{...n,body:e?.toString()}}}return n},xe=({archive:e,resourcePath:t})=>async n=>be({archive:e,resourcePath:t})(n),Se=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(r?.basename.endsWith(`.css`)){let e=(typeof n.body==`string`?n.body:await S(r)).replaceAll(`-webkit-writing-mode`,`writing-mode`);return{...n,body:e}}return n},Ce=async(e,t)=>{let n=await w(e);if(n){let{opf:r}=n,i=A(r.manifestItems,e,()=>``).find(e=>t.endsWith(e.href))?.mediaType;if(i)return{mediaType:i}}return{mediaType:we(t)}},we=e=>{if(e.endsWith(`.css`))return`text/css; charset=UTF-8`;if(e.endsWith(`.jpg`))return`image/jpg`;if(e.endsWith(`.xhtml`))return`application/xhtml+xml`;if(e.endsWith(`.mp4`))return`video/mp4`;if(e.endsWith(`.svg`))return`image/svg+xml`},Te=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(!r)return n;let i=await Ce(e,t);return{...n,params:{...n.params,...r?.encodingFormat&&{contentType:r.encodingFormat},...i.mediaType&&{contentType:i.mediaType}}}},q=`div.span.p.a.li.ul.ol.h1.h2.h3.h4.h5.h6.table.tr.td.th.thead.tbody.tfoot.section.article.header.footer.nav.aside.main.figure.figcaption.blockquote.pre.code.form.textarea.select.option.button.label.fieldset.legend.caption.dl.dt.dd.iframe.video.audio.canvas.script.style`.split(`.`),Ee=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(r?.basename.endsWith(`.xhtml`)){let e=typeof n.body==`string`?n.body:await S(r);if(!RegExp(`<(${q.join(`|`)})[\\s/>]`,`i`).test(e))return n;let t=RegExp(`<(${q.join(`|`)})(\\s[^>]*)?\\s*/>`,`gi`),i=e.replace(t,(e,t,n=``)=>`<${t} ${n.trim()}></${t}>`);return{...n,body:i}}return n},J=async(t,n,{hooks:r=[]}={})=>{let i={params:{}},a=[...r.map(e=>e({archive:t,resourcePath:n})),Te({archive:t,resourcePath:n}),Ee({archive:t,resourcePath:n}),Se({archive:t,resourcePath:n}),xe({archive:t,resourcePath:n})];try{let r=await a.reduce(async(e,t)=>await t(await e),Promise.resolve(i));if(e.s.log(`Generated resource`,n,r),r.body!==void 0)return r;let o=b(t,n);if(!o)throw Error(`no file found for resourcePath:${n}`);return{...r,body:await o.blob()}}catch(t){throw e.s.error(t),t}},De=class{constructor(e){this.cleanArchiveAfter=e,this.state$=new a.BehaviorSubject({status:`idle`,locks:0})}update(e){this.state$.next({...this.state$.getValue(),...e})}get locks$(){return this.state$.pipe((0,a.map)(({locks:e})=>e))}get state(){return this.state$.getValue()}get isUnlocked$(){return this.locks$.pipe((0,a.map)(e=>e<=0),(0,a.distinctUntilChanged)(),(0,a.shareReplay)())}get overTTL$(){return this.isUnlocked$.pipe((0,a.switchMap)(e=>e?this.cleanArchiveAfter===1/0?a.NEVER:(0,a.timer)(this.cleanArchiveAfter):a.NEVER))}},Oe=({getArchive:t,cleanArchiveAfter:n=300*1e3})=>{let r=new a.Subject,i=new a.Subject,o=new a.Subject,s={};return r.pipe((0,a.mergeMap)(n=>{let r=s[n];if(r?.state.status!==`idle`)return a.EMPTY;let i=!1,c=t=>{e.s.debug(`Cleaning up archive with key: ${t}`);let n=s[t];delete s[t],i||=(n?.state.archive?.close(),!0)};r.update({status:`loading`});let l=r.locks$,u=r.isUnlocked$,d=l.pipe((0,a.pairwise)(),(0,a.filter)(([e,t])=>t>e),(0,a.startWith)(!0));return(0,a.from)(t(n)).pipe((0,a.tap)(e=>{r.update({archive:e,status:`success`})}),(0,a.catchError)(e=>(c(n),r.update({status:`error`,error:e}),a.EMPTY)),(0,a.switchMap)(()=>(0,a.merge)(d.pipe((0,a.switchMap)(()=>o),(0,a.switchMap)(()=>u),(0,a.filter)(e=>e)),r.overTTL$).pipe((0,a.first)(),(0,a.tap)(()=>{c(n)}))))}),(0,a.takeUntil)(i)).subscribe(),{access:e=>{let t=!1,i=s[e]??new De(n);s[e]=i,i.update({locks:i.state.locks+1});let o=()=>{t||(t=!0,i.update({locks:i.state.locks-1}))};return r.next(e),(0,a.merge)(i.state$.pipe((0,a.map)(({archive:e})=>e),(0,a.filter)(e=>!!e)),i.state$.pipe((0,a.tap)(({error:e})=>{if(e)throw e}),(0,a.ignoreElements)())).pipe((0,a.first)(),(0,a.map)(e=>({archive:e,release:o})),(0,a.catchError)(e=>{throw o(),e}))},purge:()=>{o.next()},_archives:s}},Y=e=>e?/^\d+$/.test(e)?{valid:!0,value:Number.parseInt(e,10)}:{valid:!1,value:void 0}:{valid:!0,value:void 0},ke=e=>{if(!e.toLowerCase().startsWith(`bytes=`))return{kind:`missing`};let t=e.slice(6).trim();if(!t)return{kind:`invalid`};if(t.includes(`,`))return{kind:`multi`};let n=/^(\d*)-(\d*)$/.exec(t);if(!n)return{kind:`invalid`};let[,r=``,i=``]=n,a=Y(r.trim()),o=Y(i.trim());return!a.valid||!o.valid?{kind:`invalid`}:{kind:`single`,start:a.value,end:o.value}},Ae=e=>{if(e instanceof Blob)return{size:e.size,slice:(t,n)=>{let r=e.slice(t,n);return{content:r,length:r.size}}};let t=new TextEncoder().encode(e);return{size:t.byteLength,slice:(e,n)=>{let r=t.slice(e,n);return{content:r,length:r.byteLength}}}},X=({body:e,contentType:t,rangeHeader:n})=>{let r=new Headers;if(t&&r.set(`Content-Type`,t),r.set(`Accept-Ranges`,`bytes`),!n)return e instanceof Blob&&r.set(`Content-Length`,String(e.size)),new Response(e,{status:200,headers:r});let i=ke(n);if(i.kind===`missing`||i.kind===`multi`)return e instanceof Blob&&r.set(`Content-Length`,String(e.size)),new Response(e,{status:200,headers:r});let a=Ae(e),o=a.size;if(i.kind===`invalid`)return new Response(null,{status:416,headers:{"Content-Range":`bytes */${o}`}});let s=i.start,c=i.end;if(s===void 0&&c===void 0||(s===void 0?(s=Math.max(0,o-Math.min(c??0,o)),c=o-1):(c===void 0||c>=o)&&(c=o-1),s<0||c<0||s>=o||c>=o||s>c))return new Response(null,{status:416,headers:{"Content-Range":`bytes */${o}`}});let l=a.slice(s,c+1);return r.set(`Content-Length`,String(l.length)),r.set(`Content-Range`,`bytes ${s}-${c}/${o}`),new Response(l.content,{status:206,headers:r})},Z=`file://`,je=/^https?:\/\//,Me=e=>{try{return decodeURIComponent(e)}catch{return e}},Q=e=>e.startsWith(Z)?e.slice(Z.length):e,Ne=e=>{let t=Q(e);return je.test(t)?t:Q(Me(t))},$=class{constructor({hooks:e,onError:t,onManifestSuccess:n,...r}){this.onError=e=>(console.error(e),new Response(String(e),{status:500})),this.archiveLoader=Oe(r),this.hooks=e??{},this.onManifestSuccess=n??(({manifest:e})=>Promise.resolve(e)),this.onError=t??this.onError}prune(){this.archiveLoader.purge()}accessArchive(e){return this.lastAccessedKey!==void 0&&this.lastAccessedKey!==e&&this.archiveLoader.purge(),this.lastAccessedKey=e,this.archiveLoader.access(e)}accessArchiveWithoutLock(e){return this.accessArchive(e).pipe((0,a.map)(({archive:e,release:t})=>(t(),e)))}withArchiveResponse({key:e,getResponse:t}){return(0,a.lastValueFrom)(this.accessArchive(e).pipe((0,a.mergeMap)(({archive:e,release:n})=>(0,a.from)(t(e)).pipe((0,a.finalize)(()=>{n()}))),(0,a.catchError)(e=>(0,a.of)(this.onError(e)))))}fetchManifest({key:e,baseUrl:t}){return this.withArchiveResponse({key:e,getResponse:e=>(0,a.from)(K(e,{baseUrl:t,hooks:this.hooks.manifest})).pipe((0,a.switchMap)(t=>(0,a.from)(this.onManifestSuccess({manifest:t,archive:e}))),(0,a.map)(e=>new Response(JSON.stringify(e),{status:200})))})}fetchResource({key:e,resourcePath:t,request:n}){return this.withArchiveResponse({key:e,getResponse:e=>(0,a.from)(J(e,Ne(t),{hooks:this.hooks.resource})).pipe((0,a.map)(e=>X({body:e.body??``,contentType:e.params.contentType,rangeHeader:n?.headers.get(`range`)})))})}},Pe=class extends ${constructor({getUriInfo:e,...t}){super(t),this.getUriInfo=e,this.fetchEventListener=this.fetchEventListener.bind(this)}fetchEventListener(t){try{let n=this.getUriInfo(t);if(!n)return;let r=e.i(n.baseUrl),i=t.request.url.substring(r.length+1),[a=``]=i.split(`/`),o=e.i(i.substring(a.length+1));i.endsWith(`/manifest`)?t.respondWith(this.fetchManifest({key:a,baseUrl:`${r}/${a}/`})):t.respondWith(this.fetchResource({key:a,resourcePath:o,request:t.request}))}catch(e){t.respondWith(new Response(String(e),{status:500}))}}};exports.ServiceWorkerStreamer=Pe,exports.Streamer=$,exports.arrayBufferFileAccessors=t.t,exports.blobFileAccessors=t.n,exports.configure=ne,exports.createArchive=e.o,exports.createArchiveFromArrayBufferList=o,exports.createArchiveFromEntries=e.t,exports.createArchiveFromText=s,exports.createArchiveFromUrls=ee,exports.createManifestResourceHref=O,exports.createUniqueXmlSafeId=g,exports.createXmlSafeId=h,exports.createXmlSafeIdFactory=_,exports.generateManifestFromArchive=K,exports.generateResourceFromArchive=J,exports.getArchiveFileRecordByUri=b,exports.getArchiveHasComicInfo=x,exports.getArchiveOpfInfo=C,exports.getUriBasePath=e.n,exports.getUriBasename=e.r,exports.isDirectoryRecord=y,exports.isFileRecord=v,exports.readRecordAsText=S,exports.removeTrailingSlash=e.i,exports.sortByTitleComparator=e.a;
32
32
  //# sourceMappingURL=index.cjs.map