rapier-html 1.2.46 → 1.2.48

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.
package/BUILD.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "package": "rapier-html",
3
- "version": "1.2.46",
3
+ "version": "1.2.48",
4
4
  "path": "dist/rapier.html",
5
- "bytes": 5934524,
6
- "sha256": "f517fef79e14aa898b4bfaf519c679032f6df7538128892e6374280cb9511432",
7
- "builtAt": "2026-10-27T10:37:55.443Z",
5
+ "bytes": 5967960,
6
+ "sha256": "be629bc50b6a201e8889ce4c2768ee350015e8dfbafe7cfe880a6a6113865595",
7
+ "builtAt": "2026-10-28T02:28:38.799Z",
8
8
  "node": "v22.23.4",
9
9
  "canonical": true,
10
10
  "packing": "zopfli",
package/README.md CHANGED
@@ -7,8 +7,8 @@ Turn Markdown into one offline HTML file that contains the full Rapier editor.
7
7
  <img src="https://raw.githubusercontent.com/jackskip22/rapier-plugins/main/assets/write-390-light.png" alt="The Rapier editor on a phone: a launch plan with an agent's change marked" width="320">
8
8
  </picture>
9
9
 
10
- Try it: `npx rapier-html@1.2.46 notes.md`, then open `notes.rapier.html` in any browser.
11
- Install: `npm install rapier-html@1.2.46`.
10
+ Try it: `npx rapier-html@1.2.48 notes.md`, then open `notes.rapier.html` in any browser.
11
+ Install: `npm install rapier-html@1.2.48`.
12
12
 
13
13
  It opens on a phone or computer, with no account. People read, edit, draw and paint; agents hand over documents, show
14
14
  what changed and get the edited copy back.
@@ -21,19 +21,20 @@ The file needs no hosted workspace.
21
21
  - Where scripts don't run (a mail preview, a strict viewer), the file shows the document's words.
22
22
  - `--return` adds a one-use Send back address from the agent door.
23
23
  - `--view draw` opens on Draw. `--compare original.md` opens the edit with its diff; `--by <name>` attributes it.
24
+ - `--editor page.html` uses another Rapier page as the editor, such as one the agent door exported.
24
25
  - `writePage(text, name)` makes the page in one call; `unwrap` gives the document back, exactly.
25
26
 
26
27
  Needs Node 22 or newer.
27
28
 
28
29
  ```sh
29
- npx -- rapier-html@1.2.46 notes.md # the editor, notes.md inside it, written beside the file
30
- npx -- rapier-html@1.2.46 notes.md --view draw # opens on Draw: sketch and paint, the document behind it
31
- npx -- rapier-html@1.2.46 notes.md --include draw,math # carries Draw and Math (default: what the document needs)
32
- npx -- rapier-html@1.2.46 notes.md --drawing sketch.svg # carries a drawing, opened on Draw over the document
33
- npx -- rapier-html@1.2.46 revised.md --compare original.md # opens showing what changed
34
- npx -- rapier-html@1.2.46 notes.md --return "$RETURN_URL" --return-expires-at "$RETURN_EXPIRES_AT" # Send back
35
- npx -- rapier-html@1.2.46 notes.md out.html # a named output
36
- npm install rapier-html@1.2.46 # as a library: writePage, unwrap
30
+ npx -- rapier-html@1.2.48 notes.md # the editor, notes.md inside it, written beside the file
31
+ npx -- rapier-html@1.2.48 notes.md --view draw # opens on Draw: sketch and paint, the document behind it
32
+ npx -- rapier-html@1.2.48 notes.md --include draw,math # carries Draw and Math (default: what the document needs)
33
+ npx -- rapier-html@1.2.48 notes.md --drawing sketch.svg # carries a drawing, opened on Draw over the document
34
+ npx -- rapier-html@1.2.48 revised.md --compare original.md # opens showing what changed
35
+ npx -- rapier-html@1.2.48 notes.md --return <return_url> --return-expires-at <return_expires_at> # Send back
36
+ npx -- rapier-html@1.2.48 notes.md out.html # a named output
37
+ npm install rapier-html@1.2.48 # as a library: writePage, unwrap
37
38
  ```
38
39
 
39
40
  The first `--` is for npm, so `--help` reaches the command. It never overwrites a file.
@@ -52,7 +53,7 @@ Will markers in the Markdown (`keep`, `append`, `edit`) control what agents may
52
53
  ## Send an edited document back
53
54
 
54
55
  1. Call `show {target:"return"}` on the Rapier agent door for the document's workspace.
55
- 2. Pass its `return_url` and `return_expires_at` as `--return "$RETURN_URL" --return-expires-at "$RETURN_EXPIRES_AT"`,
56
+ 2. Pass its `return_url` and `return_expires_at` as `--return <return_url> --return-expires-at <return_expires_at>`,
56
57
  or `wrap(..., {return: return_url, return_expires_at})`. Only `https://mcp.rapier.website/return/…` is accepted.
57
58
  Share then shows Send back; a page without an address doesn't.
58
59
  3. The person edits offline and taps Send back. The source and filename go once; the page shows acceptance or
@@ -56,11 +56,19 @@ export function documentTrailer(text, options) {
56
56
  export function writeDocument(text, options) {
57
57
  return text + documentTrailer(text, options);
58
58
  }
59
+ function trailerOpening(source) {
60
+ const marker = '<!-- rapier-carried/1', at = source.lastIndexOf(marker);
61
+ if (at < 0) return null;
62
+ if (source.slice(at - 2, at + marker.length + 1) === OPEN) return {start: at - 2, body: at + marker.length + 1};
63
+ const before = /(?:\r\n|\r|\n){2}$/.exec(source.slice(Math.max(0, at - 4), at));
64
+ const after = /^(?:\r\n|\r|\n)/.exec(source.slice(at + marker.length, at + marker.length + 2));
65
+ return before && after ? {start: at - before[0].length, body: at + marker.length + after[0].length} : null;
66
+ }
59
67
  function unfinishedTrailer(source) {
60
- if (!source.includes(OPEN)) return false;
61
- const at = source.lastIndexOf(OPEN);
68
+ const opening = trailerOpening(source);
69
+ if (!opening) return false;
62
70
  let fence = null;
63
- for (const line of source.slice(0, at).split('\n')) {
71
+ for (const line of source.slice(0, opening.start).split(/\r\n?|\n/)) {
64
72
  const found = /^ {0,3}(`{3,}|~{3,})/.exec(line);
65
73
  if (!found) continue;
66
74
  if (!fence) fence = found[1];
@@ -69,17 +77,18 @@ function unfinishedTrailer(source) {
69
77
  return !fence;
70
78
  }
71
79
  export function readDocument(source) {
72
- if (!source.endsWith(CLOSE)) {
80
+ const closing = /(?:\r\n|\r|\n)-->(?:\r\n|\r|\n)$/.exec(source.slice(-7));
81
+ if (!closing) {
73
82
  if (unfinishedTrailer(source)) throw fault('unfinished document metadata');
74
83
  return {text: source, ledger: null, authorship: null};
75
84
  }
76
- const at = source.lastIndexOf(OPEN);
77
- if (at < 0) return {text: source, ledger: null, authorship: null};
85
+ const opening = trailerOpening(source);
86
+ if (!opening) return {text: source, ledger: null, authorship: null};
78
87
  let parts;
79
- try { parts = JSON.parse(source.slice(at + OPEN.length, -CLOSE.length)); }
88
+ try { parts = JSON.parse(source.slice(opening.body, -closing[0].length)); }
80
89
  catch (_) { throw fault('invalid document metadata'); }
81
90
  if (!parts || Object.keys(parts).length !== 2 || !Object.hasOwn(parts, 'ledger') || !Object.hasOwn(parts, 'authorship')) throw fault('invalid document parts');
82
- const text = source.slice(0, at);
91
+ const text = source.slice(0, opening.start);
83
92
  return {text, ...validateParts(text, parts)};
84
93
  }
85
94
 
@@ -5,7 +5,7 @@ export function separate(c, endA = c.before.length, endB = c.after.length) {
5
5
  const {before, after, safe, raw, spend} = c;
6
6
  if (!raw) for (let i = c.result.length - 1; i > 0; i--) {
7
7
  const p = c.result[i - 1], q = c.result[i], side = p[0][0] === p[0][1] ? 1 : p[1][0] === p[1][1] ? 0 : -1, text = side ? after : before;
8
- if (side >= 0 && !/\S/.test(text.slice(...p[side]))) {
8
+ if (!c.evidence && side >= 0 && !/\S/.test(text.slice(...p[side]))) {
9
9
  let n = 0;
10
10
  while (p[0][1] + n < q[0][0] && text[p[side][0] + n] === text[p[side][1] + n] && spend()) n++;
11
11
  if (p[0][1] + n === q[0][0] && p.slice(0, 2).every((span, k) => safe(k ? after : before, span[0] + n) && safe(k ? after : before, span[1] + n)))
@@ -20,7 +20,7 @@ export function separate(c, endA = c.before.length, endB = c.after.length) {
20
20
  keep[3][0] = x[0] === x[1] ? 2 : y[0] === y[1] ? 0 : 1;
21
21
  c.result.splice(i - 1, 2, [x, y, false, keep[3]]);
22
22
  }
23
- if (!raw) for (let i = 0; i < c.result.length; i++) {
23
+ if (!raw && !c.evidence) for (let i = 0; i < c.result.length; i++) {
24
24
  const p = c.result[i], q = c.result[i + 1], side = p[0][0] === p[0][1] ? 1 : p[1][0] === p[1][1] ? 0 : -1;
25
25
  if (side < 0 || p[2]) continue;
26
26
  const text = side ? after : before;
@@ -18,12 +18,19 @@ function parserFor(parser) {
18
18
  return md;
19
19
  }
20
20
 
21
+ const sourceMetadataFields = ['license', 'origin'];
22
+ function sourceMetadata(value) {
23
+ return Object.fromEntries(sourceMetadataFields.filter(field => value[field] != null).map(field => [field, value[field]]));
24
+ }
25
+
21
26
  function faceOf(value) {
22
27
  const family = normalizeFontFamily(value?.family), style = value?.style || 'normal';
23
28
  const weight = value?.weight ?? 400, stretch = value?.stretch ?? 100;
24
29
  if (!family || !['normal', 'italic', 'oblique'].includes(style) || !Number.isFinite(weight) || weight < 1 || weight > 1000 ||
25
30
  !Number.isFinite(stretch) || stretch <= 0 || stretch > 1000) return null;
26
31
  const result = {family, style, weight, stretch};
32
+ if (value.subsetted != null && typeof value.subsetted !== 'boolean') return null;
33
+ if (value.subsetted === true || value.subset?.subset === true) result.subsetted = true;
27
34
  if (value.weightRange != null) {
28
35
  const range = value.weightRange;
29
36
  if (!Array.isArray(range) || range.length !== 2 || range.some(number => !Number.isFinite(number) || number < 1 || number > 1000) || range[0] > range[1]) return null;
@@ -44,6 +51,25 @@ function faceOf(value) {
44
51
  if (!/^f[0-9a-f]{24}$/.test(value.sourceId)) return null;
45
52
  result.sourceId = value.sourceId;
46
53
  }
54
+ if (value.license != null) {
55
+ const license = value.license;
56
+ if (!license || !['OFL-1.0', 'OFL-1.1', 'Apache-2.0', 'Ubuntu-font-1.0'].includes(license.id) ||
57
+ typeof license.text !== 'string' || !license.text.trim() || new TextEncoder().encode(license.text).length > 128 * 1024 ||
58
+ typeof license.url !== 'string' || typeof license.sri !== 'string' || !/^sha384-[A-Za-z0-9+/]{64}$/.test(license.sri)) return null;
59
+ let url;
60
+ try { url = new URL(license.url); } catch (_) { return null; }
61
+ if (url.protocol !== 'https:' || url.username || url.password || url.search || url.hash) return null;
62
+ result.license = {id: license.id, text: license.text, url: license.url, sri: license.sri};
63
+ }
64
+ if (value.origin != null) {
65
+ const origin = value.origin;
66
+ if (!result.license || result.subsetted || !origin || origin.catalog !== 'google-fonts' ||
67
+ typeof origin.family !== 'string' || !/^[a-z0-9][a-z0-9-]{0,95}$/.test(origin.family) ||
68
+ typeof origin.version !== 'string' || !origin.version || origin.version.length > 128 || /[\u0000-\u001f\u007f]/u.test(origin.version) ||
69
+ typeof origin.file !== 'string' || !/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}\.woff2$/.test(origin.file) ||
70
+ typeof origin.sri !== 'string' || !/^sha384-[A-Za-z0-9+/]{64}$/.test(origin.sri)) return null;
71
+ result.origin = {catalog: origin.catalog, family: origin.family, version: origin.version, file: origin.file, sri: origin.sri};
72
+ }
47
73
  return result;
48
74
  }
49
75
 
@@ -63,7 +89,7 @@ export function readFontAssets(markdown, parser) {
63
89
  else if (source[at] === '\n') starts.push(at + 1);
64
90
  }
65
91
  md.block.parse(frame.body.replace(/\r\n?/g, '\n').replace(/\0/g, '\ufffd'), md, env, tokens);
66
- const labels = new Set(), faces = new Set();
92
+ const labels = new Set(), faces = new Set(), metadata = new Map(), faceMetadata = new Map(), subsetUrls = new Set();
67
93
  for (const token of tokens) {
68
94
  if (token.type !== 'reference_definition' || !token.map) continue;
69
95
  const id = token.meta.label, first = !labels.has(id);
@@ -79,18 +105,33 @@ export function readFontAssets(markdown, parser) {
79
105
  if (!match) continue;
80
106
  const label = md.utils.unescapeAll(match[1]);
81
107
  if (!data) { refused.push({name: label, reason: 'The font reference must contain an embedded font.'}); continue; }
82
- let metadata = {family: label.slice(5)};
108
+ let definitionMetadata = {family: label.slice(5)};
83
109
  if (definition.title) {
84
- try { metadata = JSON.parse(definition.title); }
110
+ try { definitionMetadata = JSON.parse(definition.title); }
85
111
  catch (_) { refused.push({name: label, reason: 'The font reference has invalid metadata.'}); continue; }
86
112
  }
87
- const face = faceOf(metadata);
113
+ const face = faceOf(definitionMetadata);
88
114
  if (!face) { refused.push({name: label, reason: 'The font reference has invalid metadata.'}); continue; }
89
115
  const key = fontAssetKey(face), active = first && !faces.has(key);
116
+ const conflict = sourceMetadataFields.find(field => face[field] && [metadata.get(url)?.[field], faceMetadata.get(key)?.[field]]
117
+ .some(prior => prior && JSON.stringify(prior) !== JSON.stringify(face[field])));
118
+ if (conflict) { refused.push({name: label, reason: 'The font references have conflicting ' + conflict + ' metadata.'}); continue; }
119
+ if (face.subsetted && metadata.get(url)?.origin || face.origin && subsetUrls.has(url)) {
120
+ refused.push({name: label, reason: 'A font subset cannot claim an original catalog file.'}); continue;
121
+ }
122
+ metadata.set(url, {...metadata.get(url), ...sourceMetadata(face)});
123
+ faceMetadata.set(key, {...faceMetadata.get(key), ...sourceMetadata(face)});
124
+ if (face.subsetted) subsetUrls.add(url);
90
125
  const row = {...face, ...data, url, label, id, key, source: raw, start, end, next, active, topLevel: token.level === 0};
91
126
  blocks.push(row);
92
127
  if (active) { assets.push(row); faces.add(key); }
93
128
  }
129
+ for (let index = 0; index < assets.length; index++) {
130
+ const asset = assets[index], declared = metadata.get(asset.url);
131
+ for (const field of sourceMetadataFields) if (!asset[field] && declared?.[field])
132
+ assets[index] = {...assets[index], [field]: declared[field]};
133
+ if (subsetUrls.has(asset.url) && !asset.subsetted) assets[index] = {...assets[index], subsetted: true};
134
+ }
94
135
  return {assets, blocks, refused, references: env.references || Object.create(null)};
95
136
  }
96
137
 
@@ -113,13 +154,26 @@ function escapeFontLabel(label) {
113
154
  }
114
155
 
115
156
  export function writeFontAssets(markdown, assets, parser) {
116
- const source = String(markdown ?? ''), md = parserFor(parser), index = readFontAssets(source, md), wanted = new Map();
157
+ const source = String(markdown ?? ''), md = parserFor(parser), index = readFontAssets(source, md), wanted = new Map(), metadata = new Map(), subsetUrls = new Set();
117
158
  for (const asset of assets || []) {
118
- const key = fontAssetKey(asset);
159
+ const key = fontAssetKey(asset), face = faceOf(asset);
119
160
  if (!key || !fontDataUrl(asset?.url)) throw new TypeError('font: invalid embedded asset');
120
161
  if (wanted.has(key) && wanted.get(key).url !== asset.url) throw new TypeError('font: one file owns each family face');
162
+ const conflict = sourceMetadataFields.find(field => face[field] && metadata.get(asset.url)?.[field] &&
163
+ JSON.stringify(metadata.get(asset.url)[field]) !== JSON.stringify(face[field]));
164
+ if (conflict) throw new TypeError('font: conflicting ' + conflict + ' metadata');
165
+ if (face.subsetted && metadata.get(asset.url)?.origin || face.origin && subsetUrls.has(asset.url))
166
+ throw new TypeError('font: a subset cannot claim an original catalog file');
167
+ metadata.set(asset.url, {...metadata.get(asset.url), ...sourceMetadata(face)});
168
+ if (face.subsetted) subsetUrls.add(asset.url);
121
169
  wanted.set(key, asset);
122
170
  }
171
+ for (const [key, asset] of wanted) {
172
+ const declared = metadata.get(asset.url);
173
+ for (const field of sourceMetadataFields) if (!asset[field] && declared?.[field])
174
+ wanted.set(key, {...wanted.get(key), [field]: declared[field]});
175
+ if (subsetUrls.has(asset.url) && !asset.subsetted) wanted.set(key, {...wanted.get(key), subsetted: true});
176
+ }
123
177
  const edits = [], consumed = new Set(), labels = new Set(Object.keys(index.references));
124
178
  const retired = index.assets.filter(row => !wanted.has(row.key));
125
179
  for (const row of index.blocks) {
@@ -70,13 +70,42 @@ function sourceString(node) {
70
70
  }
71
71
  const replacements = new WeakMap(), texts = new WeakMap(), edits = new WeakMap();
72
72
  export const sourceEdit = source => edits.get(source) || null;
73
+ const INITIAL_LEAF_CHARS = 16384;
73
74
  export class HistorySource {
74
75
  #root;
75
- constructor(text) { this.#root = sourceLeaf(text); Object.freeze(this); }
76
+ constructor(text) {
77
+ if (typeof text === 'string' && text.length > INITIAL_LEAF_CHARS) {
78
+ const leaves = [];
79
+ for (let from = 0; from < text.length;) {
80
+ let to = Math.min(text.length, from + INITIAL_LEAF_CHARS);
81
+ if (to < text.length && (text.charCodeAt(to - 1) & 0xfc00) === 0xd800 && (text.charCodeAt(to) & 0xfc00) === 0xdc00) to++;
82
+ leaves.push(sourceLeaf(text, from, to));
83
+ from = to;
84
+ }
85
+ const build = (from, to) => from === to ? null : to - from === 1 ? leaves[from]
86
+ : sourceNode(build(from, (from + to) >> 1), build((from + to) >> 1, to));
87
+ this.#root = build(0, leaves.length);
88
+ } else this.#root = sourceLeaf(text);
89
+ Object.freeze(this);
90
+ }
76
91
  static owns(value) { return value !== null && typeof value === 'object' && #root in value; }
77
92
  static #fromRoot(root) { const source = new HistorySource(''); source.#root = root; return source; }
78
93
  static fromParts(parts) {
79
- const leaves = Array.from(parts, text => sourceLeaf(text)).filter(Boolean);
94
+ const leaves = [];
95
+ for (const text of parts) {
96
+ if (typeof text !== 'string') throw new TypeError('source string required');
97
+ if (text.length <= INITIAL_LEAF_CHARS) {
98
+ const leaf = sourceLeaf(text);
99
+ if (leaf) leaves.push(leaf);
100
+ continue;
101
+ }
102
+ for (let from = 0; from < text.length;) {
103
+ let to = Math.min(text.length, from + INITIAL_LEAF_CHARS);
104
+ if (to < text.length && (text.charCodeAt(to - 1) & 0xfc00) === 0xd800 && (text.charCodeAt(to) & 0xfc00) === 0xdc00) to++;
105
+ leaves.push(sourceLeaf(text, from, to));
106
+ from = to;
107
+ }
108
+ }
80
109
  const build = (from, to) => from === to ? null : to - from === 1 ? leaves[from]
81
110
  : sourceNode(build(from, Math.floor((from + to) / 2)), build(Math.floor((from + to) / 2), to));
82
111
  return HistorySource.#fromRoot(build(0, leaves.length));
@@ -0,0 +1,253 @@
1
+ {
2
+ "format": "rapier-markdown-readable/1",
3
+ "description": "The pinned markdown-it 15.0.3 compiled unminified from its published sources, as the page's copy is, with its runtime dependencies and plugins as published, for the installed helpers. Written by tools/markdown-readable-vendor.mjs; licences in agent/vendor/NOTICE.txt and agent/vendor/markdown-licenses/.",
4
+ "packages": [
5
+ {
6
+ "name": "markdown-it",
7
+ "version": "15.0.3",
8
+ "tarball": "https://registry.npmjs.org/markdown-it/-/markdown-it-15.0.3.tgz",
9
+ "integrity": "sha512-+Az7Ojz3iRGu8KYMvJ6xVhvrxP3eE+vEtJX75Ow88XBpcQNV/0lGX5ZynIIBftREo4DC2jsveAMDaeltmm8QvQ=="
10
+ },
11
+ {
12
+ "name": "entities",
13
+ "version": "8.1.0",
14
+ "tarball": "https://registry.npmjs.org/entities/-/entities-8.1.0.tgz",
15
+ "integrity": "sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA=="
16
+ },
17
+ {
18
+ "name": "linkify-it",
19
+ "version": "6.1.0",
20
+ "tarball": "https://registry.npmjs.org/linkify-it/-/linkify-it-6.1.0.tgz",
21
+ "integrity": "sha512-wJ/TwpSDTLepCrQoYWYIExIKg5Zchex2Nn5yk2mFnB+6PtdkHtyLx742md9csRjjOnGkKIS/RrbY7l8D6gT9Vw=="
22
+ },
23
+ {
24
+ "name": "mdurl",
25
+ "version": "2.1.0",
26
+ "tarball": "https://registry.npmjs.org/mdurl/-/mdurl-2.1.0.tgz",
27
+ "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg=="
28
+ },
29
+ {
30
+ "name": "uc.micro",
31
+ "version": "3.0.0",
32
+ "tarball": "https://registry.npmjs.org/uc.micro/-/uc.micro-3.0.0.tgz",
33
+ "integrity": "sha512-U3PppEkleoTnIfi8BozMx3yju3qc/L6SwqWo2Sw+54PX+PX0q9I+r1Um5HCmqD7n9VDX5/v3vQH/AjA6deDdtw=="
34
+ },
35
+ {
36
+ "name": "punycode.js",
37
+ "version": "2.3.1",
38
+ "tarball": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
39
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="
40
+ },
41
+ {
42
+ "name": "markdown-it-task-lists",
43
+ "version": "2.1.1",
44
+ "tarball": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
45
+ "integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA=="
46
+ },
47
+ {
48
+ "name": "markdown-it-footnote",
49
+ "version": "4.0.0",
50
+ "tarball": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-4.0.0.tgz",
51
+ "integrity": "sha512-WYJ7urf+khJYl3DqofQpYfEYkZKbmXmwxQV8c8mO/hGIhgZ1wOe7R4HLFNwqx7TjILbnC98fuyeSsin19JdFcQ=="
52
+ },
53
+ {
54
+ "name": "markdown-it-mark",
55
+ "version": "4.0.0",
56
+ "tarball": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-4.0.0.tgz",
57
+ "integrity": "sha512-YLhzaOsU9THO/cal0lUjfMjrqSMPjjyjChYM7oyj4DnyaXEzA8gnW6cVJeyCrCVeyesrY2PlEdUYJSPFYL4Nkg=="
58
+ },
59
+ {
60
+ "name": "markdown-it-sup",
61
+ "version": "2.0.0",
62
+ "tarball": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-2.0.0.tgz",
63
+ "integrity": "sha512-5VgmdKlkBd8sgXuoDoxMpiU+BiEt3I49GItBzzw7Mxq9CxvnhE/k09HFli09zgfFDRixDQDfDxi0mgBCXtaTvA=="
64
+ },
65
+ {
66
+ "name": "markdown-it-emoji",
67
+ "version": "3.1.0",
68
+ "tarball": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-3.1.0.tgz",
69
+ "integrity": "sha512-NhmMEH2ywduD4Nty1E8uB5NqfLhAT1VR0dyvoJyStKOqCzbZmVdn/+8wj7zpDsb/fLBikpCPsWwxqKlvMmbz4g=="
70
+ },
71
+ {
72
+ "name": "markdown-it-abbr",
73
+ "version": "2.0.0",
74
+ "tarball": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-2.0.0.tgz",
75
+ "integrity": "sha512-of7C8pXSjXjDojW4neNP+jD7inUYH/DO0Ca+K/4FUEccg0oHAEX/nfscw0jfz66PJbYWOAT9U8mjO21X5p6aAw=="
76
+ },
77
+ {
78
+ "name": "markdown-it-ins",
79
+ "version": "4.0.0",
80
+ "tarball": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-4.0.0.tgz",
81
+ "integrity": "sha512-sWbjK2DprrkINE4oYDhHdCijGT+MIDhEupjSHLXe5UXeVr5qmVxs/nTUVtgi0Oh/qtF+QKV0tNWDhQBEPxiMew=="
82
+ },
83
+ {
84
+ "name": "markdown-it-deflist",
85
+ "version": "4.0.0",
86
+ "tarball": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-4.0.0.tgz",
87
+ "integrity": "sha512-06186ZWDwNLg638THD70MxBeFrDMF0+nL7IWU/qwCGHGOcUIm4MTYXbfjpv0ooWnVjkSnAjW8msKaOQmNRfY6Q=="
88
+ }
89
+ ],
90
+ "build": {
91
+ "path": "markdown-it.mjs",
92
+ "package": "markdown-it",
93
+ "map": "dist/markdown-it.mjs.map",
94
+ "imports": {
95
+ "mdurl": "./mdurl/index.mjs",
96
+ "uc.micro": "./uc.micro.mjs",
97
+ "entities": "./entities.mjs",
98
+ "linkify-it": "./linkify-it.mjs",
99
+ "punycode.js": "./punycode.mjs"
100
+ }
101
+ },
102
+ "copies": [
103
+ {
104
+ "path": "linkify-it.mjs",
105
+ "package": "linkify-it",
106
+ "from": "build/index.mjs",
107
+ "imports": {
108
+ "uc.micro": "./uc.micro.mjs"
109
+ }
110
+ },
111
+ {
112
+ "path": "uc.micro.mjs",
113
+ "package": "uc.micro",
114
+ "from": "build/index.mjs"
115
+ },
116
+ {
117
+ "path": "punycode.mjs",
118
+ "package": "punycode.js",
119
+ "from": "punycode.es6.js"
120
+ },
121
+ {
122
+ "path": "entities/decode-codepoint.mjs",
123
+ "package": "entities",
124
+ "from": "dist/decode-codepoint.js"
125
+ },
126
+ {
127
+ "path": "mdurl/index.mjs",
128
+ "package": "mdurl",
129
+ "from": "index.mjs"
130
+ },
131
+ {
132
+ "path": "mdurl/lib/decode.mjs",
133
+ "package": "mdurl",
134
+ "from": "lib/decode.mjs"
135
+ },
136
+ {
137
+ "path": "mdurl/lib/encode.mjs",
138
+ "package": "mdurl",
139
+ "from": "lib/encode.mjs"
140
+ },
141
+ {
142
+ "path": "mdurl/lib/format.mjs",
143
+ "package": "mdurl",
144
+ "from": "lib/format.mjs"
145
+ },
146
+ {
147
+ "path": "mdurl/lib/parse.mjs",
148
+ "package": "mdurl",
149
+ "from": "lib/parse.mjs"
150
+ }
151
+ ],
152
+ "plugins": [
153
+ {
154
+ "package": "markdown-it-task-lists",
155
+ "from": "dist/markdown-it-task-lists.js"
156
+ },
157
+ {
158
+ "package": "markdown-it-footnote",
159
+ "from": "dist/markdown-it-footnote.js"
160
+ },
161
+ {
162
+ "package": "markdown-it-mark",
163
+ "from": "dist/markdown-it-mark.js"
164
+ },
165
+ {
166
+ "package": "markdown-it-sup",
167
+ "from": "dist/markdown-it-sup.js"
168
+ },
169
+ {
170
+ "package": "markdown-it-emoji",
171
+ "from": "dist/markdown-it-emoji-light.js"
172
+ },
173
+ {
174
+ "package": "markdown-it-abbr",
175
+ "from": "dist/markdown-it-abbr.js"
176
+ },
177
+ {
178
+ "package": "markdown-it-ins",
179
+ "from": "dist/markdown-it-ins.js"
180
+ },
181
+ {
182
+ "package": "markdown-it-deflist",
183
+ "from": "dist/markdown-it-deflist.js"
184
+ }
185
+ ],
186
+ "files": [
187
+ {
188
+ "path": "entities.mjs",
189
+ "bytes": 50594,
190
+ "sha256": "7914d95849325717065db7db37b8fcd6f8ffaaa3aa481f1bde687209f844da38"
191
+ },
192
+ {
193
+ "path": "entities/decode-codepoint.mjs",
194
+ "bytes": 948,
195
+ "sha256": "d80628653e792234aca25c5b431523753af5c827339140d38e265d726a136579"
196
+ },
197
+ {
198
+ "path": "linkify-it.mjs",
199
+ "bytes": 16516,
200
+ "sha256": "9e2b21808450980d055f1cc159293c32eb0eecc205fe19b67ded4d7fee08aca6"
201
+ },
202
+ {
203
+ "path": "markdown-it.mjs",
204
+ "bytes": 111298,
205
+ "sha256": "73c4a1041d82dddb670375e9889bc91492c0c1c150c2c8f33267cfb3790c5d05"
206
+ },
207
+ {
208
+ "path": "markdown-plugins.mjs",
209
+ "bytes": 45734,
210
+ "sha256": "0a935c55fb20f684271d32f37819d0811ca0772c2e9cd4b1822aab2507525555"
211
+ },
212
+ {
213
+ "path": "markdown-runtime.mjs",
214
+ "bytes": 110,
215
+ "sha256": "8ce7c709299538e10b844b7f051dd784b67f0515efdd4bd167be13e0deb97f5b"
216
+ },
217
+ {
218
+ "path": "mdurl/index.mjs",
219
+ "bytes": 200,
220
+ "sha256": "8ea430f1f8a107f529e2dac519d2f18e71ec9befe6f23f78bf6510cf86d3f9a0"
221
+ },
222
+ {
223
+ "path": "mdurl/lib/decode.mjs",
224
+ "bytes": 2692,
225
+ "sha256": "6a854a029a7211a14575cbb43922734fa8a11be28a00e184463848582a349d6a"
226
+ },
227
+ {
228
+ "path": "mdurl/lib/encode.mjs",
229
+ "bytes": 1697,
230
+ "sha256": "65aa62a0e96659b9bb53ab0b4e64d5917be86e964e2f121dfce21e30a88448cb"
231
+ },
232
+ {
233
+ "path": "mdurl/lib/format.mjs",
234
+ "bytes": 465,
235
+ "sha256": "ac3695720223d7e38b1a8c061c8615b8a74b2dd56f383d3029db073430322ea6"
236
+ },
237
+ {
238
+ "path": "mdurl/lib/parse.mjs",
239
+ "bytes": 6205,
240
+ "sha256": "ac8f5a5a4a68f2c03f4624f672a5c28b425e0ddd52b8483d6c2b9a60056dcc81"
241
+ },
242
+ {
243
+ "path": "punycode.mjs",
244
+ "bytes": 5921,
245
+ "sha256": "ad32ca11244584756cc645b69679cb0df608428443f081f20bbad269afd15ff1"
246
+ },
247
+ {
248
+ "path": "uc.micro.mjs",
249
+ "bytes": 6384,
250
+ "sha256": "17ece0a12a868a21119fd68dad490664cc5f7e116102ec939f586bf203a977cb"
251
+ }
252
+ ]
253
+ }
@@ -0,0 +1,27 @@
1
+ const c1 = [
2
+ 8364, 0, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 0,
3
+ 381, 0, 0, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250,
4
+ 339, 0, 382, 376,
5
+ ];
6
+ function isInvalidCodePoint(codePoint) {
7
+ return (codePoint === 0 ||
8
+ (codePoint >= 0xd8_00 && codePoint <= 0xdf_ff) ||
9
+ codePoint > 0x10_ff_ff);
10
+ }
11
+ export function replaceCodePoint(codePoint) {
12
+ if (isInvalidCodePoint(codePoint)) {
13
+ return 0xff_fd;
14
+ }
15
+ if (codePoint >= 128 && codePoint <= 159) {
16
+ return c1[codePoint - 128] || codePoint;
17
+ }
18
+ return codePoint;
19
+ }
20
+ export function replaceCodePointXML(codePoint) {
21
+ return isInvalidCodePoint(codePoint) ? 0xff_fd : codePoint;
22
+ }
23
+ export function codePointToString(codePoint) {
24
+ return (codePoint - 1) >>> 0 < 0x7f || (codePoint - 0xa0) >>> 0 < 0xd7_60
25
+ ? String.fromCharCode(codePoint)
26
+ : String.fromCodePoint(replaceCodePoint(codePoint));
27
+ }