@loaders.gl/wkt 4.3.2 → 4.4.0-alpha.2

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 (111) hide show
  1. package/dist/dist.dev.js +1281 -1266
  2. package/dist/dist.min.js +2 -2
  3. package/dist/hex-wkb-loader.d.ts +6 -5
  4. package/dist/hex-wkb-loader.d.ts.map +1 -1
  5. package/dist/hex-wkb-loader.js +4 -4
  6. package/dist/index.cjs +51 -1622
  7. package/dist/index.cjs.map +4 -4
  8. package/dist/index.d.ts +0 -5
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +0 -5
  11. package/dist/lib/version.d.ts.map +1 -0
  12. package/dist/lib/{utils/version.js → version.js} +1 -1
  13. package/dist/twkb-loader.d.ts +3 -3
  14. package/dist/twkb-loader.d.ts.map +1 -1
  15. package/dist/twkb-loader.js +4 -4
  16. package/dist/twkb-writer.d.ts +2 -1
  17. package/dist/twkb-writer.d.ts.map +1 -1
  18. package/dist/twkb-writer.js +5 -4
  19. package/dist/wkb-loader.d.ts +13 -11
  20. package/dist/wkb-loader.d.ts.map +1 -1
  21. package/dist/wkb-loader.js +14 -6
  22. package/dist/wkb-writer.d.ts +3 -2
  23. package/dist/wkb-writer.d.ts.map +1 -1
  24. package/dist/wkb-writer.js +5 -4
  25. package/dist/wkt-crs-loader.d.ts +1 -1
  26. package/dist/wkt-crs-loader.d.ts.map +1 -1
  27. package/dist/wkt-crs-loader.js +2 -2
  28. package/dist/wkt-crs-writer.d.ts +1 -1
  29. package/dist/wkt-crs-writer.d.ts.map +1 -1
  30. package/dist/wkt-crs-writer.js +2 -2
  31. package/dist/wkt-loader.d.ts +2 -2
  32. package/dist/wkt-loader.d.ts.map +1 -1
  33. package/dist/wkt-loader.js +4 -4
  34. package/dist/wkt-worker.js +26 -13
  35. package/dist/wkt-writer.d.ts +6 -5
  36. package/dist/wkt-writer.d.ts.map +1 -1
  37. package/dist/wkt-writer.js +10 -7
  38. package/package.json +6 -6
  39. package/src/hex-wkb-loader.ts +8 -8
  40. package/src/index.ts +0 -10
  41. package/src/twkb-loader.ts +5 -5
  42. package/src/twkb-writer.ts +6 -5
  43. package/src/wkb-loader.ts +24 -12
  44. package/src/wkb-writer.ts +8 -7
  45. package/src/wkt-crs-loader.ts +3 -3
  46. package/src/wkt-crs-writer.ts +3 -5
  47. package/src/wkt-loader.ts +6 -5
  48. package/src/wkt-writer.ts +11 -8
  49. package/dist/lib/encode-twkb.d.ts +0 -6
  50. package/dist/lib/encode-twkb.d.ts.map +0 -1
  51. package/dist/lib/encode-twkb.js +0 -195
  52. package/dist/lib/encode-wkb.d.ts +0 -33
  53. package/dist/lib/encode-wkb.d.ts.map +0 -1
  54. package/dist/lib/encode-wkb.js +0 -286
  55. package/dist/lib/encode-wkt-crs.d.ts +0 -10
  56. package/dist/lib/encode-wkt-crs.d.ts.map +0 -1
  57. package/dist/lib/encode-wkt-crs.js +0 -35
  58. package/dist/lib/encode-wkt.d.ts +0 -8
  59. package/dist/lib/encode-wkt.d.ts.map +0 -1
  60. package/dist/lib/encode-wkt.js +0 -47
  61. package/dist/lib/parse-hex-wkb.d.ts +0 -1
  62. package/dist/lib/parse-hex-wkb.d.ts.map +0 -1
  63. package/dist/lib/parse-hex-wkb.js +0 -1
  64. package/dist/lib/parse-twkb.d.ts +0 -9
  65. package/dist/lib/parse-twkb.d.ts.map +0 -1
  66. package/dist/lib/parse-twkb.js +0 -253
  67. package/dist/lib/parse-wkb-header.d.ts +0 -39
  68. package/dist/lib/parse-wkb-header.d.ts.map +0 -1
  69. package/dist/lib/parse-wkb-header.js +0 -134
  70. package/dist/lib/parse-wkb.d.ts +0 -5
  71. package/dist/lib/parse-wkb.d.ts.map +0 -1
  72. package/dist/lib/parse-wkb.js +0 -241
  73. package/dist/lib/parse-wkt-crs.d.ts +0 -15
  74. package/dist/lib/parse-wkt-crs.d.ts.map +0 -1
  75. package/dist/lib/parse-wkt-crs.js +0 -120
  76. package/dist/lib/parse-wkt.d.ts +0 -30
  77. package/dist/lib/parse-wkt.d.ts.map +0 -1
  78. package/dist/lib/parse-wkt.js +0 -288
  79. package/dist/lib/utils/base64-encoder.d.ts +0 -5
  80. package/dist/lib/utils/base64-encoder.d.ts.map +0 -1
  81. package/dist/lib/utils/base64-encoder.js +0 -153
  82. package/dist/lib/utils/binary-reader.d.ts +0 -18
  83. package/dist/lib/utils/binary-reader.d.ts.map +0 -1
  84. package/dist/lib/utils/binary-reader.js +0 -69
  85. package/dist/lib/utils/binary-writer.d.ts +0 -28
  86. package/dist/lib/utils/binary-writer.d.ts.map +0 -1
  87. package/dist/lib/utils/binary-writer.js +0 -121
  88. package/dist/lib/utils/hex-encoder.d.ts +0 -15
  89. package/dist/lib/utils/hex-encoder.d.ts.map +0 -1
  90. package/dist/lib/utils/hex-encoder.js +0 -54
  91. package/dist/lib/utils/hex-transcoder.d.ts +0 -15
  92. package/dist/lib/utils/hex-transcoder.d.ts.map +0 -1
  93. package/dist/lib/utils/hex-transcoder.js +0 -50
  94. package/dist/lib/utils/version.d.ts.map +0 -1
  95. package/src/lib/encode-twkb.ts +0 -308
  96. package/src/lib/encode-wkb.ts +0 -390
  97. package/src/lib/encode-wkt-crs.ts +0 -41
  98. package/src/lib/encode-wkt.ts +0 -56
  99. package/src/lib/parse-hex-wkb.ts +0 -0
  100. package/src/lib/parse-twkb.ts +0 -365
  101. package/src/lib/parse-wkb-header.ts +0 -174
  102. package/src/lib/parse-wkb.ts +0 -343
  103. package/src/lib/parse-wkt-crs.ts +0 -149
  104. package/src/lib/parse-wkt.ts +0 -327
  105. package/src/lib/utils/base64-encoder.ts +0 -157
  106. package/src/lib/utils/binary-reader.ts +0 -76
  107. package/src/lib/utils/binary-writer.ts +0 -127
  108. package/src/lib/utils/hex-encoder.ts +0 -60
  109. package/src/lib/utils/hex-transcoder.ts +0 -54
  110. /package/dist/lib/{utils/version.d.ts → version.d.ts} +0 -0
  111. /package/src/lib/{utils/version.ts → version.ts} +0 -0
@@ -1,343 +0,0 @@
1
- // loaders.gl
2
- // SPDX-License-Identifier: MIT
3
- // Copyright (c) vis.gl contributors
4
-
5
- import type {
6
- TypedArray,
7
- BinaryGeometry,
8
- BinaryPointGeometry,
9
- BinaryLineGeometry,
10
- BinaryPolygonGeometry,
11
- Geometry
12
- } from '@loaders.gl/schema';
13
- import {binaryToGeometry} from '@loaders.gl/gis';
14
- import type {WKBLoaderOptions} from '../wkb-loader';
15
-
16
- import {parseWKBHeader, WKBGeometryType} from './parse-wkb-header';
17
-
18
- export function parseWKB(
19
- arrayBuffer: ArrayBuffer,
20
- options?: WKBLoaderOptions
21
- ): BinaryGeometry | Geometry {
22
- const binaryGeometry = parseWKBToBinary(arrayBuffer, options);
23
- const shape = options?.wkb?.shape || 'binary-geometry';
24
- switch (shape) {
25
- case 'binary-geometry':
26
- return binaryGeometry;
27
- case 'geojson-geometry':
28
- return binaryToGeometry(binaryGeometry);
29
- case 'geometry':
30
- // eslint-disable-next-line no-console
31
- console.error('WKBLoader: "geometry" shape is deprecated, use "binary-geometry" instead');
32
- return binaryToGeometry(binaryGeometry);
33
- default:
34
- throw new Error(shape);
35
- }
36
- }
37
-
38
- export function parseWKBToBinary(
39
- arrayBuffer: ArrayBuffer,
40
- options?: WKBLoaderOptions
41
- ): BinaryGeometry {
42
- const dataView = new DataView(arrayBuffer);
43
-
44
- const wkbHeader = parseWKBHeader(dataView);
45
-
46
- const {geometryType, dimensions, littleEndian} = wkbHeader;
47
- const offset = wkbHeader.byteOffset;
48
-
49
- switch (geometryType) {
50
- case WKBGeometryType.Point:
51
- const point = parsePoint(dataView, offset, dimensions, littleEndian);
52
- return point.geometry;
53
- case WKBGeometryType.LineString:
54
- const line = parseLineString(dataView, offset, dimensions, littleEndian);
55
- return line.geometry;
56
- case WKBGeometryType.Polygon:
57
- const polygon = parsePolygon(dataView, offset, dimensions, littleEndian);
58
- return polygon.geometry;
59
- case WKBGeometryType.MultiPoint:
60
- const multiPoint = parseMultiPoint(dataView, offset, dimensions, littleEndian);
61
- multiPoint.type = 'Point';
62
- return multiPoint;
63
- case WKBGeometryType.MultiLineString:
64
- const multiLine = parseMultiLineString(dataView, offset, dimensions, littleEndian);
65
- multiLine.type = 'LineString';
66
- return multiLine;
67
- case WKBGeometryType.MultiPolygon:
68
- const multiPolygon = parseMultiPolygon(dataView, offset, dimensions, littleEndian);
69
- multiPolygon.type = 'Polygon';
70
- return multiPolygon;
71
- // case WKBGeometryType.GeometryCollection:
72
- // TODO: handle GeometryCollections
73
- // return parseGeometryCollection(dataView, offset, dimensions, littleEndian);
74
- default:
75
- throw new Error(`WKB: Unsupported geometry type: ${geometryType}`);
76
- }
77
- }
78
-
79
- // Primitives; parse point and linear ring
80
- function parsePoint(
81
- dataView: DataView,
82
- offset: number,
83
- dimension: number,
84
- littleEndian: boolean
85
- ): {geometry: BinaryPointGeometry; offset: number} {
86
- const positions = new Float64Array(dimension);
87
- for (let i = 0; i < dimension; i++) {
88
- positions[i] = dataView.getFloat64(offset, littleEndian);
89
- offset += 8;
90
- }
91
-
92
- return {
93
- geometry: {type: 'Point', positions: {value: positions, size: dimension}},
94
- offset
95
- };
96
- }
97
-
98
- function parseLineString(
99
- dataView: DataView,
100
- offset: number,
101
- dimension: number,
102
- littleEndian: boolean
103
- ): {geometry: BinaryLineGeometry; offset: number} {
104
- const nPoints = dataView.getUint32(offset, littleEndian);
105
- offset += 4;
106
-
107
- // Instantiate array
108
- const positions = new Float64Array(nPoints * dimension);
109
- for (let i = 0; i < nPoints * dimension; i++) {
110
- positions[i] = dataView.getFloat64(offset, littleEndian);
111
- offset += 8;
112
- }
113
-
114
- const pathIndices = [0];
115
- if (nPoints > 0) {
116
- pathIndices.push(nPoints);
117
- }
118
-
119
- return {
120
- geometry: {
121
- type: 'LineString',
122
- positions: {value: positions, size: dimension},
123
- pathIndices: {value: new Uint32Array(pathIndices), size: 1}
124
- },
125
- offset
126
- };
127
- }
128
-
129
- // https://stackoverflow.com/a/55261098
130
- const cumulativeSum = (sum: number) => (value: number) => (sum += value);
131
-
132
- function parsePolygon(
133
- dataView: DataView,
134
- offset: number,
135
- dimension: number,
136
- littleEndian: boolean
137
- ): {geometry: BinaryPolygonGeometry; offset: number} {
138
- const nRings = dataView.getUint32(offset, littleEndian);
139
- offset += 4;
140
-
141
- const rings: TypedArray[] = [];
142
- for (let i = 0; i < nRings; i++) {
143
- const parsed = parseLineString(dataView, offset, dimension, littleEndian);
144
- const {positions} = parsed.geometry;
145
- offset = parsed.offset;
146
- rings.push(positions.value);
147
- }
148
-
149
- const concatenatedPositions = new Float64Array(concatTypedArrays(rings).buffer);
150
- const polygonIndices = [0];
151
- if (concatenatedPositions.length > 0) {
152
- polygonIndices.push(concatenatedPositions.length / dimension);
153
- }
154
- const primitivePolygonIndices = rings.map((l) => l.length / dimension).map(cumulativeSum(0));
155
- primitivePolygonIndices.unshift(0);
156
-
157
- return {
158
- geometry: {
159
- type: 'Polygon',
160
- positions: {value: concatenatedPositions, size: dimension},
161
- polygonIndices: {
162
- value: new Uint32Array(polygonIndices),
163
- size: 1
164
- },
165
- primitivePolygonIndices: {value: new Uint32Array(primitivePolygonIndices), size: 1}
166
- },
167
- offset
168
- };
169
- }
170
-
171
- function parseMultiPoint(
172
- dataView: DataView,
173
- offset: number,
174
- dimension: number,
175
- littleEndian: boolean
176
- ): BinaryPointGeometry {
177
- const nPoints = dataView.getUint32(offset, littleEndian);
178
- offset += 4;
179
-
180
- const binaryPointGeometries: BinaryPointGeometry[] = [];
181
- for (let i = 0; i < nPoints; i++) {
182
- // Byte order for point
183
- const littleEndianPoint = dataView.getUint8(offset) === 1;
184
- offset++;
185
-
186
- // Assert point type
187
- if (dataView.getUint32(offset, littleEndianPoint) % 1000 !== 1) {
188
- throw new Error('WKB: Inner geometries of MultiPoint not of type Point');
189
- }
190
-
191
- offset += 4;
192
-
193
- const parsed = parsePoint(dataView, offset, dimension, littleEndianPoint);
194
- offset = parsed.offset;
195
- binaryPointGeometries.push(parsed.geometry);
196
- }
197
-
198
- return concatenateBinaryPointGeometries(binaryPointGeometries, dimension);
199
- }
200
-
201
- function parseMultiLineString(
202
- dataView: DataView,
203
- offset: number,
204
- dimension: number,
205
- littleEndian: boolean
206
- ): BinaryLineGeometry {
207
- const nLines = dataView.getUint32(offset, littleEndian);
208
- offset += 4;
209
-
210
- const binaryLineGeometries: BinaryLineGeometry[] = [];
211
- for (let i = 0; i < nLines; i++) {
212
- // Byte order for line
213
- const littleEndianLine = dataView.getUint8(offset) === 1;
214
- offset++;
215
-
216
- // Assert type LineString
217
- if (dataView.getUint32(offset, littleEndianLine) % 1000 !== 2) {
218
- throw new Error('WKB: Inner geometries of MultiLineString not of type LineString');
219
- }
220
- offset += 4;
221
-
222
- const parsed = parseLineString(dataView, offset, dimension, littleEndianLine);
223
- offset = parsed.offset;
224
- binaryLineGeometries.push(parsed.geometry);
225
- }
226
-
227
- return concatenateBinaryLineGeometries(binaryLineGeometries, dimension);
228
- }
229
-
230
- function parseMultiPolygon(
231
- dataView: DataView,
232
- offset: number,
233
- dimension: number,
234
- littleEndian: boolean
235
- ): BinaryPolygonGeometry {
236
- const nPolygons = dataView.getUint32(offset, littleEndian);
237
- offset += 4;
238
-
239
- const binaryPolygonGeometries: BinaryPolygonGeometry[] = [];
240
- for (let i = 0; i < nPolygons; i++) {
241
- // Byte order for polygon
242
- const littleEndianPolygon = dataView.getUint8(offset) === 1;
243
- offset++;
244
-
245
- // Assert type Polygon
246
- if (dataView.getUint32(offset, littleEndianPolygon) % 1000 !== 3) {
247
- throw new Error('WKB: Inner geometries of MultiPolygon not of type Polygon');
248
- }
249
- offset += 4;
250
-
251
- const parsed = parsePolygon(dataView, offset, dimension, littleEndianPolygon);
252
- offset = parsed.offset;
253
- binaryPolygonGeometries.push(parsed.geometry);
254
- }
255
-
256
- return concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension);
257
- }
258
-
259
- // TODO - move to loaders.gl/schema/gis
260
-
261
- function concatenateBinaryPointGeometries(
262
- binaryPointGeometries: BinaryPointGeometry[],
263
- dimension: number
264
- ): BinaryPointGeometry {
265
- const positions: TypedArray[] = binaryPointGeometries.map((geometry) => geometry.positions.value);
266
- const concatenatedPositions = new Float64Array(concatTypedArrays(positions).buffer);
267
-
268
- return {
269
- type: 'Point',
270
- positions: {value: concatenatedPositions, size: dimension}
271
- };
272
- }
273
-
274
- function concatenateBinaryLineGeometries(
275
- binaryLineGeometries: BinaryLineGeometry[],
276
- dimension: number
277
- ): BinaryLineGeometry {
278
- const lines: TypedArray[] = binaryLineGeometries.map((geometry) => geometry.positions.value);
279
- const concatenatedPositions = new Float64Array(concatTypedArrays(lines).buffer);
280
- const pathIndices = lines.map((line) => line.length / dimension).map(cumulativeSum(0));
281
- pathIndices.unshift(0);
282
-
283
- return {
284
- type: 'LineString',
285
- positions: {value: concatenatedPositions, size: dimension},
286
- pathIndices: {value: new Uint32Array(pathIndices), size: 1}
287
- };
288
- }
289
-
290
- function concatenateBinaryPolygonGeometries(
291
- binaryPolygonGeometries: BinaryPolygonGeometry[],
292
- dimension: number
293
- ): BinaryPolygonGeometry {
294
- const polygons: TypedArray[] = [];
295
- const primitivePolygons: TypedArray[] = [];
296
-
297
- for (const binaryPolygon of binaryPolygonGeometries) {
298
- const {positions, primitivePolygonIndices} = binaryPolygon;
299
- polygons.push(positions.value);
300
- primitivePolygons.push(primitivePolygonIndices.value);
301
- }
302
-
303
- const concatenatedPositions = new Float64Array(concatTypedArrays(polygons).buffer);
304
- const polygonIndices = polygons.map((p) => p.length / dimension).map(cumulativeSum(0));
305
- polygonIndices.unshift(0);
306
-
307
- // Combine primitivePolygonIndices from each individual polygon
308
- const primitivePolygonIndices = [0];
309
- for (const primitivePolygon of primitivePolygons) {
310
- primitivePolygonIndices.push(
311
- ...primitivePolygon
312
- .filter((x: number) => x > 0)
313
- .map((x: number) => x + primitivePolygonIndices[primitivePolygonIndices.length - 1])
314
- );
315
- }
316
-
317
- return {
318
- type: 'Polygon',
319
- positions: {value: concatenatedPositions, size: dimension},
320
- polygonIndices: {value: new Uint32Array(polygonIndices), size: 1},
321
- primitivePolygonIndices: {value: new Uint32Array(primitivePolygonIndices), size: 1}
322
- };
323
- }
324
-
325
- // TODO: remove copy; import from typed-array-utils
326
- // modules/math/src/geometry/typed-arrays/typed-array-utils.js
327
- function concatTypedArrays(arrays: TypedArray[]): TypedArray {
328
- let byteLength = 0;
329
- for (let i = 0; i < arrays.length; ++i) {
330
- byteLength += arrays[i].byteLength;
331
- }
332
- const buffer = new Uint8Array(byteLength);
333
-
334
- let byteOffset = 0;
335
- for (let i = 0; i < arrays.length; ++i) {
336
- const data = new Uint8Array(arrays[i].buffer);
337
- byteLength = data.length;
338
- for (let j = 0; j < byteLength; ++j) {
339
- buffer[byteOffset++] = data[j];
340
- }
341
- }
342
- return buffer;
343
- }
@@ -1,149 +0,0 @@
1
- // loaders.gl
2
- // SPDX-License-Identifier: MIT
3
- // Copyright (c) vis.gl contributors
4
- // parse-wkt-crs was forked from https://github.com/DanielJDufour/wkt-crs under Creative Commons CC0 1.0 license.
5
-
6
- /* eslint-disable no-console */ // TODO switch to options.log
7
-
8
- export type ParseWKTCRSOptions = {
9
- sort?: boolean;
10
- keywords?: string[];
11
- raw?: boolean;
12
- debug?: boolean;
13
- };
14
-
15
- export type WKTCRS = any;
16
-
17
- /**
18
- *
19
- * @param wkt
20
- * @param options
21
- * @returns
22
- */
23
- export function parseWKTCRS(wkt: string, options?: ParseWKTCRSOptions): WKTCRS {
24
- if (options?.debug) {
25
- console.log('[wktcrs] parse starting with\n', wkt);
26
- }
27
-
28
- // move all keywords into first array item slot
29
- // from PARAM[12345, 67890] to ["PARAM", 12345, 67890]
30
- wkt = wkt.replace(/[A-Z][A-Z\d_]+\[/gi, (match) => `["${match.substr(0, match.length - 1)}",`);
31
-
32
- // wrap variables in strings
33
- // from [...,NORTH] to [...,"NORTH"]
34
- wkt = wkt.replace(/, ?([A-Z][A-Z\d_]+[,\]])/gi, (match, p1) => {
35
- const varname = p1.substr(0, p1.length - 1);
36
- return ',' + `"${options?.raw ? 'raw:' : ''}${varname}"${p1[p1.length - 1]}`;
37
- });
38
-
39
- if (options?.raw) {
40
- // replace all numbers with strings
41
- wkt = wkt.replace(/, {0,2}(-?[\.\d]+)(?=,|\])/g, function (match, p1) {
42
- return ',' + `"${options?.raw ? 'raw:' : ''}${p1}"`;
43
- });
44
- }
45
-
46
- // str should now be valid JSON
47
- if (options?.debug) {
48
- console.log(`[wktcrs] json'd wkt: '${wkt}'`);
49
- }
50
-
51
- let data;
52
- try {
53
- data = JSON.parse(wkt);
54
- } catch (error) {
55
- console.error(`[wktcrs] failed to parse '${wkt}'`);
56
- throw error;
57
- }
58
-
59
- if (options?.debug) {
60
- console.log(`[wktcrs] json parsed: '${wkt}'`);
61
- }
62
-
63
- function process(data, parent) {
64
- const kw = data[0];
65
-
66
- // after removing the first element with .shift()
67
- // data is now just an array of attributes
68
-
69
- data.forEach(function (it) {
70
- if (Array.isArray(it)) {
71
- process(it, data);
72
- }
73
- });
74
-
75
- const kwarr = `MULTIPLE_${kw}`;
76
-
77
- if (kwarr in parent) {
78
- parent[kwarr].push(data);
79
- } else if (kw in parent) {
80
- parent[kwarr] = [parent[kw], data];
81
- delete parent[kw];
82
- } else {
83
- parent[kw] = data;
84
- }
85
- return parent;
86
- }
87
-
88
- const result = process(data, [data]);
89
- if (options?.debug) {
90
- console.log('[wktcrs] parse returning', result);
91
- }
92
-
93
- if (options?.sort) {
94
- sort(result, options);
95
- }
96
-
97
- return result;
98
- }
99
-
100
- function sort(data: string[], options?: {keywords?: string[]}) {
101
- const keys = Object.keys(data).filter((k) => !/\d+/.test(k));
102
-
103
- const keywords: string[] = options?.keywords || [];
104
- if (!options?.keywords) {
105
- // try to find multiples
106
- const counts = {};
107
- if (Array.isArray(data)) {
108
- data.forEach((it) => {
109
- if (Array.isArray(it) && it.length >= 2 && typeof it[1] === 'string') {
110
- const k = it[0];
111
- if (!counts[k]) counts[k] = 0;
112
- counts[k]++;
113
- }
114
- });
115
- for (const k in counts) {
116
- if (counts[k] > 0) keywords.push(k);
117
- }
118
- }
119
- }
120
-
121
- keys.forEach((key) => {
122
- data[key] = sort(data[key]);
123
- });
124
-
125
- keywords.forEach((key) => {
126
- const indices: number[] = [];
127
- const params: string[] = [];
128
-
129
- data.forEach((item, i) => {
130
- if (Array.isArray(item) && item[0] === key) {
131
- indices.push(i);
132
- params.push(item);
133
- }
134
- });
135
-
136
- params.sort((a, b) => {
137
- a = a[1].toString();
138
- b = b[1].toString();
139
- return a < b ? -1 : a > b ? 1 : 0;
140
- });
141
-
142
- // replace in order
143
- params.forEach((param, i) => {
144
- data[indices[i]] = param;
145
- });
146
- });
147
-
148
- return data;
149
- }