@prose-reader/streamer 1.305.0 → 1.307.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.
Files changed (47) hide show
  1. package/dist/archives/createArchive.d.ts +10 -0
  2. package/dist/archives/createArchiveFromJszip/index.cjs.js +2 -0
  3. package/dist/archives/createArchiveFromJszip/index.cjs.js.map +1 -0
  4. package/dist/archives/createArchiveFromJszip/index.es.js +39 -0
  5. package/dist/archives/createArchiveFromJszip/index.es.js.map +1 -0
  6. package/dist/archives/createArchiveFromJszip.d.ts +2 -29
  7. package/dist/archives/createArchiveFromLibArchive/index.cjs.js +2 -0
  8. package/dist/archives/createArchiveFromLibArchive/index.cjs.js.map +1 -0
  9. package/dist/archives/createArchiveFromLibArchive/index.es.js +24 -0
  10. package/dist/archives/createArchiveFromLibArchive/index.es.js.map +1 -0
  11. package/dist/archives/createArchiveFromLibArchive.d.ts +3 -10
  12. package/dist/archives/createArchiveFromText.d.ts +1 -2
  13. package/dist/archives/createArchiveFromUnzipper/index.cjs.js +2 -0
  14. package/dist/archives/createArchiveFromUnzipper/index.cjs.js.map +1 -0
  15. package/dist/archives/createArchiveFromUnzipper/index.es.js +42 -0
  16. package/dist/archives/createArchiveFromUnzipper/index.es.js.map +1 -0
  17. package/dist/archives/createArchiveFromUnzipper.d.ts +7 -0
  18. package/dist/archives/fileAccessors.d.ts +15 -0
  19. package/dist/archives/readRecordAsText.d.ts +7 -0
  20. package/dist/archives/types.d.ts +21 -14
  21. package/dist/epubs/getSpineItemFilesFromArchive.d.ts +1 -1
  22. package/dist/fileAccessors-DWVChFUB.cjs +2 -0
  23. package/dist/fileAccessors-DWVChFUB.cjs.map +1 -0
  24. package/dist/fileAccessors-etcCPnpQ.js +12 -0
  25. package/dist/fileAccessors-etcCPnpQ.js.map +1 -0
  26. package/dist/index/index.cjs.js +32 -0
  27. package/dist/index/index.cjs.js.map +1 -0
  28. package/dist/index/index.es.js +827 -0
  29. package/dist/index/index.es.js.map +1 -0
  30. package/dist/index.d.ts +5 -3
  31. package/dist/printTree-CJzGASVu.js +20 -0
  32. package/dist/printTree-CJzGASVu.js.map +1 -0
  33. package/dist/printTree-DTFYKvW1.cjs +3 -0
  34. package/dist/printTree-DTFYKvW1.cjs.map +1 -0
  35. package/dist/report-Cs9DVdJl.cjs +2 -0
  36. package/dist/report-Cs9DVdJl.cjs.map +1 -0
  37. package/dist/report-uURLD5cl.js +15 -0
  38. package/dist/report-uURLD5cl.js.map +1 -0
  39. package/dist/uri-DBZYnB1I.js +13 -0
  40. package/dist/uri-DBZYnB1I.js.map +1 -0
  41. package/dist/uri-DW0-P-ng.cjs +2 -0
  42. package/dist/uri-DW0-P-ng.cjs.map +1 -0
  43. package/package.json +44 -10
  44. package/dist/index.js +0 -899
  45. package/dist/index.js.map +0 -1
  46. package/dist/index.umd.cjs +0 -33
  47. package/dist/index.umd.cjs.map +0 -1
@@ -0,0 +1,827 @@
1
+ import { n as e, t } from "../report-uURLD5cl.js";
2
+ import { i as n, n as r, r as i, t as a } from "../uri-DBZYnB1I.js";
3
+ import { n as o, t as s } from "../fileAccessors-etcCPnpQ.js";
4
+ import { detectMimeTypeFromName as c, escapeXmlAttributeValue as l, isMediaContentMimeType as u, isXmlBasedMimeType as d, parseContentType as f, urlJoin as p } from "@prose-reader/shared";
5
+ import { APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME as m, COMIC_INFO_FILENAME as h, KOBO_DISPLAY_OPTIONS_FILENAME as g, parseAppleDisplayOptionsXml as ee, parseComicInfo as te, parseKoboXml as ne, parseOpf as re, resolveArchiveMetadata as _, tokenizeXmlSpaceSeparatedList as ie } from "@prose-reader/archive-parser";
6
+ import { XmlDocument as v, XmlElement as ae, XmlTextNode as oe } from "xmldoc";
7
+ import { BehaviorSubject as se, EMPTY as y, NEVER as b, Subject as x, catchError as S, distinctUntilChanged as ce, filter as C, finalize as le, first as w, from as T, ignoreElements as ue, lastValueFrom as de, map as E, merge as D, mergeMap as O, of as fe, pairwise as pe, shareReplay as me, startWith as he, switchMap as k, takeUntil as ge, tap as A, timer as _e } from "rxjs";
8
+ //#region src/archives/createArchiveFromArrayBufferList.ts
9
+ var ve = async (t, { orderByAlpha: i, name: a, encodingFormat: o } = {}) => {
10
+ let l = t;
11
+ return i && (l = l.slice().sort((e, t) => n(e.name, t.name))), e({
12
+ filename: a,
13
+ encodingFormat: o,
14
+ records: l.map((e) => {
15
+ let t = r(e.name);
16
+ return e.isDir ? {
17
+ dir: !0,
18
+ basename: t,
19
+ uri: e.name
20
+ } : {
21
+ dir: e.isDir,
22
+ basename: t,
23
+ encodingFormat: c(e.name),
24
+ uri: e.name,
25
+ size: e.size,
26
+ ...s(e.data, c(e.name) ?? "")
27
+ };
28
+ }),
29
+ close: () => Promise.resolve()
30
+ });
31
+ }, ye = async (t, { mimeType: n, direction: i } = { mimeType: "text/plain" }) => {
32
+ let a = `
33
+ <?xml version="1.0" encoding="UTF-8"?>
34
+ <package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="ja" prefix="rendition: http://www.idpf.org/vocab/rendition/#"
35
+ unique-identifier="ootuya-id">
36
+ <metadata xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/"
37
+ xmlns:dcterms="http://purl.org/dc/terms/">
38
+ <meta property="rendition:layout">reflowable</meta>
39
+ </metadata>
40
+ <manifest>
41
+ <item id="p01" href="p01.txt" media-type="text/plain"/>
42
+ </manifest>
43
+ <spine page-progression-direction="${i ?? "ltr"}">
44
+ <itemref idref="p01" />
45
+ </spine>
46
+ </package>
47
+ `;
48
+ return e({
49
+ filename: "content.txt",
50
+ encodingFormat: n,
51
+ records: [{
52
+ dir: !1,
53
+ basename: r("generated.opf"),
54
+ uri: "generated.opf",
55
+ size: 0,
56
+ ...o(async () => new Blob([a]))
57
+ }, {
58
+ dir: !1,
59
+ basename: r("p01.txt"),
60
+ uri: "p01.txt",
61
+ size: typeof t == "string" ? new Blob([t]).size : t.size,
62
+ encodingFormat: n,
63
+ ...o(async () => typeof t == "string" ? new Blob([t]) : t)
64
+ }],
65
+ close: () => Promise.resolve()
66
+ });
67
+ }, be = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/, xe = /^[A-Za-z0-9_]/, j = /^xml/i, Se = /[^A-Za-z0-9_.-]+/g, M = "_", Ce = (e) => e.replace(/^_+|_+$/g, ""), we = (e) => Ce(e.trim().replaceAll("/", "_").replace(Se, "_")), N = (e) => {
68
+ if (be.test(e) && !j.test(e)) return e;
69
+ let t = we(e), n = t && !j.test(t) ? t : `${M}${t}`;
70
+ return xe.test(n) ? n : `${M}${n}`;
71
+ }, P = (e, t) => {
72
+ let n = N(e);
73
+ if (!t.has(n)) return t.add(n), n;
74
+ let r = 2, i = `${n}-${r}`;
75
+ for (; t.has(i);) r += 1, i = `${n}-${r}`;
76
+ return t.add(i), i;
77
+ }, F = () => {
78
+ let e = /* @__PURE__ */ new Set();
79
+ return (t) => P(t, e);
80
+ }, Te = async (t, n) => {
81
+ let i = F(), a = t.map((e) => ({
82
+ id: i(e),
83
+ url: e
84
+ })), s = `
85
+ <?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
86
+ <metadata>
87
+ <meta property="rendition:layout">${n?.useRenditionFlow ? "reflowable" : "pre-paginated"}</meta>
88
+ ${n?.useRenditionFlow ? "<meta property=\"rendition:flow\">scrolled-continuous</meta>" : ""}
89
+ </metadata>
90
+ <manifest>
91
+ ${a.map(({ id: e, url: t }) => {
92
+ let n = c(t);
93
+ return `<item id="${e}" href="${l(t)}" media-type="${l(n ?? "")}"/>`;
94
+ }).join("\n")}
95
+ </manifest>
96
+ <spine>
97
+ ${a.map(({ id: e }) => `<itemref idref="${e}" />`).join("\n")}
98
+ </spine>
99
+ </package>
100
+ `, u = t.map((e) => ({
101
+ dir: !1,
102
+ basename: r(e),
103
+ encodingFormat: c(e),
104
+ uri: e,
105
+ size: 0,
106
+ ...o(async () => (await fetch(e)).blob())
107
+ }));
108
+ return e({
109
+ records: [{
110
+ dir: !1,
111
+ basename: "content.opf",
112
+ uri: "content.opf",
113
+ size: 0,
114
+ ...o(async () => new Blob([s]))
115
+ }, ...u],
116
+ close: () => Promise.resolve()
117
+ });
118
+ }, I = (e) => !e.dir, Ee = (e) => e.dir, L = (e, t) => {
119
+ let n = e.recordsByUri.get(t);
120
+ return n && I(n) ? n : void 0;
121
+ }, De = h.toLowerCase(), R = (e) => e.records.find((e) => I(e) && e.basename.toLowerCase() === De), z = async (e) => new TextDecoder().decode(await e.arrayBuffer()), Oe = ({ enableReport: e } = {}) => {
122
+ t.enable(!!e);
123
+ }, B = (e) => {
124
+ let t = e.records.filter((e) => !e.dir).find((e) => e.uri.endsWith(".opf"));
125
+ return {
126
+ data: t,
127
+ basePath: t?.uri.substring(0, t.uri.lastIndexOf("/")) || ""
128
+ };
129
+ };
130
+ //#endregion
131
+ //#region src/epubs/readArchiveOpf.ts
132
+ async function V(e) {
133
+ let { data: t, basePath: n } = B(e) || {};
134
+ if (!(!t || t.dir)) return {
135
+ opf: re(await z(t)),
136
+ basePath: n
137
+ };
138
+ }
139
+ //#endregion
140
+ //#region src/generators/manifest/hooks/apple.ts
141
+ var ke = m.toLowerCase(), Ae = ({ archive: e }) => async (t) => {
142
+ let n = e.records.find((e) => !e.dir && e.basename.toLowerCase() === ke);
143
+ if (!n || n.dir) return t;
144
+ let r = await z(n);
145
+ try {
146
+ let { renditionLayout: e } = _(ee(r));
147
+ return {
148
+ ...t,
149
+ renditionLayout: t.renditionLayout ?? e
150
+ };
151
+ } catch (e) {
152
+ return console.error(`Unable to parse ${m} for content\n`, r), console.error(e), t;
153
+ }
154
+ }, je = h.toLowerCase(), Me = ({ archive: e }) => async (t) => {
155
+ let n = R(e);
156
+ if (!n) return t;
157
+ let r = {
158
+ ...t,
159
+ spineItems: t.spineItems.filter((e) => !e.id.toLowerCase().endsWith(je)).map((e, t, n) => ({
160
+ ...e,
161
+ progressionWeight: 1 / n.length
162
+ }))
163
+ }, i = await z(n);
164
+ try {
165
+ let e = _(te(i));
166
+ return {
167
+ ...r,
168
+ readingDirection: e.readingDirection ?? r.readingDirection
169
+ };
170
+ } catch (e) {
171
+ return console.error(`Unable to parse ${h} for content\n`, i), console.error(e), r;
172
+ }
173
+ }, Ne = ({ baseUrl: e = "", resourcePath: t }) => {
174
+ if (!e && /^https?:\/\//.test(t)) return encodeURI(t);
175
+ let n = e ? `${e}${e.endsWith("/") ? "" : "/"}` : "file://";
176
+ return encodeURI(`${n}${t}`);
177
+ }, Pe = ({ archive: e, baseUrl: t }) => async () => {
178
+ let n = e.records.filter((e) => !e.dir), r = F(), i = n.map((e) => ({
179
+ file: e,
180
+ id: r(e.uri)
181
+ }));
182
+ return {
183
+ filename: e.filename ?? "",
184
+ title: e.records.find(({ dir: e }) => e)?.basename.replace(/\/$/, "") || e.filename || "",
185
+ renditionLayout: void 0,
186
+ renditionSpread: "auto",
187
+ readingDirection: void 0,
188
+ spineItems: i.filter(({ file: e }) => !e.basename.endsWith(".db")).map(({ file: e, id: r }, i) => ({
189
+ id: r,
190
+ index: i,
191
+ href: Ne({
192
+ baseUrl: t,
193
+ resourcePath: e.uri
194
+ }),
195
+ renditionLayout: void 0,
196
+ progressionWeight: 1 / n.length,
197
+ pageSpreadLeft: void 0,
198
+ pageSpreadRight: void 0,
199
+ mediaType: e.encodingFormat
200
+ })),
201
+ items: i.map(({ file: e, id: n }) => ({
202
+ id: n,
203
+ href: encodeURI(`${t}${e.uri}`)
204
+ }))
205
+ };
206
+ }, H = async ({ archive: e, archiveOpf: t }) => {
207
+ if (!t) return [];
208
+ let { opf: n, basePath: r } = t, { spineRows: i } = n;
209
+ return e.records.filter((e) => i.find((t) => r ? `${r}/${t.href}` === e.uri : `${t.href}` === e.uri));
210
+ }, U = (e, t, n) => {
211
+ let { basePath: r } = B(t) || {};
212
+ return e.map((e) => {
213
+ let t = e.href, i = n?.(t) ?? "";
214
+ return {
215
+ href: r ? `${i}${r}/${t}` : `${i}${t}`,
216
+ id: e.id,
217
+ mediaType: e.mediaType
218
+ };
219
+ });
220
+ }, Fe = (e) => {
221
+ let t = e?.trim();
222
+ return t === "scrolled-continuous" || t === "scrolled-doc" || t === "paginated" || t === "auto" ? t : "auto";
223
+ }, Ie = (e) => {
224
+ let t = e?.trim();
225
+ if (t === "none" || t === "landscape" || t === "portrait" || t === "both" || t === "auto") return t;
226
+ }, Le = (e) => {
227
+ let t = e?.trim();
228
+ if (t === "cover" || t === "title-page" || t === "copyright-page" || t === "text") return t;
229
+ }, Re = ({ archive: e, baseUrl: n, archiveOpf: r }) => async (i) => {
230
+ if (!r) return i;
231
+ let { opf: a, basePath: o } = r, s = _(a);
232
+ t.groupCollapsed(...t.getGroupArgs("OPF parsed")), t.log("opf", a), t.groupEnd();
233
+ let c = a.renditionLayoutMeta?.trim(), l = c === "reflowable" || c === "pre-paginated" ? c : s.renditionLayout, u = a.title?.trim() || e.records.find(({ dir: e }) => e)?.basename || "", d = s.readingDirection ?? i.readingDirection, f = (await H({
234
+ archive: e,
235
+ archiveOpf: r
236
+ })).filter(I).reduce((e, t) => t.size + e, 0), p = a.guide, m = [];
237
+ for (let e of p) {
238
+ let t = Le(e.type);
239
+ t !== void 0 && m.push({
240
+ href: e.href,
241
+ title: e.title,
242
+ type: t
243
+ });
244
+ }
245
+ return {
246
+ filename: e.filename ?? "",
247
+ renditionLayout: l,
248
+ renditionFlow: Fe(a.renditionFlowMeta),
249
+ renditionSpread: Ie(a.renditionSpreadMeta),
250
+ title: u,
251
+ readingDirection: d,
252
+ spineItems: a.spineRows.map((t, r) => {
253
+ let i = L(e, o ? `${o}/${t.href}` : t.href), s = i ? i.size : 0, c = n || (/^https?:\/\//.test(t.href) ? "" : "file://");
254
+ return {
255
+ id: t.id,
256
+ index: r,
257
+ href: t.href.startsWith("https://") ? t.href : o ? `${c}${o}/${t.href}` : `${c}${t.href}`,
258
+ renditionLayout: t.renditionLayout ?? l,
259
+ ...t.renditionFlow === void 0 ? {} : { renditionFlow: t.renditionFlow },
260
+ progressionWeight: f > 0 ? s / f : 1 / a.spineRows.length,
261
+ pageSpreadLeft: t.pageSpreadLeft,
262
+ pageSpreadRight: t.pageSpreadRight,
263
+ mediaType: t.mediaType
264
+ };
265
+ }),
266
+ items: U(a.manifestItems, e, (e) => /^https?:\/\//.test(e) ? "" : n || "file://"),
267
+ guide: m.length > 0 ? m : void 0
268
+ };
269
+ }, ze = (e) => {
270
+ let t = e.descendantWithPath("head")?.childrenNamed("meta").find((e) => e.attr.name === "viewport");
271
+ return !!(t && t.attr.name === "viewport");
272
+ }, Be = (e) => e.reduce(async (e, t) => {
273
+ if (!await e || !d({
274
+ mimeType: I(t) ? t.encodingFormat : void 0,
275
+ uri: t.uri
276
+ })) return !1;
277
+ let n = t.dir ? null : await z(t);
278
+ return n ? ze(new v(n)) : !1;
279
+ }, Promise.resolve(!0)), Ve = ({ archive: e, archiveOpf: t }) => async (n) => n.renditionLayout === "reflowable" && n.spineItems.every((e) => e.renditionLayout === "reflowable") && await Be(await H({
280
+ archive: e,
281
+ archiveOpf: t
282
+ })) ? {
283
+ ...n,
284
+ spineItems: n.spineItems.map((e) => ({
285
+ ...e,
286
+ renditionLayout: "pre-paginated"
287
+ })),
288
+ renditionLayout: "pre-paginated"
289
+ } : n, He = () => (e) => ({
290
+ ...e,
291
+ readingDirection: e.readingDirection ?? "ltr"
292
+ }), Ue = async (e) => {
293
+ let t;
294
+ return await Promise.all(e.records.map(async (e) => {
295
+ if (e.dir || !e.uri.endsWith(g)) return;
296
+ let n = await z(e);
297
+ try {
298
+ let { renditionLayout: e } = ne(n);
299
+ e && (t = e);
300
+ } catch (e) {
301
+ console.error(`Unable to parse ${g} for content\n`, n), console.error(e);
302
+ }
303
+ })), {
304
+ kind: "kobo",
305
+ ...t === void 0 ? {} : { renditionLayout: t }
306
+ };
307
+ }, We = ({ archive: e }) => async (t) => {
308
+ let { renditionLayout: n } = _(await Ue(e));
309
+ return {
310
+ ...t,
311
+ renditionLayout: t.renditionLayout ?? n
312
+ };
313
+ }, W = (e) => e.toLowerCase().endsWith(".opf"), Ge = (e) => e.records.some((e) => !e.dir && (W(e.basename) || W(e.uri))), Ke = ({ archive: e }) => async (t) => Ge(e) ? t : {
314
+ ...t,
315
+ spineItems: t.spineItems.map((t) => {
316
+ let n = e.records.find((e) => decodeURI(t.href).endsWith(e.uri)), r = f((n && I(n) ? n.encodingFormat : void 0) ?? "") || c(n?.basename ?? "");
317
+ return {
318
+ ...t,
319
+ renditionLayout: r && u(r) ? "pre-paginated" : t.renditionLayout
320
+ };
321
+ })
322
+ }, G = (e) => e ? e.children.map((e) => e instanceof oe ? e.text : e instanceof ae ? G(e) : "").join("").trim() : "", qe = (e) => ie(e.properties).includes("nav"), K = (e, { basePath: t, baseUrl: n }) => {
323
+ let r = {
324
+ contents: [],
325
+ path: "",
326
+ href: "",
327
+ title: ""
328
+ }, i = e.childNamed("span") || e.childNamed("a");
329
+ r.title = (i?.attr.title || i?.val.trim() || G(i)) ?? "";
330
+ let a = i?.name;
331
+ a !== "a" && (i = e.descendantWithPath(`${a}.a`), i && (a = i.name.toLowerCase())), a === "a" && i?.attr.href && (r.path = p(t, i.attr.href), r.href = p(n, t, i.attr.href));
332
+ let o = e.childNamed("ol");
333
+ if (o) {
334
+ let e = o.childrenNamed("li");
335
+ e && e.length > 0 && (r.contents = e.map((e) => K(e, {
336
+ basePath: t,
337
+ baseUrl: n
338
+ })));
339
+ }
340
+ return r;
341
+ }, Je = (e, { basePath: t, baseUrl: n }) => {
342
+ let r = [], i;
343
+ 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) => {
344
+ r.push(K(e, {
345
+ basePath: t,
346
+ baseUrl: n
347
+ }));
348
+ }), r;
349
+ }, Ye = async (e, t, { baseUrl: n }) => {
350
+ let r = e.manifestItems.find(qe);
351
+ if (r?.href) {
352
+ let e = t.records.find((e) => e.uri.endsWith(r.href));
353
+ if (e && !e.dir) return Je(new v(await z(e)), {
354
+ basePath: a(e.uri),
355
+ baseUrl: n
356
+ });
357
+ }
358
+ }, q = (e, { opfBasePath: t, baseUrl: n, prefix: r }) => {
359
+ let i = e?.childNamed(`${r}content`)?.attr.src || "", a = {
360
+ title: e?.descendantWithPath(`${r}navLabel.${r}text`)?.val || "",
361
+ path: p(t, i),
362
+ href: p(n, t, i),
363
+ contents: []
364
+ }, o = e.childrenNamed(`${r}navPoint`);
365
+ return o && o.length > 0 && (a.contents = o.map((e) => q(e, {
366
+ opfBasePath: t,
367
+ baseUrl: n,
368
+ prefix: r
369
+ }))), a;
370
+ }, Xe = (e, { opfBasePath: t, baseUrl: n }) => {
371
+ let r = [], i = e.name, a = "";
372
+ return i.indexOf(":") !== -1 && (a = `${i.split(":")[0]}:`), e.childNamed(`${a}navMap`)?.childrenNamed(`${a}navPoint`).forEach((e) => {
373
+ r.push(q(e, {
374
+ opfBasePath: t,
375
+ baseUrl: n,
376
+ prefix: a
377
+ }));
378
+ }), r;
379
+ }, Ze = async ({ opf: e, opfBasePath: t, baseUrl: n, archive: r }) => {
380
+ let i = e.spineTocIdref;
381
+ if (i) {
382
+ let a = e.manifestItems.find((e) => e.id === i);
383
+ if (a) {
384
+ let e = `${t}${t === "" ? "" : "/"}${a.href}`, i = r.records.find((t) => t.uri.endsWith(e));
385
+ if (i && !i.dir) return Xe(new v(await z(i)), {
386
+ opfBasePath: t,
387
+ baseUrl: n
388
+ });
389
+ }
390
+ }
391
+ }, Qe = async (e, t, { baseUrl: n }) => {
392
+ let { basePath: r } = B(t) || {}, i = await Ye(e, t, { baseUrl: n });
393
+ if (i) return i;
394
+ let a = await Ze({
395
+ opf: e,
396
+ opfBasePath: r ?? "",
397
+ archive: t,
398
+ baseUrl: n
399
+ });
400
+ if (a) return a;
401
+ }, $e = (e) => e.replace(/\.[^.]+$/, "").replace(/[_-]/g, " ").replace(/\s+/g, " ").trim(), et = (e, t) => {
402
+ if (e.spineItems.length !== 0 && e.spineItems.every((e) => (f(e.mediaType ?? "") || c(e.href))?.startsWith("audio/"))) return e.spineItems.map((e) => {
403
+ let n = t.records.find((t) => !t.dir && decodeURI(e.href).endsWith(t.uri));
404
+ return {
405
+ title: $e(n?.basename ?? e.href),
406
+ href: e.href,
407
+ path: n?.uri ?? e.href,
408
+ contents: []
409
+ };
410
+ });
411
+ }, tt = (e, { baseUrl: t }) => {
412
+ let r = [...e.records].sort((e, t) => n(e.uri, t.uri)), i = (e, t, n, r, a) => {
413
+ let o = e.find((e) => e.title === t), [s, ...c] = n;
414
+ return o ? s ? [...e.filter((e) => e !== o), {
415
+ ...o,
416
+ contents: [...o.contents, ...i(o.contents, s, c, r, a)]
417
+ }] : o.path.split("/").length > a.split("/").length ? [...e.filter((e) => e !== o), {
418
+ ...o,
419
+ path: a,
420
+ href: r
421
+ }] : e : s ? [...e, {
422
+ contents: i([], s, c, r, a),
423
+ href: r,
424
+ path: a,
425
+ title: t
426
+ }] : [...e, {
427
+ contents: [],
428
+ href: r,
429
+ path: a,
430
+ title: t
431
+ }];
432
+ };
433
+ return r.reduce((e, n) => {
434
+ if (n.dir) return e;
435
+ let [r, ...a] = n.uri.split("/").slice(0, -1);
436
+ return r ? i(e, r, a, p(t, encodeURI(n.uri)).replace(/\/$/, ""), n.uri.replace(/\/$/, "")) : e;
437
+ }, []);
438
+ }, nt = async (e, t, { baseUrl: n, archiveOpf: r }) => {
439
+ if (r) return await Qe(r.opf, e, { baseUrl: n }) || [];
440
+ let i = et(t, e);
441
+ if (i) return i;
442
+ let a = tt(e, { baseUrl: n });
443
+ if (a.length !== 0) return a;
444
+ }, rt = ({ archive: e, baseUrl: t, archiveOpf: n }) => async (r) => {
445
+ if (r.nav) return r;
446
+ let i = await nt(e, r, {
447
+ baseUrl: t,
448
+ archiveOpf: n
449
+ });
450
+ return i ? {
451
+ ...r,
452
+ nav: { toc: i }
453
+ } : r;
454
+ }, it = (e) => e ? e.endsWith("/") ? e : `${e}/` : "", J = async (e, { baseUrl: n = "", hooks: r = {} } = {}) => {
455
+ t.log("Generating manifest from archive", e);
456
+ let i = await V(e), a = it(n), o = (t) => (t ?? []).map((t) => t({
457
+ archive: e,
458
+ baseUrl: a
459
+ })), s = [
460
+ Re({
461
+ archive: e,
462
+ baseUrl: a,
463
+ archiveOpf: i
464
+ }),
465
+ Me({
466
+ archive: e,
467
+ baseUrl: a
468
+ }),
469
+ Ae({
470
+ archive: e,
471
+ baseUrl: a
472
+ }),
473
+ Ke({
474
+ archive: e,
475
+ baseUrl: a
476
+ }),
477
+ ...o(r.content)
478
+ ], c = o(r.spine), l = [
479
+ Ve({
480
+ archive: e,
481
+ baseUrl: a,
482
+ archiveOpf: i
483
+ }),
484
+ We({
485
+ archive: e,
486
+ baseUrl: a
487
+ }),
488
+ ...o(r.presentation)
489
+ ], u = [rt({
490
+ archive: e,
491
+ baseUrl: a,
492
+ archiveOpf: i
493
+ }), ...o(r.navigation)], d = [
494
+ ...s,
495
+ ...c,
496
+ ...l,
497
+ ...u,
498
+ He()
499
+ ];
500
+ try {
501
+ let n = Pe({
502
+ archive: e,
503
+ baseUrl: a
504
+ })(), r = await d.reduce(async (e, t) => await t(await e), n);
505
+ if (t.log("Generated manifest", r), process.env.NODE_ENV === "development" && t.isEnabled()) {
506
+ let e = JSON.stringify(r, null, 2);
507
+ t.groupCollapsed(...t.getGroupArgs("Generated manifest")), t.log(`\n${e}`), t.groupEnd();
508
+ }
509
+ return r;
510
+ } catch (e) {
511
+ throw t.error(e), e;
512
+ }
513
+ }, at = (e) => {
514
+ let t = e.descendantWithPath("head")?.childrenNamed("meta").find((e) => e.attr.name === "calibre:cover");
515
+ return !!(t && t.attr.name === "calibre:cover");
516
+ }, ot = (e) => e.descendantWithPath("body")?.descendantWithPath("div")?.childrenNamed("svg")?.find((e) => e.attr.width === "100%" && e.attr.preserveAspectRatio === "none"), st = ({ archive: e, resourcePath: t }) => async (n) => {
517
+ let r = L(e, t);
518
+ if (r?.basename.endsWith(".xhtml")) {
519
+ let e = new v(typeof n.body == "string" ? n.body : await z(r));
520
+ if (at(e)) {
521
+ let t = ot(e);
522
+ return t && delete t.attr.preserveAspectRatio, {
523
+ ...n,
524
+ body: e?.toString()
525
+ };
526
+ }
527
+ }
528
+ return n;
529
+ }, ct = ({ archive: e, resourcePath: t }) => async (n) => st({
530
+ archive: e,
531
+ resourcePath: t
532
+ })(n), lt = ({ archive: e, resourcePath: t }) => async (n) => {
533
+ let r = L(e, t);
534
+ if (r?.basename.endsWith(".css")) {
535
+ let e = (typeof n.body == "string" ? n.body : await z(r)).replaceAll("-webkit-writing-mode", "writing-mode");
536
+ return {
537
+ ...n,
538
+ body: e
539
+ };
540
+ }
541
+ return n;
542
+ }, ut = async (e, t) => {
543
+ let n = await V(e);
544
+ if (n) {
545
+ let { opf: r } = n, i = U(r.manifestItems, e, () => "").find((e) => t.endsWith(e.href))?.mediaType;
546
+ if (i) return { mediaType: i };
547
+ }
548
+ return { mediaType: dt(t) };
549
+ }, dt = (e) => {
550
+ if (e.endsWith(".css")) return "text/css; charset=UTF-8";
551
+ if (e.endsWith(".jpg")) return "image/jpg";
552
+ if (e.endsWith(".xhtml")) return "application/xhtml+xml";
553
+ if (e.endsWith(".mp4")) return "video/mp4";
554
+ if (e.endsWith(".svg")) return "image/svg+xml";
555
+ }, ft = ({ archive: e, resourcePath: t }) => async (n) => {
556
+ let r = L(e, t);
557
+ if (!r) return n;
558
+ let i = await ut(e, t);
559
+ return {
560
+ ...n,
561
+ params: {
562
+ ...n.params,
563
+ ...r?.encodingFormat && { contentType: r.encodingFormat },
564
+ ...i.mediaType && { contentType: i.mediaType }
565
+ }
566
+ };
567
+ }, Y = /* @__PURE__ */ "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("."), pt = ({ archive: e, resourcePath: t }) => async (n) => {
568
+ let r = L(e, t);
569
+ if (r?.basename.endsWith(".xhtml")) {
570
+ let e = typeof n.body == "string" ? n.body : await z(r);
571
+ if (!RegExp(`<(${Y.join("|")})[\\s/>]`, "i").test(e)) return n;
572
+ let t = RegExp(`<(${Y.join("|")})(\\s[^>]*)?\\s*/>`, "gi"), i = e.replace(t, (e, t, n = "") => `<${t} ${n.trim()}></${t}>`);
573
+ return {
574
+ ...n,
575
+ body: i
576
+ };
577
+ }
578
+ return n;
579
+ }, X = async (e, n, { hooks: r = [] } = {}) => {
580
+ let i = { params: {} }, a = [
581
+ ...r.map((t) => t({
582
+ archive: e,
583
+ resourcePath: n
584
+ })),
585
+ ft({
586
+ archive: e,
587
+ resourcePath: n
588
+ }),
589
+ pt({
590
+ archive: e,
591
+ resourcePath: n
592
+ }),
593
+ lt({
594
+ archive: e,
595
+ resourcePath: n
596
+ }),
597
+ ct({
598
+ archive: e,
599
+ resourcePath: n
600
+ })
601
+ ];
602
+ try {
603
+ let r = await a.reduce(async (e, t) => await t(await e), Promise.resolve(i));
604
+ if (t.log("Generated resource", n, r), r.body !== void 0) return r;
605
+ let o = L(e, n);
606
+ if (!o) throw Error(`no file found for resourcePath:${n}`);
607
+ return {
608
+ ...r,
609
+ body: await o.blob()
610
+ };
611
+ } catch (e) {
612
+ throw t.error(e), e;
613
+ }
614
+ }, mt = class {
615
+ constructor(e) {
616
+ this.cleanArchiveAfter = e, this.state$ = new se({
617
+ status: "idle",
618
+ locks: 0
619
+ });
620
+ }
621
+ update(e) {
622
+ this.state$.next({
623
+ ...this.state$.getValue(),
624
+ ...e
625
+ });
626
+ }
627
+ get locks$() {
628
+ return this.state$.pipe(E(({ locks: e }) => e));
629
+ }
630
+ get state() {
631
+ return this.state$.getValue();
632
+ }
633
+ get isUnlocked$() {
634
+ return this.locks$.pipe(E((e) => e <= 0), ce(), me());
635
+ }
636
+ get overTTL$() {
637
+ return this.isUnlocked$.pipe(k((e) => e ? this.cleanArchiveAfter === Infinity ? b : _e(this.cleanArchiveAfter) : b));
638
+ }
639
+ }, ht = ({ getArchive: e, cleanArchiveAfter: n = 300 * 1e3 }) => {
640
+ let r = new x(), i = new x(), a = new x(), o = {};
641
+ return r.pipe(O((n) => {
642
+ let r = o[n];
643
+ if (!r || r.state.status !== "idle") return y;
644
+ let i = !1, s = (e) => {
645
+ t.debug(`Cleaning up archive with key: ${e}`);
646
+ let n = o[e];
647
+ delete o[e], i ||= (n?.state.archive?.close(), !0);
648
+ };
649
+ r.update({ status: "loading" });
650
+ let c = r.locks$, l = r.isUnlocked$, u = c.pipe(pe(), C(([e, t]) => t > e), he(!0));
651
+ return T(e(n)).pipe(A((e) => {
652
+ r.update({
653
+ archive: e,
654
+ status: "success"
655
+ });
656
+ }), S((e) => (s(n), r.update({
657
+ status: "error",
658
+ error: e
659
+ }), y)), k(() => D(u.pipe(k(() => a), k(() => l), C((e) => e)), r.overTTL$).pipe(w(), A(() => {
660
+ s(n);
661
+ }))));
662
+ }), ge(i)).subscribe(), {
663
+ access: (e) => {
664
+ let t = !1, i = o[e] ?? new mt(n);
665
+ o[e] = i, i.update({ locks: i.state.locks + 1 });
666
+ let a = () => {
667
+ t || (t = !0, i.update({ locks: i.state.locks - 1 }));
668
+ };
669
+ return r.next(e), D(i.state$.pipe(E(({ archive: e }) => e), C((e) => !!e)), i.state$.pipe(A(({ error: e }) => {
670
+ if (e) throw e;
671
+ }), ue())).pipe(w(), E((e) => ({
672
+ archive: e,
673
+ release: a
674
+ })), S((e) => {
675
+ throw a(), e;
676
+ }));
677
+ },
678
+ purge: () => {
679
+ a.next();
680
+ },
681
+ _archives: o
682
+ };
683
+ }, Z = (e) => e ? /^\d+$/.test(e) ? {
684
+ valid: !0,
685
+ value: Number.parseInt(e, 10)
686
+ } : {
687
+ valid: !1,
688
+ value: void 0
689
+ } : {
690
+ valid: !0,
691
+ value: void 0
692
+ }, gt = (e) => {
693
+ if (!e.toLowerCase().startsWith("bytes=")) return { kind: "missing" };
694
+ let t = e.slice(6).trim();
695
+ if (!t) return { kind: "invalid" };
696
+ if (t.includes(",")) return { kind: "multi" };
697
+ let n = /^(\d*)-(\d*)$/.exec(t);
698
+ if (!n) return { kind: "invalid" };
699
+ let [, r = "", i = ""] = n, a = Z(r.trim()), o = Z(i.trim());
700
+ return !a.valid || !o.valid ? { kind: "invalid" } : {
701
+ kind: "single",
702
+ start: a.value,
703
+ end: o.value
704
+ };
705
+ }, _t = (e) => {
706
+ if (e instanceof Blob) return {
707
+ size: e.size,
708
+ slice: (t, n) => {
709
+ let r = e.slice(t, n);
710
+ return {
711
+ content: r,
712
+ length: r.size
713
+ };
714
+ }
715
+ };
716
+ let t = new TextEncoder().encode(e);
717
+ return {
718
+ size: t.byteLength,
719
+ slice: (e, n) => {
720
+ let r = t.slice(e, n);
721
+ return {
722
+ content: r,
723
+ length: r.byteLength
724
+ };
725
+ }
726
+ };
727
+ }, vt = ({ body: e, contentType: t, rangeHeader: n }) => {
728
+ let r = new Headers();
729
+ 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, {
730
+ status: 200,
731
+ headers: r
732
+ });
733
+ let i = gt(n);
734
+ if (i.kind === "missing" || i.kind === "multi") return e instanceof Blob && r.set("Content-Length", String(e.size)), new Response(e, {
735
+ status: 200,
736
+ headers: r
737
+ });
738
+ let a = _t(e), o = a.size;
739
+ if (i.kind === "invalid") return new Response(null, {
740
+ status: 416,
741
+ headers: { "Content-Range": `bytes */${o}` }
742
+ });
743
+ let s = i.start, c = i.end;
744
+ 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, {
745
+ status: 416,
746
+ headers: { "Content-Range": `bytes */${o}` }
747
+ });
748
+ let l = a.slice(s, c + 1);
749
+ return r.set("Content-Length", String(l.length)), r.set("Content-Range", `bytes ${s}-${c}/${o}`), new Response(l.content, {
750
+ status: 206,
751
+ headers: r
752
+ });
753
+ }, Q = "file://", yt = /^https?:\/\//, bt = (e) => {
754
+ try {
755
+ return decodeURIComponent(e);
756
+ } catch {
757
+ return e;
758
+ }
759
+ }, xt = (e) => e.startsWith(Q) ? e.slice(Q.length) : e, St = (e) => {
760
+ let t = xt(e);
761
+ return yt.test(t) ? t : xt(bt(t));
762
+ }, $ = class {
763
+ constructor({ hooks: e, onError: t, onManifestSuccess: n, ...r }) {
764
+ this.onError = (e) => (console.error(e), new Response(String(e), { status: 500 })), this.archiveLoader = ht(r), this.hooks = e ?? {}, this.onManifestSuccess = n ?? (({ manifest: e }) => Promise.resolve(e)), this.onError = t ?? this.onError;
765
+ }
766
+ prune() {
767
+ this.archiveLoader.purge();
768
+ }
769
+ accessArchive(e) {
770
+ return this.lastAccessedKey !== void 0 && this.lastAccessedKey !== e && this.archiveLoader.purge(), this.lastAccessedKey = e, this.archiveLoader.access(e);
771
+ }
772
+ accessArchiveWithoutLock(e) {
773
+ return this.accessArchive(e).pipe(E(({ archive: e, release: t }) => (t(), e)));
774
+ }
775
+ withArchiveResponse({ key: e, getResponse: t }) {
776
+ return de(this.accessArchive(e).pipe(O(({ archive: e, release: n }) => T(t(e)).pipe(le(() => {
777
+ n();
778
+ }))), S((e) => fe(this.onError(e)))));
779
+ }
780
+ fetchManifest({ key: e, baseUrl: t }) {
781
+ return this.withArchiveResponse({
782
+ key: e,
783
+ getResponse: (e) => T(J(e, {
784
+ baseUrl: t,
785
+ hooks: this.hooks.manifest
786
+ })).pipe(k((t) => T(this.onManifestSuccess({
787
+ manifest: t,
788
+ archive: e
789
+ }))), E((e) => new Response(JSON.stringify(e), { status: 200 })))
790
+ });
791
+ }
792
+ fetchResource({ key: e, resourcePath: t, request: n }) {
793
+ return this.withArchiveResponse({
794
+ key: e,
795
+ getResponse: (e) => T(X(e, St(t), { hooks: this.hooks.resource })).pipe(E((e) => vt({
796
+ body: e.body ?? "",
797
+ contentType: e.params.contentType,
798
+ rangeHeader: n?.headers.get("range")
799
+ })))
800
+ });
801
+ }
802
+ }, Ct = class extends $ {
803
+ constructor({ getUriInfo: e, ...t }) {
804
+ super(t), this.getUriInfo = e, this.fetchEventListener = this.fetchEventListener.bind(this);
805
+ }
806
+ fetchEventListener(e) {
807
+ try {
808
+ let t = this.getUriInfo(e);
809
+ if (!t) return;
810
+ let n = i(t.baseUrl), r = e.request.url.substring(n.length + 1), [a = ""] = r.split("/"), o = i(r.substring(a.length + 1));
811
+ r.endsWith("/manifest") ? e.respondWith(this.fetchManifest({
812
+ key: a,
813
+ baseUrl: `${n}/${a}/`
814
+ })) : e.respondWith(this.fetchResource({
815
+ key: a,
816
+ resourcePath: o,
817
+ request: e.request
818
+ }));
819
+ } catch (t) {
820
+ e.respondWith(new Response(String(t), { status: 500 }));
821
+ }
822
+ }
823
+ };
824
+ //#endregion
825
+ export { Ct as ServiceWorkerStreamer, $ as Streamer, s as arrayBufferFileAccessors, o as blobFileAccessors, Oe as configure, e as createArchive, ve as createArchiveFromArrayBufferList, ye as createArchiveFromText, Te as createArchiveFromUrls, P as createUniqueXmlSafeId, N as createXmlSafeId, F as createXmlSafeIdFactory, J as generateManifestFromArchive, X as generateResourceFromArchive, L as getArchiveFileRecordByUri, R as getArchiveHasComicInfo, B as getArchiveOpfInfo, a as getUriBasePath, r as getUriBasename, Ee as isDirectoryRecord, I as isFileRecord, z as readRecordAsText, i as removeTrailingSlash, n as sortByTitleComparator };
826
+
827
+ //# sourceMappingURL=index.es.js.map