codepage-bridge-mcp 0.1.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 (97) hide show
  1. package/.claude-plugin/marketplace.json +19 -0
  2. package/.claude-plugin/plugin.json +15 -0
  3. package/.mcp.json +11 -0
  4. package/LICENSE +21 -0
  5. package/README.md +990 -0
  6. package/README_CN.md +781 -0
  7. package/dist/src/core.d.ts +56 -0
  8. package/dist/src/core.js +166 -0
  9. package/dist/src/core.js.map +1 -0
  10. package/dist/src/diff.d.ts +8 -0
  11. package/dist/src/diff.js +11 -0
  12. package/dist/src/diff.js.map +1 -0
  13. package/dist/src/encoding/codec.d.ts +5 -0
  14. package/dist/src/encoding/codec.js +75 -0
  15. package/dist/src/encoding/codec.js.map +1 -0
  16. package/dist/src/encoding/index.d.ts +3 -0
  17. package/dist/src/encoding/index.js +4 -0
  18. package/dist/src/encoding/index.js.map +1 -0
  19. package/dist/src/encoding/rules.d.ts +4 -0
  20. package/dist/src/encoding/rules.js +70 -0
  21. package/dist/src/encoding/rules.js.map +1 -0
  22. package/dist/src/encoding/types.d.ts +22 -0
  23. package/dist/src/encoding/types.js +2 -0
  24. package/dist/src/encoding/types.js.map +1 -0
  25. package/dist/src/filesystem/atomic.d.ts +6 -0
  26. package/dist/src/filesystem/atomic.js +91 -0
  27. package/dist/src/filesystem/atomic.js.map +1 -0
  28. package/dist/src/filesystem/cache.d.ts +21 -0
  29. package/dist/src/filesystem/cache.js +40 -0
  30. package/dist/src/filesystem/cache.js.map +1 -0
  31. package/dist/src/filesystem/index.d.ts +4 -0
  32. package/dist/src/filesystem/index.js +5 -0
  33. package/dist/src/filesystem/index.js.map +1 -0
  34. package/dist/src/filesystem/mutex.d.ts +5 -0
  35. package/dist/src/filesystem/mutex.js +23 -0
  36. package/dist/src/filesystem/mutex.js.map +1 -0
  37. package/dist/src/filesystem/path.d.ts +9 -0
  38. package/dist/src/filesystem/path.js +53 -0
  39. package/dist/src/filesystem/path.js.map +1 -0
  40. package/dist/src/media/errors.d.ts +14 -0
  41. package/dist/src/media/errors.js +29 -0
  42. package/dist/src/media/errors.js.map +1 -0
  43. package/dist/src/media/image.d.ts +11 -0
  44. package/dist/src/media/image.js +81 -0
  45. package/dist/src/media/image.js.map +1 -0
  46. package/dist/src/media/index.d.ts +5 -0
  47. package/dist/src/media/index.js +6 -0
  48. package/dist/src/media/index.js.map +1 -0
  49. package/dist/src/media/notebook.d.ts +47 -0
  50. package/dist/src/media/notebook.js +122 -0
  51. package/dist/src/media/notebook.js.map +1 -0
  52. package/dist/src/media/pdf.d.ts +25 -0
  53. package/dist/src/media/pdf.js +104 -0
  54. package/dist/src/media/pdf.js.map +1 -0
  55. package/dist/src/media/types.d.ts +14 -0
  56. package/dist/src/media/types.js +2 -0
  57. package/dist/src/media/types.js.map +1 -0
  58. package/dist/src/prompts.d.ts +8 -0
  59. package/dist/src/prompts.js +46 -0
  60. package/dist/src/prompts.js.map +1 -0
  61. package/dist/src/schemas.d.ts +138 -0
  62. package/dist/src/schemas.js +81 -0
  63. package/dist/src/schemas.js.map +1 -0
  64. package/dist/src/server.d.ts +159 -0
  65. package/dist/src/server.js +98 -0
  66. package/dist/src/server.js.map +1 -0
  67. package/dist/src/toolTypes.d.ts +31 -0
  68. package/dist/src/toolTypes.js +2 -0
  69. package/dist/src/toolTypes.js.map +1 -0
  70. package/dist/src/tools/edit.d.ts +3 -0
  71. package/dist/src/tools/edit.js +168 -0
  72. package/dist/src/tools/edit.js.map +1 -0
  73. package/dist/src/tools/grep.d.ts +21 -0
  74. package/dist/src/tools/grep.js +192 -0
  75. package/dist/src/tools/grep.js.map +1 -0
  76. package/dist/src/tools/read.d.ts +3 -0
  77. package/dist/src/tools/read.js +137 -0
  78. package/dist/src/tools/read.js.map +1 -0
  79. package/dist/src/tools/write.d.ts +3 -0
  80. package/dist/src/tools/write.js +80 -0
  81. package/dist/src/tools/write.js.map +1 -0
  82. package/dist/src/validation.d.ts +6 -0
  83. package/dist/src/validation.js +42 -0
  84. package/dist/src/validation.js.map +1 -0
  85. package/examples/claude-config/settings.fragment.json +17 -0
  86. package/examples/minimal-project/.encoding-rules +10 -0
  87. package/examples/minimal-project/.mcp.json +11 -0
  88. package/examples/minimal-project/CLAUDE.md +15 -0
  89. package/install/download-release-unix.sh +72 -0
  90. package/install/download-release-windows.ps1 +61 -0
  91. package/install/install-from-release-unix.sh +18 -0
  92. package/install/install-from-release-windows.ps1 +19 -0
  93. package/install/install-from-source-unix.sh +44 -0
  94. package/install/install-from-source-windows.ps1 +45 -0
  95. package/install/install-this-release-unix.sh +37 -0
  96. package/install/install-this-release-windows.ps1 +36 -0
  97. package/package.json +64 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/filesystem/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAwB/C,SAAS,MAAM,CAAC,MAAc;IAC5B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,OAAO,cAAc;IACR,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEzD,KAAK,CAAC,QAAiB;QACrB,IAAI,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;;YAC5C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,KAAa,EAAE,UAA6B,EAAE;QACrE,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3F,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QAC9D,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/F,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;QAC3D,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACtG,OAAO;YACL,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,MAAM,KAAK,CAAC,IAAI,GAAG,KAAK,KAAK,CAAC,MAAM,CAAC,MAAM;YACpD,MAAM;YACN,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC;IACJ,CAAC;CACF;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./atomic.js";
2
+ export * from "./cache.js";
3
+ export * from "./mutex.js";
4
+ export * from "./path.js";
@@ -0,0 +1,5 @@
1
+ export * from "./atomic.js";
2
+ export * from "./cache.js";
3
+ export * from "./mutex.js";
4
+ export * from "./path.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/filesystem/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare class PathMutex {
2
+ private readonly tails;
3
+ runExclusive<T>(pathKey: string, operation: () => Promise<T>): Promise<T>;
4
+ }
5
+ export declare const pathMutex: PathMutex;
@@ -0,0 +1,23 @@
1
+ export class PathMutex {
2
+ tails = new Map();
3
+ async runExclusive(pathKey, operation) {
4
+ const previous = this.tails.get(pathKey) ?? Promise.resolve();
5
+ let release;
6
+ const current = new Promise((resolve) => {
7
+ release = resolve;
8
+ });
9
+ const tail = previous.then(() => current);
10
+ this.tails.set(pathKey, tail);
11
+ await previous;
12
+ try {
13
+ return await operation();
14
+ }
15
+ finally {
16
+ release();
17
+ if (this.tails.get(pathKey) === tail)
18
+ this.tails.delete(pathKey);
19
+ }
20
+ }
21
+ }
22
+ export const pathMutex = new PathMutex();
23
+ //# sourceMappingURL=mutex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutex.js","sourceRoot":"","sources":["../../../src/filesystem/mutex.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAS;IACH,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE1D,KAAK,CAAC,YAAY,CAAI,OAAe,EAAE,SAA2B;QAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC9D,IAAI,OAAoB,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC5C,OAAO,GAAG,OAAO,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9B,MAAM,QAAQ,CAAC;QACf,IAAI,CAAC;YACH,OAAO,MAAM,SAAS,EAAE,CAAC;QAC3B,CAAC;gBAAS,CAAC;YACT,OAAO,EAAE,CAAC;YACV,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface SafePath {
2
+ root: string;
3
+ path: string;
4
+ target: string;
5
+ symbolicLink: boolean;
6
+ }
7
+ export declare function isPathWithin(candidate: string, root: string): boolean;
8
+ export declare function resolveProjectPath(root: string, input: string): string;
9
+ export declare function inspectProjectPath(root: string, input: string, allowMissing?: boolean): Promise<SafePath>;
@@ -0,0 +1,53 @@
1
+ import { lstat, readlink, realpath } from "node:fs/promises";
2
+ import path from "node:path";
3
+ function containsNul(value) {
4
+ return value.includes("\0");
5
+ }
6
+ function isUnc(value) {
7
+ return /^[/\\]{2}/.test(value) || /^\\\\[?.]\\/.test(value);
8
+ }
9
+ export function isPathWithin(candidate, root) {
10
+ const relative = path.relative(root, candidate);
11
+ return relative === "" || (relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
12
+ }
13
+ export function resolveProjectPath(root, input) {
14
+ if (containsNul(root) || containsNul(input))
15
+ throw new Error("Paths must not contain NUL bytes");
16
+ if (isUnc(root) || isUnc(input))
17
+ throw new Error("UNC and device paths are not allowed");
18
+ const absoluteRoot = path.resolve(root);
19
+ if (path.isAbsolute(input))
20
+ return path.resolve(input);
21
+ const candidate = path.resolve(absoluteRoot, input);
22
+ if (!isPathWithin(candidate, absoluteRoot))
23
+ throw new Error(`Path is outside project root: ${input}`);
24
+ return candidate;
25
+ }
26
+ export async function inspectProjectPath(root, input, allowMissing = false) {
27
+ const absoluteRoot = await realpath(path.resolve(root));
28
+ const candidate = resolveProjectPath(absoluteRoot, input);
29
+ try {
30
+ const info = await lstat(candidate);
31
+ if (info.isSymbolicLink()) {
32
+ const link = await readlink(candidate);
33
+ const target = await realpath(path.resolve(path.dirname(candidate), link));
34
+ if (!isPathWithin(target, absoluteRoot))
35
+ throw new Error(`Symbolic link escapes project root: ${input}`);
36
+ return { root: absoluteRoot, path: candidate, target, symbolicLink: true };
37
+ }
38
+ const target = await realpath(candidate);
39
+ if (!isPathWithin(target, absoluteRoot))
40
+ throw new Error(`Path escapes project root: ${input}`);
41
+ return { root: absoluteRoot, path: candidate, target, symbolicLink: false };
42
+ }
43
+ catch (error) {
44
+ const code = error.code;
45
+ if (!allowMissing || code !== "ENOENT")
46
+ throw error;
47
+ const parent = await realpath(path.dirname(candidate));
48
+ if (!isPathWithin(parent, absoluteRoot))
49
+ throw new Error(`Parent escapes project root: ${input}`);
50
+ return { root: absoluteRoot, path: candidate, target: candidate, symbolicLink: false };
51
+ }
52
+ }
53
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../../src/filesystem/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,IAAI,MAAM,WAAW,CAAC;AAS7B,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,SAAiB,EAAE,IAAY;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAChD,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;AACvH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,KAAa;IAC5D,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACjG,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACzF,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;IACtG,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY,EAAE,KAAa,EAAE,YAAY,GAAG,KAAK;IACxF,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,kBAAkB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAC3E,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,KAAK,EAAE,CAAC,CAAC;YACzG,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QAC7E,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,EAAE,CAAC,CAAC;QAChG,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;IAC9E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAI,KAA+B,CAAC,IAAI,CAAC;QACnD,IAAI,CAAC,YAAY,IAAI,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAC;QAClG,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;IACzF,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type MediaErrorCode = "UNSUPPORTED_IMAGE" | "IMAGE_PROCESSING_FAILED" | "INVALID_PDF" | "INVALID_PAGES" | "PDF_PAGES_REQUIRED" | "FILE_TOO_LARGE" | "PDF_TOOL_FAILED" | "INVALID_NOTEBOOK" | "INVALID_CELL_REFERENCE" | "CELL_NOT_FOUND";
2
+ export interface StructuredMediaError {
3
+ name: "MediaError";
4
+ code: MediaErrorCode;
5
+ message: string;
6
+ details?: Readonly<Record<string, unknown>>;
7
+ }
8
+ export declare class MediaError extends Error {
9
+ readonly code: MediaErrorCode;
10
+ readonly details?: Readonly<Record<string, unknown>>;
11
+ constructor(code: MediaErrorCode, message: string, details?: Readonly<Record<string, unknown>>, options?: ErrorOptions);
12
+ toJSON(): StructuredMediaError;
13
+ }
14
+ export declare function toStructuredMediaError(error: unknown): StructuredMediaError;
@@ -0,0 +1,29 @@
1
+ export class MediaError extends Error {
2
+ code;
3
+ details;
4
+ constructor(code, message, details, options) {
5
+ super(message, options);
6
+ this.name = "MediaError";
7
+ this.code = code;
8
+ if (details !== undefined)
9
+ this.details = details;
10
+ }
11
+ toJSON() {
12
+ return {
13
+ name: "MediaError",
14
+ code: this.code,
15
+ message: this.message,
16
+ ...(this.details === undefined ? {} : { details: this.details }),
17
+ };
18
+ }
19
+ }
20
+ export function toStructuredMediaError(error) {
21
+ if (error instanceof MediaError)
22
+ return error.toJSON();
23
+ return {
24
+ name: "MediaError",
25
+ code: "IMAGE_PROCESSING_FAILED",
26
+ message: error instanceof Error ? error.message : String(error),
27
+ };
28
+ }
29
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/media/errors.ts"],"names":[],"mappings":"AAmBA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAiB;IACrB,OAAO,CAAqC;IAErD,YAAY,IAAoB,EAAE,OAAe,EAAE,OAA2C,EAAE,OAAsB;QACpH,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACpD,CAAC;IAED,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;SACjE,CAAC;IACJ,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,IAAI,KAAK,YAAY,UAAU;QAAE,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;IACvD,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,yBAAyB;QAC/B,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;KAChE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { BinaryFileReader, McpImageBlock } from "./types.js";
2
+ export type SupportedImageMime = McpImageBlock["mimeType"];
3
+ export interface ImageTransformOptions {
4
+ maxWidth?: number;
5
+ maxHeight?: number;
6
+ quality?: number;
7
+ }
8
+ export declare function detectImageMime(bytes: Uint8Array): SupportedImageMime | undefined;
9
+ export declare function imageBytesToBlock(bytes: Uint8Array, mimeType?: SupportedImageMime): McpImageBlock;
10
+ export declare function transformImage(bytes: Uint8Array, options?: ImageTransformOptions): Promise<McpImageBlock>;
11
+ export declare function readImage(path: string, options?: ImageTransformOptions, files?: BinaryFileReader): Promise<McpImageBlock>;
@@ -0,0 +1,81 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import sharp from "sharp";
3
+ import { MediaError } from "./errors.js";
4
+ const defaultFileReader = { readFile };
5
+ function hasBytes(bytes, offset, expected) {
6
+ return expected.every((value, index) => bytes[offset + index] === value);
7
+ }
8
+ function hasAscii(bytes, offset, expected) {
9
+ return [...expected].every((character, index) => bytes[offset + index] === character.charCodeAt(0));
10
+ }
11
+ export function detectImageMime(bytes) {
12
+ if (hasBytes(bytes, 0, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))
13
+ return "image/png";
14
+ if (hasBytes(bytes, 0, [0xff, 0xd8, 0xff]))
15
+ return "image/jpeg";
16
+ if (hasAscii(bytes, 0, "GIF87a") || hasAscii(bytes, 0, "GIF89a"))
17
+ return "image/gif";
18
+ if (hasAscii(bytes, 0, "RIFF") && hasAscii(bytes, 8, "WEBP"))
19
+ return "image/webp";
20
+ return undefined;
21
+ }
22
+ function validateOptions(options) {
23
+ for (const [name, value] of [["maxWidth", options.maxWidth], ["maxHeight", options.maxHeight]]) {
24
+ if (value !== undefined && (!Number.isInteger(value) || value <= 0)) {
25
+ throw new MediaError("IMAGE_PROCESSING_FAILED", `${name} must be a positive integer`, { [name]: value });
26
+ }
27
+ }
28
+ if (options.quality !== undefined && (!Number.isInteger(options.quality) || options.quality < 1 || options.quality > 100)) {
29
+ throw new MediaError("IMAGE_PROCESSING_FAILED", "quality must be an integer from 1 to 100", { quality: options.quality });
30
+ }
31
+ }
32
+ export function imageBytesToBlock(bytes, mimeType) {
33
+ const detectedMime = detectImageMime(bytes);
34
+ if (detectedMime === undefined || (mimeType !== undefined && detectedMime !== mimeType)) {
35
+ throw new MediaError("UNSUPPORTED_IMAGE", "Image content is not a supported PNG, JPEG, GIF, or WebP file");
36
+ }
37
+ return { type: "image", data: Buffer.from(bytes).toString("base64"), mimeType: detectedMime };
38
+ }
39
+ export async function transformImage(bytes, options = {}) {
40
+ validateOptions(options);
41
+ const mimeType = detectImageMime(bytes);
42
+ if (mimeType === undefined) {
43
+ throw new MediaError("UNSUPPORTED_IMAGE", "Image content is not a supported PNG, JPEG, GIF, or WebP file");
44
+ }
45
+ try {
46
+ let pipeline = sharp(bytes, { animated: mimeType === "image/gif" });
47
+ if (options.maxWidth !== undefined || options.maxHeight !== undefined) {
48
+ pipeline = pipeline.resize({
49
+ width: options.maxWidth,
50
+ height: options.maxHeight,
51
+ fit: "inside",
52
+ withoutEnlargement: true,
53
+ });
54
+ }
55
+ const quality = options.quality ?? 80;
56
+ switch (mimeType) {
57
+ case "image/jpeg":
58
+ pipeline = pipeline.jpeg({ quality, mozjpeg: true });
59
+ break;
60
+ case "image/png":
61
+ pipeline = pipeline.png({ compressionLevel: 9, quality });
62
+ break;
63
+ case "image/gif":
64
+ pipeline = pipeline.gif({ effort: 7 });
65
+ break;
66
+ case "image/webp":
67
+ pipeline = pipeline.webp({ quality, effort: 5 });
68
+ break;
69
+ }
70
+ return imageBytesToBlock(await pipeline.toBuffer(), mimeType);
71
+ }
72
+ catch (error) {
73
+ if (error instanceof MediaError)
74
+ throw error;
75
+ throw new MediaError("IMAGE_PROCESSING_FAILED", "Unable to process image", { mimeType }, { cause: error });
76
+ }
77
+ }
78
+ export async function readImage(path, options = {}, files = defaultFileReader) {
79
+ return transformImage(await files.readFile(path), options);
80
+ }
81
+ //# sourceMappingURL=image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../../../src/media/image.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from "./errors.js";
2
+ export * from "./image.js";
3
+ export * from "./notebook.js";
4
+ export * from "./pdf.js";
5
+ export * from "./types.js";
@@ -0,0 +1,6 @@
1
+ export * from "./errors.js";
2
+ export * from "./image.js";
3
+ export * from "./notebook.js";
4
+ export * from "./pdf.js";
5
+ export * from "./types.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/media/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { DecodeBytes, McpContentBlock } from "./types.js";
2
+ export type NotebookCellType = "code" | "markdown" | "raw";
3
+ export interface NotebookOutput {
4
+ output_type?: string;
5
+ name?: string;
6
+ text?: string | string[];
7
+ data?: Record<string, unknown>;
8
+ ename?: string;
9
+ evalue?: string;
10
+ traceback?: string[];
11
+ [key: string]: unknown;
12
+ }
13
+ export interface NotebookCell {
14
+ id?: string;
15
+ cell_type: NotebookCellType;
16
+ source: string | string[];
17
+ metadata?: Record<string, unknown>;
18
+ outputs?: NotebookOutput[];
19
+ execution_count?: number | null;
20
+ [key: string]: unknown;
21
+ }
22
+ export interface NotebookDocument {
23
+ cells: NotebookCell[];
24
+ metadata?: Record<string, unknown>;
25
+ nbformat?: number;
26
+ nbformat_minor?: number;
27
+ [key: string]: unknown;
28
+ }
29
+ export interface ParsedNotebookCell {
30
+ id: string;
31
+ cellType: NotebookCellType;
32
+ content: McpContentBlock[];
33
+ }
34
+ export interface ReadNotebookOptions {
35
+ cell?: string;
36
+ outputLimit?: number;
37
+ }
38
+ export interface NotebookReadDependencies {
39
+ readFile(path: string): Promise<Uint8Array>;
40
+ decode: DecodeBytes;
41
+ }
42
+ export declare function parseNotebook(text: string): NotebookDocument;
43
+ export declare function parseCellReference(reference: string): number;
44
+ export declare function mapNotebookCell(cell: NotebookCell, index: number, outputLimit?: number): ParsedNotebookCell;
45
+ export declare function mapNotebook(notebook: NotebookDocument, options?: ReadNotebookOptions): ParsedNotebookCell[];
46
+ export declare function readNotebook(path: string, options: ReadNotebookOptions, dependencies: NotebookReadDependencies): Promise<ParsedNotebookCell[]>;
47
+ export declare function createNotebookReader(decode: DecodeBytes): (path: string, options?: ReadNotebookOptions) => Promise<ParsedNotebookCell[]>;
@@ -0,0 +1,122 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { imageBytesToBlock } from "./image.js";
3
+ import { MediaError } from "./errors.js";
4
+ function joinText(value) {
5
+ if (typeof value === "string")
6
+ return value;
7
+ if (Array.isArray(value) && value.every((part) => typeof part === "string"))
8
+ return value.join("");
9
+ return undefined;
10
+ }
11
+ function textBlock(text) { return { type: "text", text }; }
12
+ function imageBlock(value, mimeType) {
13
+ const data = joinText(value)?.replace(/\s/g, "");
14
+ if (data === undefined)
15
+ return undefined;
16
+ if (!/^[A-Za-z0-9+/]*={0,2}$/.test(data) || data.length % 4 !== 0) {
17
+ throw new MediaError("INVALID_NOTEBOOK", `Notebook contains invalid ${mimeType} base64 data`);
18
+ }
19
+ let bytes;
20
+ try {
21
+ bytes = Buffer.from(data, "base64");
22
+ }
23
+ catch (error) {
24
+ throw new MediaError("INVALID_NOTEBOOK", `Notebook contains invalid ${mimeType} base64 data`, undefined, { cause: error });
25
+ }
26
+ if (bytes.length === 0 || bytes.toString("base64").replace(/=+$/, "") !== data.replace(/=+$/, "")) {
27
+ throw new MediaError("INVALID_NOTEBOOK", `Notebook contains invalid ${mimeType} base64 data`);
28
+ }
29
+ try {
30
+ return imageBytesToBlock(bytes, mimeType);
31
+ }
32
+ catch (error) {
33
+ throw new MediaError("INVALID_NOTEBOOK", `Notebook ${mimeType} data does not match its MIME type`, undefined, { cause: error });
34
+ }
35
+ }
36
+ function limitedOutput(text, cellId, limit) {
37
+ if (text.length <= limit)
38
+ return textBlock(text);
39
+ return textBlock(`Output omitted (${text.length} characters). Read ${cellId} directly to inspect this large output.`);
40
+ }
41
+ function mapOutput(output, cellId, limit) {
42
+ const blocks = [];
43
+ const directText = joinText(output.text);
44
+ if (directText !== undefined)
45
+ blocks.push(limitedOutput(directText, cellId, limit));
46
+ const plainText = joinText(output.data?.["text/plain"]);
47
+ if (plainText !== undefined)
48
+ blocks.push(limitedOutput(plainText, cellId, limit));
49
+ const png = imageBlock(output.data?.["image/png"], "image/png");
50
+ if (png !== undefined)
51
+ blocks.push(png);
52
+ const jpeg = imageBlock(output.data?.["image/jpeg"] ?? output.data?.["image/jpg"], "image/jpeg");
53
+ if (jpeg !== undefined)
54
+ blocks.push(jpeg);
55
+ if (output.output_type === "error") {
56
+ const errorText = output.traceback?.join("\n") ?? [output.ename, output.evalue].filter(Boolean).join(": ");
57
+ if (errorText.length > 0)
58
+ blocks.push(limitedOutput(errorText, cellId, limit));
59
+ }
60
+ return blocks;
61
+ }
62
+ function isNotebookCell(value) {
63
+ if (typeof value !== "object" || value === null)
64
+ return false;
65
+ const cell = value;
66
+ return (cell.cell_type === "code" || cell.cell_type === "markdown" || cell.cell_type === "raw")
67
+ && (typeof cell.source === "string" || (Array.isArray(cell.source) && cell.source.every((part) => typeof part === "string")));
68
+ }
69
+ export function parseNotebook(text) {
70
+ try {
71
+ const value = JSON.parse(text);
72
+ if (typeof value !== "object" || value === null || !Array.isArray(value.cells)
73
+ || !value.cells.every(isNotebookCell)) {
74
+ throw new Error("cells must be an array of valid notebook cells");
75
+ }
76
+ return value;
77
+ }
78
+ catch (error) {
79
+ throw new MediaError("INVALID_NOTEBOOK", "Unable to parse notebook JSON", undefined, { cause: error });
80
+ }
81
+ }
82
+ export function parseCellReference(reference) {
83
+ const match = /^cell-(0|[1-9]\d*)$/i.exec(reference.trim());
84
+ if (match?.[1] === undefined) {
85
+ throw new MediaError("INVALID_CELL_REFERENCE", "Cell references must use zero-based cell-N", { cell: reference });
86
+ }
87
+ return Number(match[1]);
88
+ }
89
+ export function mapNotebookCell(cell, index, outputLimit = 10_000) {
90
+ const id = `cell-${index}`;
91
+ const source = joinText(cell.source) ?? "";
92
+ const content = source.length === 0 ? [] : [textBlock(source)];
93
+ for (const output of cell.outputs ?? [])
94
+ content.push(...mapOutput(output, id, outputLimit));
95
+ return { id, cellType: cell.cell_type, content };
96
+ }
97
+ export function mapNotebook(notebook, options = {}) {
98
+ const outputLimit = options.outputLimit ?? 10_000;
99
+ if (!Number.isInteger(outputLimit) || outputLimit < 1) {
100
+ throw new MediaError("INVALID_NOTEBOOK", "outputLimit must be a positive integer", { outputLimit });
101
+ }
102
+ if (options.cell === undefined) {
103
+ return notebook.cells.map((cell, index) => mapNotebookCell(cell, index, outputLimit));
104
+ }
105
+ const index = parseCellReference(options.cell);
106
+ const cell = notebook.cells[index];
107
+ if (cell === undefined) {
108
+ throw new MediaError("CELL_NOT_FOUND", `Notebook does not contain ${options.cell}`, {
109
+ cell: options.cell, cellCount: notebook.cells.length,
110
+ });
111
+ }
112
+ const selectedCellLimit = options.outputLimit ?? Number.MAX_SAFE_INTEGER;
113
+ return [mapNotebookCell(cell, index, selectedCellLimit)];
114
+ }
115
+ export async function readNotebook(path, options, dependencies) {
116
+ const bytes = await dependencies.readFile(path);
117
+ return mapNotebook(parseNotebook(dependencies.decode(bytes)), options);
118
+ }
119
+ export function createNotebookReader(decode) {
120
+ return (path, options = {}) => readNotebook(path, options, { readFile, decode });
121
+ }
122
+ //# sourceMappingURL=notebook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notebook.js","sourceRoot":"","sources":["../../../src/media/notebook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { McpImageBlock } from "./types.js";
2
+ export declare const MAX_PDF_PAGES = 20;
3
+ export declare const MAX_WHOLE_PDF_BYTES: number;
4
+ export declare const MAX_EXTRACT_PDF_BYTES: number;
5
+ export interface CommandResult {
6
+ stdout: Uint8Array;
7
+ stderr: Uint8Array;
8
+ }
9
+ export interface PdfDependencies {
10
+ stat(path: string): Promise<{
11
+ size: number;
12
+ }>;
13
+ readFile(path: string): Promise<Uint8Array>;
14
+ makeTempDirectory(prefix: string): Promise<string>;
15
+ removeDirectory(path: string): Promise<void>;
16
+ runCommand(command: string, args: readonly string[]): Promise<CommandResult>;
17
+ }
18
+ export interface ReadPdfOptions {
19
+ pages?: string;
20
+ quality?: number;
21
+ }
22
+ export declare function parsePdfPageCount(output: Uint8Array | string): number;
23
+ export declare function parsePdfPages(expression: string, pageCount: number, maximum?: number): number[];
24
+ export declare function getPdfPageCount(path: string, dependencies?: PdfDependencies): Promise<number>;
25
+ export declare function readPdf(path: string, options?: ReadPdfOptions, dependencies?: PdfDependencies): Promise<McpImageBlock[]>;
@@ -0,0 +1,104 @@
1
+ import { execFile } from "node:child_process";
2
+ import { mkdtemp, readFile, rm, stat } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { promisify } from "node:util";
6
+ import { MediaError } from "./errors.js";
7
+ import { imageBytesToBlock } from "./image.js";
8
+ const execFileAsync = promisify(execFile);
9
+ export const MAX_PDF_PAGES = 20;
10
+ export const MAX_WHOLE_PDF_BYTES = 20 * 1024 * 1024;
11
+ export const MAX_EXTRACT_PDF_BYTES = 100 * 1024 * 1024;
12
+ const defaultDependencies = {
13
+ stat,
14
+ readFile,
15
+ makeTempDirectory: (prefix) => mkdtemp(join(tmpdir(), prefix)),
16
+ removeDirectory: (path) => rm(path, { recursive: true, force: true }),
17
+ async runCommand(command, args) {
18
+ const result = await execFileAsync(command, [...args], { encoding: "buffer", maxBuffer: 10 * 1024 * 1024 });
19
+ return { stdout: result.stdout, stderr: result.stderr };
20
+ },
21
+ };
22
+ function ascii(bytes) {
23
+ let result = "";
24
+ for (const byte of bytes)
25
+ result += byte <= 0x7f ? String.fromCharCode(byte) : "?";
26
+ return result;
27
+ }
28
+ export function parsePdfPageCount(output) {
29
+ const text = typeof output === "string" ? output : ascii(output);
30
+ const match = /^Pages:\s*(\d+)\s*$/im.exec(text);
31
+ const count = match?.[1] === undefined ? Number.NaN : Number(match[1]);
32
+ if (!Number.isSafeInteger(count) || count < 1) {
33
+ throw new MediaError("INVALID_PDF", "pdfinfo did not report a valid page count");
34
+ }
35
+ return count;
36
+ }
37
+ export function parsePdfPages(expression, pageCount, maximum = MAX_PDF_PAGES) {
38
+ const value = expression.trim();
39
+ const match = /^(\d+)(?:-(\d*))?$/.exec(value);
40
+ if (match?.[1] === undefined) {
41
+ throw new MediaError("INVALID_PAGES", "pages must use N, N-M, or N- syntax", { pages: expression });
42
+ }
43
+ const first = Number(match[1]);
44
+ const hasRange = value.includes("-");
45
+ const last = hasRange ? (match[2] === "" ? pageCount : Number(match[2])) : first;
46
+ if (!Number.isSafeInteger(first) || !Number.isSafeInteger(last) || first < 1 || last < first || last > pageCount) {
47
+ throw new MediaError("INVALID_PAGES", `pages must be within 1-${pageCount}`, { pages: expression, pageCount });
48
+ }
49
+ const count = last - first + 1;
50
+ if (count > maximum) {
51
+ throw new MediaError("INVALID_PAGES", `At most ${maximum} pages may be extracted`, { pages: expression, count, maximum });
52
+ }
53
+ return Array.from({ length: count }, (_, index) => first + index);
54
+ }
55
+ async function runPdfTool(dependencies, command, args) {
56
+ try {
57
+ return await dependencies.runCommand(command, args);
58
+ }
59
+ catch (error) {
60
+ throw new MediaError("PDF_TOOL_FAILED", `${command} failed`, { command, args: [...args] }, { cause: error });
61
+ }
62
+ }
63
+ export async function getPdfPageCount(path, dependencies = defaultDependencies) {
64
+ return parsePdfPageCount((await runPdfTool(dependencies, "pdfinfo", [path])).stdout);
65
+ }
66
+ export async function readPdf(path, options = {}, dependencies = defaultDependencies) {
67
+ const file = await dependencies.stat(path);
68
+ const limit = options.pages === undefined ? MAX_WHOLE_PDF_BYTES : MAX_EXTRACT_PDF_BYTES;
69
+ if (file.size > limit) {
70
+ throw new MediaError("FILE_TOO_LARGE", `PDF exceeds the ${limit / 1024 / 1024} MB limit`, {
71
+ size: file.size, limit, mode: options.pages === undefined ? "whole" : "extract",
72
+ });
73
+ }
74
+ const pageCount = await getPdfPageCount(path, dependencies);
75
+ if (options.pages === undefined && pageCount > 10) {
76
+ throw new MediaError("PDF_PAGES_REQUIRED", "PDFs over 10 pages require the pages option", { pageCount });
77
+ }
78
+ const pages = options.pages === undefined
79
+ ? Array.from({ length: pageCount }, (_, index) => index + 1)
80
+ : parsePdfPages(options.pages, pageCount);
81
+ const quality = options.quality ?? 85;
82
+ if (!Number.isInteger(quality) || quality < 1 || quality > 100) {
83
+ throw new MediaError("INVALID_PAGES", "quality must be an integer from 1 to 100", { quality });
84
+ }
85
+ let temporaryDirectory;
86
+ try {
87
+ temporaryDirectory = await dependencies.makeTempDirectory("mcp-pdf-");
88
+ const blocks = [];
89
+ for (const page of pages) {
90
+ const prefix = join(temporaryDirectory, `page-${String(page).padStart(5, "0")}`);
91
+ await runPdfTool(dependencies, "pdftoppm", [
92
+ "-f", String(page), "-l", String(page), "-singlefile", "-jpeg",
93
+ "-jpegopt", `quality=${quality}`, path, prefix,
94
+ ]);
95
+ blocks.push(imageBytesToBlock(await dependencies.readFile(`${prefix}.jpg`), "image/jpeg"));
96
+ }
97
+ return blocks;
98
+ }
99
+ finally {
100
+ if (temporaryDirectory !== undefined)
101
+ await dependencies.removeDirectory(temporaryDirectory);
102
+ }
103
+ }
104
+ //# sourceMappingURL=pdf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf.js","sourceRoot":"","sources":["../../../src/media/pdf.ts"],"names":[],"mappings":"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"}