@keymanapp/common-types 18.0.17-alpha → 18.0.18-alpha

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 (147) hide show
  1. package/build/src/consts/virtual-key-constants.js +222 -221
  2. package/build/src/consts/virtual-key-constants.js.map +1 -1
  3. package/build/src/keyman-touch-layout/keyman-touch-layout-file-reader.js +73 -72
  4. package/build/src/keyman-touch-layout/keyman-touch-layout-file-reader.js.map +1 -1
  5. package/build/src/keyman-touch-layout/keyman-touch-layout-file-writer.js +121 -120
  6. package/build/src/keyman-touch-layout/keyman-touch-layout-file-writer.js.map +1 -1
  7. package/build/src/keyman-touch-layout/keyman-touch-layout-file.js +55 -54
  8. package/build/src/keyman-touch-layout/keyman-touch-layout-file.js.map +1 -1
  9. package/build/src/kmx/element-string.d.ts.map +1 -1
  10. package/build/src/kmx/element-string.js +126 -120
  11. package/build/src/kmx/element-string.js.map +1 -1
  12. package/build/src/kmx/keyman-targets.js +80 -79
  13. package/build/src/kmx/keyman-targets.js.map +1 -1
  14. package/build/src/kmx/kmx-builder.js +190 -189
  15. package/build/src/kmx/kmx-builder.js.map +1 -1
  16. package/build/src/kmx/kmx-file-reader.js +135 -134
  17. package/build/src/kmx/kmx-file-reader.js.map +1 -1
  18. package/build/src/kmx/kmx-plus-builder/build-disp.js +28 -27
  19. package/build/src/kmx/kmx-plus-builder/build-disp.js.map +1 -1
  20. package/build/src/kmx/kmx-plus-builder/build-elem.js +90 -89
  21. package/build/src/kmx/kmx-plus-builder/build-elem.js.map +1 -1
  22. package/build/src/kmx/kmx-plus-builder/build-keys.js +108 -107
  23. package/build/src/kmx/kmx-plus-builder/build-keys.js.map +1 -1
  24. package/build/src/kmx/kmx-plus-builder/build-layr.js +102 -101
  25. package/build/src/kmx/kmx-plus-builder/build-layr.js.map +1 -1
  26. package/build/src/kmx/kmx-plus-builder/build-list.js +67 -66
  27. package/build/src/kmx/kmx-plus-builder/build-list.js.map +1 -1
  28. package/build/src/kmx/kmx-plus-builder/build-loca.js +22 -21
  29. package/build/src/kmx/kmx-plus-builder/build-loca.js.map +1 -1
  30. package/build/src/kmx/kmx-plus-builder/build-meta.js +23 -22
  31. package/build/src/kmx/kmx-plus-builder/build-meta.js.map +1 -1
  32. package/build/src/kmx/kmx-plus-builder/build-sect.js +16 -15
  33. package/build/src/kmx/kmx-plus-builder/build-sect.js.map +1 -1
  34. package/build/src/kmx/kmx-plus-builder/build-strs.js +47 -46
  35. package/build/src/kmx/kmx-plus-builder/build-strs.js.map +1 -1
  36. package/build/src/kmx/kmx-plus-builder/build-tran.js +70 -69
  37. package/build/src/kmx/kmx-plus-builder/build-tran.js.map +1 -1
  38. package/build/src/kmx/kmx-plus-builder/build-uset.js +61 -60
  39. package/build/src/kmx/kmx-plus-builder/build-uset.js.map +1 -1
  40. package/build/src/kmx/kmx-plus-builder/build-vars.js +49 -48
  41. package/build/src/kmx/kmx-plus-builder/build-vars.js.map +1 -1
  42. package/build/src/kmx/kmx-plus-builder/builder-section.js +5 -4
  43. package/build/src/kmx/kmx-plus-builder/builder-section.js.map +1 -1
  44. package/build/src/kmx/kmx-plus-builder/kmx-plus-builder.js +138 -137
  45. package/build/src/kmx/kmx-plus-builder/kmx-plus-builder.js.map +1 -1
  46. package/build/src/kmx/kmx-plus.d.ts +3 -2
  47. package/build/src/kmx/kmx-plus.d.ts.map +1 -1
  48. package/build/src/kmx/kmx-plus.js +831 -823
  49. package/build/src/kmx/kmx-plus.js.map +1 -1
  50. package/build/src/kmx/kmx.d.ts.map +1 -1
  51. package/build/src/kmx/kmx.js +303 -299
  52. package/build/src/kmx/kmx.js.map +1 -1
  53. package/build/src/kmx/string-list.js +89 -88
  54. package/build/src/kmx/string-list.js.map +1 -1
  55. package/build/src/kpj/keyman-developer-project.js +196 -195
  56. package/build/src/kpj/keyman-developer-project.js.map +1 -1
  57. package/build/src/kpj/kpj-file-reader.js +120 -119
  58. package/build/src/kpj/kpj-file-reader.js.map +1 -1
  59. package/build/src/kpj/kpj-file.js +13 -12
  60. package/build/src/kpj/kpj-file.js.map +1 -1
  61. package/build/src/kvk/kvk-file-reader.js +38 -37
  62. package/build/src/kvk/kvk-file-reader.js.map +1 -1
  63. package/build/src/kvk/kvk-file-writer.js +78 -77
  64. package/build/src/kvk/kvk-file-writer.js.map +1 -1
  65. package/build/src/kvk/kvk-file.js +91 -90
  66. package/build/src/kvk/kvk-file.js.map +1 -1
  67. package/build/src/kvk/kvks-file-reader.js +176 -175
  68. package/build/src/kvk/kvks-file-reader.js.map +1 -1
  69. package/build/src/kvk/kvks-file-writer.js +107 -106
  70. package/build/src/kvk/kvks-file-writer.js.map +1 -1
  71. package/build/src/kvk/kvks-file.js +12 -11
  72. package/build/src/kvk/kvks-file.js.map +1 -1
  73. package/build/src/kvk/visual-keyboard.js +76 -75
  74. package/build/src/kvk/visual-keyboard.js.map +1 -1
  75. package/build/src/ldml-keyboard/ldml-keyboard-testdata-xml.js +22 -21
  76. package/build/src/ldml-keyboard/ldml-keyboard-testdata-xml.js.map +1 -1
  77. package/build/src/ldml-keyboard/ldml-keyboard-xml-reader.js +410 -409
  78. package/build/src/ldml-keyboard/ldml-keyboard-xml-reader.js.map +1 -1
  79. package/build/src/ldml-keyboard/ldml-keyboard-xml.js +58 -57
  80. package/build/src/ldml-keyboard/ldml-keyboard-xml.js.map +1 -1
  81. package/build/src/ldml-keyboard/pattern-parser.js +491 -490
  82. package/build/src/ldml-keyboard/pattern-parser.js.map +1 -1
  83. package/build/src/ldml-keyboard/unicodeset-parser-api.js +30 -29
  84. package/build/src/ldml-keyboard/unicodeset-parser-api.js.map +1 -1
  85. package/build/src/main.js +35 -34
  86. package/build/src/main.js.map +1 -1
  87. package/build/src/package/kmp-json-file.js +4 -3
  88. package/build/src/package/kmp-json-file.js.map +1 -1
  89. package/build/src/package/kps-file.js +18 -17
  90. package/build/src/package/kps-file.js.map +1 -1
  91. package/build/src/schema-validators.js +28 -27
  92. package/build/src/schema-validators.js.map +1 -1
  93. package/build/src/schemas/displaymap.schema.js +38 -37
  94. package/build/src/schemas/displaymap.schema.js.map +1 -1
  95. package/build/src/schemas/displaymap.schema.validator.mjs +267 -266
  96. package/build/src/schemas/displaymap.schema.validator.mjs.map +1 -1
  97. package/build/src/schemas/keyboard_info.schema.js +101 -100
  98. package/build/src/schemas/keyboard_info.schema.js.map +1 -1
  99. package/build/src/schemas/keyboard_info.schema.validator.mjs +1161 -1160
  100. package/build/src/schemas/keyboard_info.schema.validator.mjs.map +1 -1
  101. package/build/src/schemas/keyman-touch-layout.clean.spec.js +154 -153
  102. package/build/src/schemas/keyman-touch-layout.clean.spec.js.map +1 -1
  103. package/build/src/schemas/keyman-touch-layout.clean.spec.validator.mjs +1095 -1094
  104. package/build/src/schemas/keyman-touch-layout.clean.spec.validator.mjs.map +1 -1
  105. package/build/src/schemas/keyman-touch-layout.spec.js +143 -142
  106. package/build/src/schemas/keyman-touch-layout.spec.js.map +1 -1
  107. package/build/src/schemas/keyman-touch-layout.spec.validator.mjs +1437 -1436
  108. package/build/src/schemas/keyman-touch-layout.spec.validator.mjs.map +1 -1
  109. package/build/src/schemas/kmp.schema.js +356 -355
  110. package/build/src/schemas/kmp.schema.js.map +1 -1
  111. package/build/src/schemas/kmp.schema.validator.mjs +1628 -1627
  112. package/build/src/schemas/kmp.schema.validator.mjs.map +1 -1
  113. package/build/src/schemas/kpj-9.0.schema.js +134 -133
  114. package/build/src/schemas/kpj-9.0.schema.js.map +1 -1
  115. package/build/src/schemas/kpj-9.0.schema.validator.mjs +656 -655
  116. package/build/src/schemas/kpj-9.0.schema.validator.mjs.map +1 -1
  117. package/build/src/schemas/kpj.schema.js +132 -131
  118. package/build/src/schemas/kpj.schema.js.map +1 -1
  119. package/build/src/schemas/kpj.schema.validator.mjs +516 -515
  120. package/build/src/schemas/kpj.schema.validator.mjs.map +1 -1
  121. package/build/src/schemas/kvks.schema.js +185 -184
  122. package/build/src/schemas/kvks.schema.js.map +1 -1
  123. package/build/src/schemas/kvks.schema.validator.mjs +626 -625
  124. package/build/src/schemas/kvks.schema.validator.mjs.map +1 -1
  125. package/build/src/schemas/ldml-keyboard3.schema.js +699 -698
  126. package/build/src/schemas/ldml-keyboard3.schema.js.map +1 -1
  127. package/build/src/schemas/ldml-keyboard3.schema.validator.mjs +3118 -3117
  128. package/build/src/schemas/ldml-keyboard3.schema.validator.mjs.map +1 -1
  129. package/build/src/schemas/ldml-keyboardtest3.schema.js +228 -227
  130. package/build/src/schemas/ldml-keyboardtest3.schema.js.map +1 -1
  131. package/build/src/schemas/ldml-keyboardtest3.schema.validator.mjs +745 -744
  132. package/build/src/schemas/ldml-keyboardtest3.schema.validator.mjs.map +1 -1
  133. package/build/src/schemas.js +26 -25
  134. package/build/src/schemas.js.map +1 -1
  135. package/build/src/util/common-events.js +29 -28
  136. package/build/src/util/common-events.js.map +1 -1
  137. package/build/src/util/compiler-interfaces.js +381 -380
  138. package/build/src/util/compiler-interfaces.js.map +1 -1
  139. package/build/src/util/errors.js +8 -7
  140. package/build/src/util/errors.js.map +1 -1
  141. package/build/src/util/file-types.js +143 -142
  142. package/build/src/util/file-types.js.map +1 -1
  143. package/build/src/util/util.d.ts +4 -0
  144. package/build/src/util/util.d.ts.map +1 -1
  145. package/build/src/util/util.js +369 -362
  146. package/build/src/util/util.js.map +1 -1
  147. package/package.json +2 -2
@@ -1,824 +1,832 @@
1
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="551e923f-be50-506a-8fac-8168c09bce5b")}catch(e){}}();
2
- import { constants } from '@keymanapp/ldml-keyboard-constants';
3
- import * as r from 'restructure';
4
- import { ElementString } from './element-string.js';
5
- import { ListItem } from './string-list.js';
6
- import { isOneChar, toOneChar, unescapeString } from '../util/util.js';
7
- import { KMXFile } from './kmx.js';
8
- import { VariableParser } from '../ldml-keyboard/pattern-parser.js';
9
- import { MarkerParser } from '../ldml-keyboard/pattern-parser.js';
10
- // Implementation of file structures from /core/src/ldml/C7043_ldml.md
11
- // Writer in kmx-builder.ts
12
- // Reader in kmx-loader.ts
13
- export class Section {
14
- }
15
- // 'sect'
16
- export class Sect extends Section {
17
- }
18
- ;
19
- // 'bksp' -- see 'tran'
20
- // 'elem'
21
- export class Elem extends Section {
22
- strings = [];
23
- constructor(sections) {
24
- super();
25
- this.strings.push(ElementString.fromStrings(sections, '')); // C7043: null element string
26
- }
27
- /**
28
- * @param source if a string array, does not get reinterpreted as UnicodeSet. This is used with vars, etc. Or pass `["str"]` for an explicit 1-element elem.
29
- * If it is a string, will be interpreted per reorder element ruls.
30
- */
31
- allocElementString(sections, source, order, tertiary, tertiary_base, prebase) {
32
- let s = ElementString.fromStrings(sections, source, order, tertiary, tertiary_base, prebase);
33
- if (!s)
34
- return s;
35
- let result = this.strings.find(item => item.isEqual(s));
36
- if (result === undefined) {
37
- result = s;
38
- this.strings.push(result);
39
- }
40
- return result;
41
- }
42
- }
43
- ;
44
- // 'keys' is now `keys2.kmap`
45
- // 'loca'
46
- export class Loca extends Section {
47
- locales = [];
48
- }
49
- ;
50
- // 'meta'
51
- export var KeyboardSettings;
52
- (function (KeyboardSettings) {
53
- KeyboardSettings[KeyboardSettings["none"] = 0] = "none";
54
- KeyboardSettings[KeyboardSettings["normalizationDisabled"] = constants.meta_settings_normalization_disabled] = "normalizationDisabled";
55
- })(KeyboardSettings || (KeyboardSettings = {}));
56
- ;
57
- export class Meta extends Section {
58
- author;
59
- conform;
60
- layout;
61
- name;
62
- indicator;
63
- version; // semver version string, defaults to "0"
64
- settings;
65
- /** convenience for checking settings */
66
- get normalizationDisabled() {
67
- return this?.settings & KeyboardSettings.normalizationDisabled;
68
- }
69
- }
70
- ;
71
- // 'strs'
72
- /**
73
- * A string item in memory. This will be replaced with an index
74
- * into the string table at finalization.
75
- */
76
- export class StrsItem {
77
- /** string value */
78
- value;
79
- /** char value if this is a single-char placeholder item (CharStrsItem) */
80
- char;
81
- constructor(value, char) {
82
- if (char !== undefined) {
83
- if (!isOneChar(value)) {
84
- throw new Error(`StrsItem: ${value} is not a single char`);
85
- }
86
- if (char !== toOneChar(value)) {
87
- throw new Error(`StrsItem: ${char} is not the right codepoint for ${value}`);
88
- }
89
- }
90
- this.value = value;
91
- this.char = char;
92
- }
93
- compareTo(o) {
94
- return StrsItem.binaryStringCompare(this.value, o.value);
95
- }
96
- static binaryStringCompare(a, b) {
97
- // https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islessthan
98
- if (typeof a != 'string' || typeof b != 'string') {
99
- throw new Error('binaryStringCompare: inputs must be strings');
100
- }
101
- if (a < b)
102
- return -1;
103
- if (a > b)
104
- return 1;
105
- return 0;
106
- }
107
- get isOneChar() {
108
- return this.char !== undefined;
109
- }
110
- }
111
- ;
112
- /**
113
- * A StrsItem for a single char. Used as a placeholder and hint to the builder
114
- */
115
- export class CharStrsItem extends StrsItem {
116
- constructor(value) {
117
- if (!isOneChar(value)) {
118
- throw RangeError(`not a 1-char string`);
119
- }
120
- super(value, toOneChar(value));
121
- }
122
- }
123
- ;
124
- ;
125
- export class Strs extends Section {
126
- /** the in-memory string table */
127
- strings = [new StrsItem('')]; // C7043: The null string is always required
128
- /** for validating */
129
- allProcessedStrings = new Set();
130
- /**
131
- * Allocate a StrsItem given the string, unescaping if necessary.
132
- * @param s escaped string
133
- * @param opts options for allocation
134
- * @param sections other sections, if needed
135
- * @returns StrsItem
136
- */
137
- allocString(s, opts, sections) {
138
- // Run the string processing pipeline
139
- s = Strs.processString(s, opts, sections);
140
- // add to the set, for testing
141
- if (s) {
142
- this.allProcessedStrings.add(s);
143
- }
144
- // if it's a single char, don't push it into the strs table
145
- if (opts?.singleOk && isOneChar(s)) {
146
- return new CharStrsItem(s);
147
- }
148
- // default: look to see if the string is already present
149
- let result = this.strings.find(item => item.value === s);
150
- if (result === undefined) {
151
- // only add if not already present
152
- result = new StrsItem(s);
153
- this.strings.push(result);
154
- }
155
- return result;
156
- }
157
- /** process everything according to opts */
158
- static processString(s, opts, sections) {
159
- s = s ?? '';
160
- // type check everything else
161
- if (typeof s !== 'string') {
162
- throw new Error('alloc_string: s must be a string, undefined, or null.');
163
- }
164
- // substitute variables
165
- if (opts?.stringVariables) {
166
- s = sections.vars.substituteStrings(s, sections);
167
- }
168
- // substitute markers
169
- if (opts?.markers) {
170
- s = sections.vars.substituteMarkerString(s);
171
- }
172
- // unescape \u{…}
173
- if (opts?.unescape) {
174
- s = unescapeString(s);
175
- }
176
- // nfd
177
- if (opts?.nfd) {
178
- if (!sections?.meta?.normalizationDisabled) {
179
- if (opts?.markers) {
180
- s = MarkerParser.nfd_markers(s, false);
181
- }
182
- else {
183
- s = s.normalize("NFD");
184
- }
185
- }
186
- }
187
- return s;
188
- }
189
- }
190
- ;
191
- /**
192
- * See LKVariables
193
- */
194
- export class Vars extends Section {
195
- totalCount() {
196
- return this.strings.length + this.sets.length + this.usets.length;
197
- }
198
- markers;
199
- strings = []; // ≠ StrsItem
200
- sets = [];
201
- usets = [];
202
- /**
203
- *
204
- * @returns false if any invalid variables
205
- */
206
- valid() {
207
- for (const t of [this.sets, this.strings, this.usets]) {
208
- for (const i of t) {
209
- if (!i.valid()) {
210
- return false;
211
- }
212
- }
213
- }
214
- return true;
215
- }
216
- // utilities for making use of Vars in other sections
217
- substituteSets(str, sections) {
218
- return str.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
219
- const val = Vars.findVariable(this.sets, id);
220
- if (val === null) {
221
- // Should have been caught during validation.
222
- throw Error(`Internal Error: reference to missing set variable ${id}`);
223
- }
224
- return val.value.value;
225
- });
226
- }
227
- substituteUnicodeSets(value, sections) {
228
- return value.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
229
- const v = Vars.findVariable(this.usets, id);
230
- if (v === null) {
231
- // Should have been caught during validation.
232
- throw Error(`Internal Error: reference to missing UnicodeSet variable ${id}`);
233
- }
234
- return v.value.value; // string value
235
- });
236
- }
237
- substituteStrings(str, sections) {
238
- if (!str)
239
- return str;
240
- return str.replaceAll(VariableParser.STRING_REFERENCE, (_entire, id) => {
241
- const val = this.findStringVariableValue(id);
242
- if (val === null) {
243
- // Should have been caught during validation.
244
- throw Error(`Internal Error: reference to missing string variable ${id}`);
245
- }
246
- return val;
247
- });
248
- }
249
- findStringVariableValue(id) {
250
- return Vars.findVariable(this.strings, id)?.value?.value; // Unwrap: Variable, StrsItem
251
- }
252
- substituteSetRegex(str, sections) {
253
- return str.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
254
- // try as set
255
- const set = Vars.findVariable(this.sets, id);
256
- if (set !== null) {
257
- const { items } = set;
258
- const inner = items.map(i => i.value.value).join('|');
259
- return `(?:${inner})`; // TODO-LDML: need to escape here
260
- }
261
- // try as unicodeset
262
- const uset = Vars.findVariable(this.usets, id);
263
- if (uset !== null) {
264
- const { unicodeSet } = uset;
265
- const inner = unicodeSet.ranges.map(([start, end]) => {
266
- const s = String.fromCodePoint(start);
267
- if (start === end) {
268
- return s;
269
- }
270
- else {
271
- const e = String.fromCodePoint(end);
272
- return `${s}-${e}`;
273
- }
274
- }).join('');
275
- return `[${inner}]`;
276
- }
277
- // else, missing
278
- throw Error(`Internal Error: reference to missing set variable ${id}`);
279
- });
280
- }
281
- /**
282
- * Variable locator facility
283
- * @param array
284
- * @param id
285
- * @returns
286
- */
287
- static findVariable(array, id) {
288
- const v = array.filter(e => e.id.value === id);
289
- if (v.length === 0) {
290
- return null;
291
- }
292
- else if (v.length !== 1) {
293
- // Should have been caught during validation
294
- throw Error(`Internal Error: Duplicate variable id ${id} crept into a variable list.`);
295
- }
296
- else {
297
- return v[0];
298
- }
299
- }
300
- substituteMarkerString(s, forMatch) {
301
- return MarkerParser.toSentinelString(s, this.markers, forMatch);
302
- }
303
- }
304
- ;
305
- /**
306
- * Common base for variable sections
307
- * See Variable
308
- */
309
- export class VarsItem extends Section {
310
- id;
311
- value;
312
- constructor(id, value, sections) {
313
- super();
314
- this.id = sections.strs.allocString(id);
315
- this.value = sections.strs.allocString(value, { unescape: true });
316
- }
317
- valid() {
318
- return true;
319
- }
320
- }
321
- ;
322
- export class UnicodeSetItem extends VarsItem {
323
- constructor(id, value, sections, usetparser) {
324
- super(id, value, sections);
325
- const needRanges = sections.usetparser.sizeUnicodeSet(value);
326
- if (needRanges >= 0) {
327
- this.unicodeSet = sections.usetparser.parseUnicodeSet(value, needRanges);
328
- } // otherwise: error (was recorded via callback)
329
- }
330
- unicodeSet;
331
- valid() {
332
- return !!this.unicodeSet;
333
- }
334
- }
335
- ;
336
- export class SetVarItem extends VarsItem {
337
- constructor(id, value, sections) {
338
- super(id, value.join(' '), sections);
339
- this.items = sections.elem.allocElementString(sections, value);
340
- }
341
- items;
342
- valid() {
343
- return !!this.items;
344
- }
345
- }
346
- ;
347
- export class StringVarItem extends VarsItem {
348
- constructor(id, value, sections) {
349
- super(id, value, sections);
350
- }
351
- }
352
- ;
353
- // 'tran'
354
- export class TranTransform {
355
- from;
356
- to;
357
- mapFrom; // var name
358
- mapTo; // var name
359
- }
360
- export class TranGroup {
361
- type; // tran_group_type_transform | tran_group_type_reorder
362
- transforms = [];
363
- reorders = [];
364
- }
365
- export class TranReorder {
366
- elements;
367
- before;
368
- }
369
- ;
370
- export class Tran extends Section {
371
- groups = [];
372
- get id() {
373
- return constants.section.tran;
374
- }
375
- }
376
- ;
377
- export class UsetItem {
378
- uset;
379
- str;
380
- constructor(uset, str) {
381
- this.uset = uset;
382
- this.str = str;
383
- }
384
- compareTo(other) {
385
- return this.str.compareTo(other.str);
386
- }
387
- }
388
- ;
389
- export class Uset extends Section {
390
- usets = [];
391
- allocUset(set, sections) {
392
- // match the same pattern
393
- let result = this.usets.find(s => set.pattern == s.uset.pattern);
394
- if (result === undefined) {
395
- result = new UsetItem(set, sections.strs.allocString(set.pattern));
396
- this.usets.push(result);
397
- }
398
- return result;
399
- }
400
- }
401
- ;
402
- // alias type for 'bksp'
403
- export class Bksp extends Tran {
404
- get id() {
405
- return constants.section.bksp;
406
- }
407
- }
408
- ;
409
- // 'disp'
410
- export class DispItem {
411
- to;
412
- id;
413
- display;
414
- }
415
- ;
416
- export class Disp extends Section {
417
- baseCharacter;
418
- disps = [];
419
- }
420
- ;
421
- // 'layr'
422
- /**
423
- * In-memory `<layers>`
424
- */
425
- export class LayrList {
426
- hardware;
427
- layers = [];
428
- minDeviceWidth; // millimeters
429
- }
430
- ;
431
- /**
432
- * In-memory `<layer>`
433
- */
434
- export class LayrEntry {
435
- id;
436
- mod;
437
- rows = [];
438
- }
439
- ;
440
- /**
441
- * In-memory `<row>`
442
- */
443
- export class LayrRow {
444
- keys = [];
445
- }
446
- ;
447
- export class Layr extends Section {
448
- lists = [];
449
- }
450
- ;
451
- export class KeysKeys {
452
- flags;
453
- flicks; // for in-memory only
454
- id;
455
- longPress;
456
- longPressDefault;
457
- multiTap;
458
- switch;
459
- to;
460
- width;
461
- }
462
- ;
463
- export class KeysKmap {
464
- vkey;
465
- mod;
466
- key; // for in-memory only
467
- }
468
- ;
469
- export class KeysFlicks {
470
- flicks = [];
471
- id;
472
- compareTo(b) {
473
- return this.id.compareTo(b.id);
474
- }
475
- constructor(id) {
476
- this.id = id;
477
- }
478
- }
479
- ;
480
- export class KeysFlick {
481
- directions;
482
- keyId;
483
- }
484
- ;
485
- export class Keys extends Section {
486
- keys = [];
487
- flicks = [];
488
- kmap = [];
489
- constructor(strs) {
490
- super();
491
- let nullFlicks = new KeysFlicks(strs.allocString(''));
492
- this.flicks.push(nullFlicks); // C7043: null element string
493
- }
494
- }
495
- ;
496
- export class List extends Section {
497
- /**
498
- * Allocate a list from a space-separated list of items.
499
- * Note that passing undefined or null or `''` will
500
- * end up being the same as the empty list `[]`
501
- * @param s space-separated list of items
502
- * @param opts string options
503
- * @param sections sections
504
- * @returns a List object
505
- */
506
- allocListFromSpaces(s, opts, sections) {
507
- s = s ?? '';
508
- return this.allocList(s.split(' '), opts, sections);
509
- }
510
- /**
511
- * Return a List object referring to the string list.
512
- * Note that a falsy list, or a list containing only an empty string
513
- * `['']` will be stored as an empty list `[]`.
514
- * @param strs Strs section for allocation
515
- * @param s string list to allocate
516
- * @returns
517
- */
518
- allocList(s, opts, sections) {
519
- // Special case the 'null' list for [] or ['']
520
- if (!s || (s.length === 1 && s[0] === '')) {
521
- return this.lists[0];
522
- }
523
- let result = this.lists.find(item => item.isEqual(s));
524
- if (result === undefined) {
525
- // allocate a new ListItem
526
- result = ListItem.fromStrings(s, opts, sections);
527
- this.lists.push(result);
528
- }
529
- return result;
530
- }
531
- constructor(strs) {
532
- super();
533
- this.lists.push(ListItem.fromStrings([], {}, { strs })); // C7043: null element string
534
- }
535
- lists = [];
536
- }
537
- ;
538
- export { ListItem as ListItem };
539
- ;
540
- export class KMXPlusFile extends KMXFile {
541
- /* KMXPlus file structures */
542
- COMP_PLUS_SECT_ITEM;
543
- COMP_PLUS_SECT;
544
- // COMP_PLUS_BKSP == COMP_PLUS_TRAN
545
- COMP_PLUS_BKSP_ITEM;
546
- COMP_PLUS_BKSP;
547
- COMP_PLUS_DISP_ITEM;
548
- COMP_PLUS_DISP;
549
- COMP_PLUS_ELEM_ELEMENT;
550
- COMP_PLUS_ELEM_STRING;
551
- COMP_PLUS_ELEM;
552
- // COMP_PLUS_KEYS is now COMP_PLUS_KEYS_KMAP
553
- COMP_PLUS_LAYR_ENTRY;
554
- COMP_PLUS_LAYR_KEY;
555
- COMP_PLUS_LAYR_LIST;
556
- COMP_PLUS_LAYR_ROW;
557
- COMP_PLUS_LAYR;
558
- COMP_PLUS_KEYS_FLICK;
559
- COMP_PLUS_KEYS_FLICKS;
560
- COMP_PLUS_KEYS_KEY;
561
- COMP_PLUS_KEYS_KMAP;
562
- COMP_PLUS_KEYS;
563
- COMP_PLUS_LIST_LIST;
564
- COMP_PLUS_LIST_INDEX;
565
- COMP_PLUS_LIST;
566
- COMP_PLUS_LOCA_ITEM;
567
- COMP_PLUS_LOCA;
568
- COMP_PLUS_META;
569
- COMP_PLUS_STRS_ITEM;
570
- COMP_PLUS_STRS;
571
- COMP_PLUS_TRAN_GROUP;
572
- COMP_PLUS_TRAN_TRANSFORM;
573
- COMP_PLUS_TRAN_REORDER;
574
- COMP_PLUS_TRAN;
575
- COMP_PLUS_USET_USET;
576
- COMP_PLUS_USET_RANGE;
577
- COMP_PLUS_USET;
578
- COMP_PLUS_VKEY_ITEM;
579
- COMP_PLUS_VKEY;
580
- COMP_PLUS_VARS;
581
- COMP_PLUS_VARS_ITEM;
582
- /* File in-memory data */
583
- kmxplus = {};
584
- constructor() {
585
- super();
586
- // Binary-correct structures matching kmx_plus.h
587
- // helpers
588
- const STR_REF = r.uint32le;
589
- const ELEM_REF = r.uint32le;
590
- const LIST_REF = r.uint32le;
591
- const STR_OR_CHAR32 = r.uint32le;
592
- const CHAR32 = r.uint32le;
593
- const STR_OR_CHAR32_OR_USET = r.uint32le;
594
- const IDENT = r.uint32le;
595
- // 'sect'
596
- this.COMP_PLUS_SECT_ITEM = new r.Struct({
597
- sect: r.uint32le,
598
- offset: r.uint32le //? new r.VoidPointer(r.uint32le, {type: 'global'})
599
- });
600
- this.COMP_PLUS_SECT = new r.Struct({
601
- ident: IDENT,
602
- size: r.uint32le,
603
- total: r.uint32le,
604
- count: r.uint32le,
605
- items: new r.Array(this.COMP_PLUS_SECT_ITEM, 'count')
606
- });
607
- // 'bksp' - see 'tran'
608
- // 'disp'
609
- this.COMP_PLUS_DISP_ITEM = new r.Struct({
610
- to: STR_REF,
611
- id: STR_REF,
612
- display: STR_REF,
613
- });
614
- this.COMP_PLUS_DISP = new r.Struct({
615
- ident: IDENT,
616
- size: r.uint32le,
617
- count: r.uint32le,
618
- baseCharacter: CHAR32,
619
- items: new r.Array(this.COMP_PLUS_DISP_ITEM, 'count'),
620
- });
621
- // 'elem'
622
- this.COMP_PLUS_ELEM_ELEMENT = new r.Struct({
623
- element: STR_OR_CHAR32_OR_USET,
624
- flags: r.uint32le
625
- });
626
- this.COMP_PLUS_ELEM_STRING = new r.Struct({
627
- offset: r.uint32le,
628
- length: r.uint32le
629
- });
630
- this.COMP_PLUS_ELEM = new r.Struct({
631
- ident: IDENT,
632
- size: r.uint32le,
633
- count: r.uint32le,
634
- strings: new r.Array(this.COMP_PLUS_ELEM_STRING, 'count')
635
- // + variable subtable: Element data (see KMXPlusBuilder.emitElements())
636
- });
637
- // 'finl' - see 'tran'
638
- // 'keys' - see 'keys.kmap'
639
- // 'layr'
640
- this.COMP_PLUS_LAYR_ENTRY = new r.Struct({
641
- id: r.uint32le,
642
- mod: r.uint32le,
643
- row: r.uint32le,
644
- count: r.uint32le,
645
- });
646
- this.COMP_PLUS_LAYR_KEY = new r.Struct({
647
- key: r.uint32le, // str: key id
648
- });
649
- this.COMP_PLUS_LAYR_LIST = new r.Struct({
650
- hardware: STR_REF,
651
- layer: r.uint32le,
652
- count: r.uint32le,
653
- minDeviceWidth: r.uint32le, // integer: millimeters
654
- });
655
- this.COMP_PLUS_LAYR_ROW = new r.Struct({
656
- key: r.uint32le,
657
- count: r.uint32le,
658
- });
659
- this.COMP_PLUS_LAYR = new r.Struct({
660
- ident: IDENT,
661
- size: r.uint32le,
662
- listCount: r.uint32le,
663
- layerCount: r.uint32le,
664
- rowCount: r.uint32le,
665
- keyCount: r.uint32le,
666
- lists: new r.Array(this.COMP_PLUS_LAYR_LIST, 'listCount'),
667
- layers: new r.Array(this.COMP_PLUS_LAYR_ENTRY, 'layerCount'),
668
- rows: new r.Array(this.COMP_PLUS_LAYR_ROW, 'rowCount'),
669
- keys: new r.Array(this.COMP_PLUS_LAYR_KEY, 'keyCount'),
670
- });
671
- this.COMP_PLUS_KEYS_FLICK = new r.Struct({
672
- directions: LIST_REF,
673
- to: STR_OR_CHAR32, // str | codepoint
674
- });
675
- this.COMP_PLUS_KEYS_FLICKS = new r.Struct({
676
- count: r.uint32le,
677
- flick: r.uint32le,
678
- id: STR_REF, // str
679
- });
680
- this.COMP_PLUS_KEYS_KEY = new r.Struct({
681
- to: STR_OR_CHAR32,
682
- flags: r.uint32le,
683
- id: STR_REF,
684
- switch: STR_REF,
685
- width: r.uint32le,
686
- longPress: LIST_REF,
687
- longPressDefault: STR_REF,
688
- multiTap: LIST_REF,
689
- flicks: r.uint32le, // index into flicks table
690
- });
691
- this.COMP_PLUS_KEYS_KMAP = new r.Struct({
692
- vkey: r.uint32le,
693
- mod: r.uint32le,
694
- key: r.uint32le, // index into 'keys' subtable
695
- });
696
- this.COMP_PLUS_KEYS = new r.Struct({
697
- ident: IDENT,
698
- size: r.uint32le,
699
- keyCount: r.uint32le,
700
- flicksCount: r.uint32le,
701
- flickCount: r.uint32le,
702
- kmapCount: r.uint32le,
703
- keys: new r.Array(this.COMP_PLUS_KEYS_KEY, 'keyCount'),
704
- flicks: new r.Array(this.COMP_PLUS_KEYS_FLICKS, 'flicksCount'),
705
- flick: new r.Array(this.COMP_PLUS_KEYS_FLICK, 'flickCount'),
706
- kmap: new r.Array(this.COMP_PLUS_KEYS_KMAP, 'kmapCount'),
707
- });
708
- // 'list'
709
- this.COMP_PLUS_LIST_LIST = new r.Struct({
710
- index: r.uint32le,
711
- count: r.uint32le,
712
- });
713
- this.COMP_PLUS_LIST_INDEX = new r.Struct({
714
- str: STR_REF, // str
715
- });
716
- this.COMP_PLUS_LIST = new r.Struct({
717
- ident: IDENT,
718
- size: r.uint32le,
719
- listCount: r.uint32le,
720
- indexCount: r.uint32le,
721
- lists: new r.Array(this.COMP_PLUS_LIST_LIST, 'listCount'),
722
- indices: new r.Array(this.COMP_PLUS_LIST_INDEX, 'indexCount'),
723
- });
724
- // 'loca'
725
- this.COMP_PLUS_LOCA_ITEM = r.uint32le; //str
726
- this.COMP_PLUS_LOCA = new r.Struct({
727
- ident: IDENT,
728
- size: r.uint32le,
729
- count: r.uint32le,
730
- items: new r.Array(this.COMP_PLUS_LOCA_ITEM, 'count')
731
- });
732
- // 'meta'
733
- this.COMP_PLUS_META = new r.Struct({
734
- ident: IDENT,
735
- size: r.uint32le,
736
- author: STR_REF,
737
- conform: STR_REF,
738
- layout: STR_REF,
739
- name: STR_REF,
740
- indicator: STR_REF,
741
- version: STR_REF,
742
- settings: r.uint32le, //new r.Bitfield(r.uint32le, ['normalizationDisabled'])
743
- });
744
- // 'name' is gone
745
- // 'ordr' now part of 'tran'
746
- // 'strs'
747
- this.COMP_PLUS_STRS_ITEM = new r.Struct({
748
- // While we use length which is number of utf-16 code units excluding null terminator,
749
- // we always write a null terminator, so we can get restructure to do that for us here
750
- offset: r.uint32le,
751
- length: r.uint32le
752
- });
753
- this.COMP_PLUS_STRS = new r.Struct({
754
- ident: IDENT,
755
- size: r.uint32le,
756
- count: r.uint32le,
757
- items: new r.Array(this.COMP_PLUS_STRS_ITEM, 'count')
758
- // + variable subtable: String data (see KMXPlusBuilder.emitStrings())
759
- });
760
- // 'tran'
761
- this.COMP_PLUS_TRAN_GROUP = new r.Struct({
762
- type: r.uint32le,
763
- count: r.uint32le,
764
- index: r.uint32le, //index into subtable
765
- });
766
- this.COMP_PLUS_TRAN_TRANSFORM = new r.Struct({
767
- from: STR_REF,
768
- to: STR_REF,
769
- mapFrom: ELEM_REF,
770
- mapTo: ELEM_REF //elem
771
- });
772
- this.COMP_PLUS_TRAN_REORDER = new r.Struct({
773
- elements: ELEM_REF,
774
- before: ELEM_REF, //elem
775
- });
776
- this.COMP_PLUS_TRAN = new r.Struct({
777
- ident: IDENT,
778
- size: r.uint32le,
779
- groupCount: r.uint32le,
780
- transformCount: r.uint32le,
781
- reorderCount: r.uint32le,
782
- groups: new r.Array(this.COMP_PLUS_TRAN_GROUP, 'groupCount'),
783
- transforms: new r.Array(this.COMP_PLUS_TRAN_TRANSFORM, 'transformCount'),
784
- reorders: new r.Array(this.COMP_PLUS_TRAN_REORDER, 'reorderCount'),
785
- });
786
- // 'uset'
787
- this.COMP_PLUS_USET_USET = new r.Struct({
788
- range: r.uint32le,
789
- count: r.uint32le,
790
- pattern: STR_REF, // str
791
- });
792
- this.COMP_PLUS_USET_RANGE = new r.Struct({
793
- start: CHAR32,
794
- end: CHAR32,
795
- });
796
- this.COMP_PLUS_USET = new r.Struct({
797
- ident: IDENT,
798
- size: r.uint32le,
799
- usetCount: r.uint32le,
800
- rangeCount: r.uint32le,
801
- usets: new r.Array(this.COMP_PLUS_USET_USET, 'usetCount'),
802
- ranges: new r.Array(this.COMP_PLUS_USET_RANGE, 'rangeCount'),
803
- });
804
- // 'vars'
805
- this.COMP_PLUS_VARS_ITEM = new r.Struct({
806
- type: r.uint32le,
807
- id: STR_REF,
808
- value: STR_REF,
809
- elem: ELEM_REF,
810
- });
811
- this.COMP_PLUS_VARS = new r.Struct({
812
- ident: IDENT,
813
- size: r.uint32le,
814
- markers: LIST_REF,
815
- varCount: r.uint32le,
816
- varEntries: new r.Array(this.COMP_PLUS_VARS_ITEM, 'varCount'),
817
- });
818
- // 'vkey' is removed
819
- // Aliases
820
- this.COMP_PLUS_BKSP = this.COMP_PLUS_TRAN;
821
- }
822
- }
823
- //# debugId=551e923f-be50-506a-8fac-8168c09bce5b
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="13f36df0-a89d-554b-8fe1-c2f2e8d02022")}catch(e){}}();
3
+ import { constants } from '@keymanapp/ldml-keyboard-constants';
4
+ import * as r from 'restructure';
5
+ import { ElementString } from './element-string.js';
6
+ import { ListItem } from './string-list.js';
7
+ import { isOneChar, toOneChar, unescapeString, escapeStringForRegex } from '../util/util.js';
8
+ import { KMXFile } from './kmx.js';
9
+ import { VariableParser } from '../ldml-keyboard/pattern-parser.js';
10
+ import { MarkerParser } from '../ldml-keyboard/pattern-parser.js';
11
+ // Implementation of file structures from /core/src/ldml/C7043_ldml.md
12
+ // Writer in kmx-builder.ts
13
+ // Reader in kmx-loader.ts
14
+ export class Section {
15
+ }
16
+ // 'sect'
17
+ export class Sect extends Section {
18
+ }
19
+ ;
20
+ // 'bksp' -- see 'tran'
21
+ // 'elem'
22
+ export class Elem extends Section {
23
+ strings = [];
24
+ constructor(sections) {
25
+ super();
26
+ this.strings.push(ElementString.fromStrings(sections, '')); // C7043: null element string
27
+ }
28
+ /**
29
+ * @param source if a string array, does not get reinterpreted as UnicodeSet. This is used with vars, etc. Or pass `["str"]` for an explicit 1-element elem.
30
+ * If it is a string, will be interpreted per reorder element ruls.
31
+ */
32
+ allocElementString(sections, source, order, tertiary, tertiary_base, prebase) {
33
+ let s = ElementString.fromStrings(sections, source, order, tertiary, tertiary_base, prebase);
34
+ if (!s)
35
+ return s;
36
+ let result = this.strings.find(item => item.isEqual(s));
37
+ if (result === undefined) {
38
+ result = s;
39
+ this.strings.push(result);
40
+ }
41
+ return result;
42
+ }
43
+ }
44
+ ;
45
+ // 'keys' is now `keys2.kmap`
46
+ // 'loca'
47
+ export class Loca extends Section {
48
+ locales = [];
49
+ }
50
+ ;
51
+ // 'meta'
52
+ export var KeyboardSettings;
53
+ (function (KeyboardSettings) {
54
+ KeyboardSettings[KeyboardSettings["none"] = 0] = "none";
55
+ KeyboardSettings[KeyboardSettings["normalizationDisabled"] = constants.meta_settings_normalization_disabled] = "normalizationDisabled";
56
+ })(KeyboardSettings || (KeyboardSettings = {}));
57
+ ;
58
+ export class Meta extends Section {
59
+ author;
60
+ conform;
61
+ layout;
62
+ name;
63
+ indicator;
64
+ version; // semver version string, defaults to "0"
65
+ settings;
66
+ /** convenience for checking settings */
67
+ get normalizationDisabled() {
68
+ return this?.settings & KeyboardSettings.normalizationDisabled;
69
+ }
70
+ }
71
+ ;
72
+ // 'strs'
73
+ /**
74
+ * A string item in memory. This will be replaced with an index
75
+ * into the string table at finalization.
76
+ */
77
+ export class StrsItem {
78
+ /** string value */
79
+ value;
80
+ /** char value if this is a single-char placeholder item (CharStrsItem) */
81
+ char;
82
+ constructor(value, char) {
83
+ if (char !== undefined) {
84
+ if (!isOneChar(value)) {
85
+ throw new Error(`StrsItem: ${value} is not a single char`);
86
+ }
87
+ if (char !== toOneChar(value)) {
88
+ throw new Error(`StrsItem: ${char} is not the right codepoint for ${value}`);
89
+ }
90
+ }
91
+ this.value = value;
92
+ this.char = char;
93
+ }
94
+ compareTo(o) {
95
+ return StrsItem.binaryStringCompare(this.value, o.value);
96
+ }
97
+ static binaryStringCompare(a, b) {
98
+ // https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islessthan
99
+ if (typeof a != 'string' || typeof b != 'string') {
100
+ throw new Error('binaryStringCompare: inputs must be strings');
101
+ }
102
+ if (a < b)
103
+ return -1;
104
+ if (a > b)
105
+ return 1;
106
+ return 0;
107
+ }
108
+ get isOneChar() {
109
+ return this.char !== undefined;
110
+ }
111
+ }
112
+ ;
113
+ /**
114
+ * A StrsItem for a single char. Used as a placeholder and hint to the builder
115
+ */
116
+ export class CharStrsItem extends StrsItem {
117
+ constructor(value) {
118
+ if (!isOneChar(value)) {
119
+ throw RangeError(`not a 1-char string`);
120
+ }
121
+ super(value, toOneChar(value));
122
+ }
123
+ }
124
+ ;
125
+ ;
126
+ export class Strs extends Section {
127
+ /** the in-memory string table */
128
+ strings = [new StrsItem('')]; // C7043: The null string is always required
129
+ /** for validating */
130
+ allProcessedStrings = new Set();
131
+ /**
132
+ * Allocate a StrsItem given the string, unescaping if necessary.
133
+ * @param s escaped string
134
+ * @param opts options for allocation
135
+ * @param sections other sections, if needed
136
+ * @returns StrsItem
137
+ */
138
+ allocString(s, opts, sections) {
139
+ // Run the string processing pipeline
140
+ s = Strs.processString(s, opts, sections);
141
+ // add to the set, for testing
142
+ if (s) {
143
+ this.allProcessedStrings.add(s);
144
+ }
145
+ // if it's a single char, don't push it into the strs table
146
+ if (opts?.singleOk && isOneChar(s)) {
147
+ return new CharStrsItem(s);
148
+ }
149
+ // default: look to see if the string is already present
150
+ let result = this.strings.find(item => item.value === s);
151
+ if (result === undefined) {
152
+ // only add if not already present
153
+ result = new StrsItem(s);
154
+ this.strings.push(result);
155
+ }
156
+ return result;
157
+ }
158
+ /** process everything according to opts */
159
+ static processString(s, opts, sections) {
160
+ s = s ?? '';
161
+ // type check everything else
162
+ if (typeof s !== 'string') {
163
+ throw new Error('alloc_string: s must be a string, undefined, or null.');
164
+ }
165
+ // substitute variables
166
+ if (opts?.stringVariables) {
167
+ s = sections.vars.substituteStrings(s, sections);
168
+ }
169
+ // substitute markers
170
+ if (opts?.markers) {
171
+ s = sections.vars.substituteMarkerString(s);
172
+ }
173
+ // unescape \u{…}
174
+ if (opts?.unescape) {
175
+ s = unescapeString(s);
176
+ }
177
+ // nfd
178
+ if (opts?.nfd) {
179
+ if (!sections?.meta?.normalizationDisabled) {
180
+ if (opts?.markers) {
181
+ s = MarkerParser.nfd_markers(s, false);
182
+ }
183
+ else {
184
+ s = s.normalize("NFD");
185
+ }
186
+ }
187
+ }
188
+ return s;
189
+ }
190
+ }
191
+ ;
192
+ /**
193
+ * See LKVariables
194
+ */
195
+ export class Vars extends Section {
196
+ totalCount() {
197
+ return this.strings.length + this.sets.length + this.usets.length;
198
+ }
199
+ markers;
200
+ strings = []; // ≠ StrsItem
201
+ sets = [];
202
+ usets = [];
203
+ /**
204
+ *
205
+ * @returns false if any invalid variables
206
+ */
207
+ valid() {
208
+ for (const t of [this.sets, this.strings, this.usets]) {
209
+ for (const i of t) {
210
+ if (!i.valid()) {
211
+ return false;
212
+ }
213
+ }
214
+ }
215
+ return true;
216
+ }
217
+ // utilities for making use of Vars in other sections
218
+ substituteSets(str, sections) {
219
+ return str.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
220
+ const val = Vars.findVariable(this.sets, id);
221
+ if (val === null) {
222
+ // Should have been caught during validation.
223
+ throw Error(`Internal Error: reference to missing set variable ${id}`);
224
+ }
225
+ return val.value.value;
226
+ });
227
+ }
228
+ substituteUnicodeSets(value, sections) {
229
+ return value.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
230
+ const v = Vars.findVariable(this.usets, id);
231
+ if (v === null) {
232
+ // Should have been caught during validation.
233
+ throw Error(`Internal Error: reference to missing UnicodeSet variable ${id}`);
234
+ }
235
+ return v.value.value; // string value
236
+ });
237
+ }
238
+ substituteStrings(str, sections, forMatch) {
239
+ if (!str)
240
+ return str;
241
+ return str.replaceAll(VariableParser.STRING_REFERENCE, (_entire, id) => {
242
+ const val = this.findStringVariableValue(id);
243
+ if (val === null) {
244
+ // Should have been caught during validation.
245
+ throw Error(`Internal Error: reference to missing string variable ${id}`);
246
+ }
247
+ if (forMatch)
248
+ return escapeStringForRegex(val);
249
+ return val;
250
+ });
251
+ }
252
+ findStringVariableValue(id) {
253
+ return Vars.findVariable(this.strings, id)?.value?.value; // Unwrap: Variable, StrsItem
254
+ }
255
+ substituteSetRegex(str, sections) {
256
+ return str.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
257
+ // try as set
258
+ const set = Vars.findVariable(this.sets, id);
259
+ if (set !== null) {
260
+ const { items } = set;
261
+ const escapedStrings = items.map(v => escapeStringForRegex(v.value.value));
262
+ const inner = escapedStrings.join('|');
263
+ return `(?:${inner})`;
264
+ }
265
+ // try as unicodeset
266
+ const uset = Vars.findVariable(this.usets, id);
267
+ if (uset !== null) {
268
+ const { unicodeSet } = uset;
269
+ const inner = unicodeSet.ranges.map(([start, end]) => {
270
+ const s = String.fromCodePoint(start);
271
+ if (start === end) {
272
+ return s;
273
+ }
274
+ else {
275
+ const e = String.fromCodePoint(end);
276
+ return `${s}-${e}`;
277
+ }
278
+ }).join('');
279
+ return `[${inner}]`;
280
+ }
281
+ // else, missing
282
+ throw Error(`Internal Error: reference to missing set variable ${id}`);
283
+ });
284
+ }
285
+ /**
286
+ * Variable locator facility
287
+ * @param array
288
+ * @param id
289
+ * @returns
290
+ */
291
+ static findVariable(array, id) {
292
+ const v = array.filter(e => e.id.value === id);
293
+ if (v.length === 0) {
294
+ return null;
295
+ }
296
+ else if (v.length !== 1) {
297
+ // Should have been caught during validation
298
+ throw Error(`Internal Error: Duplicate variable id ${id} crept into a variable list.`);
299
+ }
300
+ else {
301
+ return v[0];
302
+ }
303
+ }
304
+ substituteMarkerString(s, forMatch) {
305
+ return MarkerParser.toSentinelString(s, this.markers, forMatch);
306
+ }
307
+ }
308
+ ;
309
+ /**
310
+ * Common base for variable sections
311
+ * See Variable
312
+ */
313
+ export class VarsItem extends Section {
314
+ id;
315
+ value;
316
+ constructor(id, value, sections) {
317
+ super();
318
+ this.id = sections.strs.allocString(id);
319
+ this.value = sections.strs.allocString(value, { unescape: true });
320
+ }
321
+ valid() {
322
+ return true;
323
+ }
324
+ }
325
+ ;
326
+ export class UnicodeSetItem extends VarsItem {
327
+ constructor(id, value, sections, usetparser) {
328
+ super(id, value, sections);
329
+ const needRanges = sections.usetparser.sizeUnicodeSet(value);
330
+ if (needRanges >= 0) {
331
+ this.unicodeSet = sections.usetparser.parseUnicodeSet(value, needRanges);
332
+ } // otherwise: error (was recorded via callback)
333
+ }
334
+ unicodeSet;
335
+ valid() {
336
+ return !!this.unicodeSet;
337
+ }
338
+ }
339
+ ;
340
+ export class SetVarItem extends VarsItem {
341
+ constructor(id, value, sections, rawItems) {
342
+ super(id, value.join(' '), sections);
343
+ this.items = sections.elem.allocElementString(sections, value);
344
+ this.rawItems = rawItems;
345
+ }
346
+ // element string array
347
+ items;
348
+ // like items, but with unprocessed marker strings
349
+ rawItems;
350
+ valid() {
351
+ return !!this.items;
352
+ }
353
+ }
354
+ ;
355
+ export class StringVarItem extends VarsItem {
356
+ constructor(id, value, sections) {
357
+ super(id, value, sections);
358
+ }
359
+ }
360
+ ;
361
+ // 'tran'
362
+ export class TranTransform {
363
+ from;
364
+ to;
365
+ mapFrom; // var name
366
+ mapTo; // var name
367
+ }
368
+ export class TranGroup {
369
+ type; // tran_group_type_transform | tran_group_type_reorder
370
+ transforms = [];
371
+ reorders = [];
372
+ }
373
+ export class TranReorder {
374
+ elements;
375
+ before;
376
+ }
377
+ ;
378
+ export class Tran extends Section {
379
+ groups = [];
380
+ get id() {
381
+ return constants.section.tran;
382
+ }
383
+ }
384
+ ;
385
+ export class UsetItem {
386
+ uset;
387
+ str;
388
+ constructor(uset, str) {
389
+ this.uset = uset;
390
+ this.str = str;
391
+ }
392
+ compareTo(other) {
393
+ return this.str.compareTo(other.str);
394
+ }
395
+ }
396
+ ;
397
+ export class Uset extends Section {
398
+ usets = [];
399
+ allocUset(set, sections) {
400
+ // match the same pattern
401
+ let result = this.usets.find(s => set.pattern == s.uset.pattern);
402
+ if (result === undefined) {
403
+ result = new UsetItem(set, sections.strs.allocString(set.pattern));
404
+ this.usets.push(result);
405
+ }
406
+ return result;
407
+ }
408
+ }
409
+ ;
410
+ // alias type for 'bksp'
411
+ export class Bksp extends Tran {
412
+ get id() {
413
+ return constants.section.bksp;
414
+ }
415
+ }
416
+ ;
417
+ // 'disp'
418
+ export class DispItem {
419
+ to;
420
+ id;
421
+ display;
422
+ }
423
+ ;
424
+ export class Disp extends Section {
425
+ baseCharacter;
426
+ disps = [];
427
+ }
428
+ ;
429
+ // 'layr'
430
+ /**
431
+ * In-memory `<layers>`
432
+ */
433
+ export class LayrList {
434
+ hardware;
435
+ layers = [];
436
+ minDeviceWidth; // millimeters
437
+ }
438
+ ;
439
+ /**
440
+ * In-memory `<layer>`
441
+ */
442
+ export class LayrEntry {
443
+ id;
444
+ mod;
445
+ rows = [];
446
+ }
447
+ ;
448
+ /**
449
+ * In-memory `<row>`
450
+ */
451
+ export class LayrRow {
452
+ keys = [];
453
+ }
454
+ ;
455
+ export class Layr extends Section {
456
+ lists = [];
457
+ }
458
+ ;
459
+ export class KeysKeys {
460
+ flags;
461
+ flicks; // for in-memory only
462
+ id;
463
+ longPress;
464
+ longPressDefault;
465
+ multiTap;
466
+ switch;
467
+ to;
468
+ width;
469
+ }
470
+ ;
471
+ export class KeysKmap {
472
+ vkey;
473
+ mod;
474
+ key; // for in-memory only
475
+ }
476
+ ;
477
+ export class KeysFlicks {
478
+ flicks = [];
479
+ id;
480
+ compareTo(b) {
481
+ return this.id.compareTo(b.id);
482
+ }
483
+ constructor(id) {
484
+ this.id = id;
485
+ }
486
+ }
487
+ ;
488
+ export class KeysFlick {
489
+ directions;
490
+ keyId;
491
+ }
492
+ ;
493
+ export class Keys extends Section {
494
+ keys = [];
495
+ flicks = [];
496
+ kmap = [];
497
+ constructor(strs) {
498
+ super();
499
+ let nullFlicks = new KeysFlicks(strs.allocString(''));
500
+ this.flicks.push(nullFlicks); // C7043: null element string
501
+ }
502
+ }
503
+ ;
504
+ export class List extends Section {
505
+ /**
506
+ * Allocate a list from a space-separated list of items.
507
+ * Note that passing undefined or null or `''` will
508
+ * end up being the same as the empty list `[]`
509
+ * @param s space-separated list of items
510
+ * @param opts string options
511
+ * @param sections sections
512
+ * @returns a List object
513
+ */
514
+ allocListFromSpaces(s, opts, sections) {
515
+ s = s ?? '';
516
+ return this.allocList(s.split(' '), opts, sections);
517
+ }
518
+ /**
519
+ * Return a List object referring to the string list.
520
+ * Note that a falsy list, or a list containing only an empty string
521
+ * `['']` will be stored as an empty list `[]`.
522
+ * @param strs Strs section for allocation
523
+ * @param s string list to allocate
524
+ * @returns
525
+ */
526
+ allocList(s, opts, sections) {
527
+ // Special case the 'null' list for [] or ['']
528
+ if (!s || (s.length === 1 && s[0] === '')) {
529
+ return this.lists[0];
530
+ }
531
+ let result = this.lists.find(item => item.isEqual(s));
532
+ if (result === undefined) {
533
+ // allocate a new ListItem
534
+ result = ListItem.fromStrings(s, opts, sections);
535
+ this.lists.push(result);
536
+ }
537
+ return result;
538
+ }
539
+ constructor(strs) {
540
+ super();
541
+ this.lists.push(ListItem.fromStrings([], {}, { strs })); // C7043: null element string
542
+ }
543
+ lists = [];
544
+ }
545
+ ;
546
+ export { ListItem as ListItem };
547
+ ;
548
+ export class KMXPlusFile extends KMXFile {
549
+ /* KMXPlus file structures */
550
+ COMP_PLUS_SECT_ITEM;
551
+ COMP_PLUS_SECT;
552
+ // COMP_PLUS_BKSP == COMP_PLUS_TRAN
553
+ COMP_PLUS_BKSP_ITEM;
554
+ COMP_PLUS_BKSP;
555
+ COMP_PLUS_DISP_ITEM;
556
+ COMP_PLUS_DISP;
557
+ COMP_PLUS_ELEM_ELEMENT;
558
+ COMP_PLUS_ELEM_STRING;
559
+ COMP_PLUS_ELEM;
560
+ // COMP_PLUS_KEYS is now COMP_PLUS_KEYS_KMAP
561
+ COMP_PLUS_LAYR_ENTRY;
562
+ COMP_PLUS_LAYR_KEY;
563
+ COMP_PLUS_LAYR_LIST;
564
+ COMP_PLUS_LAYR_ROW;
565
+ COMP_PLUS_LAYR;
566
+ COMP_PLUS_KEYS_FLICK;
567
+ COMP_PLUS_KEYS_FLICKS;
568
+ COMP_PLUS_KEYS_KEY;
569
+ COMP_PLUS_KEYS_KMAP;
570
+ COMP_PLUS_KEYS;
571
+ COMP_PLUS_LIST_LIST;
572
+ COMP_PLUS_LIST_INDEX;
573
+ COMP_PLUS_LIST;
574
+ COMP_PLUS_LOCA_ITEM;
575
+ COMP_PLUS_LOCA;
576
+ COMP_PLUS_META;
577
+ COMP_PLUS_STRS_ITEM;
578
+ COMP_PLUS_STRS;
579
+ COMP_PLUS_TRAN_GROUP;
580
+ COMP_PLUS_TRAN_TRANSFORM;
581
+ COMP_PLUS_TRAN_REORDER;
582
+ COMP_PLUS_TRAN;
583
+ COMP_PLUS_USET_USET;
584
+ COMP_PLUS_USET_RANGE;
585
+ COMP_PLUS_USET;
586
+ COMP_PLUS_VKEY_ITEM;
587
+ COMP_PLUS_VKEY;
588
+ COMP_PLUS_VARS;
589
+ COMP_PLUS_VARS_ITEM;
590
+ /* File in-memory data */
591
+ kmxplus = {};
592
+ constructor() {
593
+ super();
594
+ // Binary-correct structures matching kmx_plus.h
595
+ // helpers
596
+ const STR_REF = r.uint32le;
597
+ const ELEM_REF = r.uint32le;
598
+ const LIST_REF = r.uint32le;
599
+ const STR_OR_CHAR32 = r.uint32le;
600
+ const CHAR32 = r.uint32le;
601
+ const STR_OR_CHAR32_OR_USET = r.uint32le;
602
+ const IDENT = r.uint32le;
603
+ // 'sect'
604
+ this.COMP_PLUS_SECT_ITEM = new r.Struct({
605
+ sect: r.uint32le,
606
+ offset: r.uint32le //? new r.VoidPointer(r.uint32le, {type: 'global'})
607
+ });
608
+ this.COMP_PLUS_SECT = new r.Struct({
609
+ ident: IDENT,
610
+ size: r.uint32le,
611
+ total: r.uint32le,
612
+ count: r.uint32le,
613
+ items: new r.Array(this.COMP_PLUS_SECT_ITEM, 'count')
614
+ });
615
+ // 'bksp' - see 'tran'
616
+ // 'disp'
617
+ this.COMP_PLUS_DISP_ITEM = new r.Struct({
618
+ to: STR_REF,
619
+ id: STR_REF,
620
+ display: STR_REF,
621
+ });
622
+ this.COMP_PLUS_DISP = new r.Struct({
623
+ ident: IDENT,
624
+ size: r.uint32le,
625
+ count: r.uint32le,
626
+ baseCharacter: CHAR32,
627
+ items: new r.Array(this.COMP_PLUS_DISP_ITEM, 'count'),
628
+ });
629
+ // 'elem'
630
+ this.COMP_PLUS_ELEM_ELEMENT = new r.Struct({
631
+ element: STR_OR_CHAR32_OR_USET,
632
+ flags: r.uint32le
633
+ });
634
+ this.COMP_PLUS_ELEM_STRING = new r.Struct({
635
+ offset: r.uint32le,
636
+ length: r.uint32le
637
+ });
638
+ this.COMP_PLUS_ELEM = new r.Struct({
639
+ ident: IDENT,
640
+ size: r.uint32le,
641
+ count: r.uint32le,
642
+ strings: new r.Array(this.COMP_PLUS_ELEM_STRING, 'count')
643
+ // + variable subtable: Element data (see KMXPlusBuilder.emitElements())
644
+ });
645
+ // 'finl' - see 'tran'
646
+ // 'keys' - see 'keys.kmap'
647
+ // 'layr'
648
+ this.COMP_PLUS_LAYR_ENTRY = new r.Struct({
649
+ id: r.uint32le,
650
+ mod: r.uint32le,
651
+ row: r.uint32le,
652
+ count: r.uint32le,
653
+ });
654
+ this.COMP_PLUS_LAYR_KEY = new r.Struct({
655
+ key: r.uint32le, // str: key id
656
+ });
657
+ this.COMP_PLUS_LAYR_LIST = new r.Struct({
658
+ hardware: STR_REF,
659
+ layer: r.uint32le,
660
+ count: r.uint32le,
661
+ minDeviceWidth: r.uint32le, // integer: millimeters
662
+ });
663
+ this.COMP_PLUS_LAYR_ROW = new r.Struct({
664
+ key: r.uint32le,
665
+ count: r.uint32le,
666
+ });
667
+ this.COMP_PLUS_LAYR = new r.Struct({
668
+ ident: IDENT,
669
+ size: r.uint32le,
670
+ listCount: r.uint32le,
671
+ layerCount: r.uint32le,
672
+ rowCount: r.uint32le,
673
+ keyCount: r.uint32le,
674
+ lists: new r.Array(this.COMP_PLUS_LAYR_LIST, 'listCount'),
675
+ layers: new r.Array(this.COMP_PLUS_LAYR_ENTRY, 'layerCount'),
676
+ rows: new r.Array(this.COMP_PLUS_LAYR_ROW, 'rowCount'),
677
+ keys: new r.Array(this.COMP_PLUS_LAYR_KEY, 'keyCount'),
678
+ });
679
+ this.COMP_PLUS_KEYS_FLICK = new r.Struct({
680
+ directions: LIST_REF,
681
+ to: STR_OR_CHAR32, // str | codepoint
682
+ });
683
+ this.COMP_PLUS_KEYS_FLICKS = new r.Struct({
684
+ count: r.uint32le,
685
+ flick: r.uint32le,
686
+ id: STR_REF, // str
687
+ });
688
+ this.COMP_PLUS_KEYS_KEY = new r.Struct({
689
+ to: STR_OR_CHAR32,
690
+ flags: r.uint32le,
691
+ id: STR_REF,
692
+ switch: STR_REF,
693
+ width: r.uint32le,
694
+ longPress: LIST_REF,
695
+ longPressDefault: STR_REF,
696
+ multiTap: LIST_REF,
697
+ flicks: r.uint32le, // index into flicks table
698
+ });
699
+ this.COMP_PLUS_KEYS_KMAP = new r.Struct({
700
+ vkey: r.uint32le,
701
+ mod: r.uint32le,
702
+ key: r.uint32le, // index into 'keys' subtable
703
+ });
704
+ this.COMP_PLUS_KEYS = new r.Struct({
705
+ ident: IDENT,
706
+ size: r.uint32le,
707
+ keyCount: r.uint32le,
708
+ flicksCount: r.uint32le,
709
+ flickCount: r.uint32le,
710
+ kmapCount: r.uint32le,
711
+ keys: new r.Array(this.COMP_PLUS_KEYS_KEY, 'keyCount'),
712
+ flicks: new r.Array(this.COMP_PLUS_KEYS_FLICKS, 'flicksCount'),
713
+ flick: new r.Array(this.COMP_PLUS_KEYS_FLICK, 'flickCount'),
714
+ kmap: new r.Array(this.COMP_PLUS_KEYS_KMAP, 'kmapCount'),
715
+ });
716
+ // 'list'
717
+ this.COMP_PLUS_LIST_LIST = new r.Struct({
718
+ index: r.uint32le,
719
+ count: r.uint32le,
720
+ });
721
+ this.COMP_PLUS_LIST_INDEX = new r.Struct({
722
+ str: STR_REF, // str
723
+ });
724
+ this.COMP_PLUS_LIST = new r.Struct({
725
+ ident: IDENT,
726
+ size: r.uint32le,
727
+ listCount: r.uint32le,
728
+ indexCount: r.uint32le,
729
+ lists: new r.Array(this.COMP_PLUS_LIST_LIST, 'listCount'),
730
+ indices: new r.Array(this.COMP_PLUS_LIST_INDEX, 'indexCount'),
731
+ });
732
+ // 'loca'
733
+ this.COMP_PLUS_LOCA_ITEM = r.uint32le; //str
734
+ this.COMP_PLUS_LOCA = new r.Struct({
735
+ ident: IDENT,
736
+ size: r.uint32le,
737
+ count: r.uint32le,
738
+ items: new r.Array(this.COMP_PLUS_LOCA_ITEM, 'count')
739
+ });
740
+ // 'meta'
741
+ this.COMP_PLUS_META = new r.Struct({
742
+ ident: IDENT,
743
+ size: r.uint32le,
744
+ author: STR_REF,
745
+ conform: STR_REF,
746
+ layout: STR_REF,
747
+ name: STR_REF,
748
+ indicator: STR_REF,
749
+ version: STR_REF,
750
+ settings: r.uint32le, //new r.Bitfield(r.uint32le, ['normalizationDisabled'])
751
+ });
752
+ // 'name' is gone
753
+ // 'ordr' now part of 'tran'
754
+ // 'strs'
755
+ this.COMP_PLUS_STRS_ITEM = new r.Struct({
756
+ // While we use length which is number of utf-16 code units excluding null terminator,
757
+ // we always write a null terminator, so we can get restructure to do that for us here
758
+ offset: r.uint32le,
759
+ length: r.uint32le
760
+ });
761
+ this.COMP_PLUS_STRS = new r.Struct({
762
+ ident: IDENT,
763
+ size: r.uint32le,
764
+ count: r.uint32le,
765
+ items: new r.Array(this.COMP_PLUS_STRS_ITEM, 'count')
766
+ // + variable subtable: String data (see KMXPlusBuilder.emitStrings())
767
+ });
768
+ // 'tran'
769
+ this.COMP_PLUS_TRAN_GROUP = new r.Struct({
770
+ type: r.uint32le,
771
+ count: r.uint32le,
772
+ index: r.uint32le, //index into subtable
773
+ });
774
+ this.COMP_PLUS_TRAN_TRANSFORM = new r.Struct({
775
+ from: STR_REF,
776
+ to: STR_REF,
777
+ mapFrom: ELEM_REF,
778
+ mapTo: ELEM_REF //elem
779
+ });
780
+ this.COMP_PLUS_TRAN_REORDER = new r.Struct({
781
+ elements: ELEM_REF,
782
+ before: ELEM_REF, //elem
783
+ });
784
+ this.COMP_PLUS_TRAN = new r.Struct({
785
+ ident: IDENT,
786
+ size: r.uint32le,
787
+ groupCount: r.uint32le,
788
+ transformCount: r.uint32le,
789
+ reorderCount: r.uint32le,
790
+ groups: new r.Array(this.COMP_PLUS_TRAN_GROUP, 'groupCount'),
791
+ transforms: new r.Array(this.COMP_PLUS_TRAN_TRANSFORM, 'transformCount'),
792
+ reorders: new r.Array(this.COMP_PLUS_TRAN_REORDER, 'reorderCount'),
793
+ });
794
+ // 'uset'
795
+ this.COMP_PLUS_USET_USET = new r.Struct({
796
+ range: r.uint32le,
797
+ count: r.uint32le,
798
+ pattern: STR_REF, // str
799
+ });
800
+ this.COMP_PLUS_USET_RANGE = new r.Struct({
801
+ start: CHAR32,
802
+ end: CHAR32,
803
+ });
804
+ this.COMP_PLUS_USET = new r.Struct({
805
+ ident: IDENT,
806
+ size: r.uint32le,
807
+ usetCount: r.uint32le,
808
+ rangeCount: r.uint32le,
809
+ usets: new r.Array(this.COMP_PLUS_USET_USET, 'usetCount'),
810
+ ranges: new r.Array(this.COMP_PLUS_USET_RANGE, 'rangeCount'),
811
+ });
812
+ // 'vars'
813
+ this.COMP_PLUS_VARS_ITEM = new r.Struct({
814
+ type: r.uint32le,
815
+ id: STR_REF,
816
+ value: STR_REF,
817
+ elem: ELEM_REF,
818
+ });
819
+ this.COMP_PLUS_VARS = new r.Struct({
820
+ ident: IDENT,
821
+ size: r.uint32le,
822
+ markers: LIST_REF,
823
+ varCount: r.uint32le,
824
+ varEntries: new r.Array(this.COMP_PLUS_VARS_ITEM, 'varCount'),
825
+ });
826
+ // 'vkey' is removed
827
+ // Aliases
828
+ this.COMP_PLUS_BKSP = this.COMP_PLUS_TRAN;
829
+ }
830
+ }
824
831
  //# sourceMappingURL=kmx-plus.js.map
832
+ //# debugId=13f36df0-a89d-554b-8fe1-c2f2e8d02022