rapier-markdown-kit 1.1.102 → 1.2.3
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/LICENSE +5 -2
- package/README.md +245 -54
- package/dist/agent/vendor/hyphen-en-us/LICENSE +14 -0
- package/dist/agent/vendor/hyphen-en-us/SOURCE.json +33 -0
- package/dist/agent/vendor/hyphen-en-us/hyph-en-us.hyp.txt +14 -0
- package/dist/agent/vendor/hyphen-en-us/hyph-en-us.pat.txt +4938 -0
- package/dist/agent/vendor/hyphen-en-us/patterns.js +25 -0
- package/dist/agent/vendor/pretext/LICENSE +208 -0
- package/dist/agent/vendor/pretext/NOTICE +26 -13
- package/dist/agent/vendor/pretext/SOURCE.json +213 -45
- package/dist/agent/vendor/pretext/analysis.js +675 -1224
- package/dist/agent/vendor/pretext/entry-geometry.js +183 -0
- package/dist/agent/vendor/pretext/gecko-line-breaks.js +688 -0
- package/dist/agent/vendor/pretext/generated/engine-break-data.js +57 -0
- package/dist/agent/vendor/pretext/generated/webkit-generic-families.js +80 -0
- package/dist/agent/vendor/pretext/graphemes.js +98 -0
- package/dist/agent/vendor/pretext/han-kerning.js +253 -0
- package/dist/agent/vendor/pretext/layout.js +352 -290
- package/dist/agent/vendor/pretext/line-break.js +1154 -588
- package/dist/agent/vendor/pretext/line-breaks.js +892 -0
- package/dist/agent/vendor/pretext/line-text.js +81 -39
- package/dist/agent/vendor/pretext/measurement.js +1105 -176
- package/dist/agent/vendor/pretext/prepare.js +807 -0
- package/dist/agent/vendor/pretext/rich-inline.js +1242 -273
- package/dist/agent/will.mjs +2 -0
- package/dist/images/gif.mjs +47 -0
- package/dist/images/playback.mjs +101 -0
- package/dist/kit/assets.mjs +5 -1
- package/dist/kit/conformance/03-wrap-around-silhouette.md +1 -1
- package/dist/kit/conformance/04-wrap-box.md +1 -1
- package/dist/kit/conformance/05-behind.md +1 -1
- package/dist/kit/conformance/06-front.md +1 -1
- package/dist/kit/conformance/07-rotate-raster.md +1 -1
- package/dist/kit/conformance/08-drawing-rotation.md +1 -1
- package/dist/kit/conformance/09-drawing-ring-interior.expected.json +18 -18
- package/dist/kit/conformance/09-drawing-ring-interior.md +1 -1
- package/dist/kit/conformance/10-both-sides.md +1 -1
- package/dist/kit/conformance/11-neighbour-skips-image.md +1 -1
- package/dist/kit/conformance/{12-heading-barrier.expected.json → 12-rule-barrier.expected.json} +1 -1
- package/dist/kit/conformance/{12-heading-barrier.md → 12-rule-barrier.md} +2 -2
- package/dist/kit/conformance/README.md +19 -28
- package/dist/kit/conformance/run.mjs +13 -11
- package/dist/kit/export-fonts.mjs +26 -11
- package/dist/kit/index.mjs +1 -0
- package/dist/kit/ledger/carried.mjs +17 -10
- package/dist/kit/ledger/data.mjs +73 -13
- package/dist/kit/ledger/format.mjs +176 -54
- package/dist/kit/ledger/hash.mjs +91 -18
- package/dist/kit/ledger/history.mjs +156 -116
- package/dist/kit/ledger/inverse-source.mjs +158 -19
- package/dist/kit/ledger/journal-records.mjs +292 -67
- package/dist/kit/ledger/merge.mjs +4 -3
- package/dist/kit/model.mjs +1 -1
- package/dist/kit/pdf-glyphs.mjs +4 -4
- package/dist/kit/pdf-vectors.mjs +4 -1
- package/dist/kit/rapier-ledger.mjs +2 -2
- package/dist/kit/render-ink.mjs +1 -1
- package/dist/kit/render-markdown.mjs +400 -148
- package/dist/kit/render-print.mjs +131 -55
- package/dist/kit/render-sanitize.mjs +30 -7
- package/dist/kit/render-work.mjs +99 -20
- package/dist/kit/render.mjs +133 -140
- package/dist/kit/typography.mjs +2 -0
- package/dist/layout/hyphenation.mjs +127 -0
- package/dist/layout/line-plan.mjs +88 -96
- package/dist/layout/model.mjs +71 -88
- package/dist/layout/paragraph-fit.mjs +191 -0
- package/dist/layout/preparation.mjs +373 -0
- package/dist/layout/prepared-paragraph.mjs +223 -0
- package/dist/layout/typography.mjs +345 -111
- package/dist/packages/rapier-diff/index.mjs +359 -224
- package/dist/spec/document-fonts.mjs +14 -5
- package/dist/spec/document-settings.mjs +11 -164
- package/dist/spec/html-blocks.mjs +618 -79
- package/dist/spec/md-assets.mjs +178 -36
- package/dist/spec/md-layout.mjs +13 -2
- package/dist/spec/md-marks.mjs +220 -127
- package/dist/spec/md-source.mjs +157 -0
- package/package.json +2 -1
- package/style.css +15 -50
- package/dist/agent/vendor/pretext/bidi.js +0 -151
- package/dist/agent/vendor/pretext/generated/bidi-data.js +0 -3831
|
@@ -111,16 +111,47 @@ function _rapierValidAuthored(origin) {
|
|
|
111
111
|
!/[\uD800-\uDFFF]/u.test(row.removed) && !/[\uD800-\uDFFF]/u.test(row.inserted));
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
// The lookup is an observation of one call's supplied records. Material rows keep
|
|
115
|
+
// their existing borrowed-row API; an inverse owns fresh rows. Navigation only
|
|
116
|
+
// follows strictly earlier revisions, including when an unadmitted list is unordered.
|
|
117
|
+
function _rapierRecordIndex(records) {
|
|
118
|
+
const byId = new Map(), splices = new Map(), metadata = new Map();
|
|
119
|
+
for (const record of records) {
|
|
120
|
+
const id = record?.transaction?.id;
|
|
121
|
+
if (!byId.has(id)) byId.set(id, []);
|
|
122
|
+
byId.get(id).push(record);
|
|
123
|
+
}
|
|
124
|
+
const resolve = (entry, effects) => {
|
|
125
|
+
const cache = effects ? metadata : splices, path = [], pending = new Set();
|
|
126
|
+
let current = entry, value;
|
|
127
|
+
while (true) {
|
|
128
|
+
if (cache.has(current)) { value = cache.get(current); break; }
|
|
129
|
+
if (!current || pending.has(current)) { value = effects ? undefined : null; break; }
|
|
130
|
+
if (effects && Object.hasOwn(current, 'metadata')) {
|
|
131
|
+
value = _rapierValidMetadataEffect(current.metadata) ? current.metadata : undefined; break;
|
|
132
|
+
}
|
|
133
|
+
if (Array.isArray(current.splices)) { value = effects ? null : current.splices; break; }
|
|
134
|
+
const tx = current.transaction, id = tx?.reverts || tx?.reapplies;
|
|
135
|
+
const target = id && byId.get(id)?.find(record => record?.transaction?.revision < tx.revision);
|
|
136
|
+
if (!target) { value = effects ? undefined : null; break; }
|
|
137
|
+
pending.add(current); path.push(current); current = target;
|
|
138
|
+
}
|
|
139
|
+
cache.set(current, value);
|
|
140
|
+
for (let i = path.length - 1; i >= 0; i--) {
|
|
141
|
+
if (path[i].transaction.reverts && value != null) value = effects
|
|
142
|
+
? Object.fromEntries(Object.entries(value).map(([key, pair]) => [key, {before: pair.after, after: pair.before}]))
|
|
143
|
+
: value.slice().reverse().map(row => ({pos: row.pos, removed: row.inserted, inserted: row.removed}));
|
|
144
|
+
cache.set(path[i], value);
|
|
145
|
+
}
|
|
146
|
+
return value;
|
|
147
|
+
};
|
|
148
|
+
return {byId, splices: record => resolve(record, false), metadata: record => resolve(record, true)};
|
|
149
|
+
}
|
|
150
|
+
|
|
114
151
|
function _rapierRecordSplices(entry, ledger) {
|
|
115
152
|
try {
|
|
116
153
|
if (entry && Array.isArray(entry.splices)) return entry.splices;
|
|
117
|
-
|
|
118
|
-
const prior = (ledger || []).filter(record => record?.transaction?.revision < tx?.revision);
|
|
119
|
-
const target = targetId && prior.find(record => record?.transaction?.id === targetId);
|
|
120
|
-
if (!target) return null;
|
|
121
|
-
const rows = _rapierRecordSplices(target, prior);
|
|
122
|
-
if (!rows) return null;
|
|
123
|
-
return tx.reverts ? rows.slice().reverse().map(row => ({pos: row.pos, removed: row.inserted, inserted: row.removed})) : rows;
|
|
154
|
+
return _rapierRecordIndex(ledger || []).splices(entry);
|
|
124
155
|
} catch (_) { return null; }
|
|
125
156
|
}
|
|
126
157
|
|
|
@@ -128,16 +159,18 @@ function _rapierRecordSplices(entry, ledger) {
|
|
|
128
159
|
function journalOperations(before, after, journal) {
|
|
129
160
|
if (typeof before !== 'string' || typeof after !== 'string' || !Array.isArray(journal)) return;
|
|
130
161
|
if (before === after) return [];
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
162
|
+
try {
|
|
163
|
+
let text = after;
|
|
164
|
+
const lookup = _rapierRecordIndex(journal), groups = [];
|
|
165
|
+
for (let index = journal.length - 1; index >= 0; index--) {
|
|
166
|
+
const rows = lookup.splices(journal[index]);
|
|
167
|
+
const prior = _rapierTransformSplices(text, rows, true);
|
|
168
|
+
if (prior === null) return;
|
|
169
|
+
groups.push(rows);
|
|
170
|
+
if (prior === before) return groups.reverse().flat().map(({pos, removed, inserted}) => ({pos, removed, inserted}));
|
|
171
|
+
text = prior;
|
|
172
|
+
}
|
|
173
|
+
} catch (_) { return; }
|
|
141
174
|
}
|
|
142
175
|
|
|
143
176
|
function _rapierRecordMetadata(entry, ledger) {
|
|
@@ -145,20 +178,13 @@ function _rapierRecordMetadata(entry, ledger) {
|
|
|
145
178
|
if (Object.hasOwn(entry, 'metadata')) return _rapierValidMetadataEffect(entry.metadata) ? entry.metadata : undefined;
|
|
146
179
|
// An expanded record owns its complete effect; only compact navigation inherits one.
|
|
147
180
|
if (Array.isArray(entry.splices)) return null;
|
|
148
|
-
|
|
149
|
-
const prior = (ledger || []).filter(record => record?.transaction?.revision < tx.revision);
|
|
150
|
-
const target = targetId && prior.find(record => record?.transaction?.id === targetId);
|
|
151
|
-
if (!target) return undefined;
|
|
152
|
-
const effect = _rapierRecordMetadata(target, prior);
|
|
153
|
-
if (effect == null) return effect;
|
|
154
|
-
return tx.reverts ? Object.fromEntries(Object.entries(effect).map(([key, pair]) =>
|
|
155
|
-
[key, {before: pair.after, after: pair.before}])) : effect;
|
|
181
|
+
return _rapierRecordIndex(ledger || []).metadata(entry);
|
|
156
182
|
} catch (_) { return undefined; }
|
|
157
183
|
}
|
|
158
184
|
|
|
159
185
|
// A codec replacement owns only one inserted definition and its reference. Its
|
|
160
186
|
// source act remains the picture's author; an arbitrary edit cannot claim upkeep.
|
|
161
|
-
function _rapierPictureFinish(record, original, earlier) {
|
|
187
|
+
function _rapierPictureFinish(record, original, earlier, lookup) {
|
|
162
188
|
const tx = record?.transaction, rows = record?.splices;
|
|
163
189
|
if (tx?.operation !== 'document.finish-picture' || !tx.sourceTransactionId || tx.sourceTransactionIds ||
|
|
164
190
|
tx.reverts || tx.reapplies || record.metadata || !Array.isArray(rows) || rows.length !== 2 ||
|
|
@@ -192,7 +218,7 @@ function _rapierPictureFinish(record, original, earlier) {
|
|
|
192
218
|
};
|
|
193
219
|
for (const prior of rows.slice(0, index).reverse()) if (cross(prior, false)) return false;
|
|
194
220
|
for (let at = earlier.length - 1; at >= 0; at--) {
|
|
195
|
-
const prior = earlier[at], source =
|
|
221
|
+
const prior = earlier[at], source = lookup.splices(prior);
|
|
196
222
|
if (!source) return false;
|
|
197
223
|
const owner = prior === original || prior.transaction?.reapplies === original.transaction.id;
|
|
198
224
|
for (const splice of source.slice().reverse()) {
|
|
@@ -207,7 +233,7 @@ function _rapierPictureFinish(record, original, earlier) {
|
|
|
207
233
|
// Every active inverse keeps its original targets suppressed. Independent inverses
|
|
208
234
|
// can share a target; withdrawing one restores it only after the last blocker leaves.
|
|
209
235
|
// This includes assignments hidden by later choices. No second history is retained.
|
|
210
|
-
function
|
|
236
|
+
function _rapierWalkHistoryEffects(records, lookup, visit = null, observe = null) {
|
|
211
237
|
try {
|
|
212
238
|
if (!Array.isArray(records)) return {ok: false};
|
|
213
239
|
const nodes = new Map(), references = new Map(), pictures = new Map(), byId = new Map(), finished = new Set(), earlier = [];
|
|
@@ -221,6 +247,25 @@ function _rapierHistoryEffects(records, visit = null) {
|
|
|
221
247
|
if (was !== node.active) for (const ref of node.references) pending.push([ref, node.active ? 1 : -1]);
|
|
222
248
|
}
|
|
223
249
|
};
|
|
250
|
+
// Most admission needs only the final effect graph. A backwards pass proves it
|
|
251
|
+
// in linear work; prefix activity is asked only by native Redo, picture custody,
|
|
252
|
+
// or a metadata assignment. The explicit stack also bounds long inverse chains.
|
|
253
|
+
const activity = new Map();
|
|
254
|
+
const active = id => {
|
|
255
|
+
if (visit) return nodes.get(id).active;
|
|
256
|
+
const pending = [[id, 0]];
|
|
257
|
+
while (pending.length) {
|
|
258
|
+
const frame = pending.at(-1), target = frame[0];
|
|
259
|
+
if (activity.has(target)) { pending.pop(); continue; }
|
|
260
|
+
const dependents = nodes.get(target).dependents;
|
|
261
|
+
if (frame[1] === dependents.length) { activity.set(target, true); pending.pop(); continue; }
|
|
262
|
+
const next = dependents[frame[1]];
|
|
263
|
+
if (!activity.has(next)) pending.push([next, 0]);
|
|
264
|
+
else if (activity.get(next)) { activity.set(target, false); pending.pop(); }
|
|
265
|
+
else frame[1]++;
|
|
266
|
+
}
|
|
267
|
+
return activity.get(id);
|
|
268
|
+
};
|
|
224
269
|
const lastUndo = new Map(), contexts = new Map(), order = [];
|
|
225
270
|
// Native Redo names an original act. Its inverse target is the last Undo
|
|
226
271
|
// in the author's proved causal view, not an unrelated later arrival.
|
|
@@ -256,7 +301,8 @@ function _rapierHistoryEffects(records, visit = null) {
|
|
|
256
301
|
let refs = supplied;
|
|
257
302
|
if (tx.operation === 'document.finish-picture' && tx.sourceTransactionId) {
|
|
258
303
|
const owner = tx.sourceTransactionId;
|
|
259
|
-
if (!nodes.
|
|
304
|
+
if (!nodes.has(owner) || !active(owner) || finished.has(owner) ||
|
|
305
|
+
!_rapierPictureFinish(record, byId.get(owner), earlier, lookup ||= _rapierRecordIndex(records))) return {ok: false};
|
|
260
306
|
pictures.set(tx.id, owner); finished.add(owner); refs = [];
|
|
261
307
|
}
|
|
262
308
|
if (tx.reverts || tx.reapplies) {
|
|
@@ -266,16 +312,19 @@ function _rapierHistoryEffects(records, visit = null) {
|
|
|
266
312
|
else {
|
|
267
313
|
const context = contextOf(record.authored || tx.authored);
|
|
268
314
|
const undo = (lastUndo.get(target) || []).findLast(id => context
|
|
269
|
-
? context.known.has(id) && !context.inactive.has(id) :
|
|
315
|
+
? context.known.has(id) && !context.inactive.has(id) : active(id));
|
|
270
316
|
if (!undo) return {ok: false};
|
|
271
317
|
refs = [undo];
|
|
272
318
|
}
|
|
273
319
|
}
|
|
274
320
|
if (refs.some(id => typeof id !== 'string' || !nodes.has(id) || pictures.has(id))) return {ok: false};
|
|
275
|
-
nodes.set(tx.id, {active: true, blockers: 0, references: refs}); references.set(tx.id, refs.slice());
|
|
276
|
-
byId.set(tx.id, record);
|
|
277
|
-
|
|
278
|
-
|
|
321
|
+
nodes.set(tx.id, {active: true, blockers: 0, references: refs, dependents: []}); references.set(tx.id, refs.slice());
|
|
322
|
+
byId.set(tx.id, record); earlier.push(record);
|
|
323
|
+
for (const ref of refs) {
|
|
324
|
+
nodes.get(ref).dependents.push(tx.id);
|
|
325
|
+
if (visit) update(ref, 1);
|
|
326
|
+
}
|
|
327
|
+
activity.clear();
|
|
279
328
|
const origin = record.authored || tx.authored;
|
|
280
329
|
contexts.set(tx.id, {index: order.length, basis: origin?.basis || null}); order.push(tx.id);
|
|
281
330
|
if (tx.reverts) {
|
|
@@ -283,55 +332,219 @@ function _rapierHistoryEffects(records, visit = null) {
|
|
|
283
332
|
lastUndo.get(tx.reverts).push(tx.id);
|
|
284
333
|
}
|
|
285
334
|
if (visit) visit(record, nodes, refs);
|
|
335
|
+
if (observe) observe(record, refs, active);
|
|
336
|
+
}
|
|
337
|
+
if (!visit) for (let i = order.length - 1; i >= 0; i--) {
|
|
338
|
+
const node = nodes.get(order[i]); node.active = node.blockers === 0;
|
|
339
|
+
if (node.active) for (const ref of node.references) nodes.get(ref).blockers++;
|
|
286
340
|
}
|
|
287
341
|
const effectiveActIds = [...nodes].filter(([id, node]) => node.active && !pictures.has(id)).map(([id]) => id);
|
|
288
342
|
return {ok: true, effectiveActIds, active: new Set(effectiveActIds), references, pictures};
|
|
289
343
|
} catch (_) { return {ok: false}; }
|
|
290
344
|
}
|
|
291
345
|
|
|
346
|
+
function _rapierHistoryEffects(records, visit = null) {
|
|
347
|
+
return _rapierWalkHistoryEffects(records, null, visit);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Every transition constrains the two initial metadata scalars. This proves each
|
|
351
|
+
// inverse's result once, before the caller supplies the exact initial metadata.
|
|
352
|
+
function _rapierMetadataProof(lookup) {
|
|
353
|
+
const values = {}, required = {}, assignments = {filename: [], docKind: []};
|
|
354
|
+
const requireInitial = (key, value) => {
|
|
355
|
+
if (Object.hasOwn(required, key) && required[key] !== value) throw Error('metadata_effect');
|
|
356
|
+
required[key] = value;
|
|
357
|
+
};
|
|
358
|
+
const observe = (record, refs, active) => {
|
|
359
|
+
const effect = lookup.metadata(record);
|
|
360
|
+
if (effect === undefined) throw Error('metadata');
|
|
361
|
+
for (const [key, pair] of Object.entries(effect || {})) {
|
|
362
|
+
if (!Object.hasOwn(values, key)) requireInitial(key, pair.before);
|
|
363
|
+
else if (values[key] !== pair.before) throw Error('metadata');
|
|
364
|
+
values[key] = pair.after;
|
|
365
|
+
if (!refs.length) assignments[key].push({id: record.transaction.id, value: pair.after});
|
|
366
|
+
}
|
|
367
|
+
// Source-only rows cannot change a previously proved metadata assignment.
|
|
368
|
+
if (!effect && !refs.length) return;
|
|
369
|
+
for (const key of ['filename', 'docKind']) {
|
|
370
|
+
const expected = assignments[key].findLast(row => active(row.id));
|
|
371
|
+
if (expected) {
|
|
372
|
+
if (!Object.hasOwn(values, key)) requireInitial(key, expected.value);
|
|
373
|
+
else if (values[key] !== expected.value) throw Error('metadata_effect');
|
|
374
|
+
} else if (Object.hasOwn(values, key)) requireInitial(key, values[key]);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
const replay = initial => {
|
|
378
|
+
if (!_rapierValidMetadata(initial) || Object.keys(required).some(key => initial[key] !== required[key])) return null;
|
|
379
|
+
return {...initial, ...values};
|
|
380
|
+
};
|
|
381
|
+
return {observe, replay};
|
|
382
|
+
}
|
|
383
|
+
|
|
292
384
|
function _rapierMetadataState(initial, records, effects = _rapierHistoryEffects(records)) {
|
|
293
385
|
if (!_rapierValidMetadata(initial) || !effects.ok) return null;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
386
|
+
try {
|
|
387
|
+
const state = {...initial}, lookup = _rapierRecordIndex(records);
|
|
388
|
+
for (const record of records) if (effects.active.has(record.transaction.id) && !effects.references.get(record.transaction.id)?.length) {
|
|
389
|
+
const effect = lookup.metadata(record);
|
|
390
|
+
if (effect === undefined) return null;
|
|
391
|
+
for (const [key, pair] of Object.entries(effect || {})) state[key] = pair.after;
|
|
392
|
+
}
|
|
393
|
+
return state;
|
|
394
|
+
} catch (_) { return null; }
|
|
301
395
|
}
|
|
302
396
|
|
|
303
397
|
// Prove each recorded transition and each inverse's semantic result, not only the final values.
|
|
304
398
|
function _rapierReplayMetadata(initial, records) {
|
|
305
399
|
if (!_rapierValidMetadata(initial)) return null;
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
if (effect === undefined) throw Error('metadata');
|
|
311
|
-
state = _rapierTransformMetadata(state, effect);
|
|
312
|
-
if (!state) throw Error('metadata');
|
|
313
|
-
if (!refs.length) for (const [key, pair] of Object.entries(effect || {}))
|
|
314
|
-
assignments[key].push({id: record.transaction.id, value: pair.after});
|
|
315
|
-
for (const key of ['filename', 'docKind']) {
|
|
316
|
-
let expected = initial[key];
|
|
317
|
-
for (let i = assignments[key].length - 1; i >= 0; i--) if (nodes.get(assignments[key][i].id).active) {
|
|
318
|
-
expected = assignments[key][i].value; break;
|
|
319
|
-
}
|
|
320
|
-
if (state[key] !== expected) throw Error('metadata_effect');
|
|
321
|
-
}
|
|
322
|
-
earlier.push(record);
|
|
323
|
-
});
|
|
324
|
-
return effects.ok ? state : null;
|
|
400
|
+
try {
|
|
401
|
+
const lookup = _rapierRecordIndex(records), proof = _rapierMetadataProof(lookup);
|
|
402
|
+
return _rapierWalkHistoryEffects(records, lookup, null, proof.observe).ok ? proof.replay(initial) : null;
|
|
403
|
+
} catch (_) { return null; }
|
|
325
404
|
}
|
|
326
405
|
|
|
327
406
|
function _rapierHasHistoryEffect(record, earlier = []) {
|
|
328
407
|
const tx = record?.transaction;
|
|
329
408
|
if (!tx || !(tx.reverts || tx.reapplies || tx.sourceTransactionId || tx.sourceTransactionIds?.length)) return false;
|
|
330
409
|
let id = tx.id;
|
|
331
|
-
if (!id) {
|
|
410
|
+
if (!id) {
|
|
411
|
+
const ids = new Set(earlier.map(row => row?.transaction?.id));
|
|
412
|
+
id = 'candidate'; while (ids.has(id)) id += ':';
|
|
413
|
+
}
|
|
332
414
|
return _rapierHistoryEffects([...earlier, {...record, transaction: {...tx, id}}]).ok;
|
|
333
415
|
}
|
|
334
416
|
|
|
417
|
+
// A cached observation owns every byte-bearing record. Mutable graphs are compared
|
|
418
|
+
// through descriptors on every call; only a proved, recursively frozen graph can
|
|
419
|
+
// bypass that walk. Per-object weak entries keep one latest copy, not a revision log.
|
|
420
|
+
const _rapierPrepareHistoryRecords = (() => {
|
|
421
|
+
const copies = new WeakMap();
|
|
422
|
+
// Repeated queries share the latest proved snapshot. A live but inactive input
|
|
423
|
+
// does not need to retain its record/effect indexes; immutable copies remain weak.
|
|
424
|
+
let prepared = new WeakMap();
|
|
425
|
+
// Object.freeze does not freeze Map/Set entries. Keep those collections inside
|
|
426
|
+
// the preparation and expose only immutable values through reading closures.
|
|
427
|
+
const view = collection => Object.freeze({size: collection.size, has: key => collection.has(key),
|
|
428
|
+
...(collection instanceof Map ? {get: key => collection.get(key)} : {}),
|
|
429
|
+
keys: () => collection.keys(), values: () => collection.values(), entries: () => collection.entries(),
|
|
430
|
+
[Symbol.iterator]: () => collection[Symbol.iterator]()});
|
|
431
|
+
const capture = value => {
|
|
432
|
+
const active = new Set(), pending = [{value, depth: 0}], result = {};
|
|
433
|
+
const finish = (frame, value, immutable, height = -1) => {
|
|
434
|
+
const parent = frame.parent;
|
|
435
|
+
if (!parent) { result.value = value; return; }
|
|
436
|
+
parent.immutable &&= immutable;
|
|
437
|
+
parent.height = Math.max(parent.height, height + 1);
|
|
438
|
+
if (!parent.out && parent.previous[frame.key] !== value)
|
|
439
|
+
parent.out = Array.isArray(parent.previous) ? parent.previous.slice() : {...parent.previous};
|
|
440
|
+
if (parent.out) parent.out[frame.key] = value;
|
|
441
|
+
};
|
|
442
|
+
while (pending.length) {
|
|
443
|
+
const frame = pending.pop(), value = frame.value;
|
|
444
|
+
if (frame.leaving) {
|
|
445
|
+
active.delete(value);
|
|
446
|
+
const copy = frame.out ? Object.freeze(frame.out) : frame.previous;
|
|
447
|
+
copies.set(value, {copy, immutable: frame.immutable, height: frame.height, ...(frame.frozen && !frame.immutable ? {frozen: true, descriptors: frame.descriptors, fields: frame.fields} : {})});
|
|
448
|
+
copies.set(copy, {copy, immutable: true, height: frame.height});
|
|
449
|
+
finish(frame, copy, frame.immutable, frame.height); continue;
|
|
450
|
+
}
|
|
451
|
+
const old = frame.parent?.previous;
|
|
452
|
+
if (old && Object.hasOwn(old, frame.key) && Object.is(value, old[frame.key]) && (value === null || typeof value !== 'object')) {
|
|
453
|
+
finish(frame, value, true); continue;
|
|
454
|
+
}
|
|
455
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'string' && !/[\uD800-\uDFFF]/u.test(value) ||
|
|
456
|
+
typeof value === 'number' && Number.isFinite(value) && !Object.is(value, -0)) {
|
|
457
|
+
finish(frame, value, true); continue;
|
|
458
|
+
}
|
|
459
|
+
if (!value || typeof value !== 'object' || frame.depth > 64 || active.has(value)) throw Error('history_data');
|
|
460
|
+
const previous = copies.get(value);
|
|
461
|
+
if (previous?.immutable) {
|
|
462
|
+
if (frame.depth + previous.height > 64) throw Error('history_data');
|
|
463
|
+
finish(frame, previous.copy, true, previous.height); continue;
|
|
464
|
+
}
|
|
465
|
+
frame.previous = previous?.copy;
|
|
466
|
+
frame.height = 0;
|
|
467
|
+
if (previous?.frozen) {
|
|
468
|
+
// A frozen shell fixes its descriptors, but every mutable child is still
|
|
469
|
+
// observed afresh. Fixed scalar fields need no second Unicode/data proof.
|
|
470
|
+
frame.frozen = frame.immutable = true;
|
|
471
|
+
frame.descriptors = previous.descriptors; frame.fields = previous.fields;
|
|
472
|
+
frame.out = null; frame.leaving = true; active.add(value); pending.push(frame);
|
|
473
|
+
for (let at = frame.fields.length - 1; at >= 0; at--) {
|
|
474
|
+
const key = frame.fields[at], child = frame.descriptors[key].value;
|
|
475
|
+
if (child && typeof child === 'object') pending.push({value: child, parent: frame, key, depth: frame.depth + 1});
|
|
476
|
+
}
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
// Check frozen-ness before capturing descriptors. A caller freezing a mutable
|
|
480
|
+
// input later cannot retroactively certify an earlier view of its properties.
|
|
481
|
+
frame.frozen = frame.immutable = Object.isFrozen(value);
|
|
482
|
+
const array = Array.isArray(value), proto = Object.getPrototypeOf(value);
|
|
483
|
+
if (!array && proto !== null && (Object.getPrototypeOf(proto) !== null ||
|
|
484
|
+
Object.getOwnPropertyDescriptor(Object.getOwnPropertyDescriptor(proto, 'constructor')?.value || {}, 'name')?.value !== 'Object')) throw Error('history_data');
|
|
485
|
+
const descriptors = Object.getOwnPropertyDescriptors(value), keys = Reflect.ownKeys(descriptors);
|
|
486
|
+
if (array && keys.length !== descriptors.length.value + 1) throw Error('history_data');
|
|
487
|
+
for (const key of keys) {
|
|
488
|
+
if (array && key === 'length') continue;
|
|
489
|
+
const field = descriptors[key];
|
|
490
|
+
if (typeof key !== 'string' || ['__proto__', 'constructor', 'prototype'].includes(key) ||
|
|
491
|
+
!Object.hasOwn(field, 'value') || !field.enumerable || array &&
|
|
492
|
+
(!/^(0|[1-9]\d*)$/.test(key) || +key >= descriptors.length.value)) throw Error('history_data');
|
|
493
|
+
}
|
|
494
|
+
const fields = array ? keys.filter(key => key !== 'length') : keys;
|
|
495
|
+
const sameKeys = frame.previous && Object.keys(frame.previous).length === fields.length && fields.every(key => Object.hasOwn(frame.previous, key));
|
|
496
|
+
frame.out = sameKeys ? null : array ? [] : {};
|
|
497
|
+
if (!sameKeys && !array) fields.sort();
|
|
498
|
+
frame.descriptors = descriptors; frame.fields = fields;
|
|
499
|
+
frame.leaving = true; active.add(value); pending.push(frame);
|
|
500
|
+
for (let at = fields.length - 1; at >= 0; at--) {
|
|
501
|
+
const key = fields[at]; pending.push({value: descriptors[key].value, parent: frame, key, depth: frame.depth + 1});
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return result.value;
|
|
505
|
+
};
|
|
506
|
+
return (input, earlier = input) => {
|
|
507
|
+
try {
|
|
508
|
+
if (!Array.isArray(input) || !Array.isArray(earlier)) return {ok: false};
|
|
509
|
+
const records = capture(input), basis = input === earlier ? records : capture(earlier), previous = prepared.get(records);
|
|
510
|
+
if (previous?.basis === basis) return previous.observation;
|
|
511
|
+
const byId = new Map();
|
|
512
|
+
for (const record of records) {
|
|
513
|
+
const id = record?.transaction?.id;
|
|
514
|
+
if (typeof id !== 'string' || !id || byId.has(id)) return {ok: false};
|
|
515
|
+
byId.set(id, record);
|
|
516
|
+
}
|
|
517
|
+
const lookup = _rapierRecordIndex(basis), proof = _rapierMetadataProof(lookup);
|
|
518
|
+
const rows = records.map(record => {
|
|
519
|
+
const splices = lookup.splices(record), metadata = lookup.metadata(record);
|
|
520
|
+
if (splices && !Object.isFrozen(splices)) {
|
|
521
|
+
for (const row of splices) Object.freeze(row);
|
|
522
|
+
Object.freeze(splices);
|
|
523
|
+
}
|
|
524
|
+
if (metadata && !Object.isFrozen(metadata)) {
|
|
525
|
+
for (const pair of Object.values(metadata)) Object.freeze(pair);
|
|
526
|
+
Object.freeze(metadata);
|
|
527
|
+
}
|
|
528
|
+
return Object.freeze({record, splices, metadata});
|
|
529
|
+
});
|
|
530
|
+
const effects = _rapierWalkHistoryEffects(records, lookup, null, proof.observe);
|
|
531
|
+
if (!effects.ok) return {ok: false};
|
|
532
|
+
for (const refs of effects.references.values()) Object.freeze(refs);
|
|
533
|
+
const effectView = Object.freeze({ok: true, effectiveActIds: Object.freeze(effects.effectiveActIds),
|
|
534
|
+
active: view(effects.active), references: view(effects.references), pictures: view(effects.pictures)});
|
|
535
|
+
const observation = Object.freeze({ok: effects.ok, records, rows: Object.freeze(rows), effects: effectView, byId: view(byId),
|
|
536
|
+
replayMetadata: initial => effects.ok ? proof.replay(initial) : null,
|
|
537
|
+
validRecord: (index, documentAuthority, maxDocumentBytes, utf8Length, allowGap = false) => {
|
|
538
|
+
if (!effects.ok || !Number.isSafeInteger(index) || index < 0 || index >= records.length) return false;
|
|
539
|
+
const row = rows[index], tx = row.record.transaction;
|
|
540
|
+
return _rapierCheckLedgerRecord(row.record, records[index - 1] || null, documentAuthority, maxDocumentBytes, utf8Length, allowGap,
|
|
541
|
+
{...row, duplicate: false, semantic: !!(tx.reverts || tx.reapplies || tx.sourceTransactionId || tx.sourceTransactionIds?.length)});
|
|
542
|
+
}});
|
|
543
|
+
prepared = new WeakMap([[records, {basis, observation}]]); return observation;
|
|
544
|
+
} catch (_) { return {ok: false}; }
|
|
545
|
+
};
|
|
546
|
+
})();
|
|
547
|
+
|
|
335
548
|
// A ledger record as the journal and the Notes return validate it below: plain data, nothing
|
|
336
549
|
// undefined anywhere in it. A live record could carry a row whose type or order is not yet known (a
|
|
337
550
|
// block just inserted, before its first render: `type: undefined`), and the validator would refuse
|
|
@@ -353,15 +566,28 @@ function _rapierValidLedgerRecord(record, prior, earlier, documentAuthority, max
|
|
|
353
566
|
// Iterative traversal refuses cycles without exhausting the call stack. Proxies/counters that
|
|
354
567
|
// throw are refused by the same gate rather than escaping into document recovery.
|
|
355
568
|
try {
|
|
356
|
-
if (!_rapierPlainLedgerData(record) ||
|
|
569
|
+
if (!_rapierPlainLedgerData(record) || !Array.isArray(earlier)) return false;
|
|
570
|
+
const own = Array.isArray(record?.splices), lookup = own ? null : _rapierRecordIndex(earlier);
|
|
571
|
+
const metadata = Object.hasOwn(record, 'metadata')
|
|
572
|
+
? _rapierValidMetadataEffect(record.metadata) ? record.metadata : undefined : own ? null : lookup.metadata(record);
|
|
573
|
+
return _rapierCheckLedgerRecord(record, prior, documentAuthority, maxDocumentBytes, utf8Length, allowGap,
|
|
574
|
+
{splices: own ? record.splices : lookup.splices(record), metadata,
|
|
575
|
+
semantic: _rapierHasHistoryEffect(record, earlier), duplicate: earlier.some(row => row?.transaction?.id === record?.transaction?.id)});
|
|
576
|
+
} catch (_) { return false; }
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Both callers proved plain data themselves: the public single-row validator above,
|
|
580
|
+
// or the private owned-snapshot preparation. No caller-supplied trusted flag exists.
|
|
581
|
+
function _rapierCheckLedgerRecord(record, prior, documentAuthority, maxDocumentBytes, utf8Length, allowGap,
|
|
582
|
+
{splices, metadata, semantic, duplicate}) {
|
|
583
|
+
try {
|
|
584
|
+
if (Object.hasOwn(record, 'authored') && !_rapierValidAuthored(record.authored)) return false;
|
|
357
585
|
if (!record || typeof record !== 'object' ||
|
|
358
586
|
typeof record.beforeHash !== 'string' || !record.beforeHash.length ||
|
|
359
587
|
typeof record.afterHash !== 'string' || !record.afterHash.length) return false;
|
|
360
588
|
const own = Array.isArray(record.splices), navigation = !!(record.transaction?.reverts || record.transaction?.reapplies);
|
|
361
589
|
if ((!own && !navigation) || (own && record.splices.length > 64) ||
|
|
362
590
|
(record.transaction?.reverts && record.transaction?.reapplies)) return false;
|
|
363
|
-
const splices = _rapierRecordSplices(record, earlier), metadata = _rapierRecordMetadata(record, earlier);
|
|
364
|
-
const semantic = _rapierHasHistoryEffect(record, earlier);
|
|
365
591
|
if (metadata === undefined || (!splices?.length && !Object.values(metadata || {}).some(pair => pair.before !== pair.after) && !semantic) ||
|
|
366
592
|
(record.beforeHash === record.afterHash && splices?.length) ||
|
|
367
593
|
(record.beforeHash !== record.afterHash && !splices?.length) ||
|
|
@@ -380,8 +606,7 @@ function _rapierValidLedgerRecord(record, prior, earlier, documentAuthority, max
|
|
|
380
606
|
const optional = (value, valid) => value === undefined || valid(value);
|
|
381
607
|
const identity = (value, limit) => typeof value === 'string' && value.length > 0 && value.length <= limit;
|
|
382
608
|
if (!transaction || typeof transaction.id !== 'string' || !transaction.id.length ||
|
|
383
|
-
transaction.id.length > 256 ||
|
|
384
|
-
earlier.some(row => row?.transaction?.id === transaction.id) ||
|
|
609
|
+
transaction.id.length > 256 || duplicate ||
|
|
385
610
|
typeof transaction.documentAuthority !== 'string' ||
|
|
386
611
|
transaction.documentAuthority !== documentAuthority ||
|
|
387
612
|
(transaction.transport !== 'platform' && transaction.transport !== 'webmcp') ||
|
|
@@ -419,4 +644,4 @@ function _rapierValidLedgerRecord(record, prior, earlier, documentAuthority, max
|
|
|
419
644
|
} catch (_) { return false; }
|
|
420
645
|
}
|
|
421
646
|
|
|
422
|
-
export { _rapierValidAuthored, _RAPIER_TRANSACTION_ACTOR_LIMIT, _RAPIER_TRANSACTION_OPERATION_LIMIT, _RAPIER_TRANSACTION_REQUEST_LIMIT, _rapierTransformSplices, _rapierRecordSplices, _rapierValidLedgerRecord, _rapierJournalRecord, _rapierValidMetadata, _rapierValidMetadataEffect, _rapierMetadataDelta, _rapierTransformMetadata, _rapierRecordMetadata, _rapierHistoryEffects, _rapierMetadataState, _rapierReplayMetadata, _rapierHasHistoryEffect, journalOperations};
|
|
647
|
+
export { _rapierPrepareHistoryRecords, _rapierValidAuthored, _RAPIER_TRANSACTION_ACTOR_LIMIT, _RAPIER_TRANSACTION_OPERATION_LIMIT, _RAPIER_TRANSACTION_REQUEST_LIMIT, _rapierTransformSplices, _rapierRecordSplices, _rapierValidLedgerRecord, _rapierJournalRecord, _rapierValidMetadata, _rapierValidMetadataEffect, _rapierMetadataDelta, _rapierTransformMetadata, _rapierRecordMetadata, _rapierHistoryEffects, _rapierMetadataState, _rapierReplayMetadata, _rapierHasHistoryEffect, journalOperations};
|
|
@@ -190,7 +190,9 @@ export function merge(first, second) {
|
|
|
190
190
|
const local = localIds.get(record.transaction.id);
|
|
191
191
|
if (local) mappedIds.set(record.transaction.id, local.transaction.id);
|
|
192
192
|
}
|
|
193
|
-
|
|
193
|
+
// Kept text arriving from the other copy waits for the person; this copy's own kept edits merge like any other.
|
|
194
|
+
const incomingKept = canonicalJSON(kept(theirs.text));
|
|
195
|
+
const keepDiffers = incomingKept !== canonicalJSON(kept(ours.text)) && incomingKept !== canonicalJSON(kept(common.text));
|
|
194
196
|
let conflicted = keepDiffers && unseen.length > 0, incomingSource = common.text;
|
|
195
197
|
if (!conflicted) for (const record of incoming) {
|
|
196
198
|
const beforeSource = incomingSource;
|
|
@@ -240,8 +242,7 @@ export function merge(first, second) {
|
|
|
240
242
|
let conflicts = [];
|
|
241
243
|
if (conflicted) {
|
|
242
244
|
if (unseen.length !== incoming.length) return refused('history', 'record_transport_conflict');
|
|
243
|
-
if (incomingFields.size
|
|
244
|
-
return metadataConflict('record_transport_conflict', {fields: [...incomingFields]});
|
|
245
|
+
if (incomingFields.size) return metadataConflict('record_transport_conflict', {fields: [...incomingFields]});
|
|
245
246
|
// Restart from the original local head: partially transported records never leak into a conflict result.
|
|
246
247
|
records.splice(ours.ledger.records.length); text = ours.text; metadata = {...ours.metadata}; root = ours.root;
|
|
247
248
|
const merged = mergeText(keepDiffers ? null : common.text, ours.text, theirs.text, {oursId: 'copy-' + ours.ledger.sha256.slice(0, 16), theirsId: 'copy-' + theirs.ledger.sha256.slice(0, 16)});
|
package/dist/kit/model.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
export * from '../layout/model.mjs';
|
|
3
|
-
export {
|
|
3
|
+
export {layoutNextRichInlineLineRange, materializeRichInlineLineRange} from '../agent/vendor/pretext/rich-inline.js';
|
package/dist/kit/pdf-glyphs.mjs
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
// The licensed static faces retain the shipped variable font's exact glyphs and metrics.
|
|
3
3
|
// Browser ranges own placement; unsupported shaping stays in the original page paint.
|
|
4
4
|
|
|
5
|
-
const fontCache = new Map();
|
|
6
5
|
const familyName = value => value.trim().replace(/^['"]|['"]$/g, '');
|
|
7
6
|
|
|
8
|
-
function readFont(asset) {
|
|
7
|
+
function readFont(asset, fontCache) {
|
|
9
8
|
if (fontCache.has(asset)) return fontCache.get(asset);
|
|
10
|
-
const bytes = Uint8Array.from(atob(asset.data), character => character.charCodeAt(0));
|
|
9
|
+
const bytes = typeof asset.read === 'function' ? asset.read() : Uint8Array.from(atob(asset.data), character => character.charCodeAt(0));
|
|
11
10
|
const view = new DataView(bytes.buffer), u16 = at => view.getUint16(at), i16 = at => view.getInt16(at), u32 = at => view.getUint32(at);
|
|
12
11
|
const tag = at => String.fromCharCode(...bytes.subarray(at, at + 4)), tables = new Map();
|
|
13
12
|
for (let at = 12, end = 12 + u16(4) * 16; at < end; at += 16) tables.set(tag(at), {at: u32(at + 8), length: u32(at + 12)});
|
|
@@ -94,6 +93,7 @@ function shape(value, font, preserve, ligatures) {
|
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
export async function collectPdfGlyphs(main, {width, check, faces = []}) {
|
|
96
|
+
const fontCache = new Map(); // Parsed byte copies belong to this PDF operation.
|
|
97
97
|
const document = main.ownerDocument, window = document.defaultView, origin = main.getBoundingClientRect();
|
|
98
98
|
const nodes = new Map(), hidden = [], canvas = document.createElement('canvas'); canvas.width = canvas.height = 1;
|
|
99
99
|
const context = canvas.getContext('2d', {willReadFrequently: true});
|
|
@@ -134,7 +134,7 @@ export async function collectPdfGlyphs(main, {width, check, faces = []}) {
|
|
|
134
134
|
if (generated || altered || !Array.from(document.fonts).some(face => familyName(face.family) === family && face.status === 'loaded')) continue;
|
|
135
135
|
const asset = faces.find(face => face.family === family && face.weight === weight);
|
|
136
136
|
if (!asset) continue;
|
|
137
|
-
const font = readFont(asset), preserve = /pre|break-spaces/.test(style.whiteSpace), node = textNodes[0];
|
|
137
|
+
const font = readFont(asset, fontCache), preserve = /pre|break-spaces/.test(style.whiteSpace), node = textNodes[0];
|
|
138
138
|
const shaped = shape(node.data, font, preserve, style.fontVariantLigatures === 'normal' && !(Number.parseFloat(style.letterSpacing) || 0));
|
|
139
139
|
if (!shaped) continue;
|
|
140
140
|
context.font = [style.fontStyle, style.fontWeight, style.fontSize, style.fontFamily].join(' ');
|
package/dist/kit/pdf-vectors.mjs
CHANGED
|
@@ -151,7 +151,10 @@ export async function collectPdfVectors(main, {width, height, count, capture, si
|
|
|
151
151
|
const left = Math.max(0, bounds.left - box.left - 2), top = Math.max(0, bounds.top - box.top - 2);
|
|
152
152
|
const right = Math.min(box.width, bounds.right - box.left + 2), bottom = Math.min(box.height, bounds.bottom - box.top + 2);
|
|
153
153
|
if (!(right > left && bottom > top)) return;
|
|
154
|
-
const result = await capture({root: wrap, clip: {x: left, y: top, width: right - left, height: bottom - top}, transparent: true, scale: 2, signal, current}); check();
|
|
154
|
+
const result = await capture({root: wrap, clip: {x: left, y: top, width: right - left, height: bottom - top}, transparent: true, scale: 2, signal, current, pixels: true}); check();
|
|
155
|
+
if (result?.rgb instanceof Uint8Array && result?.alpha instanceof Uint8Array) {
|
|
156
|
+
return {image: {rgb: await compress(result.rgb), alpha: await compress(result.alpha), width: result.width, height: result.height}, x: box.left - origin.left + left, y: box.top - origin.top + top, width: right - left, height: bottom - top};
|
|
157
|
+
}
|
|
155
158
|
const image = new window.Image(); image.src = 'data:' + result.mimeType + ';base64,' + result.data; await image.decode(); check();
|
|
156
159
|
const canvas = document.createElement('canvas'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight;
|
|
157
160
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
import {exportLedger, replaceLedgerText, readLedger, textRoot, rootAfter, historyEnvelope, agentActorId} from './ledger/format.mjs';
|
|
3
|
-
export {exportLedger, replaceLedgerText, readLedger, textRoot, rootAfter, historyEnvelope, agentActorId};
|
|
2
|
+
import {exportLedger, replaceLedgerText, readLedger, ledgerWithStart, textRoot, rootAfter, historyEnvelope, agentActorId} from './ledger/format.mjs';
|
|
3
|
+
export {exportLedger, replaceLedgerText, readLedger, ledgerWithStart, textRoot, rootAfter, historyEnvelope, agentActorId};
|
|
4
4
|
import {authorship, readAuthorship, ledgerFromAuthorship} from './ledger/authorship.mjs';
|
|
5
5
|
export {authorship, readAuthorship, ledgerFromAuthorship};
|
|
6
6
|
import {merge, transportInterval, transportTouchedInterval} from './ledger/merge.mjs';
|
package/dist/kit/render-ink.mjs
CHANGED
|
@@ -63,7 +63,7 @@ export async function freezePublishedInk(root, {document: doc, css, fontCss = ''
|
|
|
63
63
|
frame.srcdoc = '<!doctype html><html lang="' + documentLanguage(settings, language) + '" data-rapier-theme="' + theme + '"><head><meta charset="utf-8">'
|
|
64
64
|
+ '<meta http-equiv="Content-Security-Policy" content="' + policy + '"><meta name="referrer" content="no-referrer">'
|
|
65
65
|
+ '<style>' + css + '</style></head><body class="' + (theme === 'light' ? 'light' : '')
|
|
66
|
-
+ '"><main class="rapier-page md-render" data-md-theme="' + theme + '"
|
|
66
|
+
+ '"><main class="rapier-page md-render" data-md-theme="' + theme + '">' + root.innerHTML + '</main></body></html>';
|
|
67
67
|
doc.body.appendChild(frame);
|
|
68
68
|
await wait(loaded);
|
|
69
69
|
const paper = frame.contentDocument, main = paper?.querySelector('main.rapier-page');
|