@osmix/vt 0.0.1 → 0.0.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # @osmix/vt
2
2
 
3
+ ## 0.0.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 2c03b6c: Add shortbread vector tile generation option
8
+ - 0cd8a2e: Explore patterns for extending Osmix worker
9
+ - Updated dependencies [0cd8a2e]
10
+ - @osmix/shared@0.0.6
11
+
12
+ ## 0.0.5
13
+
14
+ ### Patch Changes
15
+
16
+ - bb629cf: Simplify raster drawing when geometry is smaller than a pixel
17
+ - edbb26b: Handle more Relation types
18
+ - Updated dependencies [bb629cf]
19
+ - Updated dependencies [edbb26b]
20
+ - Updated dependencies [69a36bd]
21
+ - @osmix/shared@0.0.5
22
+
23
+ ## 0.0.4
24
+
25
+ ### Patch Changes
26
+
27
+ - d001d9a: Refactor to align around new main external API
28
+ - Updated dependencies [572cbd8]
29
+ - Updated dependencies [d001d9a]
30
+ - @osmix/shared@0.0.4
31
+
32
+ ## 0.0.3
33
+
34
+ ### Patch Changes
35
+
36
+ - b4a3ff2: Improve Relation handling and display
37
+ - Updated dependencies [b4a3ff2]
38
+ - @osmix/shared@0.0.3
39
+ - @osmix/json@0.0.3
40
+
41
+ ## 0.0.2
42
+
43
+ ### Patch Changes
44
+
45
+ - Updated dependencies [33d9c12]
46
+ - @osmix/shared@0.0.2
47
+ - @osmix/json@0.0.2
48
+
3
49
  ## 0.0.1
4
50
 
5
51
  ### Patch Changes
package/README.md CHANGED
@@ -1,23 +1,23 @@
1
1
  # @osmix/vt
2
2
 
3
- `@osmix/vt` converts Osmix binary overlays (typed-array node and way payloads) into Mapbox Vector Tiles. It also ships a lightweight tile index with LRU caching so workers or web apps can request tiles on demand without re-projecting data for every request.
3
+ `@osmix/vt` converts `@osmix/core` OSM into Mapbox Vector Tiles.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```sh
8
- npm install @osmix/vt
8
+ bun install @osmix/vt
9
9
  ```
10
10
 
11
11
  ## Usage
12
12
 
13
- ### Encode a single vector tile from an Osmix dataset
13
+ ### Encode a single vector tile from an Osm dataset
14
14
 
15
15
  ```ts
16
- import { Osmix } from "@osmix/core"
16
+ import { Osm } from "@osmix/core"
17
17
  import { OsmixVtEncoder } from "@osmix/vt"
18
18
 
19
- // Load or build an Osmix dataset (indexed nodes/ways/relations)
20
- const osm = await Osmix.fromPbf(fetch("/fixtures/monaco.pbf").then((r) => r.arrayBuffer()))
19
+ // Load your Osm dataset
20
+ const osm = await Osmix.fromPbf(Bun.file('./monaco.pbf').stream())
21
21
 
22
22
  // Create an encoder. Defaults: extent=4096, buffer=64px
23
23
  const encoder = new OsmixVtEncoder(osm)
@@ -25,62 +25,49 @@ const encoder = new OsmixVtEncoder(osm)
25
25
  // XYZ tile tuple: [x, y, z]
26
26
  const tile: [number, number, number] = [9372, 12535, 15]
27
27
 
28
- // Returns an ArrayBuffer containing an MVT PBF for two layers:
29
- // "@osmix:<id>:ways" and "@osmix:<id>:nodes"
28
+ // Returns an ArrayBuffer containing up to three layers:
29
+ // "@osmix:<id>:ways", "@osmix:<id>:nodes", "@osmix:<id>:relations"
30
30
  const pbfBuffer = encoder.getTile(tile)
31
-
32
- // Persist or send somewhere
33
- await Deno.writeFile("tile.mvt", new Uint8Array(pbfBuffer))
34
31
  ```
35
32
 
36
- ### Custom bounding box and projection
33
+ ### Displaying in a browser (manual Blob URL)
37
34
 
38
- If you already have a WGS84 bbox and a lon/lat tile-pixel projection, you can render directly:
35
+ Most viewers expect tile URLs. To see a Maplibre implementation in the [example merge app](/apps/merge/src/lib/osmix-vector-protocol.ts).
39
36
 
40
- ```ts
41
- import { OsmixVtEncoder, projectToTile } from "@osmix/vt"
37
+ ## What gets encoded
42
38
 
43
- const encoder = new OsmixVtEncoder(osm, 4096, 64)
44
- const bbox: [number, number, number, number] = [-73.99, 40.73, -73.98, 40.74]
45
- const proj = projectToTile([9372, 12535, 15], 4096)
39
+ - Ways become LINE features; AREA-like ways (per `wayIsArea`) become POLYGON features.
40
+ - Multipolygon relations render as POLYGON features in a dedicated layer so holes and shared ways stay intact.
41
+ - Nodes with tags become POINT features. Untagged nodes are skipped.
42
+ - Each feature includes properties `{ type: "node" | "way" | "relation", ...tags }` and `id`.
43
+ - Three layers are emitted per tile: `@osmix:<datasetId>:ways`, `@osmix:<datasetId>:nodes`, and `@osmix:<datasetId>:relations` (empty layers are omitted automatically).
46
44
 
47
- const pbf = encoder.getTileForBbox(bbox, proj)
48
- ```
45
+ ## API
49
46
 
50
- ### Displaying in a browser (manual Blob URL)
47
+ ### `OsmixVtEncoder`
51
48
 
52
- Most viewers expect tile URLs. For quick inspection, you can create a Blob URL for a single tile:
49
+ The main class for encoding vector tiles.
53
50
 
54
51
  ```ts
55
- const buf = encoder.getTile([9372, 12535, 15])
56
- const url = URL.createObjectURL(new Blob([buf], { type: "application/x-protobuf" }))
57
- // Use `url` anywhere a single MVT URL is accepted (debug tooling, downloads, etc.)
52
+ constructor(osm: Osm, extent = 4096, buffer = 64)
58
53
  ```
59
54
 
60
- For full map integration, serve tiles from a handler that calls `getTile([x,y,z])` and returns the bytes. MapLibre/Mapbox GL can then point a `vector` source at `https://your-host/tiles/{z}/{x}/{y}.mvt`.
55
+ - `osm`: The `@osmix/core` dataset to encode.
56
+ - `extent`: Tile extent (default 4096). Higher values offer more precision.
57
+ - `buffer`: Buffer around the tile in extent units (default 64).
61
58
 
62
- ## What gets encoded
59
+ #### `getTile(tile: [x, y, z]): ArrayBuffer`
63
60
 
64
- - Ways become LINE features; AREA-like ways (per `wayIsArea`) become POLYGON features.
65
- - Nodes with tags become POINT features. Untagged nodes are skipped.
66
- - Each feature includes properties `{ type: "node" | "way", ...tags }` and `id`.
67
- - Two layers are emitted per tile: `@osmix:<datasetId>:ways` and `@osmix:<datasetId>:nodes`.
61
+ Encodes a single tile identified by its XYZ coordinates. Returns a PBF `ArrayBuffer`.
68
62
 
69
- ## API overview
63
+ #### `getTileForBbox(bbox: [w, s, e, n], proj: (ll) => [x, y]): ArrayBuffer`
70
64
 
71
- - `class OsmixVtEncoder(osmix: Osmix, extent=4096, buffer=64)`
72
- - `getTile(tile: [x, y, z]): ArrayBuffer` – Encodes a tile using internal bbox/projection.
73
- - `getTileForBbox(bbox, proj): ArrayBuffer` – Encode for a WGS84 bbox with a lon/lat → tile-pixel projector.
74
- - Internals expose generators for `nodeFeatures` and `wayFeatures` if you need to post-process.
75
- - `projectToTile(tile: [x, y, z], extent=4096): (lonLat) => [x, y]` – Helper to build a projector matching the encoder.
76
- - Types (from `src/types.ts`):
77
- - `VtSimpleFeature` – `{ id, type, properties, geometry }`
78
- - `VtPbfLayer` – `{ name, version, extent, features }`
65
+ Lower-level method to encode a specific bounding box with a custom projection function. Useful if you are projecting to non-Mercator tiles or need custom bounds.
79
66
 
80
67
  ## Environment and limitations
81
68
 
82
69
  - Designed for modern runtimes (Node 20+, Bun, browser workers). Uses typed arrays throughout.
83
- - Polygon handling currently assumes a single outer ring; holes/multi-polygons (relations) are not encoded in v0.0.1.
70
+ - Multipolygon relations are supported, but other relation types are skipped.
84
71
  - Ways are clipped to tile bounds; nodes outside the tile are omitted.
85
72
  - Extent defaults to 4096; set a larger extent if you need higher precision.
86
73
 
@@ -88,8 +75,17 @@ For full map integration, serve tiles from a handler that calls `getTile([x,y,z]
88
75
 
89
76
  - Feature properties include the OSM tags available in the source dataset. Styling keys can be derived at ingestion time; for very large tag sets consider pre-filtering to a stable subset to keep tile size reasonable.
90
77
 
91
- ## See also
78
+ ## Related Packages
79
+
80
+ - [`@osmix/core`](../core/README.md) – In-memory index used to source node/way geometry.
81
+ - [`@osmix/shared`](../shared/README.md) – Supplies `wayIsArea` heuristics and entity types.
82
+ - [`@osmix/raster`](../raster/README.md) – Raster tile rendering if you prefer PNG/WebP output.
83
+ - [`osmix`](../osmix/README.md) – High-level API with `getVectorTile()` helper.
84
+
85
+ ## Development
86
+
87
+ - `bun run test packages/vt`
88
+ - `bun run lint packages/vt`
89
+ - `bun run typecheck packages/vt`
92
90
 
93
- - `@osmix/core` In-memory index used to source node/way geometry.
94
- - `@osmix/json` – Supplies `wayIsArea` heuristics and entity types used by the encoder.
95
- - `@osmix/raster` – If you prefer raster previews or a protocol helper for MapLibre.
91
+ Run `bun run check` at the repo root before publishing to ensure formatting, lint, and type coverage.
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Vector tile encoding for OSM data.
3
+ *
4
+ * The OsmixVtEncoder class converts Osmix datasets into Mapbox Vector Tiles,
5
+ * handling geometry projection, clipping, area detection, and proper
6
+ * MVT encoding for nodes, ways, and relations.
7
+ *
8
+ * @module
9
+ */
10
+ import type { Osm } from "@osmix/core";
11
+ import type { GeoBbox2D, LonLat, Tile, XY } from "@osmix/shared/types";
12
+ import type { VtSimpleFeature } from "./types";
13
+ /**
14
+ * Returns a projection function that converts [lon, lat] to [x, y] pixel coordinates
15
+ * relative to the given tile. The extent determines the resolution of the tile
16
+ * (e.g. 4096 means coordinates range from 0 to 4096).
17
+ */
18
+ export declare function projectToTile(tile: Tile, extent?: number): (ll: LonLat) => XY;
19
+ /**
20
+ * Encode an Osm instance into a Mapbox Vector Tile PBF.
21
+ */
22
+ export declare class OsmixVtEncoder {
23
+ readonly nodeLayerName: string;
24
+ readonly wayLayerName: string;
25
+ readonly relationLayerName: string;
26
+ private readonly osm;
27
+ private readonly extent;
28
+ private readonly extentBbox;
29
+ static layerNames(id: string): {
30
+ nodeLayerName: string;
31
+ wayLayerName: string;
32
+ relationLayerName: string;
33
+ };
34
+ constructor(osm: Osm, extent?: number, buffer?: number);
35
+ /**
36
+ * Get a vector tile PBF for a specific tile coordinate.
37
+ * Returns an empty buffer if the tile does not intersect with the OSM dataset.
38
+ */
39
+ getTile(tile: Tile): ArrayBuffer;
40
+ /**
41
+ * Get a vector tile PBF for a specific geographic bounding box.
42
+ * @param bbox The bounding box to include features from.
43
+ * @param proj A function to project [lon, lat] to [x, y] within the tile extent.
44
+ */
45
+ getTileForBbox(bbox: GeoBbox2D, proj: (ll: LonLat) => XY): ArrayBuffer;
46
+ nodeFeatures(bbox: GeoBbox2D, proj: (ll: LonLat) => XY): Generator<VtSimpleFeature>;
47
+ wayFeatures(bbox: GeoBbox2D, proj: (ll: LonLat) => XY, relationWayIds?: Set<number>): Generator<VtSimpleFeature>;
48
+ clipProjectedPolyline(points: XY[]): XY[][];
49
+ clipProjectedPolygon(points: XY[]): XY[][];
50
+ processClippedPolygonRing(rawRing: XY[], isOuter: boolean): XY[];
51
+ /**
52
+ * Super relations and logical relations are not directly rendered; they would need recursive expansion.
53
+ */
54
+ relationFeatures(bbox: GeoBbox2D, proj: (ll: LonLat) => XY): Generator<VtSimpleFeature>;
55
+ clampAndRoundPoint(xy: XY): XY;
56
+ }
57
+ //# sourceMappingURL=encode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../src/encode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAItC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAEtE,OAAO,KAAK,EACX,eAAe,EAGf,MAAM,SAAS,CAAA;AA6BhB;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,IAAI,EAAE,IAAI,EACV,MAAM,SAAiB,GACrB,CAAC,EAAE,EAAE,MAAM,KAAK,EAAE,CAEpB;AAED;;GAEG;AACH,qBAAa,cAAc;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAE7D,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM;;;;;gBAQhB,GAAG,EAAE,GAAG,EAAE,MAAM,SAAiB,EAAE,MAAM,SAAiB;IActE;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW;IAShC;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,EAAE,GAAG,WAAW;IA2BrE,YAAY,CACZ,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,EAAE,GACtB,SAAS,CAAC,eAAe,CAAC;IAkB5B,WAAW,CACX,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,EAAE,EACxB,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,SAAS,CAAC,eAAe,CAAC;IA8D7B,qBAAqB,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IAI3C,oBAAoB,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IAO1C,yBAAyB,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,EAAE;IAkBhE;;OAEG;IACF,gBAAgB,CAChB,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,EAAE,GACtB,SAAS,CAAC,eAAe,CAAC;IA4G7B,kBAAkB,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE;CAS9B"}
package/dist/encode.js ADDED
@@ -0,0 +1,370 @@
1
+ /**
2
+ * Vector tile encoding for OSM data.
3
+ *
4
+ * The OsmixVtEncoder class converts Osmix datasets into Mapbox Vector Tiles,
5
+ * handling geometry projection, clipping, area detection, and proper
6
+ * MVT encoding for nodes, ways, and relations.
7
+ *
8
+ * @module
9
+ */
10
+ import { bboxContainsOrIntersects } from "@osmix/shared/bbox-intersects";
11
+ import { clipPolygon, clipPolyline } from "@osmix/shared/lineclip";
12
+ import { llToTilePx, tileToBbox } from "@osmix/shared/tile";
13
+ import { wayIsArea } from "@osmix/shared/way-is-area";
14
+ import writeVtPbf from "./write-vt-pbf";
15
+ /** Default tile extent (coordinate resolution). */
16
+ const DEFAULT_EXTENT = 4096;
17
+ /** Default buffer around tile in extent units. */
18
+ const DEFAULT_BUFFER = 64;
19
+ const SF_TYPE = {
20
+ POINT: 1,
21
+ LINE: 2,
22
+ POLYGON: 3,
23
+ };
24
+ const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
25
+ function dedupePoints(points) {
26
+ if (points.length < 2)
27
+ return points;
28
+ const result = [];
29
+ let lastPoint = [Number.NaN, Number.NaN];
30
+ for (const point of points) {
31
+ if (point[0] === lastPoint[0] && point[1] === lastPoint[1])
32
+ continue;
33
+ result.push(point);
34
+ lastPoint = point;
35
+ }
36
+ return result;
37
+ }
38
+ /**
39
+ * Returns a projection function that converts [lon, lat] to [x, y] pixel coordinates
40
+ * relative to the given tile. The extent determines the resolution of the tile
41
+ * (e.g. 4096 means coordinates range from 0 to 4096).
42
+ */
43
+ export function projectToTile(tile, extent = DEFAULT_EXTENT) {
44
+ return (lonLat) => llToTilePx(lonLat, tile, extent);
45
+ }
46
+ /**
47
+ * Encode an Osm instance into a Mapbox Vector Tile PBF.
48
+ */
49
+ export class OsmixVtEncoder {
50
+ nodeLayerName;
51
+ wayLayerName;
52
+ relationLayerName;
53
+ osm;
54
+ extent;
55
+ extentBbox;
56
+ static layerNames(id) {
57
+ return {
58
+ nodeLayerName: `@osmix:${id}:nodes`,
59
+ wayLayerName: `@osmix:${id}:ways`,
60
+ relationLayerName: `@osmix:${id}:relations`,
61
+ };
62
+ }
63
+ constructor(osm, extent = DEFAULT_EXTENT, buffer = DEFAULT_BUFFER) {
64
+ this.osm = osm;
65
+ const min = -buffer;
66
+ const max = extent + buffer;
67
+ this.extent = extent;
68
+ this.extentBbox = [min, min, max, max];
69
+ const layerName = `@osmix:${osm.id}`;
70
+ this.nodeLayerName = `${layerName}:nodes`;
71
+ this.wayLayerName = `${layerName}:ways`;
72
+ this.relationLayerName = `${layerName}:relations`;
73
+ }
74
+ /**
75
+ * Get a vector tile PBF for a specific tile coordinate.
76
+ * Returns an empty buffer if the tile does not intersect with the OSM dataset.
77
+ */
78
+ getTile(tile) {
79
+ const bbox = tileToBbox(tile);
80
+ const osmBbox = this.osm.bbox();
81
+ if (!bboxContainsOrIntersects(bbox, osmBbox)) {
82
+ return new ArrayBuffer(0);
83
+ }
84
+ return this.getTileForBbox(bbox, (ll) => llToTilePx(ll, tile, this.extent));
85
+ }
86
+ /**
87
+ * Get a vector tile PBF for a specific geographic bounding box.
88
+ * @param bbox The bounding box to include features from.
89
+ * @param proj A function to project [lon, lat] to [x, y] within the tile extent.
90
+ */
91
+ getTileForBbox(bbox, proj) {
92
+ // Get way IDs that are part of relations (to exclude from individual rendering)
93
+ const relationWayIds = this.osm.relations.getWayMemberIds();
94
+ const layers = [
95
+ {
96
+ name: this.wayLayerName,
97
+ version: 2,
98
+ extent: this.extent,
99
+ features: this.wayFeatures(bbox, proj, relationWayIds),
100
+ },
101
+ {
102
+ name: this.nodeLayerName,
103
+ version: 2,
104
+ extent: this.extent,
105
+ features: this.nodeFeatures(bbox, proj),
106
+ },
107
+ {
108
+ name: this.relationLayerName,
109
+ version: 2,
110
+ extent: this.extent,
111
+ features: this.relationFeatures(bbox, proj),
112
+ },
113
+ ];
114
+ return writeVtPbf(layers);
115
+ }
116
+ *nodeFeatures(bbox, proj) {
117
+ const nodeIndexes = this.osm.nodes.findIndexesWithinBbox(bbox);
118
+ for (let i = 0; i < nodeIndexes.length; i++) {
119
+ const nodeIndex = nodeIndexes[i];
120
+ if (nodeIndex === undefined)
121
+ continue;
122
+ const tags = this.osm.nodes.tags.getTags(nodeIndex);
123
+ if (!tags || Object.keys(tags).length === 0)
124
+ continue;
125
+ const id = this.osm.nodes.ids.at(nodeIndex);
126
+ const ll = this.osm.nodes.getNodeLonLat({ index: nodeIndex });
127
+ yield {
128
+ id,
129
+ type: SF_TYPE.POINT,
130
+ properties: { ...tags, type: "node" },
131
+ geometry: [[proj(ll)]],
132
+ };
133
+ }
134
+ }
135
+ *wayFeatures(bbox, proj, relationWayIds) {
136
+ const wayIndexes = this.osm.ways.intersects(bbox);
137
+ for (let i = 0; i < wayIndexes.length; i++) {
138
+ const wayIndex = wayIndexes[i];
139
+ if (wayIndex === undefined)
140
+ continue;
141
+ const id = this.osm.ways.ids.at(wayIndex);
142
+ // Skip ways that are part of relations (they will be rendered via relations)
143
+ if (id !== undefined && relationWayIds?.has(id))
144
+ continue;
145
+ const tags = this.osm.ways.tags.getTags(wayIndex);
146
+ // Skip ways without tags (they are likely only for relations)
147
+ if (!tags || Object.keys(tags).length === 0)
148
+ continue;
149
+ const wayLine = this.osm.ways.getCoordinates(wayIndex);
150
+ const points = wayLine.map((ll) => proj(ll));
151
+ const isArea = wayIsArea({
152
+ id,
153
+ refs: this.osm.ways.getRefIds(wayIndex),
154
+ tags,
155
+ });
156
+ const geometry = [];
157
+ if (isArea) {
158
+ // 1. clip polygon in tile coords (returns array of rings)
159
+ const clippedRings = this.clipProjectedPolygon(points);
160
+ // 2. process each ring (first is outer, rest would be holes if from relations)
161
+ for (let ringIndex = 0; ringIndex < clippedRings.length; ringIndex++) {
162
+ const clippedRing = clippedRings[ringIndex];
163
+ if (!clippedRing)
164
+ continue;
165
+ // Normalize winding order using rewind before processing
166
+ // GeoJSON: outer counterclockwise, inner clockwise
167
+ // MVT: outer clockwise, inner counterclockwise
168
+ const isOuter = ringIndex === 0;
169
+ const processedRing = this.processClippedPolygonRing(clippedRing, isOuter);
170
+ if (processedRing.length > 0) {
171
+ geometry.push(processedRing);
172
+ }
173
+ }
174
+ }
175
+ else {
176
+ const clippedSegmentsRaw = this.clipProjectedPolyline(points);
177
+ for (const segment of clippedSegmentsRaw) {
178
+ const rounded = segment.map((xy) => this.clampAndRoundPoint(xy));
179
+ const deduped = dedupePoints(rounded);
180
+ if (deduped.length >= 2) {
181
+ geometry.push(deduped);
182
+ }
183
+ }
184
+ }
185
+ if (geometry.length === 0)
186
+ continue;
187
+ yield {
188
+ id,
189
+ type: isArea ? SF_TYPE.POLYGON : SF_TYPE.LINE,
190
+ properties: { ...tags, type: "way" },
191
+ geometry,
192
+ };
193
+ }
194
+ }
195
+ clipProjectedPolyline(points) {
196
+ return clipPolyline(points, this.extentBbox);
197
+ }
198
+ clipProjectedPolygon(points) {
199
+ // clipPolygon returns a single ring, but we return as array for consistency
200
+ // with multi-ring support (e.g., from relations)
201
+ const clipped = clipPolygon(points, this.extentBbox);
202
+ return [clipped];
203
+ }
204
+ processClippedPolygonRing(rawRing, isOuter) {
205
+ // 1. round & clamp EVERY point
206
+ const snapped = rawRing.map((xy) => this.clampAndRoundPoint(xy));
207
+ // 2. clean (dedupe + close + min length)
208
+ const cleaned = cleanRing(snapped);
209
+ if (cleaned.length === 0)
210
+ return [];
211
+ // 3. enforce winding order per MVT spec:
212
+ // - Outer rings: clockwise
213
+ // - Inner rings (holes): counterclockwise
214
+ const oriented = isOuter
215
+ ? ensureClockwise(cleaned)
216
+ : ensureCounterclockwise(cleaned);
217
+ return oriented;
218
+ }
219
+ /**
220
+ * Super relations and logical relations are not directly rendered; they would need recursive expansion.
221
+ */
222
+ *relationFeatures(bbox, proj) {
223
+ const relationIndexes = this.osm.relations.intersects(bbox);
224
+ for (const relIndex of relationIndexes) {
225
+ const relation = this.osm.relations.getByIndex(relIndex);
226
+ const relationGeometry = this.osm.relations.getRelationGeometry(relIndex);
227
+ if (!relation ||
228
+ (!relationGeometry.lineStrings &&
229
+ !relationGeometry.rings &&
230
+ !relationGeometry.points))
231
+ continue;
232
+ const id = this.osm.relations.ids.at(relIndex);
233
+ const tags = this.osm.relations.tags.getTags(relIndex);
234
+ if (relationGeometry.rings) {
235
+ // Area relations (multipolygon, boundary)
236
+ const { rings } = relationGeometry;
237
+ if (rings.length === 0)
238
+ continue;
239
+ // Process each polygon in the relation
240
+ for (const polygon of rings) {
241
+ const geometry = [];
242
+ // Process outer ring and inner rings (holes)
243
+ for (let ringIndex = 0; ringIndex < polygon.length; ringIndex++) {
244
+ const ring = polygon[ringIndex];
245
+ if (!ring || ring.length < 3)
246
+ continue;
247
+ // Project ring to tile coordinates
248
+ const projectedRing = ring.map((ll) => proj(ll));
249
+ // Clip polygon ring
250
+ const clipped = clipPolygon(projectedRing, this.extentBbox);
251
+ if (clipped.length < 3)
252
+ continue;
253
+ // Process ring (round/clamp, dedupe, close, orient)
254
+ const isOuter = ringIndex === 0;
255
+ const processedRing = this.processClippedPolygonRing(clipped, isOuter);
256
+ if (processedRing.length > 0) {
257
+ geometry.push(processedRing);
258
+ }
259
+ }
260
+ if (geometry.length === 0)
261
+ continue;
262
+ yield {
263
+ id: id ?? 0,
264
+ type: SF_TYPE.POLYGON,
265
+ properties: { ...tags, type: "relation" },
266
+ geometry,
267
+ };
268
+ }
269
+ }
270
+ else if (relationGeometry.lineStrings) {
271
+ // Line relations (route, multilinestring)
272
+ const { lineStrings } = relationGeometry;
273
+ if (lineStrings.length === 0)
274
+ continue;
275
+ for (const lineString of lineStrings) {
276
+ const geometry = [];
277
+ const points = lineString.map((ll) => proj(ll));
278
+ const clippedSegmentsRaw = this.clipProjectedPolyline(points);
279
+ for (const segment of clippedSegmentsRaw) {
280
+ const rounded = segment.map((xy) => this.clampAndRoundPoint(xy));
281
+ const deduped = dedupePoints(rounded);
282
+ if (deduped.length >= 2) {
283
+ geometry.push(deduped);
284
+ }
285
+ }
286
+ if (geometry.length === 0)
287
+ continue;
288
+ yield {
289
+ id: id ?? 0,
290
+ type: SF_TYPE.LINE,
291
+ properties: { ...tags, type: "relation" },
292
+ geometry,
293
+ };
294
+ }
295
+ }
296
+ else if (relationGeometry.points) {
297
+ // Point relations (multipoint)
298
+ const { points } = relationGeometry;
299
+ if (points.length === 0)
300
+ continue;
301
+ const geometry = [];
302
+ for (const point of points) {
303
+ const projected = proj(point);
304
+ const clamped = this.clampAndRoundPoint(projected);
305
+ geometry.push([clamped]);
306
+ }
307
+ if (geometry.length === 0)
308
+ continue;
309
+ yield {
310
+ id: id ?? 0,
311
+ type: SF_TYPE.POINT,
312
+ properties: { ...tags, type: "relation" },
313
+ geometry,
314
+ };
315
+ }
316
+ }
317
+ }
318
+ clampAndRoundPoint(xy) {
319
+ const clampedX = Math.round(clamp(xy[0], this.extentBbox[0], this.extentBbox[2]));
320
+ const clampedY = Math.round(clamp(xy[1], this.extentBbox[1], this.extentBbox[3]));
321
+ return [clampedX, clampedY];
322
+ }
323
+ }
324
+ /**
325
+ * Ensures the ring is closed (first and last points are identical).
326
+ * If not, appends the first point to the end.
327
+ */
328
+ function closeRing(ring) {
329
+ const first = ring[0];
330
+ const last = ring[ring.length - 1];
331
+ if (first === undefined || last === undefined)
332
+ return ring;
333
+ if (first[0] !== last[0] || first[1] !== last[1]) {
334
+ return [...ring, first];
335
+ }
336
+ return ring;
337
+ }
338
+ /**
339
+ * Signed area via shoelace formula.
340
+ * Positive area => CCW, Negative => CW.
341
+ */
342
+ function ringArea(ring) {
343
+ let sum = 0;
344
+ for (let i = 0; i < ring.length - 1; i++) {
345
+ const [x1, y1] = ring[i];
346
+ const [x2, y2] = ring[i + 1];
347
+ sum += x1 * y2 - x2 * y1;
348
+ }
349
+ return sum / 2;
350
+ }
351
+ function ensureClockwise(ring) {
352
+ return ringArea(ring) < 0 ? ring : [...ring].reverse();
353
+ }
354
+ function ensureCounterclockwise(ring) {
355
+ return ringArea(ring) > 0 ? ring : [...ring].reverse();
356
+ }
357
+ /**
358
+ * Clean a polygon ring by removing consecutive duplicates, ensuring it's closed,
359
+ * and checking that it has at least 4 coordinates (3 unique points).
360
+ */
361
+ function cleanRing(ring) {
362
+ const deduped = dedupePoints(ring);
363
+ // After dedupe, we still must ensure closure, and a polygon
364
+ // ring needs at least 4 coords (A,B,C,A).
365
+ const closed = closeRing(deduped);
366
+ if (closed.length < 4)
367
+ return [];
368
+ return closed;
369
+ }
370
+ //# sourceMappingURL=encode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.js","sourceRoot":"","sources":["../src/encode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAMrD,OAAO,UAAU,MAAM,gBAAgB,CAAA;AAEvC,mDAAmD;AACnD,MAAM,cAAc,GAAG,IAAI,CAAA;AAC3B,kDAAkD;AAClD,MAAM,cAAc,GAAG,EAAE,CAAA;AAEzB,MAAM,OAAO,GAAwB;IACpC,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,CAAC;CACV,CAAA;AAED,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,EAAE,CACzD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;AAEpC,SAAS,YAAY,CAAC,MAAY;IACjC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,MAAM,CAAA;IACpC,MAAM,MAAM,GAAS,EAAE,CAAA;IACvB,IAAI,SAAS,GAAO,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAA;IAC5C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;YAAE,SAAQ;QACpE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAClB,SAAS,GAAG,KAAK,CAAA;IAClB,CAAC;IACD,OAAO,MAAM,CAAA;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC5B,IAAU,EACV,MAAM,GAAG,cAAc;IAEvB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,cAAc;IACjB,aAAa,CAAQ;IACrB,YAAY,CAAQ;IACpB,iBAAiB,CAAQ;IACjB,GAAG,CAAK;IACR,MAAM,CAAQ;IACd,UAAU,CAAkC;IAE7D,MAAM,CAAC,UAAU,CAAC,EAAU;QAC3B,OAAO;YACN,aAAa,EAAE,UAAU,EAAE,QAAQ;YACnC,YAAY,EAAE,UAAU,EAAE,OAAO;YACjC,iBAAiB,EAAE,UAAU,EAAE,YAAY;SAC3C,CAAA;IACF,CAAC;IAED,YAAY,GAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,MAAM,GAAG,cAAc;QACrE,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QAEd,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;QACnB,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,CAAA;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;QAEtC,MAAM,SAAS,GAAG,UAAU,GAAG,CAAC,EAAE,EAAE,CAAA;QACpC,IAAI,CAAC,aAAa,GAAG,GAAG,SAAS,QAAQ,CAAA;QACzC,IAAI,CAAC,YAAY,GAAG,GAAG,SAAS,OAAO,CAAA;QACvC,IAAI,CAAC,iBAAiB,GAAG,GAAG,SAAS,YAAY,CAAA;IAClD,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,IAAU;QACjB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;QAC/B,IAAI,CAAC,wBAAwB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;YAC9C,OAAO,IAAI,WAAW,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED;;;;OAIG;IACH,cAAc,CAAC,IAAe,EAAE,IAAwB;QACvD,gFAAgF;QAChF,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,CAAA;QAE3D,MAAM,MAAM,GAAG;YACd;gBACC,IAAI,EAAE,IAAI,CAAC,YAAY;gBACvB,OAAO,EAAE,CAAC;gBACV,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;aACtD;YACD;gBACC,IAAI,EAAE,IAAI,CAAC,aAAa;gBACxB,OAAO,EAAE,CAAC;gBACV,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC;aACvC;YACD;gBACC,IAAI,EAAE,IAAI,CAAC,iBAAiB;gBAC5B,OAAO,EAAE,CAAC;gBACV,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC;aAC3C;SACD,CAAA;QACD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAA;IAC1B,CAAC;IAED,CAAC,YAAY,CACZ,IAAe,EACf,IAAwB;QAExB,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;QAC9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;YAChC,IAAI,SAAS,KAAK,SAAS;gBAAE,SAAQ;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YACnD,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAQ;YACrD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAA;YAC3C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;YAC7D,MAAM;gBACL,EAAE;gBACF,IAAI,EAAE,OAAO,CAAC,KAAK;gBACnB,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE;gBACrC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;aACtB,CAAA;QACF,CAAC;IACF,CAAC;IAED,CAAC,WAAW,CACX,IAAe,EACf,IAAwB,EACxB,cAA4B;QAE5B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;YAC9B,IAAI,QAAQ,KAAK,SAAS;gBAAE,SAAQ;YACpC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAA;YACzC,6EAA6E;YAC7E,IAAI,EAAE,KAAK,SAAS,IAAI,cAAc,EAAE,GAAG,CAAC,EAAE,CAAC;gBAAE,SAAQ;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;YACjD,8DAA8D;YAC9D,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAQ;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;YACtD,MAAM,MAAM,GAAS,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;YAElD,MAAM,MAAM,GAAG,SAAS,CAAC;gBACxB,EAAE;gBACF,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;gBACvC,IAAI;aACJ,CAAC,CAAA;YACF,MAAM,QAAQ,GAA4B,EAAE,CAAA;YAC5C,IAAI,MAAM,EAAE,CAAC;gBACZ,0DAA0D;gBAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAA;gBAEtD,+EAA+E;gBAC/E,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;oBACtE,MAAM,WAAW,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;oBAC3C,IAAI,CAAC,WAAW;wBAAE,SAAQ;oBAE1B,yDAAyD;oBACzD,mDAAmD;oBACnD,+CAA+C;oBAC/C,MAAM,OAAO,GAAG,SAAS,KAAK,CAAC,CAAA;oBAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,yBAAyB,CACnD,WAAW,EACX,OAAO,CACP,CAAA;oBAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC9B,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;oBAC7B,CAAC;gBACF,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,MAAM,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAA;gBAC7D,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;oBAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAA;oBAChE,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;oBACrC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;wBACzB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;oBACvB,CAAC;gBACF,CAAC;YACF,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAQ;YACnC,MAAM;gBACL,EAAE;gBACF,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI;gBAC7C,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE;gBACpC,QAAQ;aACR,CAAA;QACF,CAAC;IACF,CAAC;IAED,qBAAqB,CAAC,MAAY;QACjC,OAAO,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IAC7C,CAAC;IAED,oBAAoB,CAAC,MAAY;QAChC,4EAA4E;QAC5E,iDAAiD;QACjD,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;QACpD,OAAO,CAAC,OAAO,CAAC,CAAA;IACjB,CAAC;IAED,yBAAyB,CAAC,OAAa,EAAE,OAAgB;QACxD,+BAA+B;QAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAA;QAEhE,yCAAyC;QACzC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;QAClC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAA;QAEnC,yCAAyC;QACzC,8BAA8B;QAC9B,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,OAAO;YACvB,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC;YAC1B,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAA;QAElC,OAAO,QAAQ,CAAA;IAChB,CAAC;IAED;;OAEG;IACH,CAAC,gBAAgB,CAChB,IAAe,EACf,IAAwB;QAExB,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QAE3D,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;YACxD,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAA;YACzE,IACC,CAAC,QAAQ;gBACT,CAAC,CAAC,gBAAgB,CAAC,WAAW;oBAC7B,CAAC,gBAAgB,CAAC,KAAK;oBACvB,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAE1B,SAAQ;YAET,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAA;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;YAEtD,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;gBAC5B,0CAA0C;gBAC1C,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,CAAA;gBAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAQ;gBAEhC,uCAAuC;gBACvC,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;oBAC7B,MAAM,QAAQ,GAA4B,EAAE,CAAA;oBAE5C,6CAA6C;oBAC7C,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;wBACjE,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;wBAC/B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;4BAAE,SAAQ;wBAEtC,mCAAmC;wBACnC,MAAM,aAAa,GAAS,IAAI,CAAC,GAAG,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;wBAE9D,oBAAoB;wBACpB,MAAM,OAAO,GAAG,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;wBAC3D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;4BAAE,SAAQ;wBAEhC,oDAAoD;wBACpD,MAAM,OAAO,GAAG,SAAS,KAAK,CAAC,CAAA;wBAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,yBAAyB,CACnD,OAAO,EACP,OAAO,CACP,CAAA;wBAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BAC9B,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;wBAC7B,CAAC;oBACF,CAAC;oBAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;wBAAE,SAAQ;oBAEnC,MAAM;wBACL,EAAE,EAAE,EAAE,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO,CAAC,OAAO;wBACrB,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE;wBACzC,QAAQ;qBACR,CAAA;gBACF,CAAC;YACF,CAAC;iBAAM,IAAI,gBAAgB,CAAC,WAAW,EAAE,CAAC;gBACzC,0CAA0C;gBAC1C,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAA;gBACxC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAQ;gBAEtC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;oBACtC,MAAM,QAAQ,GAA4B,EAAE,CAAA;oBAC5C,MAAM,MAAM,GAAS,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;oBACrD,MAAM,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAA;oBAC7D,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;wBAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAA;wBAChE,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;wBACrC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;4BACzB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;wBACvB,CAAC;oBACF,CAAC;oBACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;wBAAE,SAAQ;oBAEnC,MAAM;wBACL,EAAE,EAAE,EAAE,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO,CAAC,IAAI;wBAClB,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE;wBACzC,QAAQ;qBACR,CAAA;gBACF,CAAC;YACF,CAAC;iBAAM,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC;gBACpC,+BAA+B;gBAC/B,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAA;gBACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAQ;gBAEjC,MAAM,QAAQ,GAA4B,EAAE,CAAA;gBAC5C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;oBAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAA;oBAClD,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;gBACzB,CAAC;gBAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAQ;gBAEnC,MAAM;oBACL,EAAE,EAAE,EAAE,IAAI,CAAC;oBACX,IAAI,EAAE,OAAO,CAAC,KAAK;oBACnB,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE;oBACzC,QAAQ;iBACR,CAAA;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED,kBAAkB,CAAC,EAAM;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAC1B,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CACpD,CAAA;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAC1B,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CACpD,CAAA;QACD,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAO,CAAA;IAClC,CAAC;CACD;AAED;;;GAGG;AACH,SAAS,SAAS,CAAC,IAAU;IAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;IACrB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAClC,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAC1D,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,OAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAA;IACxB,CAAC;IACD,OAAO,IAAI,CAAA;AACZ,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,IAAU;IAC3B,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAE,CAAA;QACzB,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAA;QAC7B,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;IACzB,CAAC;IACD,OAAO,GAAG,GAAG,CAAC,CAAA;AACf,CAAC;AAED,SAAS,eAAe,CAAC,IAAU;IAClC,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE,CAAA;AACvD,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAU;IACzC,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE,CAAA;AACvD,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAAC,IAAU;IAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IAClC,4DAA4D;IAC5D,0CAA0C;IAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IACjC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAChC,OAAO,MAAM,CAAA;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=encode.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.test.d.ts","sourceRoot":"","sources":["../src/encode.test.ts"],"names":[],"mappings":""}