@ifc-lite/encoding 2.0.0 → 2.2.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.
- package/dist/deterministic-uuid.d.ts +9 -0
- package/dist/deterministic-uuid.d.ts.map +1 -0
- package/dist/deterministic-uuid.js +97 -0
- package/dist/deterministic-uuid.js.map +1 -0
- package/dist/ifc-string.d.ts +45 -5
- package/dist/ifc-string.d.ts.map +1 -1
- package/dist/ifc-string.js +156 -11
- package/dist/ifc-string.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/numeric-literal.d.ts +27 -0
- package/dist/numeric-literal.d.ts.map +1 -0
- package/dist/numeric-literal.js +65 -0
- package/dist/numeric-literal.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable RFC-4122-shaped UUID derived purely from `seed`.
|
|
3
|
+
*
|
|
4
|
+
* - 8-4-4-4-12 lowercase hex
|
|
5
|
+
* - version nibble fixed to '4'
|
|
6
|
+
* - variant nibble in {8, 9, a, b}
|
|
7
|
+
*/
|
|
8
|
+
export declare function uuidFromSeed(seed: string): string;
|
|
9
|
+
//# sourceMappingURL=deterministic-uuid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deterministic-uuid.d.ts","sourceRoot":"","sources":["../src/deterministic-uuid.ts"],"names":[],"mappings":"AA+DA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqCjD"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* Deterministic, input-only UUID generation.
|
|
6
|
+
*
|
|
7
|
+
* Produces an RFC-4122-shaped identifier (8-4-4-4-12 lowercase hex) whose 128
|
|
8
|
+
* bits are derived purely from a seed string. The same seed always yields the
|
|
9
|
+
* same UUID, with no dependence on the system clock or any random source.
|
|
10
|
+
*
|
|
11
|
+
* Two callers need exactly that, which is why this sits in `@ifc-lite/encoding`
|
|
12
|
+
* beside {@link generateUuid} rather than in either of them:
|
|
13
|
+
* - `@ifc-lite/clash` makes a BCF topic guid a stable function of a clash-group
|
|
14
|
+
* id, so a re-run of the same coordination produces byte-identical topic
|
|
15
|
+
* guids and the round trip back to clashes stays anchored.
|
|
16
|
+
* - `@ifc-lite/bcf` fills the `DocumentReference/@Guid` that BCF 3.0 requires
|
|
17
|
+
* and BCF 2.1 leaves optional, so exporting one project twice yields the same
|
|
18
|
+
* bytes instead of a fresh random identifier each time (#3612).
|
|
19
|
+
*
|
|
20
|
+
* `@ifc-lite/clash` depends on `@ifc-lite/bcf`, so sharing had to go through a
|
|
21
|
+
* package below both; a second copy of the algorithm would have been two
|
|
22
|
+
* implementations of one identity scheme, kept in step by nothing but prose.
|
|
23
|
+
*
|
|
24
|
+
* The 128 bits are filled from four 32-bit words. Each word starts from an
|
|
25
|
+
* FNV-1a hash of the seed mixed with a distinct salt, then is run through a
|
|
26
|
+
* short xorshift cascade so adjacent seeds (e.g. "g1" vs "g2") diffuse into
|
|
27
|
+
* fully different words rather than differing in only a few low bits.
|
|
28
|
+
*/
|
|
29
|
+
const FNV_OFFSET_BASIS = 0x811c9dc5;
|
|
30
|
+
const FNV_PRIME = 0x01000193;
|
|
31
|
+
/** 32-bit FNV-1a over the UTF-8-ish code units of `input`, seeded with `salt`. */
|
|
32
|
+
function fnv1a(input, salt) {
|
|
33
|
+
let hash = (FNV_OFFSET_BASIS ^ salt) >>> 0;
|
|
34
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
35
|
+
const code = input.charCodeAt(i);
|
|
36
|
+
// Fold the full 16-bit code unit in two byte-sized steps so non-ASCII
|
|
37
|
+
// comment-free seeds still contribute every bit.
|
|
38
|
+
hash = (hash ^ (code & 0xff)) >>> 0;
|
|
39
|
+
hash = Math.imul(hash, FNV_PRIME) >>> 0;
|
|
40
|
+
hash = (hash ^ ((code >>> 8) & 0xff)) >>> 0;
|
|
41
|
+
hash = Math.imul(hash, FNV_PRIME) >>> 0;
|
|
42
|
+
}
|
|
43
|
+
return hash >>> 0;
|
|
44
|
+
}
|
|
45
|
+
/** A short xorshift cascade to diffuse a 32-bit word. */
|
|
46
|
+
function xorshift32(value) {
|
|
47
|
+
let x = value >>> 0;
|
|
48
|
+
x ^= x << 13;
|
|
49
|
+
x >>>= 0;
|
|
50
|
+
x ^= x >>> 17;
|
|
51
|
+
x ^= x << 5;
|
|
52
|
+
return x >>> 0;
|
|
53
|
+
}
|
|
54
|
+
/** Left-pad a non-negative 32-bit word to 8 lowercase hex chars. */
|
|
55
|
+
function hex32(value) {
|
|
56
|
+
return (value >>> 0).toString(16).padStart(8, '0');
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Stable RFC-4122-shaped UUID derived purely from `seed`.
|
|
60
|
+
*
|
|
61
|
+
* - 8-4-4-4-12 lowercase hex
|
|
62
|
+
* - version nibble fixed to '4'
|
|
63
|
+
* - variant nibble in {8, 9, a, b}
|
|
64
|
+
*/
|
|
65
|
+
export function uuidFromSeed(seed) {
|
|
66
|
+
// Four independent 32-bit words, each its own salt then xorshift-mixed.
|
|
67
|
+
const w0 = xorshift32(fnv1a(seed, 0x9e3779b1));
|
|
68
|
+
const w1 = xorshift32(fnv1a(seed, 0x85ebca77));
|
|
69
|
+
const w2 = xorshift32(fnv1a(seed, 0xc2b2ae3d));
|
|
70
|
+
const w3 = xorshift32(fnv1a(seed, 0x27d4eb2f));
|
|
71
|
+
// Cross-mix so each output nibble depends on the whole seed, not one word.
|
|
72
|
+
const a = xorshift32(w0 ^ Math.imul(w3, FNV_PRIME)) >>> 0;
|
|
73
|
+
const b = xorshift32(w1 ^ Math.imul(w0, FNV_PRIME)) >>> 0;
|
|
74
|
+
const c = xorshift32(w2 ^ Math.imul(w1, FNV_PRIME)) >>> 0;
|
|
75
|
+
const d = xorshift32(w3 ^ Math.imul(w2, FNV_PRIME)) >>> 0;
|
|
76
|
+
const hexA = hex32(a);
|
|
77
|
+
const hexB = hex32(b);
|
|
78
|
+
const hexC = hex32(c);
|
|
79
|
+
const hexD = hex32(d);
|
|
80
|
+
// Layout: AAAAAAAA-BBBB-4BBB-VCCC-CCCCDDDDDDDD
|
|
81
|
+
// time_low = hexA (8)
|
|
82
|
+
// time_mid = hexB[0..4) (4)
|
|
83
|
+
// time_hi_ver = '4' + hexB[4..7) (4, version nibble forced to 4)
|
|
84
|
+
// clock_variant = variant + hexC[1..4) (4)
|
|
85
|
+
// node = hexC[4..8) + hexD (12)
|
|
86
|
+
const timeLow = hexA;
|
|
87
|
+
const timeMid = hexB.slice(0, 4);
|
|
88
|
+
const timeHiAndVersion = `4${hexB.slice(4, 7)}`;
|
|
89
|
+
// Variant nibble: high two bits must be '10' -> one of 8, 9, a, b.
|
|
90
|
+
// Derive it from the top nibble of hexC so it is still seed-dependent.
|
|
91
|
+
const variantSource = parseInt(hexC[0], 16);
|
|
92
|
+
const variantNibble = ((variantSource & 0x3) | 0x8).toString(16);
|
|
93
|
+
const clockSeqAndVariant = `${variantNibble}${hexC.slice(1, 4)}`;
|
|
94
|
+
const node = `${hexC.slice(4, 8)}${hexD}`;
|
|
95
|
+
return `${timeLow}-${timeMid}-${timeHiAndVersion}-${clockSeqAndVariant}-${node}`;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=deterministic-uuid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deterministic-uuid.js","sourceRoot":"","sources":["../src/deterministic-uuid.ts"],"names":[],"mappings":"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"}
|
package/dist/ifc-string.d.ts
CHANGED
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
* Handles:
|
|
4
4
|
* - \X2\XXXX\X0\ - Unicode hex encoding (e.g., \X2\00E4\X0\ -> a with umlaut)
|
|
5
5
|
* - \X4\XXXXXXXX\X0\ - Unicode 4-byte hex for chars outside BMP
|
|
6
|
-
* - \X\XX\ - ISO-8859-1 hex encoding
|
|
7
|
-
*
|
|
8
|
-
* - \
|
|
6
|
+
* - \X\XX\ - ISO-8859-1 hex encoding (NOT code-page dependent: this is always
|
|
7
|
+
* the ISO 10646 row-0 value, per ISO 10303-21 6.4.3)
|
|
8
|
+
* - \S\X - Extended ASCII: code point of X plus 128, mapped through the
|
|
9
|
+
* currently selected \P?\ code page (default ISO 8859-1)
|
|
10
|
+
* - \PA\..\PI\ - Code page selectors (A=ISO 8859-1 .. I=ISO 8859-9); tracked
|
|
11
|
+
* for subsequent \S\ escapes, then the directive itself is dropped. Any
|
|
12
|
+
* other letter is dropped without changing the active page.
|
|
9
13
|
* - \\ - one literal backslash (ISO 10303-21 doubles the reverse solidus)
|
|
10
14
|
*
|
|
11
15
|
* The \\ pair is collapsed AFTER the directive arms: a directive immediately
|
|
@@ -19,12 +23,48 @@
|
|
|
19
23
|
*/
|
|
20
24
|
export declare function decodeIfcString(str: string): string;
|
|
21
25
|
/**
|
|
22
|
-
* Encode a Unicode string to IFC STEP
|
|
26
|
+
* Encode a Unicode string to IFC STEP directive escapes.
|
|
23
27
|
*
|
|
24
|
-
* - Printable ASCII (32..126) is kept as-is
|
|
28
|
+
* - Printable ASCII (32..126) is kept as-is, with ONE exception: the reverse
|
|
29
|
+
* solidus (`\`, U+005C) is printable ASCII but goes out as `\X\5C`, because
|
|
30
|
+
* a raw `\` in the output is what a reader takes for the start of a
|
|
31
|
+
* directive or of a `\\` pair.
|
|
25
32
|
* - 8-bit values are encoded as \X\HH.
|
|
26
33
|
* - BMP values are encoded as \X2\HHHH\X0\.
|
|
27
34
|
* - Non-BMP values are encoded as \X4\HHHHHHHH\X0\.
|
|
35
|
+
*
|
|
36
|
+
* This is directive encoding only — it does NOT double the apostrophe (`'`,
|
|
37
|
+
* code point 39 is printable ASCII and passes through unchanged). Its output
|
|
38
|
+
* is therefore **not** safe to place directly inside a STEP single-quoted
|
|
39
|
+
* string literal: an undoubled `'` terminates the literal early and produces
|
|
40
|
+
* a file no conformant reader parses as intended (e.g. a name like
|
|
41
|
+
* `O'Brien`). A caller writing into a literal must double `'` itself, or use
|
|
42
|
+
* `escapeStepString` from `@ifc-lite/data`, which handles the full
|
|
43
|
+
* literal-context contract: doubling `'` and `\`, mapping control characters
|
|
44
|
+
* to a space, and encoding non-ASCII —
|
|
45
|
+
* per ISO 10303-21 6.3.3.4. The two functions do not produce the same output
|
|
46
|
+
* for the same input; do not assume they agree. Sweeping U+0000..U+02FF, they
|
|
47
|
+
* disagree on exactly two of the 95 printable ASCII characters: the
|
|
48
|
+
* apostrophe (U+0027; doubled there, passed through here) and the reverse
|
|
49
|
+
* solidus (U+005C; doubled there, `\X\5C` here). They also disagree on all 32
|
|
50
|
+
* C0 controls AND on DEL (U+007F) -- a space there, `\X\HH` here, since
|
|
51
|
+
* `escapeStepString` collapses `/[\x00-\x1F\x7F]/g` to a space -- and on all
|
|
52
|
+
* 128 of U+0080..U+00FF (`\X2\HHHH\X0\` there, `\X\HH` here). That is 163
|
|
53
|
+
* disagreements in all. Above U+00FF they agree on all 512.
|
|
54
|
+
*
|
|
55
|
+
* Kept for round-trip use with {@link decodeIfcString}, within the scope the
|
|
56
|
+
* two functions actually cover: `decodeIfcString(encodeIfcString(s)) === s`
|
|
57
|
+
* for every `s` built from Unicode SCALAR values. That is not the same as
|
|
58
|
+
* every JS string. A JS string can also hold an unpaired surrogate
|
|
59
|
+
* (U+D800..U+DFFF), which is not a scalar value; this encoder writes it as a
|
|
60
|
+
* `\X2\` directive, and {@link decodeIfcString} decodes every lone surrogate
|
|
61
|
+
* to U+FFFD to stay in parity with the Rust decoder's
|
|
62
|
+
* `String::from_utf16_lossy`. Those 2048 code units are the only inputs that
|
|
63
|
+
* do not come back unchanged.
|
|
64
|
+
*
|
|
65
|
+
* Within that scope the guarantee is independent of apostrophe handling,
|
|
66
|
+
* because doubling is a literal-context requirement, not an encoding one.
|
|
67
|
+
* See https://github.com/LTplus-AG/ifc-lite/issues/3445.
|
|
28
68
|
*/
|
|
29
69
|
export declare function encodeIfcString(str: string): string;
|
|
30
70
|
//# sourceMappingURL=ifc-string.d.ts.map
|
package/dist/ifc-string.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc-string.d.ts","sourceRoot":"","sources":["../src/ifc-string.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ifc-string.d.ts","sourceRoot":"","sources":["../src/ifc-string.ts"],"names":[],"mappings":"AAuGA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyHnD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA6BnD"}
|
package/dist/ifc-string.js
CHANGED
|
@@ -1,14 +1,116 @@
|
|
|
1
1
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* Upper-half (0xA0..0xFF) code-point tables for the ISO 8859 parts a `\P?\`
|
|
6
|
+
* directive can select for a subsequent `\S\` (ISO 10303-21 6.4.3): letters
|
|
7
|
+
* A..I select ISO 8859-1..9 (A=1, the default, needs no table — its upper
|
|
8
|
+
* half is already the Unicode-identity mapping `\S\` used before this
|
|
9
|
+
* change). Index 0 below is codepage 2 (`\PB\`) .. index 7 is codepage 9
|
|
10
|
+
* (`\PI\`). `0000` marks a code position the ISO 8859 part itself leaves
|
|
11
|
+
* unassigned; ISO 10303-21 does not define decoder behaviour there, so
|
|
12
|
+
* {@link resolveExtendedChar} falls back to the raw byte value (the same
|
|
13
|
+
* answer the default page gives) rather than U+FFFD.
|
|
14
|
+
*
|
|
15
|
+
* Source: https://www.unicode.org/Public/MAPPINGS/ISO8859/8859-{2..9}.TXT
|
|
16
|
+
* (verified 2026-08-30). Keep in parity with `CODEPAGE_TABLES` in
|
|
17
|
+
* `rust/core/src/step_encoding.rs` — both are pinned by the codepage cases in
|
|
18
|
+
* `ifc_string_vectors.json`.
|
|
19
|
+
*/
|
|
20
|
+
const CODEPAGE_ROWS = [
|
|
21
|
+
// codepage 2: ISO 8859-2 (Central European)
|
|
22
|
+
'00A0 0104 02D8 0141 00A4 013D 015A 00A7 00A8 0160 015E 0164 0179 00AD 017D 017B',
|
|
23
|
+
'00B0 0105 02DB 0142 00B4 013E 015B 02C7 00B8 0161 015F 0165 017A 02DD 017E 017C',
|
|
24
|
+
'0154 00C1 00C2 0102 00C4 0139 0106 00C7 010C 00C9 0118 00CB 011A 00CD 00CE 010E',
|
|
25
|
+
'0110 0143 0147 00D3 00D4 0150 00D6 00D7 0158 016E 00DA 0170 00DC 00DD 0162 00DF',
|
|
26
|
+
'0155 00E1 00E2 0103 00E4 013A 0107 00E7 010D 00E9 0119 00EB 011B 00ED 00EE 010F',
|
|
27
|
+
'0111 0144 0148 00F3 00F4 0151 00F6 00F7 0159 016F 00FA 0171 00FC 00FD 0163 02D9',
|
|
28
|
+
// codepage 3: ISO 8859-3 (South European)
|
|
29
|
+
'00A0 0126 02D8 00A3 00A4 0000 0124 00A7 00A8 0130 015E 011E 0134 00AD 0000 017B',
|
|
30
|
+
'00B0 0127 00B2 00B3 00B4 00B5 0125 00B7 00B8 0131 015F 011F 0135 00BD 0000 017C',
|
|
31
|
+
'00C0 00C1 00C2 0000 00C4 010A 0108 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF',
|
|
32
|
+
'0000 00D1 00D2 00D3 00D4 0120 00D6 00D7 011C 00D9 00DA 00DB 00DC 016C 015C 00DF',
|
|
33
|
+
'00E0 00E1 00E2 0000 00E4 010B 0109 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF',
|
|
34
|
+
'0000 00F1 00F2 00F3 00F4 0121 00F6 00F7 011D 00F9 00FA 00FB 00FC 016D 015D 02D9',
|
|
35
|
+
// codepage 4: ISO 8859-4 (North European)
|
|
36
|
+
'00A0 0104 0138 0156 00A4 0128 013B 00A7 00A8 0160 0112 0122 0166 00AD 017D 00AF',
|
|
37
|
+
'00B0 0105 02DB 0157 00B4 0129 013C 02C7 00B8 0161 0113 0123 0167 014A 017E 014B',
|
|
38
|
+
'0100 00C1 00C2 00C3 00C4 00C5 00C6 012E 010C 00C9 0118 00CB 0116 00CD 00CE 012A',
|
|
39
|
+
'0110 0145 014C 0136 00D4 00D5 00D6 00D7 00D8 0172 00DA 00DB 00DC 0168 016A 00DF',
|
|
40
|
+
'0101 00E1 00E2 00E3 00E4 00E5 00E6 012F 010D 00E9 0119 00EB 0117 00ED 00EE 012B',
|
|
41
|
+
'0111 0146 014D 0137 00F4 00F5 00F6 00F7 00F8 0173 00FA 00FB 00FC 0169 016B 02D9',
|
|
42
|
+
// codepage 5: ISO 8859-5 (Cyrillic)
|
|
43
|
+
'00A0 0401 0402 0403 0404 0405 0406 0407 0408 0409 040A 040B 040C 00AD 040E 040F',
|
|
44
|
+
'0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F',
|
|
45
|
+
'0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 042A 042B 042C 042D 042E 042F',
|
|
46
|
+
'0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 043A 043B 043C 043D 043E 043F',
|
|
47
|
+
'0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 044A 044B 044C 044D 044E 044F',
|
|
48
|
+
'2116 0451 0452 0453 0454 0455 0456 0457 0458 0459 045A 045B 045C 00A7 045E 045F',
|
|
49
|
+
// codepage 6: ISO 8859-6 (Arabic)
|
|
50
|
+
'00A0 0000 0000 0000 00A4 0000 0000 0000 0000 0000 0000 0000 060C 00AD 0000 0000',
|
|
51
|
+
'0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 061B 0000 0000 0000 061F',
|
|
52
|
+
'0000 0621 0622 0623 0624 0625 0626 0627 0628 0629 062A 062B 062C 062D 062E 062F',
|
|
53
|
+
'0630 0631 0632 0633 0634 0635 0636 0637 0638 0639 063A 0000 0000 0000 0000 0000',
|
|
54
|
+
'0640 0641 0642 0643 0644 0645 0646 0647 0648 0649 064A 064B 064C 064D 064E 064F',
|
|
55
|
+
'0650 0651 0652 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000',
|
|
56
|
+
// codepage 7: ISO 8859-7 (Greek)
|
|
57
|
+
'00A0 2018 2019 00A3 20AC 20AF 00A6 00A7 00A8 00A9 037A 00AB 00AC 00AD 0000 2015',
|
|
58
|
+
'00B0 00B1 00B2 00B3 0384 0385 0386 00B7 0388 0389 038A 00BB 038C 00BD 038E 038F',
|
|
59
|
+
'0390 0391 0392 0393 0394 0395 0396 0397 0398 0399 039A 039B 039C 039D 039E 039F',
|
|
60
|
+
'03A0 03A1 0000 03A3 03A4 03A5 03A6 03A7 03A8 03A9 03AA 03AB 03AC 03AD 03AE 03AF',
|
|
61
|
+
'03B0 03B1 03B2 03B3 03B4 03B5 03B6 03B7 03B8 03B9 03BA 03BB 03BC 03BD 03BE 03BF',
|
|
62
|
+
'03C0 03C1 03C2 03C3 03C4 03C5 03C6 03C7 03C8 03C9 03CA 03CB 03CC 03CD 03CE 0000',
|
|
63
|
+
// codepage 8: ISO 8859-8 (Hebrew)
|
|
64
|
+
'00A0 0000 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00D7 00AB 00AC 00AD 00AE 00AF',
|
|
65
|
+
'00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00F7 00BB 00BC 00BD 00BE 0000',
|
|
66
|
+
'0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000',
|
|
67
|
+
'0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 2017',
|
|
68
|
+
'05D0 05D1 05D2 05D3 05D4 05D5 05D6 05D7 05D8 05D9 05DA 05DB 05DC 05DD 05DE 05DF',
|
|
69
|
+
'05E0 05E1 05E2 05E3 05E4 05E5 05E6 05E7 05E8 05E9 05EA 0000 0000 200E 200F 0000',
|
|
70
|
+
// codepage 9: ISO 8859-9 (Turkish)
|
|
71
|
+
'00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF',
|
|
72
|
+
'00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF',
|
|
73
|
+
'00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF',
|
|
74
|
+
'011E 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 0130 015E 00DF',
|
|
75
|
+
'00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF',
|
|
76
|
+
'011F 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 0131 015F 00FF',
|
|
77
|
+
];
|
|
78
|
+
const CODEPAGE_TABLES = (() => {
|
|
79
|
+
const tables = [];
|
|
80
|
+
for (let page = 0; page < 8; page++) {
|
|
81
|
+
const rows = CODEPAGE_ROWS.slice(page * 6, page * 6 + 6);
|
|
82
|
+
tables.push(rows.join(' ').split(' ').map((h) => parseInt(h, 16)));
|
|
83
|
+
}
|
|
84
|
+
return tables;
|
|
85
|
+
})();
|
|
86
|
+
/**
|
|
87
|
+
* Map a `\S\` result code (0x80..0xFF) through the currently selected code
|
|
88
|
+
* page. `codepage` 1 (the default, ISO 8859-1) and any `code` outside
|
|
89
|
+
* 0xA0..0xFF (the C1 control range 0x80..0x9F, or a malformed operand outside
|
|
90
|
+
* a single byte) pass through unchanged, matching the pre-codepage-aware
|
|
91
|
+
* behaviour this decoder had before.
|
|
92
|
+
*/
|
|
93
|
+
function resolveExtendedChar(codepage, code) {
|
|
94
|
+
if (codepage <= 1 || code < 0xA0 || code > 0xFF)
|
|
95
|
+
return code;
|
|
96
|
+
const table = CODEPAGE_TABLES[codepage - 2];
|
|
97
|
+
if (!table)
|
|
98
|
+
return code;
|
|
99
|
+
const mapped = table[code - 0xA0];
|
|
100
|
+
return mapped === 0 ? code : mapped;
|
|
101
|
+
}
|
|
4
102
|
/**
|
|
5
103
|
* Decode IFC STEP encoded strings.
|
|
6
104
|
* Handles:
|
|
7
105
|
* - \X2\XXXX\X0\ - Unicode hex encoding (e.g., \X2\00E4\X0\ -> a with umlaut)
|
|
8
106
|
* - \X4\XXXXXXXX\X0\ - Unicode 4-byte hex for chars outside BMP
|
|
9
|
-
* - \X\XX\ - ISO-8859-1 hex encoding
|
|
10
|
-
*
|
|
11
|
-
* - \
|
|
107
|
+
* - \X\XX\ - ISO-8859-1 hex encoding (NOT code-page dependent: this is always
|
|
108
|
+
* the ISO 10646 row-0 value, per ISO 10303-21 6.4.3)
|
|
109
|
+
* - \S\X - Extended ASCII: code point of X plus 128, mapped through the
|
|
110
|
+
* currently selected \P?\ code page (default ISO 8859-1)
|
|
111
|
+
* - \PA\..\PI\ - Code page selectors (A=ISO 8859-1 .. I=ISO 8859-9); tracked
|
|
112
|
+
* for subsequent \S\ escapes, then the directive itself is dropped. Any
|
|
113
|
+
* other letter is dropped without changing the active page.
|
|
12
114
|
* - \\ - one literal backslash (ISO 10303-21 doubles the reverse solidus)
|
|
13
115
|
*
|
|
14
116
|
* The \\ pair is collapsed AFTER the directive arms: a directive immediately
|
|
@@ -25,24 +127,31 @@ export function decodeIfcString(str) {
|
|
|
25
127
|
return str;
|
|
26
128
|
let result = '';
|
|
27
129
|
let i = 0;
|
|
130
|
+
let codepage = 1;
|
|
28
131
|
while (i < str.length) {
|
|
29
132
|
if (str[i] !== '\\') {
|
|
30
133
|
result += str[i];
|
|
31
134
|
i += 1;
|
|
32
135
|
continue;
|
|
33
136
|
}
|
|
34
|
-
// Handle code page directives like \PA\, \PB\, ...
|
|
137
|
+
// Handle code page directives like \PA\, \PB\, ... Track A..I as
|
|
138
|
+
// codepage 1..9 for subsequent \S\ escapes; any other letter (or an
|
|
139
|
+
// unrecognized custom-page form) is consumed without changing the page.
|
|
35
140
|
if (str[i + 1] === 'P' && str[i + 3] === '\\') {
|
|
141
|
+
const letter = str[i + 2];
|
|
142
|
+
if (letter >= 'A' && letter <= 'I') {
|
|
143
|
+
codepage = letter.charCodeAt(0) - 0x40;
|
|
144
|
+
}
|
|
36
145
|
i += 4;
|
|
37
146
|
continue;
|
|
38
147
|
}
|
|
39
|
-
// Handle \S\X where the value is the code point of X plus 128
|
|
40
|
-
//
|
|
41
|
-
// multi-byte X stays in parity
|
|
42
|
-
// dangling surrogate.
|
|
148
|
+
// Handle \S\X where the value is the code point of X plus 128, mapped
|
|
149
|
+
// through the active code page. Read X as a whole code point (advancing
|
|
150
|
+
// past a surrogate pair) so a malformed multi-byte X stays in parity
|
|
151
|
+
// with the Rust decoder instead of leaving a dangling surrogate.
|
|
43
152
|
if (str[i + 1] === 'S' && str[i + 2] === '\\' && i + 3 < str.length) {
|
|
44
153
|
const cp = str.codePointAt(i + 3);
|
|
45
|
-
result += String.fromCodePoint(cp + 128);
|
|
154
|
+
result += String.fromCodePoint(resolveExtendedChar(codepage, cp + 128));
|
|
46
155
|
i += 3 + (cp > 0xFFFF ? 2 : 1);
|
|
47
156
|
continue;
|
|
48
157
|
}
|
|
@@ -129,12 +238,48 @@ export function decodeIfcString(str) {
|
|
|
129
238
|
return result;
|
|
130
239
|
}
|
|
131
240
|
/**
|
|
132
|
-
* Encode a Unicode string to IFC STEP
|
|
241
|
+
* Encode a Unicode string to IFC STEP directive escapes.
|
|
133
242
|
*
|
|
134
|
-
* - Printable ASCII (32..126) is kept as-is
|
|
243
|
+
* - Printable ASCII (32..126) is kept as-is, with ONE exception: the reverse
|
|
244
|
+
* solidus (`\`, U+005C) is printable ASCII but goes out as `\X\5C`, because
|
|
245
|
+
* a raw `\` in the output is what a reader takes for the start of a
|
|
246
|
+
* directive or of a `\\` pair.
|
|
135
247
|
* - 8-bit values are encoded as \X\HH.
|
|
136
248
|
* - BMP values are encoded as \X2\HHHH\X0\.
|
|
137
249
|
* - Non-BMP values are encoded as \X4\HHHHHHHH\X0\.
|
|
250
|
+
*
|
|
251
|
+
* This is directive encoding only — it does NOT double the apostrophe (`'`,
|
|
252
|
+
* code point 39 is printable ASCII and passes through unchanged). Its output
|
|
253
|
+
* is therefore **not** safe to place directly inside a STEP single-quoted
|
|
254
|
+
* string literal: an undoubled `'` terminates the literal early and produces
|
|
255
|
+
* a file no conformant reader parses as intended (e.g. a name like
|
|
256
|
+
* `O'Brien`). A caller writing into a literal must double `'` itself, or use
|
|
257
|
+
* `escapeStepString` from `@ifc-lite/data`, which handles the full
|
|
258
|
+
* literal-context contract: doubling `'` and `\`, mapping control characters
|
|
259
|
+
* to a space, and encoding non-ASCII —
|
|
260
|
+
* per ISO 10303-21 6.3.3.4. The two functions do not produce the same output
|
|
261
|
+
* for the same input; do not assume they agree. Sweeping U+0000..U+02FF, they
|
|
262
|
+
* disagree on exactly two of the 95 printable ASCII characters: the
|
|
263
|
+
* apostrophe (U+0027; doubled there, passed through here) and the reverse
|
|
264
|
+
* solidus (U+005C; doubled there, `\X\5C` here). They also disagree on all 32
|
|
265
|
+
* C0 controls AND on DEL (U+007F) -- a space there, `\X\HH` here, since
|
|
266
|
+
* `escapeStepString` collapses `/[\x00-\x1F\x7F]/g` to a space -- and on all
|
|
267
|
+
* 128 of U+0080..U+00FF (`\X2\HHHH\X0\` there, `\X\HH` here). That is 163
|
|
268
|
+
* disagreements in all. Above U+00FF they agree on all 512.
|
|
269
|
+
*
|
|
270
|
+
* Kept for round-trip use with {@link decodeIfcString}, within the scope the
|
|
271
|
+
* two functions actually cover: `decodeIfcString(encodeIfcString(s)) === s`
|
|
272
|
+
* for every `s` built from Unicode SCALAR values. That is not the same as
|
|
273
|
+
* every JS string. A JS string can also hold an unpaired surrogate
|
|
274
|
+
* (U+D800..U+DFFF), which is not a scalar value; this encoder writes it as a
|
|
275
|
+
* `\X2\` directive, and {@link decodeIfcString} decodes every lone surrogate
|
|
276
|
+
* to U+FFFD to stay in parity with the Rust decoder's
|
|
277
|
+
* `String::from_utf16_lossy`. Those 2048 code units are the only inputs that
|
|
278
|
+
* do not come back unchanged.
|
|
279
|
+
*
|
|
280
|
+
* Within that scope the guarantee is independent of apostrophe handling,
|
|
281
|
+
* because doubling is a literal-context requirement, not an encoding one.
|
|
282
|
+
* See https://github.com/LTplus-AG/ifc-lite/issues/3445.
|
|
138
283
|
*/
|
|
139
284
|
export function encodeIfcString(str) {
|
|
140
285
|
if (!str || typeof str !== 'string')
|
package/dist/ifc-string.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc-string.js","sourceRoot":"","sources":["../src/ifc-string.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D
|
|
1
|
+
{"version":3,"file":"ifc-string.js","sourceRoot":"","sources":["../src/ifc-string.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export { decodeIfcString, encodeIfcString } from './ifc-string.js';
|
|
|
2
2
|
export { decodeStepStringLiteral } from './step-string-literal.js';
|
|
3
3
|
export { uuidToIfcGuid, ifcGuidToUuid, generateIfcGuid, generateUuid, isValidIfcGuid, isValidUuid, } from './guid.js';
|
|
4
4
|
export type { RandomSource } from './guid.js';
|
|
5
|
+
export { uuidFromSeed } from './deterministic-uuid.js';
|
|
6
|
+
export { isWhollyNumeric } from './numeric-literal.js';
|
|
5
7
|
export { parsePropertyValue } from './property-value.js';
|
|
6
8
|
export type { ParsedPropertyValue } from './property-value.js';
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EACL,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,cAAc,EACd,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EACL,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,cAAc,EACd,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,5 +4,7 @@
|
|
|
4
4
|
export { decodeIfcString, encodeIfcString } from './ifc-string.js';
|
|
5
5
|
export { decodeStepStringLiteral } from './step-string-literal.js';
|
|
6
6
|
export { uuidToIfcGuid, ifcGuidToUuid, generateIfcGuid, generateUuid, isValidIfcGuid, isValidUuid, } from './guid.js';
|
|
7
|
+
export { uuidFromSeed } from './deterministic-uuid.js';
|
|
8
|
+
export { isWhollyNumeric } from './numeric-literal.js';
|
|
7
9
|
export { parsePropertyValue } from './property-value.js';
|
|
8
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EACL,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,cAAc,EACd,WAAW,GACZ,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EACL,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,cAAc,EACd,WAAW,GACZ,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether `v` is WHOLLY a signed decimal number, optionally in exponent form:
|
|
3
|
+
* `-0.35`, `+1`, `-1.5e-3`, `-.5`, `-1.`. Anchored at BOTH ends, so `-0.35=cmd`
|
|
4
|
+
* is not one and `1,000` is not one either.
|
|
5
|
+
*
|
|
6
|
+
* Lives here, in a package with no dependencies, because three different
|
|
7
|
+
* callers need it and only two of them can afford `@ifc-lite/export`: the CSV
|
|
8
|
+
* formula guard (`packages/export/src/csv-cell.ts`) exempts a genuine number
|
|
9
|
+
* from the `+`/`-` trigger so a spreadsheet column still sums (#1772), and
|
|
10
|
+
* `@ifc-lite/lists` needs the same decision in its own CSV writer.
|
|
11
|
+
* `rust/export/src/csv_cell.rs::is_wholly_numeric` decides the same language on
|
|
12
|
+
* the other side of the language boundary; what holds those two together is the
|
|
13
|
+
* shared vector fixture, not a promise that they look alike.
|
|
14
|
+
*
|
|
15
|
+
* The regex this replaces — `/^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/` —
|
|
16
|
+
* is QUADRATIC on a failing match: `\d+\.?\d*` retries at every split point
|
|
17
|
+
* before the engine gives up. This scan is linear, which is the whole reason it
|
|
18
|
+
* is spelled out by hand. (For scale, on `-` + 60k digits + one letter the
|
|
19
|
+
* regex took ~1.8s and the scan ~1ms; the ratio is the point, not the numbers.)
|
|
20
|
+
*
|
|
21
|
+
* Cell text comes from IFC properties, so the input is attacker-controllable and
|
|
22
|
+
* a leading `-` is exactly what reaches this check. `\d` is ASCII-only in JS, and
|
|
23
|
+
* this scan matches that deliberately: a full-width or Arabic-Indic digit is NOT
|
|
24
|
+
* a number here and stays guarded.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isWhollyNumeric(v: string): boolean;
|
|
27
|
+
//# sourceMappingURL=numeric-literal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numeric-literal.d.ts","sourceRoot":"","sources":["../src/numeric-literal.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAyBlD"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* Whether `v` is WHOLLY a signed decimal number, optionally in exponent form:
|
|
6
|
+
* `-0.35`, `+1`, `-1.5e-3`, `-.5`, `-1.`. Anchored at BOTH ends, so `-0.35=cmd`
|
|
7
|
+
* is not one and `1,000` is not one either.
|
|
8
|
+
*
|
|
9
|
+
* Lives here, in a package with no dependencies, because three different
|
|
10
|
+
* callers need it and only two of them can afford `@ifc-lite/export`: the CSV
|
|
11
|
+
* formula guard (`packages/export/src/csv-cell.ts`) exempts a genuine number
|
|
12
|
+
* from the `+`/`-` trigger so a spreadsheet column still sums (#1772), and
|
|
13
|
+
* `@ifc-lite/lists` needs the same decision in its own CSV writer.
|
|
14
|
+
* `rust/export/src/csv_cell.rs::is_wholly_numeric` decides the same language on
|
|
15
|
+
* the other side of the language boundary; what holds those two together is the
|
|
16
|
+
* shared vector fixture, not a promise that they look alike.
|
|
17
|
+
*
|
|
18
|
+
* The regex this replaces — `/^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/` —
|
|
19
|
+
* is QUADRATIC on a failing match: `\d+\.?\d*` retries at every split point
|
|
20
|
+
* before the engine gives up. This scan is linear, which is the whole reason it
|
|
21
|
+
* is spelled out by hand. (For scale, on `-` + 60k digits + one letter the
|
|
22
|
+
* regex took ~1.8s and the scan ~1ms; the ratio is the point, not the numbers.)
|
|
23
|
+
*
|
|
24
|
+
* Cell text comes from IFC properties, so the input is attacker-controllable and
|
|
25
|
+
* a leading `-` is exactly what reaches this check. `\d` is ASCII-only in JS, and
|
|
26
|
+
* this scan matches that deliberately: a full-width or Arabic-Indic digit is NOT
|
|
27
|
+
* a number here and stays guarded.
|
|
28
|
+
*/
|
|
29
|
+
export function isWhollyNumeric(v) {
|
|
30
|
+
const n = v.length;
|
|
31
|
+
let i = 0;
|
|
32
|
+
if (i < n && (v[i] === '+' || v[i] === '-'))
|
|
33
|
+
i++;
|
|
34
|
+
// Mantissa: `\d+\.?\d*` or `\.\d+` — at least one digit either way.
|
|
35
|
+
let digits = 0;
|
|
36
|
+
while (i < n && v[i] >= '0' && v[i] <= '9') {
|
|
37
|
+
i++;
|
|
38
|
+
digits++;
|
|
39
|
+
}
|
|
40
|
+
if (i < n && v[i] === '.') {
|
|
41
|
+
i++;
|
|
42
|
+
while (i < n && v[i] >= '0' && v[i] <= '9') {
|
|
43
|
+
i++;
|
|
44
|
+
digits++;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (digits === 0)
|
|
48
|
+
return false;
|
|
49
|
+
// Optional exponent, which must carry at least one digit if present.
|
|
50
|
+
if (i < n && (v[i] === 'e' || v[i] === 'E')) {
|
|
51
|
+
i++;
|
|
52
|
+
if (i < n && (v[i] === '+' || v[i] === '-'))
|
|
53
|
+
i++;
|
|
54
|
+
let expDigits = 0;
|
|
55
|
+
while (i < n && v[i] >= '0' && v[i] <= '9') {
|
|
56
|
+
i++;
|
|
57
|
+
expDigits++;
|
|
58
|
+
}
|
|
59
|
+
if (expDigits === 0)
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
// Anchored at the end: trailing anything, including a newline, disqualifies.
|
|
63
|
+
return i === n;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=numeric-literal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numeric-literal.js","sourceRoot":"","sources":["../src/numeric-literal.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;QAAE,CAAC,EAAE,CAAC;IAEjD,oEAAoE;IACpE,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;QAAC,CAAC,EAAE,CAAC;QAAC,MAAM,EAAE,CAAC;IAAC,CAAC;IAC9D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QAC1B,CAAC,EAAE,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;YAAC,CAAC,EAAE,CAAC;YAAC,MAAM,EAAE,CAAC;QAAC,CAAC;IAChE,CAAC;IACD,IAAI,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE/B,qEAAqE;IACrE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QAC5C,CAAC,EAAE,CAAC;QACJ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;YAAE,CAAC,EAAE,CAAC;QACjD,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;YAAC,CAAC,EAAE,CAAC;YAAC,SAAS,EAAE,CAAC;QAAC,CAAC;QACjE,IAAI,SAAS,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IACpC,CAAC;IAED,6EAA6E;IAC7E,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ifc-lite/encoding",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "IFC string encoding/decoding and property value parsing for IFC-Lite",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"typescript": "^6.0.3",
|
|
17
|
-
"vitest": "^4.1.
|
|
17
|
+
"vitest": "^4.1.11",
|
|
18
|
+
"@ifc-lite/timing-ladder": "^0.1.0"
|
|
18
19
|
},
|
|
19
20
|
"license": "MPL-2.0",
|
|
20
21
|
"author": "Louis True",
|