@rpgm-tools/neo-angband-mod-sdk 0.18.0 → 0.19.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 (87) hide show
  1. package/bin/neo-angband-mod-build.mjs +4 -3
  2. package/bin/neo-angband-mod-check.mjs +152 -0
  3. package/dist/authoring.d.ts +239 -0
  4. package/dist/authoring.d.ts.map +1 -0
  5. package/dist/authoring.js +738 -0
  6. package/dist/authoring.js.map +1 -0
  7. package/dist/blueprints.d.ts +53 -0
  8. package/dist/blueprints.d.ts.map +1 -0
  9. package/dist/blueprints.js +4596 -0
  10. package/dist/blueprints.js.map +1 -0
  11. package/dist/capabilities.d.ts +34 -3
  12. package/dist/capabilities.d.ts.map +1 -1
  13. package/dist/capabilities.js +35 -4
  14. package/dist/capabilities.js.map +1 -1
  15. package/dist/compose.d.ts +5 -1
  16. package/dist/compose.d.ts.map +1 -1
  17. package/dist/compose.js +118 -27
  18. package/dist/compose.js.map +1 -1
  19. package/dist/contested.d.ts +1 -1
  20. package/dist/contested.d.ts.map +1 -1
  21. package/dist/contested.js.map +1 -1
  22. package/dist/fields.d.ts +123 -0
  23. package/dist/fields.d.ts.map +1 -0
  24. package/dist/fields.js +217 -0
  25. package/dist/fields.js.map +1 -0
  26. package/dist/frontend.d.ts +61 -0
  27. package/dist/frontend.d.ts.map +1 -0
  28. package/dist/frontend.js +8 -0
  29. package/dist/frontend.js.map +1 -0
  30. package/dist/index.d.ts +29 -3
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +19 -2
  33. package/dist/index.js.map +1 -1
  34. package/dist/loader.d.ts +40 -6
  35. package/dist/loader.d.ts.map +1 -1
  36. package/dist/loader.js +167 -36
  37. package/dist/loader.js.map +1 -1
  38. package/dist/manifest.d.ts +62 -0
  39. package/dist/manifest.d.ts.map +1 -1
  40. package/dist/manifest.js +107 -0
  41. package/dist/manifest.js.map +1 -1
  42. package/dist/project.d.ts +126 -0
  43. package/dist/project.d.ts.map +1 -0
  44. package/dist/project.js +248 -0
  45. package/dist/project.js.map +1 -0
  46. package/dist/provenance.d.ts +86 -0
  47. package/dist/provenance.d.ts.map +1 -0
  48. package/dist/provenance.js +98 -0
  49. package/dist/provenance.js.map +1 -0
  50. package/dist/record-key.d.ts +95 -4
  51. package/dist/record-key.d.ts.map +1 -1
  52. package/dist/record-key.js +187 -15
  53. package/dist/record-key.js.map +1 -1
  54. package/dist/references.d.ts +111 -0
  55. package/dist/references.d.ts.map +1 -0
  56. package/dist/references.js +207 -0
  57. package/dist/references.js.map +1 -0
  58. package/dist/resources.d.ts +225 -0
  59. package/dist/resources.d.ts.map +1 -0
  60. package/dist/resources.js +359 -0
  61. package/dist/resources.js.map +1 -0
  62. package/dist/standards.d.ts +137 -0
  63. package/dist/standards.d.ts.map +1 -0
  64. package/dist/standards.js +462 -0
  65. package/dist/standards.js.map +1 -0
  66. package/dist/validate.d.ts +108 -0
  67. package/dist/validate.d.ts.map +1 -0
  68. package/dist/validate.js +175 -0
  69. package/dist/validate.js.map +1 -0
  70. package/package.json +3 -2
  71. package/src/authoring.ts +880 -0
  72. package/src/blueprints.ts +4630 -0
  73. package/src/capabilities.ts +235 -203
  74. package/src/compose.ts +132 -30
  75. package/src/contested.ts +2 -1
  76. package/src/fields.ts +286 -0
  77. package/src/frontend.ts +66 -0
  78. package/src/index.ts +102 -1
  79. package/src/loader.ts +205 -32
  80. package/src/manifest.ts +181 -0
  81. package/src/project.ts +311 -0
  82. package/src/provenance.ts +113 -0
  83. package/src/record-key.ts +219 -16
  84. package/src/references.ts +259 -0
  85. package/src/resources.ts +483 -0
  86. package/src/standards.ts +507 -0
  87. package/src/validate.ts +220 -0
@@ -329,11 +329,12 @@ function pluginProblem(plugin) {
329
329
  if (
330
330
  plugin.hooks === undefined &&
331
331
  plugin.register === undefined &&
332
- plugin.controller === undefined
332
+ plugin.controller === undefined &&
333
+ plugin.frontend === undefined
333
334
  ) {
334
- return "plugin.js declares no hooks, register or controller, so it would do nothing";
335
+ return "plugin.js declares no hooks, register, controller or frontend, so it would do nothing";
335
336
  }
336
- for (const name of ["hooks", "register", "controller", "uninstall"]) {
337
+ for (const name of ["hooks", "register", "controller", "frontend", "uninstall"]) {
337
338
  if (plugin[name] !== undefined && typeof plugin[name] !== "function") {
338
339
  return `plugin.js: ${name} is not a function`;
339
340
  }
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Check a mod folder against the requirements the game enforces.
4
+ *
5
+ * neo-angband-mod-check [path] check the folder (default: .)
6
+ * neo-angband-mod-check --list print every rule and why it exists
7
+ * neo-angband-mod-check --write-docs regenerate docs/modding/REQUIREMENTS.md
8
+ *
9
+ * WHY A CLI AND NOT A DOCUMENT. An author following a document finds out whether they
10
+ * got it right when somebody else's install fails. This runs the SAME rules the game
11
+ * runs at install time - literally the same functions, imported from the SDK - so a
12
+ * green run here means the game will accept the mod, and a red one names the field.
13
+ *
14
+ * ARCHIVES. If the folder holds committed .zip files, they are read as the payload
15
+ * the way the installer reads them, so the "does this mod ship plugin.js" questions
16
+ * are asked of the UNPACKED contents. Checking the repository's file list instead
17
+ * would have answered "no plugin.js" for every mod that ships a pack, which is the
18
+ * shape of wrong answer that makes a checker worse than nothing.
19
+ *
20
+ * Exit 0 when nothing REQUIRED failed. Advice never changes the exit code: a check
21
+ * that fails a build over a missing description is a check authors route around.
22
+ */
23
+
24
+ import { readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
25
+ import { join, relative, resolve, sep } from "node:path";
26
+
27
+ import { MOD_REQUIREMENTS, checkMod, requirementsMarkdown } from "../dist/index.js";
28
+
29
+ const argv = process.argv.slice(2);
30
+ const flag = (name) => argv.includes(name);
31
+
32
+ /** Every file under `dir`, relative, with forward slashes. */
33
+ function walk(dir, base = dir) {
34
+ const out = [];
35
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
36
+ /* Skip what is never part of a mod, so the report is about the mod rather than
37
+ * about node_modules. Mirrors mod-source.ts's NOT_PAYLOAD in spirit; the game's
38
+ * own list is the authority for what actually installs. */
39
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
40
+ const full = join(dir, entry.name);
41
+ if (entry.isDirectory()) out.push(...walk(full, base));
42
+ else out.push(relative(base, full).split(sep).join("/"));
43
+ }
44
+ return out;
45
+ }
46
+
47
+ /**
48
+ * The installed file list, unpacking any committed archive the manifest declares.
49
+ *
50
+ * Uses the same reasoning as the installer: a declared archive contributes its
51
+ * CONTENTS, and its own path does not survive the install.
52
+ */
53
+ async function installedFiles(root, repoFiles, declared) {
54
+ const archives = declared?.archives ?? [];
55
+ if (archives.length === 0) return repoFiles;
56
+ let unzipSync;
57
+ try {
58
+ ({ unzipSync } = await import("fflate"));
59
+ } catch {
60
+ /* fflate is the game's unzip, not the SDK's dependency. Without it the archive
61
+ * contents cannot be seen - so say so rather than reporting a mod as missing the
62
+ * files that are inside a zip this could not open. */
63
+ console.error(
64
+ "note: fflate is not installed, so declared archives were not opened.\n" +
65
+ " Rules about the mod's files may be reported wrongly.\n" +
66
+ " Install it (npm i -D fflate) for an accurate check.",
67
+ );
68
+ return repoFiles;
69
+ }
70
+ const files = repoFiles.filter((f) => !archives.includes(f));
71
+ for (const archive of archives) {
72
+ let bytes;
73
+ try {
74
+ bytes = readFileSync(resolve(root, archive));
75
+ } catch {
76
+ console.error(`note: payload.archives names ${archive}, which is not there`);
77
+ continue;
78
+ }
79
+ try {
80
+ for (const name of Object.keys(unzipSync(bytes))) {
81
+ if (!name.endsWith("/")) files.push(name);
82
+ }
83
+ } catch (e) {
84
+ console.error(`note: ${archive} is not a readable zip (${e.message})`);
85
+ }
86
+ }
87
+ return files;
88
+ }
89
+
90
+ if (flag("--list")) {
91
+ for (const r of MOD_REQUIREMENTS) {
92
+ console.log(`${r.level === "required" ? "MUST " : "SHOULD"} ${r.title}`);
93
+ console.log(` ${r.id}`);
94
+ console.log(` ${r.why}\n`);
95
+ }
96
+ process.exit(0);
97
+ }
98
+
99
+ if (flag("--write-docs")) {
100
+ /* Written relative to this script, so it works from any directory - and it is the
101
+ * ONLY writer of that file, which is what lets a test assert the two agree. */
102
+ const out = resolve(import.meta.dirname, "..", "..", "..", "docs", "modding", "REQUIREMENTS.md");
103
+ writeFileSync(out, `${requirementsMarkdown()}\n`, "utf8");
104
+ console.log(`wrote ${out}`);
105
+ process.exit(0);
106
+ }
107
+
108
+ const root = resolve(argv.find((a) => !a.startsWith("-")) ?? ".");
109
+ try {
110
+ if (!statSync(root).isDirectory()) throw new Error("not a directory");
111
+ } catch {
112
+ console.error(`${root} is not a folder this can check.`);
113
+ process.exit(2);
114
+ }
115
+
116
+ const repoFiles = walk(root);
117
+ let manifestText = null;
118
+ try {
119
+ manifestText = readFileSync(join(root, "manifest.json"), "utf8");
120
+ } catch {
121
+ /* manifest-present reports this; reading it here must not be fatal. */
122
+ }
123
+
124
+ let declared;
125
+ try {
126
+ declared = manifestText === null ? undefined : JSON.parse(manifestText).payload;
127
+ } catch {
128
+ /* manifest-json reports this. */
129
+ }
130
+
131
+ const files = await installedFiles(root, repoFiles, declared);
132
+ const report = checkMod({ files, manifestText, repoFiles, declaredPayload: declared });
133
+
134
+ const show = (findings, label) => {
135
+ if (findings.length === 0) return;
136
+ console.log(`\n${label}\n`);
137
+ for (const f of findings) {
138
+ console.log(` ${f.title}`);
139
+ console.log(` ${f.problem}`);
140
+ console.log(` (${f.id})`);
141
+ }
142
+ };
143
+
144
+ console.log(`checked ${root}`);
145
+ console.log(` ${String(files.length)} installed file(s), ${String(MOD_REQUIREMENTS.length)} rules`);
146
+ show(report.errors, "MUST FIX - the game will refuse to install this:");
147
+ show(report.advice, "SHOULD FIX - players will notice:");
148
+
149
+ if (report.ok && report.advice.length === 0) console.log("\nAll clear.");
150
+ else if (report.ok) console.log("\nInstallable. The advice above is optional.");
151
+
152
+ process.exit(report.ok ? 0 : 1);
@@ -0,0 +1,239 @@
1
+ /**
2
+ * The shortcuts: what a new record needs, what values are typical, and what an
3
+ * author is about to forget.
4
+ *
5
+ * THE PROBLEM. Adding a record to a pack has never been hard - it is JSON, and
6
+ * composition takes it. Adding a record that WORKS is hard, and it is hard in a
7
+ * way no error message reaches: an object with no `alloc` is legal, loads
8
+ * cleanly, and never appears in the dungeon. A monster whose `base` is
9
+ * misspelled is legal, loads cleanly, and binds to nothing. A forty-first
10
+ * potion is legal, loads cleanly, and consumes the last unused flavour so that
11
+ * some other potion becomes unidentifiable. Nothing in the pipeline can say any
12
+ * of that, because nothing in the pipeline knows what a working record LOOKS
13
+ * like.
14
+ *
15
+ * Core's own 3,279 records know. This file is the three ways of asking them:
16
+ *
17
+ * - `templateRecord(file)` - the fields core always writes, filled with core's
18
+ * typical values. The starting point, so nobody has to reverse-engineer a
19
+ * record shape out of a 6,000-line JSON file.
20
+ * - `suggestFields(file, draft, records)` - what core's own comparable records
21
+ * do. A price for a level-20 sword is the median price of core's level-20
22
+ * swords, which is a derivation rather than a guess and is what the author
23
+ * actually wanted when they asked "what should this cost".
24
+ * - `checkRecords(subject, all)` - every way the draft will silently do
25
+ * nothing, named.
26
+ *
27
+ * WHY THIS IS NOT A SCHEMA. A schema says what is allowed; core's data cannot,
28
+ * because the whole point of the mod system is that a mod may do things core
29
+ * never does. So every check here is graded - `error` only where the record
30
+ * cannot work at all, `warn` where it will not do what the author meant, `hint`
31
+ * where it is worth a look - and NOTHING here refuses anything. The refusals
32
+ * live in manifest.ts and fields.ts, where the rules are the engine's own.
33
+ */
34
+ import type { FieldShape, RecordBlueprint } from "./blueprints.js";
35
+ import type { JsonRecord, JsonValue } from "./compose.js";
36
+ /**
37
+ * How much a finding costs.
38
+ *
39
+ * - `error`: the record cannot work. A required field is absent.
40
+ * - `warn`: the record loads and will not do what it looks like it does. A
41
+ * dangling reference, a missing `alloc`.
42
+ * - `hint`: worth a look. An unfamiliar value, a companion step, a field core
43
+ * always writes and this record does not.
44
+ */
45
+ export type FindingLevel = "error" | "warn" | "hint";
46
+ /** One thing worth saying about one record. */
47
+ export interface AuthoringFinding {
48
+ readonly level: FindingLevel;
49
+ /** Pack file stem. */
50
+ readonly file: string;
51
+ /** The record's name, for the message. */
52
+ readonly record: string;
53
+ /** The field path, when the finding is about one. */
54
+ readonly field?: string;
55
+ /** A full sentence naming the record, the field and what to do. */
56
+ readonly message: string;
57
+ /** Stable id of the rule that produced it, so a host can filter. */
58
+ readonly rule: string;
59
+ }
60
+ /** The blueprint for a record file, or undefined if core ships no such file. */
61
+ export declare function blueprintFor(file: string): RecordBlueprint | undefined;
62
+ /** Every record file core ships, sorted. */
63
+ export declare const BLUEPRINT_FILES: readonly string[];
64
+ /**
65
+ * The fields EVERY one of core's records in this file carries.
66
+ *
67
+ * This is the definition of "required" used throughout, and it is a measurement
68
+ * rather than a schema: if all 624 monsters have `base`, a monster without one
69
+ * is missing something core has never once omitted.
70
+ */
71
+ export declare function requiredFields(file: string): readonly string[];
72
+ /** One field of a record file, with how much of core's data uses it. */
73
+ export interface FieldUsage {
74
+ readonly name: string;
75
+ readonly shape: FieldShape;
76
+ /** Fraction of the file's records that carry it, 0 to 1. */
77
+ readonly share: number;
78
+ }
79
+ /** Every field of a record file, most-used first. */
80
+ export declare function fieldUsage(file: string): readonly FieldUsage[];
81
+ /** How much of a file's data a template includes. */
82
+ export type TemplateScope = "required" | "common" | "all";
83
+ /**
84
+ * A starting record for `file`, with core's typical value in every field.
85
+ *
86
+ * TYPICAL VALUES RATHER THAN EMPTY ONES, deliberately. An author handed
87
+ * `{"name":"","level":0,"weight":0}` has been handed the shape and none of the
88
+ * knowledge; handed `{"name":"","level":25,"weight":150,"cost":150}` they can
89
+ * see at a glance what scale the game works on and change what they mean to
90
+ * change. `name` is the one field left empty, because it is the one field
91
+ * nobody wants a default for.
92
+ *
93
+ * Scope `common` (the default) adds the fields at least half of core's records
94
+ * carry - which for an object is the difference between a shape and a working
95
+ * item, since `alloc` is on 352 of 375 and is exactly what a new object is
96
+ * likeliest to be missing.
97
+ */
98
+ export declare function templateRecord(file: string, scope?: TemplateScope): JsonRecord;
99
+ /** The comparable records a suggestion or a model is drawn from. */
100
+ export interface PeerSet {
101
+ /** Core's records comparable to the draft, nearest first when depth is known. */
102
+ readonly peers: readonly JsonRecord[];
103
+ /** Which records these are, in a sentence, for the evidence line. */
104
+ readonly because: string;
105
+ }
106
+ /**
107
+ * Core's own records that are comparable to `draft`, narrowed twice: to the
108
+ * same peer field (all swords), then to the nearest in depth (level-20 swords).
109
+ *
110
+ * Shared by suggestFields and draftRecord so a suggested number and the record
111
+ * it lands in are measured against the SAME set. Two different notions of
112
+ * "comparable" in one drafted record would produce a coherent-looking item
113
+ * whose price came from somewhere else.
114
+ */
115
+ export declare function peersFor(file: string, draft: JsonRecord, records?: Readonly<Record<string, readonly JsonRecord[]>>): PeerSet;
116
+ /** One suggested value, with the evidence behind it. */
117
+ export interface Suggestion {
118
+ readonly field: string;
119
+ readonly value: JsonValue;
120
+ /** Where the number came from, so an author can disagree with it knowingly. */
121
+ readonly because: string;
122
+ }
123
+ /**
124
+ * What core's comparable records would put in the fields this draft leaves out.
125
+ *
126
+ * THIS IS THE ANSWER TO "WHAT SHOULD IT COST". A price is not derivable from
127
+ * first principles - Angband's costs are hand-set - but it is derivable from
128
+ * precedent, and precedent is what core's 375 objects are. A draft that says
129
+ * `{type: "sword", level: 20}` gets the median cost, weight and to-hit of the
130
+ * seven core swords nearest level 20, and every suggestion carries the sentence
131
+ * explaining which records it came from.
132
+ *
133
+ * `records` is the composed data - core plus any packs already loaded - so a
134
+ * mod that has added its own tval gets suggestions from its OWN records once it
135
+ * has more than none. With no records supplied the numbers fall back to the
136
+ * blueprint's file-wide medians, which is weaker and says so.
137
+ *
138
+ * Only NUMERIC fields are suggested. A name, a description or a set of flags is
139
+ * a design decision, and filling those in from a neighbour would produce a
140
+ * record that reads like core's and is not what the author meant.
141
+ */
142
+ export declare function suggestFields(file: string, draft: JsonRecord, records?: Readonly<Record<string, readonly JsonRecord[]>>): Suggestion[];
143
+ /**
144
+ * A companion step: something the record itself is fine without and the AUTHOR
145
+ * is not.
146
+ *
147
+ * Expressed as data rather than as code so the whole list can be read at once,
148
+ * printed by a scaffolder, and extended without touching the checker. A rule
149
+ * fires when the record carries every path in `present` and none of the paths
150
+ * in `absent`.
151
+ */
152
+ export interface CompanionRule {
153
+ readonly id: string;
154
+ readonly file: string;
155
+ /** Fires only if the record carries a value at every one of these. */
156
+ readonly present?: readonly string[];
157
+ /** Fires only if the record carries a value at NONE of these. */
158
+ readonly absent?: readonly string[];
159
+ readonly level: FindingLevel;
160
+ /** What is missing and what to do about it. */
161
+ readonly message: string;
162
+ }
163
+ /**
164
+ * Every "you will not find out until you play it" rule, written down.
165
+ *
166
+ * These are Angband's rules, not the port's, and each one is a real way a
167
+ * well-formed record does nothing. They are all `warn` or `hint` because every
168
+ * one of them is legal: an object with no `alloc` is exactly how core defines
169
+ * an item that only ever comes from a store or an artifact.
170
+ */
171
+ export declare const COMPANION_RULES: readonly CompanionRule[];
172
+ /** Options for checkRecords. */
173
+ export interface CheckOptions {
174
+ /** Findings at or above this level only. Default: everything. */
175
+ readonly minLevel?: FindingLevel;
176
+ }
177
+ /**
178
+ * Every way the records in `subject` will silently not work, named.
179
+ *
180
+ * TWO ARGUMENTS, AND THE SPLIT IS THE WHOLE DESIGN. `subject` is what is
181
+ * reported on - the mod's own records. `all` is what they are allowed to resolve
182
+ * against - core plus every loaded pack, as composition produced it. Checking a
183
+ * mod against itself would report every reference to core as broken; reporting
184
+ * on everything would drown the author in upstream's own warts, of which there
185
+ * are real ones (see references.ts). Pass the same object twice to audit
186
+ * everything, which is what the tests do.
187
+ */
188
+ export declare function checkRecords(subject: Readonly<Record<string, readonly JsonRecord[]>>, all: Readonly<Record<string, readonly JsonRecord[]>>, options?: CheckOptions): AuthoringFinding[];
189
+ /** A drafted record, with everything that was decided for the author. */
190
+ export interface DraftedRecord {
191
+ /** The record itself: the model, the suggestions, then the author's values. */
192
+ readonly record: JsonRecord;
193
+ /** Every number that was chosen for them, and on what evidence. */
194
+ readonly suggestions: readonly Suggestion[];
195
+ /** Everything still worth saying about it. */
196
+ readonly findings: readonly AuthoringFinding[];
197
+ /**
198
+ * The core record the shape was taken from, when there was one.
199
+ *
200
+ * Named so the author can go and read it. "Modelled on the Main Gauche" is a
201
+ * far more useful thing to know than any list of defaults.
202
+ */
203
+ readonly modelledOn?: string;
204
+ }
205
+ /**
206
+ * The whole workflow for one new record, in one call.
207
+ *
208
+ * THIS IS THE SHORTCUT. An author who knows what they want ("a sludge-brand
209
+ * dagger for around dungeon level 20") should not have to learn what an
210
+ * Angband object record contains before they can have one:
211
+ *
212
+ * draftRecord("object", { name: "& Sludge Dagger~", type: "sword", level: 20 }, core)
213
+ *
214
+ * comes back with a complete record - cost, weight, to-hit, alloc and graphics
215
+ * all taken from core's own level-20 swords - a list of which numbers were
216
+ * chosen and why, and a list of what is still wrong with it. Every step is
217
+ * separately callable (templateRecord / suggestFields / checkRecords); this is
218
+ * the order they go in.
219
+ *
220
+ * THE AUTHOR'S VALUES ALWAYS WIN, and a value they supplied is never
221
+ * "suggested" over. The suggestions fill the gaps that remain, which is the
222
+ * only place a derived number is better than no number.
223
+ *
224
+ * MODELLED ON A REAL RECORD, NOT ASSEMBLED FROM AVERAGES. The first version of
225
+ * this built the shape from the blueprint's file-wide statistics, and produced
226
+ * a sword carrying `armor` - because 59% of core's objects have `armor`, even
227
+ * though no sword does. Field frequency across a whole file is not a statement
228
+ * about any record in it. So the shape comes from core's nearest comparable
229
+ * record, minus everything that would confer behaviour (MODEL_EXCLUDE), and
230
+ * only the numbers are averaged. When there is no comparable record at all it
231
+ * falls back to `templateRecord`, which is weaker and says so in the findings.
232
+ */
233
+ export declare function draftRecord(file: string, values?: JsonRecord, records?: Readonly<Record<string, readonly JsonRecord[]>>, scope?: TemplateScope): DraftedRecord;
234
+ /**
235
+ * A short human summary of what a record file wants, for a scaffolder or a
236
+ * `--help`.
237
+ */
238
+ export declare function describeFile(file: string): string;
239
+ //# sourceMappingURL=authoring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authoring.d.ts","sourceRoot":"","sources":["../src/authoring.ts"],"names":[],"mappings":"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"}