@honua/react 0.0.20-alpha.0 → 0.1.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/contract/discovery.d.ts +231 -0
  2. package/contract/discovery.d.ts.map +1 -0
  3. package/contract/discovery.js +554 -0
  4. package/contract/edit-sketch.d.ts +8 -0
  5. package/contract/edit-sketch.d.ts.map +1 -1
  6. package/contract/edit-sketch.js +15 -0
  7. package/contract/edit-snapping.d.ts +160 -0
  8. package/contract/edit-snapping.d.ts.map +1 -0
  9. package/contract/edit-snapping.js +675 -0
  10. package/contract/generated/projjson-v0.7-crs-validator.d.ts +35 -0
  11. package/contract/generated/projjson-v0.7-crs-validator.d.ts.map +1 -0
  12. package/contract/generated/projjson-v0.7-crs-validator.js +3941 -0
  13. package/contract/index.d.ts +12 -1
  14. package/contract/index.d.ts.map +1 -1
  15. package/contract/index.js +4 -0
  16. package/contract/pmtiles.d.ts +193 -0
  17. package/contract/pmtiles.d.ts.map +1 -0
  18. package/contract/pmtiles.js +195 -0
  19. package/contract/protocol-module.d.ts +70 -0
  20. package/contract/protocol-module.d.ts.map +1 -0
  21. package/contract/protocol-module.js +1 -0
  22. package/contract/schema-envelope.d.ts +26 -0
  23. package/contract/schema-envelope.d.ts.map +1 -0
  24. package/contract/schema-envelope.js +25 -0
  25. package/contract/schema.d.ts +582 -0
  26. package/contract/schema.d.ts.map +1 -0
  27. package/contract/schema.js +2483 -0
  28. package/contract/source-capability-support.d.ts +6 -0
  29. package/contract/source-capability-support.d.ts.map +1 -0
  30. package/contract/source-capability-support.js +154 -0
  31. package/contract/source.d.ts +57 -15
  32. package/contract/source.d.ts.map +1 -1
  33. package/contract/source.js +368 -65
  34. package/contract/types.d.ts +171 -6
  35. package/contract/types.d.ts.map +1 -1
  36. package/contract/types.js +14 -14
  37. package/core/auth/client-credentials-provider.d.ts +51 -0
  38. package/core/auth/client-credentials-provider.d.ts.map +1 -0
  39. package/core/auth/client-credentials-provider.js +115 -0
  40. package/core/auth/credential-store.d.ts +52 -0
  41. package/core/auth/credential-store.d.ts.map +1 -0
  42. package/core/auth/credential-store.js +82 -0
  43. package/core/auth/index.d.ts +23 -0
  44. package/core/auth/index.d.ts.map +1 -0
  45. package/core/auth/index.js +20 -0
  46. package/core/auth/oauth2-provider.d.ts +114 -0
  47. package/core/auth/oauth2-provider.d.ts.map +1 -0
  48. package/core/auth/oauth2-provider.js +408 -0
  49. package/core/auth/pkce.d.ts +25 -0
  50. package/core/auth/pkce.d.ts.map +1 -0
  51. package/core/auth/pkce.js +46 -0
  52. package/core/auth/static-providers.d.ts +20 -0
  53. package/core/auth/static-providers.d.ts.map +1 -0
  54. package/core/auth/static-providers.js +26 -0
  55. package/core/auth/token-endpoint.d.ts +40 -0
  56. package/core/auth/token-endpoint.d.ts.map +1 -0
  57. package/core/auth/token-endpoint.js +133 -0
  58. package/core/auth/types.d.ts +144 -0
  59. package/core/auth/types.d.ts.map +1 -0
  60. package/core/auth/types.js +8 -0
  61. package/core/bounded-json.d.ts +4 -0
  62. package/core/bounded-json.d.ts.map +1 -0
  63. package/core/bounded-json.js +38 -0
  64. package/core/cache-state.d.ts +9 -0
  65. package/core/cache-state.d.ts.map +1 -1
  66. package/core/cache-state.js +10 -0
  67. package/core/capabilities-xml.d.ts +33 -0
  68. package/core/capabilities-xml.d.ts.map +1 -0
  69. package/core/capabilities-xml.js +331 -0
  70. package/core/client.d.ts +35 -2
  71. package/core/client.d.ts.map +1 -1
  72. package/core/client.js +167 -29
  73. package/core/error-classifications.d.ts +153 -0
  74. package/core/error-classifications.d.ts.map +1 -0
  75. package/core/error-classifications.js +140 -0
  76. package/core/error-code-registry.d.ts +158 -0
  77. package/core/error-code-registry.d.ts.map +1 -0
  78. package/core/error-code-registry.js +143 -0
  79. package/core/error-envelope.d.ts +68 -0
  80. package/core/error-envelope.d.ts.map +1 -0
  81. package/core/error-envelope.js +357 -0
  82. package/core/errors.d.ts +73 -25
  83. package/core/errors.d.ts.map +1 -1
  84. package/core/errors.js +113 -46
  85. package/core/geoparquet-sql.d.ts +190 -0
  86. package/core/geoparquet-sql.d.ts.map +1 -0
  87. package/core/geoparquet-sql.js +368 -0
  88. package/core/odata-key-path.d.ts +12 -0
  89. package/core/odata-key-path.d.ts.map +1 -0
  90. package/core/odata-key-path.js +28 -0
  91. package/core/odata-write-codec.d.ts +66 -0
  92. package/core/odata-write-codec.d.ts.map +1 -0
  93. package/core/odata-write-codec.js +1083 -0
  94. package/core/odata.d.ts +59 -7
  95. package/core/odata.d.ts.map +1 -1
  96. package/core/odata.js +431 -99
  97. package/core/ogc-endpoint-layout.d.ts +70 -0
  98. package/core/ogc-endpoint-layout.d.ts.map +1 -0
  99. package/core/ogc-endpoint-layout.js +173 -0
  100. package/core/ogc-features.d.ts.map +1 -1
  101. package/core/ogc-features.js +35 -17
  102. package/core/ogc-maps.d.ts +7 -0
  103. package/core/ogc-maps.d.ts.map +1 -1
  104. package/core/ogc-maps.js +46 -7
  105. package/core/ogc-processes.d.ts +2 -1
  106. package/core/ogc-processes.d.ts.map +1 -1
  107. package/core/ogc-processes.js +33 -5
  108. package/core/ogc-records.d.ts +9 -0
  109. package/core/ogc-records.d.ts.map +1 -1
  110. package/core/ogc-records.js +78 -29
  111. package/core/ogc-tiles.d.ts +10 -1
  112. package/core/ogc-tiles.d.ts.map +1 -1
  113. package/core/ogc-tiles.js +56 -17
  114. package/core/path-utils.d.ts +9 -0
  115. package/core/path-utils.d.ts.map +1 -1
  116. package/core/path-utils.js +19 -0
  117. package/core/protocol-transport.d.ts +1 -0
  118. package/core/protocol-transport.d.ts.map +1 -1
  119. package/core/request-pipeline.d.ts.map +1 -1
  120. package/core/request-pipeline.js +1 -1
  121. package/core/spatial-filter.d.ts +8 -4
  122. package/core/spatial-filter.d.ts.map +1 -1
  123. package/core/spatial-filter.js +206 -16
  124. package/core/stac-static.d.ts +55 -0
  125. package/core/stac-static.d.ts.map +1 -0
  126. package/core/stac-static.js +386 -0
  127. package/core/stac.d.ts +12 -0
  128. package/core/stac.d.ts.map +1 -1
  129. package/core/stac.js +45 -15
  130. package/core/surfaces.d.ts +13 -0
  131. package/core/surfaces.d.ts.map +1 -1
  132. package/core/surfaces.js +127 -16
  133. package/core/types.d.ts +174 -7
  134. package/core/types.d.ts.map +1 -1
  135. package/core/wfs-capabilities.d.ts +12 -0
  136. package/core/wfs-capabilities.d.ts.map +1 -1
  137. package/core/wfs-capabilities.js +22 -3
  138. package/core/wfs.d.ts +13 -0
  139. package/core/wfs.d.ts.map +1 -1
  140. package/core/wfs.js +35 -5
  141. package/core/wms-capabilities.d.ts +56 -84
  142. package/core/wms-capabilities.d.ts.map +1 -1
  143. package/core/wms-capabilities.js +212 -509
  144. package/core/wmts-capabilities.d.ts +62 -62
  145. package/core/wmts-capabilities.d.ts.map +1 -1
  146. package/core/wmts-capabilities.js +224 -371
  147. package/esri-compat/editor.d.ts +8 -0
  148. package/esri-compat/editor.d.ts.map +1 -1
  149. package/esri-compat/editor.js +13 -0
  150. package/esri-compat/feature-layer.d.ts +2 -0
  151. package/esri-compat/feature-layer.d.ts.map +1 -1
  152. package/esri-compat/feature-layer.js +1 -0
  153. package/esri-compat/identity-manager.d.ts +43 -0
  154. package/esri-compat/identity-manager.d.ts.map +1 -1
  155. package/esri-compat/identity-manager.js +131 -1
  156. package/esri-compat/layer-list.d.ts +11 -0
  157. package/esri-compat/layer-list.d.ts.map +1 -1
  158. package/esri-compat/layer-list.js +49 -0
  159. package/esri-compat/legend.d.ts +10 -0
  160. package/esri-compat/legend.d.ts.map +1 -1
  161. package/esri-compat/legend.js +27 -0
  162. package/esri-compat/oauth-info.d.ts +15 -0
  163. package/esri-compat/oauth-info.d.ts.map +1 -1
  164. package/esri-compat/oauth-info.js +27 -0
  165. package/esri-compat/portal.d.ts +197 -0
  166. package/esri-compat/portal.d.ts.map +1 -0
  167. package/esri-compat/portal.js +251 -0
  168. package/esri-compat/renderer-objects.d.ts +40 -0
  169. package/esri-compat/renderer-objects.d.ts.map +1 -0
  170. package/esri-compat/renderer-objects.js +62 -0
  171. package/esri-compat/sketch.d.ts +43 -0
  172. package/esri-compat/sketch.d.ts.map +1 -1
  173. package/esri-compat/sketch.js +46 -0
  174. package/esri-compat/snapping.d.ts +43 -0
  175. package/esri-compat/snapping.d.ts.map +1 -0
  176. package/esri-compat/snapping.js +45 -0
  177. package/esri-compat/url.d.ts.map +1 -1
  178. package/esri-compat/url.js +1 -1
  179. package/esri-compat/widget-host.d.ts +84 -0
  180. package/esri-compat/widget-host.d.ts.map +1 -0
  181. package/esri-compat/widget-host.js +159 -0
  182. package/filter-registry/index.d.ts +145 -0
  183. package/filter-registry/index.d.ts.map +1 -0
  184. package/filter-registry/index.js +531 -0
  185. package/generated-app/errors.d.ts +18 -2
  186. package/generated-app/errors.d.ts.map +1 -1
  187. package/generated-app/errors.js +44 -11
  188. package/map/automatic-mount-integration.d.ts +134 -0
  189. package/map/automatic-mount-integration.d.ts.map +1 -0
  190. package/map/automatic-mount-integration.js +305 -0
  191. package/map/automatic-source-strategy.d.ts +125 -0
  192. package/map/automatic-source-strategy.d.ts.map +1 -0
  193. package/map/automatic-source-strategy.js +494 -0
  194. package/map/data-to-map-bridge.d.ts +293 -0
  195. package/map/data-to-map-bridge.d.ts.map +1 -0
  196. package/map/data-to-map-bridge.js +817 -0
  197. package/map/geojson-projection.d.ts +33 -0
  198. package/map/geojson-projection.d.ts.map +1 -0
  199. package/map/geojson-projection.js +118 -0
  200. package/map/index.d.ts +14 -0
  201. package/map/index.d.ts.map +1 -1
  202. package/map/index.js +8 -0
  203. package/map/raster-source-spec.d.ts +30 -0
  204. package/map/raster-source-spec.d.ts.map +1 -0
  205. package/map/raster-source-spec.js +190 -0
  206. package/map/raster-source-strategy.d.ts +65 -0
  207. package/map/raster-source-strategy.d.ts.map +1 -0
  208. package/map/raster-source-strategy.js +232 -0
  209. package/map/source-to-maplibre.d.ts +91 -0
  210. package/map/source-to-maplibre.d.ts.map +1 -0
  211. package/map/source-to-maplibre.js +454 -0
  212. package/map/temporal-playback.d.ts +139 -0
  213. package/map/temporal-playback.d.ts.map +1 -0
  214. package/map/temporal-playback.js +247 -0
  215. package/package.json +19 -1
  216. package/query-planner/canonical.d.ts +7 -0
  217. package/query-planner/canonical.d.ts.map +1 -0
  218. package/query-planner/canonical.js +145 -0
  219. package/query-planner/cql2-json.d.ts +17 -0
  220. package/query-planner/cql2-json.d.ts.map +1 -0
  221. package/query-planner/cql2-json.js +646 -0
  222. package/query-planner/diagnostics.d.ts +35 -0
  223. package/query-planner/diagnostics.d.ts.map +1 -0
  224. package/query-planner/diagnostics.js +373 -0
  225. package/query-planner/duckdb.d.ts +79 -0
  226. package/query-planner/duckdb.d.ts.map +1 -0
  227. package/query-planner/duckdb.js +758 -0
  228. package/query-planner/execution-context.d.ts +5 -0
  229. package/query-planner/execution-context.d.ts.map +1 -0
  230. package/query-planner/execution-context.js +50 -0
  231. package/query-planner/executor.d.ts +5 -0
  232. package/query-planner/executor.d.ts.map +1 -0
  233. package/query-planner/executor.js +223 -0
  234. package/query-planner/geoservices.d.ts +91 -0
  235. package/query-planner/geoservices.d.ts.map +1 -0
  236. package/query-planner/geoservices.js +667 -0
  237. package/query-planner/grpc.d.ts +100 -0
  238. package/query-planner/grpc.d.ts.map +1 -0
  239. package/query-planner/grpc.js +736 -0
  240. package/query-planner/index.d.ts +44 -0
  241. package/query-planner/index.d.ts.map +1 -0
  242. package/query-planner/index.js +30 -0
  243. package/query-planner/ir.d.ts +20 -0
  244. package/query-planner/ir.d.ts.map +1 -0
  245. package/query-planner/ir.js +417 -0
  246. package/query-planner/local-aggregate.d.ts +5 -0
  247. package/query-planner/local-aggregate.d.ts.map +1 -0
  248. package/query-planner/local-aggregate.js +126 -0
  249. package/query-planner/odata.d.ts +48 -0
  250. package/query-planner/odata.d.ts.map +1 -0
  251. package/query-planner/odata.js +662 -0
  252. package/query-planner/ogc-compiler.d.ts +55 -0
  253. package/query-planner/ogc-compiler.d.ts.map +1 -0
  254. package/query-planner/ogc-compiler.js +480 -0
  255. package/query-planner/ogc-features.d.ts +53 -0
  256. package/query-planner/ogc-features.d.ts.map +1 -0
  257. package/query-planner/ogc-features.js +617 -0
  258. package/query-planner/planner.d.ts +17 -0
  259. package/query-planner/planner.d.ts.map +1 -0
  260. package/query-planner/planner.js +818 -0
  261. package/query-planner/resource.d.ts +94 -0
  262. package/query-planner/resource.d.ts.map +1 -0
  263. package/query-planner/resource.js +526 -0
  264. package/query-planner/semantic-canonical.d.ts +15 -0
  265. package/query-planner/semantic-canonical.d.ts.map +1 -0
  266. package/query-planner/semantic-canonical.js +62 -0
  267. package/query-planner/semantic-compat.d.ts +10 -0
  268. package/query-planner/semantic-compat.d.ts.map +1 -0
  269. package/query-planner/semantic-compat.js +35 -0
  270. package/query-planner/semantic-compiler.d.ts +64 -0
  271. package/query-planner/semantic-compiler.d.ts.map +1 -0
  272. package/query-planner/semantic-compiler.js +81 -0
  273. package/query-planner/semantic-literals.d.ts +30 -0
  274. package/query-planner/semantic-literals.d.ts.map +1 -0
  275. package/query-planner/semantic-literals.js +133 -0
  276. package/query-planner/semantic-types.d.ts +265 -0
  277. package/query-planner/semantic-types.d.ts.map +1 -0
  278. package/query-planner/semantic-types.js +1 -0
  279. package/query-planner/semantic.d.ts +54 -0
  280. package/query-planner/semantic.d.ts.map +1 -0
  281. package/query-planner/semantic.js +1421 -0
  282. package/query-planner/types.d.ts +560 -0
  283. package/query-planner/types.d.ts.map +1 -0
  284. package/query-planner/types.js +49 -0
  285. package/query-planner/wfs-semantic.d.ts +58 -0
  286. package/query-planner/wfs-semantic.d.ts.map +1 -0
  287. package/query-planner/wfs-semantic.js +547 -0
  288. package/query-planner/wfs.d.ts +6 -0
  289. package/query-planner/wfs.d.ts.map +1 -0
  290. package/query-planner/wfs.js +71 -0
  291. package/react/external-map.d.ts +67 -0
  292. package/react/external-map.d.ts.map +1 -0
  293. package/react/external-map.js +63 -0
  294. package/react/honua-map.d.ts.map +1 -1
  295. package/react/honua-map.js +3 -2
  296. package/react/honua-source-layer.d.ts +110 -0
  297. package/react/honua-source-layer.d.ts.map +1 -0
  298. package/react/honua-source-layer.js +101 -0
  299. package/react/hooks.d.ts +28 -0
  300. package/react/hooks.d.ts.map +1 -1
  301. package/react/hooks.js +26 -4
  302. package/react/index.d.ts +8 -0
  303. package/react/index.d.ts.map +1 -1
  304. package/react/index.js +5 -0
  305. package/react/query-cache.d.ts +26 -4
  306. package/react/query-cache.d.ts.map +1 -1
  307. package/react/query-cache.js +51 -8
  308. package/react/selection.d.ts +177 -0
  309. package/react/selection.d.ts.map +1 -0
  310. package/react/selection.js +0 -0
  311. package/react/use-mounted-source.d.ts +69 -0
  312. package/react/use-mounted-source.d.ts.map +1 -0
  313. package/react/use-mounted-source.js +346 -0
  314. package/runtime/edit-snapping.d.ts +107 -0
  315. package/runtime/edit-snapping.d.ts.map +1 -0
  316. package/runtime/edit-snapping.js +190 -0
  317. package/runtime/errors.d.ts +3 -2
  318. package/runtime/errors.d.ts.map +1 -1
  319. package/runtime/errors.js +19 -2
  320. package/runtime/index.d.ts +8 -2
  321. package/runtime/index.d.ts.map +1 -1
  322. package/runtime/index.js +4 -4
  323. package/runtime/load-package.d.ts.map +1 -1
  324. package/runtime/load-package.js +8 -0
  325. package/runtime/map-package-validation.d.ts +0 -13
  326. package/runtime/map-package-validation.d.ts.map +1 -1
  327. package/runtime/map-package-validation.js +0 -12
  328. package/runtime/map-package.d.ts +1 -1
  329. package/runtime/map-package.d.ts.map +1 -1
  330. package/runtime/maplibre-renderer.d.ts +41 -0
  331. package/runtime/maplibre-renderer.d.ts.map +1 -0
  332. package/runtime/maplibre-renderer.js +322 -0
  333. package/runtime/pmtiles-protocol.d.ts +77 -0
  334. package/runtime/pmtiles-protocol.d.ts.map +1 -0
  335. package/runtime/pmtiles-protocol.js +120 -0
  336. package/runtime/query-tiles.d.ts +2 -1
  337. package/runtime/query-tiles.d.ts.map +1 -1
  338. package/runtime/query-tiles.js +6 -2
  339. package/runtime/source-bridge.d.ts +4 -4
  340. package/runtime/source-bridge.d.ts.map +1 -1
  341. package/runtime/source-bridge.js +36 -56
  342. package/runtime/style-interactions.d.ts +3 -2
  343. package/runtime/style-interactions.d.ts.map +1 -1
  344. package/runtime/style-interactions.js +11 -3
  345. package/runtime/terra-draw-sketch.d.ts +275 -0
  346. package/runtime/terra-draw-sketch.d.ts.map +1 -0
  347. package/runtime/terra-draw-sketch.js +404 -0
  348. package/source-capability-registry.d.ts +1 -0
  349. package/source-capability-registry.js +1 -0
  350. package/source-capability-types.d.ts +186 -0
  351. package/source-capability-types.js +7 -0
  352. package/style/index.d.ts +2 -0
  353. package/style/index.d.ts.map +1 -1
  354. package/style/index.js +2 -0
  355. package/style/renderers.d.ts +326 -0
  356. package/style/renderers.d.ts.map +1 -0
  357. package/style/renderers.js +517 -0
  358. package/webmap/convert-renderer.d.ts +24 -3
  359. package/webmap/convert-renderer.d.ts.map +1 -1
  360. package/webmap/convert-renderer.js +93 -112
  361. package/webmap/index.d.ts +1 -1
  362. package/webmap/index.d.ts.map +1 -1
  363. package/webmap/index.js +1 -1
package/core/errors.js CHANGED
@@ -1,8 +1,9 @@
1
1
  /**
2
- * Honua SDK error hierarchy. Every error thrown by `@honua/sdk-js` is an
3
- * instance of one of the classes in this file plus the runtime-type guard
4
- * `isHonuaError(error)`. See [`docs/errors.md`](../../docs/errors.md) for the
5
- * full reference table including recovery hints and the retry-policy mapping.
2
+ * Tagged hierarchy for the migrated Honua SDK error domains. The common
3
+ * `isHonuaError(error)` guard also recognizes migrated query, map, runtime,
4
+ * realtime, offline, and plugin subclasses. See
5
+ * [`docs/errors.md`](../../docs/errors.md) for exact coverage, residual domains,
6
+ * recovery hints, and the retryability classification.
6
7
  *
7
8
  * @example
8
9
  * ```ts
@@ -29,9 +30,39 @@
29
30
  *
30
31
  * @packageDocumentation
31
32
  */
32
- import { HonuaJobFailedError } from "./ogc-processes.js";
33
- import { HonuaWmsCapabilitiesParseError } from "./wms-capabilities.js";
34
- import { HonuaWmtsCapabilitiesParseError } from "./wmts-capabilities.js";
33
+ import { HonuaSdkError, isHonuaSdkError, mergeHonuaErrorContext, } from "./error-envelope.js";
34
+ /** Discovery input, metadata, or cache identity is invalid or inconsistent. */
35
+ export class HonuaDiscoveryError extends HonuaSdkError {
36
+ code;
37
+ detail;
38
+ constructor(code, message, detail, options = {}) {
39
+ super(`discovery.${code}`, message, {
40
+ ...options,
41
+ context: mergeHonuaErrorContext(detail, options.context),
42
+ });
43
+ this.code = code;
44
+ this.detail = detail;
45
+ this.name = "HonuaDiscoveryError";
46
+ }
47
+ }
48
+ /**
49
+ * Thrown when a geometry cannot be classified without guessing. The structured
50
+ * `code` and `detail` fields let callers distinguish an unsupported shape from
51
+ * a recognized-but-malformed Esri geometry without parsing the message.
52
+ */
53
+ export class HonuaGeometryError extends HonuaSdkError {
54
+ code;
55
+ detail;
56
+ constructor(code, message, detail, options = {}) {
57
+ super(`core.geometry.${code}`, message, {
58
+ ...options,
59
+ context: mergeHonuaErrorContext(detail, options.context),
60
+ });
61
+ this.code = code;
62
+ this.detail = detail;
63
+ this.name = "HonuaGeometryError";
64
+ }
65
+ }
35
66
  /**
36
67
  * Thrown when the server returns a non-2xx HTTP status. Branch on
37
68
  * `.statusCode` to decide recovery: refresh credentials on 401/403, respect
@@ -39,49 +70,58 @@ import { HonuaWmtsCapabilitiesParseError } from "./wmts-capabilities.js";
39
70
  *
40
71
  * @see [`docs/errors.md`](../../docs/errors.md)
41
72
  */
42
- export class HonuaHttpError extends Error {
73
+ export class HonuaHttpError extends HonuaSdkError {
43
74
  statusCode;
44
75
  body;
45
- constructor(statusCode, message, body) {
46
- super(`HTTP ${statusCode}: ${message}`);
76
+ constructor(statusCode, message, body, options = {}) {
77
+ super(HTTP_RETRYABLE_STATUSES.has(statusCode) ? "core.http.transient" : "core.http.rejected", `HTTP ${statusCode}: ${message}`, {
78
+ ...options,
79
+ context: mergeHonuaErrorContext(options.context, { statusCode }),
80
+ });
47
81
  this.name = "HonuaHttpError";
48
82
  this.statusCode = statusCode;
49
83
  this.body = body;
50
84
  }
51
85
  }
52
86
  /** Thrown when a request exceeds the configured timeout. */
53
- export class HonuaTimeoutError extends Error {
87
+ export class HonuaTimeoutError extends HonuaSdkError {
54
88
  timeoutMs;
55
- constructor(timeoutMs) {
56
- super(`Request timed out after ${timeoutMs}ms`);
89
+ constructor(timeoutMs, options = {}) {
90
+ super("core.timeout", `Request timed out after ${timeoutMs}ms`, {
91
+ ...options,
92
+ context: mergeHonuaErrorContext(options.context, { timeoutMs }),
93
+ });
57
94
  this.name = "HonuaTimeoutError";
58
95
  this.timeoutMs = timeoutMs;
59
96
  }
60
97
  }
61
98
  /** Thrown when a network-level failure occurs (DNS, connection refused, etc.). */
62
- export class HonuaNetworkError extends Error {
99
+ export class HonuaNetworkError extends HonuaSdkError {
63
100
  cause;
64
- constructor(message, cause) {
65
- super(message);
101
+ constructor(message, cause, metadata = {}) {
102
+ super("core.network", message, { ...metadata, cause });
66
103
  this.name = "HonuaNetworkError";
67
104
  this.cause = cause;
68
105
  }
69
106
  }
70
107
  /** Thrown when a request is aborted via a caller-provided AbortSignal. */
71
- export class HonuaAbortError extends Error {
72
- constructor(message = "Request was aborted") {
73
- super(message);
108
+ export class HonuaAbortError extends HonuaSdkError {
109
+ constructor(message = "Request was aborted", options = {}) {
110
+ super("core.cancelled", message, options);
74
111
  this.name = "HonuaAbortError";
75
112
  }
76
113
  }
77
114
  /** Thrown when a gRPC-Web request fails, wrapping the underlying ConnectError. */
78
- export class HonuaGrpcError extends Error {
115
+ export class HonuaGrpcError extends HonuaSdkError {
79
116
  code;
80
117
  details;
81
- constructor(code, message, details) {
82
- super(message);
83
- this.name = "HonuaGrpcError";
118
+ constructor(code, message, details, options = {}) {
119
+ super(GRPC_RETRYABLE_CODES.has(code) ? "core.grpc.transient" : "core.grpc.rejected", message, {
120
+ ...options,
121
+ context: mergeHonuaErrorContext(options.context, { grpcCode: code }),
122
+ });
84
123
  this.code = code;
124
+ this.name = "HonuaGrpcError";
85
125
  this.details = details;
86
126
  }
87
127
  }
@@ -92,32 +132,58 @@ export class HonuaGrpcError extends Error {
92
132
  * decide whether to swap protocols, fall back to a degraded strategy, or
93
133
  * surface the limitation to the user.
94
134
  */
95
- export class HonuaCapabilityNotSupportedError extends Error {
135
+ export class HonuaCapabilityNotSupportedError extends HonuaSdkError {
96
136
  capability;
97
137
  protocol;
98
138
  sourceId;
99
- constructor(capability, protocol, sourceId) {
100
- super(sourceId
139
+ constructor(capability, protocol, sourceId, options = {}) {
140
+ const message = sourceId
101
141
  ? `Capability "${capability}" is not supported by protocol "${protocol}" on source "${sourceId}"`
102
- : `Capability "${capability}" is not supported by protocol "${protocol}"`);
142
+ : `Capability "${capability}" is not supported by protocol "${protocol}"`;
143
+ super("core.capability-not-supported", message, {
144
+ ...options,
145
+ context: mergeHonuaErrorContext(options.context, { capability, protocol, sourceId }),
146
+ });
103
147
  this.name = "HonuaCapabilityNotSupportedError";
104
148
  this.capability = capability;
105
149
  this.protocol = protocol;
106
150
  this.sourceId = sourceId;
107
151
  }
108
152
  }
153
+ /**
154
+ * Thrown by the auth providers (`oauth2`, `clientCredentials`, …) when a
155
+ * credential cannot be produced. Branch on `.code` (see {@link HonuaAuthErrorCode})
156
+ * to decide whether to start interactive sign-in, retry the refresh later, or
157
+ * surface the failure to the user. The underlying transport/parse failure, when
158
+ * present, is preserved on `.cause`.
159
+ *
160
+ * @see [`docs/errors.md`](../../docs/errors.md)
161
+ */
162
+ export class HonuaAuthError extends HonuaSdkError {
163
+ code;
164
+ cause;
165
+ constructor(code, message, options = {}) {
166
+ super(AUTH_ERROR_CODES[code], message, options);
167
+ this.code = code;
168
+ this.name = "HonuaAuthError";
169
+ this.cause = options.cause;
170
+ }
171
+ }
109
172
  /**
110
173
  * Thrown when an `ExplorationContext` operation is invalid — for example,
111
174
  * dispatching an intent against a context that has been disposed, restoring
112
175
  * an incompatible snapshot, or binding a view that requests a slice that is
113
176
  * not exposed by the current dataset.
114
177
  */
115
- export class HonuaExplorationContextError extends Error {
178
+ export class HonuaExplorationContextError extends HonuaSdkError {
116
179
  code;
117
- constructor(code, message) {
118
- super(message);
119
- this.name = "HonuaExplorationContextError";
180
+ constructor(code, message, options = {}) {
181
+ super("core.exploration-context", message, {
182
+ ...options,
183
+ context: mergeHonuaErrorContext(options.context, { reason: code }),
184
+ });
120
185
  this.code = code;
186
+ this.name = "HonuaExplorationContextError";
121
187
  }
122
188
  }
123
189
  /**
@@ -128,13 +194,17 @@ export class HonuaExplorationContextError extends Error {
128
194
  * `src/core/wfs-capabilities.ts`; raw access lives behind the `protocol("wfs")`
129
195
  * escape hatch.
130
196
  */
131
- export class HonuaWfsExceptionError extends Error {
197
+ export class HonuaWfsExceptionError extends HonuaSdkError {
132
198
  exceptionCode;
133
199
  locator;
134
- constructor(exceptionCode, message, locator) {
135
- super(locator
200
+ constructor(exceptionCode, message, locator, options = {}) {
201
+ const formattedMessage = locator
136
202
  ? `WFS ExceptionReport ${exceptionCode} (${locator}): ${message}`
137
- : `WFS ExceptionReport ${exceptionCode}: ${message}`);
203
+ : `WFS ExceptionReport ${exceptionCode}: ${message}`;
204
+ super("core.wfs-exception", formattedMessage, {
205
+ ...options,
206
+ context: mergeHonuaErrorContext(options.context, { exceptionCode, locator }),
207
+ });
138
208
  this.name = "HonuaWfsExceptionError";
139
209
  this.exceptionCode = exceptionCode;
140
210
  this.locator = locator;
@@ -142,15 +212,12 @@ export class HonuaWfsExceptionError extends Error {
142
212
  }
143
213
  /** Type guard that narrows any value to one of the Honua SDK error types. */
144
214
  export function isHonuaError(error) {
145
- return (error instanceof HonuaHttpError ||
146
- error instanceof HonuaTimeoutError ||
147
- error instanceof HonuaNetworkError ||
148
- error instanceof HonuaAbortError ||
149
- error instanceof HonuaGrpcError ||
150
- error instanceof HonuaCapabilityNotSupportedError ||
151
- error instanceof HonuaExplorationContextError ||
152
- error instanceof HonuaWfsExceptionError ||
153
- error instanceof HonuaJobFailedError ||
154
- error instanceof HonuaWmsCapabilitiesParseError ||
155
- error instanceof HonuaWmtsCapabilitiesParseError);
215
+ return isHonuaSdkError(error);
156
216
  }
217
+ const HTTP_RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);
218
+ const GRPC_RETRYABLE_CODES = new Set([4, 8, 10, 14]);
219
+ const AUTH_ERROR_CODES = {
220
+ interaction_required: "core.auth.interaction-required",
221
+ refresh_failed: "core.auth.refresh-failed",
222
+ invalid_grant: "core.auth.invalid-grant",
223
+ };
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Pure SQL compiler for the GeoParquet / DuckDB-WASM `Source`
3
+ * (`@honua/sdk-js/geoparquet`). Translates the protocol-neutral
4
+ * {@link Query} envelope into DuckDB SQL over `read_parquet(...)` with spatial
5
+ * predicate pushdown.
6
+ *
7
+ * This module has **no runtime dependencies** (not even `@duckdb/duckdb-wasm`)
8
+ * so it can be unit- and snapshot-tested in isolation and so the SQL text is a
9
+ * pure function of its inputs. The heavy DuckDB orchestration lives in
10
+ * `src/geoparquet/`.
11
+ *
12
+ * ## SQL-injection safety
13
+ *
14
+ * Every value this compiler interpolates is either (a) a numeric literal that
15
+ * is validated to be a finite JS number and rendered with {@link numberLiteral},
16
+ * (b) a string literal escaped by {@link stringLiteral} (single quotes doubled,
17
+ * embedded NULs rejected), or (c) a SQL identifier escaped by
18
+ * {@link quoteIdentifier} (double quotes doubled, embedded NULs / control chars
19
+ * rejected). The one exception is {@link Query.where}: like the GeoServices and
20
+ * OGC adapters, `where` is caller-authored filter SQL and is passed through
21
+ * verbatim (wrapped in parentheses). Callers are responsible for the trust
22
+ * boundary on `where`, exactly as they are for a GeoServices `where` clause.
23
+ *
24
+ * @module
25
+ */
26
+ import type { AggregationSpec, Query } from "../contract/types.js";
27
+ import type { SpatialFilter } from "./spatial-filter.js";
28
+ /**
29
+ * Quote a SQL identifier for DuckDB: wrap in double quotes and double any
30
+ * embedded double quote. Rejects NUL and other control characters, which
31
+ * cannot appear in a legitimate column name and are a classic smuggling
32
+ * vector. Overture column names (`id`, `names`, `geometry`, dotted struct
33
+ * paths accessed as whole columns) are all safe under this rule.
34
+ */
35
+ export declare function quoteIdentifier(name: string): string;
36
+ /**
37
+ * Render a string SQL literal (single quotes doubled). Rejects embedded NUL.
38
+ */
39
+ export declare function stringLiteral(value: string): string;
40
+ /**
41
+ * Render a numeric SQL literal, validating the input is a finite JS number.
42
+ * Non-finite values (NaN/Infinity) throw rather than emit `'NaN'` — a spatial
43
+ * predicate must never silently widen to an infinite envelope.
44
+ */
45
+ export declare function numberLiteral(value: number): string;
46
+ /**
47
+ * Render an integer SQL literal (offset / limit). Coerces via `Math.trunc` and
48
+ * validates non-negative finiteness.
49
+ */
50
+ export declare function integerLiteral(value: number): string;
51
+ /**
52
+ * Build the `read_parquet(...)` table expression from one or more file URLs /
53
+ * globs. A single source renders `read_parquet('url')`; multiple sources
54
+ * render `read_parquet(['a', 'b'])`. Every URL is escaped as a string literal.
55
+ * `union_by_name := true` and `hive_partitioning := true` are set so mixed
56
+ * schemas across a hive-partitioned Overture theme line up by column name.
57
+ */
58
+ export declare function parquetSourceExpr(urls: readonly string[]): string;
59
+ /**
60
+ * How the geometry column is physically stored, which decides the SQL used to
61
+ * (a) evaluate a spatial predicate and (b) project GeoJSON output.
62
+ *
63
+ * - `wkb`: GeoParquet 1.0/1.1 well-known-binary BLOB — wrap with
64
+ * `ST_GeomFromWKB(...)`.
65
+ * - `native`: Parquet-native `GEOMETRY` / `GEOGRAPHY` logical type (Parquet
66
+ * 2.11, Mar 2025) — DuckDB reads it as a `GEOMETRY`, used directly.
67
+ * - `geojson`: GeoParquet `GeoJSON` encoding (string) — wrap with
68
+ * `ST_GeomFromGeoJSON(...)`.
69
+ * - `geoarrow-point` / `geoarrow-linestring` / `geoarrow-polygon` /
70
+ * `geoarrow-multipoint` / `geoarrow-multilinestring` /
71
+ * `geoarrow-multipolygon`: GeoParquet **1.1** native single-geometry
72
+ * encodings (`geo.columns[].encoding`). DuckDB exposes these as nested
73
+ * `STRUCT`/`LIST` columns, not a `GEOMETRY` value — there is no DuckDB
74
+ * spatial expression for them. Geometry projection is decoded in JS by
75
+ * `@honua/sdk-js/geoparquet`'s native decoder (`native-geometry.ts`, built
76
+ * on `src/columnar/geoarrow.ts`); a spatial predicate against one of these
77
+ * columns requires a GeoParquet 1.1 bbox-covering column
78
+ * ({@link GeometryColumnPlan.bboxColumn}) and otherwise fails closed — see
79
+ * {@link geometryExpr}.
80
+ */
81
+ export type GeometryEncoding = "wkb" | "native" | "geojson" | "geoarrow-point" | "geoarrow-linestring" | "geoarrow-polygon" | "geoarrow-multipoint" | "geoarrow-multilinestring" | "geoarrow-multipolygon";
82
+ /** The `geoarrow-*` subset of {@link GeometryEncoding} (GeoParquet 1.1 native). */
83
+ export type GeoArrowNativeGeometryEncoding = Extract<GeometryEncoding, `geoarrow-${string}`>;
84
+ /** True for a GeoParquet 1.1 native single-geometry encoding (see {@link GeometryEncoding}). */
85
+ export declare function isGeoArrowNativeEncoding(encoding: GeometryEncoding): encoding is GeoArrowNativeGeometryEncoding;
86
+ export interface GeometryColumnPlan {
87
+ /** Geometry column name in the parquet file. */
88
+ readonly column: string;
89
+ /** Physical encoding of that column. */
90
+ readonly encoding: GeometryEncoding;
91
+ /**
92
+ * Optional GeoParquet 1.1 "bbox covering" struct column (typically `bbox`
93
+ * with `xmin`/`ymin`/`xmax`/`ymax` fields). When present, an envelope filter
94
+ * can prune row groups without decoding any geometry.
95
+ */
96
+ readonly bboxColumn?: string;
97
+ /**
98
+ * Coordinate dimensions physically stored by a `geoarrow-*` encoding.
99
+ * Required (and only meaningful) when {@link encoding} is one of the
100
+ * `geoarrow-*` values; GeoParquet 1.1 native encodings carry no `M`.
101
+ */
102
+ readonly nativeDimensions?: "xy" | "xyz";
103
+ }
104
+ /**
105
+ * SQL expression that yields a DuckDB `GEOMETRY` from the stored geometry
106
+ * column, adapting to the physical encoding.
107
+ *
108
+ * @throws for a `geoarrow-*` encoding — GeoParquet 1.1 native columns are
109
+ * nested `STRUCT`/`LIST` values with no DuckDB spatial-predicate
110
+ * expression. Callers must fail closed before constructing SQL rather than
111
+ * let a malformed `ST_Intersects(...)` reach DuckDB; use a bbox-covering
112
+ * column for spatial pushdown and the dedicated native decoder for
113
+ * geometry projection instead.
114
+ */
115
+ export declare function geometryExpr(plan: GeometryColumnPlan): string;
116
+ export interface BBox {
117
+ readonly xmin: number;
118
+ readonly ymin: number;
119
+ readonly xmax: number;
120
+ readonly ymax: number;
121
+ }
122
+ /**
123
+ * Reduce any Esri-shaped {@link SpatialFilter} geometry to its axis-aligned
124
+ * bounding box. Envelopes are exact; points, polylines (`paths`), polygons
125
+ * (`rings`), and multipoints (`points`) are reduced to their coordinate
126
+ * bounds. Returns `undefined` when the geometry carries no usable coordinates.
127
+ */
128
+ export declare function bboxFromSpatialFilter(filter: SpatialFilter): BBox | undefined;
129
+ /**
130
+ * True when the spatial filter is a plain envelope (exact bbox intersection).
131
+ * Anything else is reduced to its bbox and is therefore an approximation the
132
+ * caller should be told about via a `degraded` reason.
133
+ */
134
+ export declare function isEnvelopeFilter(filter: SpatialFilter): boolean;
135
+ /**
136
+ * Compile the spatial predicate for a bbox against a geometry plan. Prefers the
137
+ * GeoParquet 1.1 bbox-covering column (row-group-skippable) when present, then
138
+ * falls back to `ST_Intersects(<geom>, ST_MakeEnvelope(...))`.
139
+ */
140
+ export declare function spatialPredicate(bbox: BBox, plan: GeometryColumnPlan): string;
141
+ export interface CompileOptions {
142
+ /** Parquet file URL(s) / glob(s). */
143
+ readonly sources: readonly string[];
144
+ /** Geometry column plan (from metadata detection), if the file is spatial. */
145
+ readonly geometry?: GeometryColumnPlan;
146
+ /**
147
+ * All non-geometry column names available in the file, used to expand a
148
+ * `returnGeometry`-only projection and to validate that requested
149
+ * `outFields` are addressable. When omitted, `*` (minus geometry) is used.
150
+ */
151
+ readonly columns?: readonly string[];
152
+ /** Output alias for the projected GeoJSON geometry. Defaults to `geometry`. */
153
+ readonly geometryAlias?: string;
154
+ }
155
+ export interface CompiledSql {
156
+ readonly sql: string;
157
+ /** True when a non-envelope spatial filter was reduced to its bbox. */
158
+ readonly bboxApproximated: boolean;
159
+ }
160
+ /**
161
+ * Compile a feature {@link Query} into a DuckDB `SELECT`. The geometry column,
162
+ * when present and `returnGeometry !== false`, is projected as GeoJSON text via
163
+ * `ST_AsGeoJSON` under the alias `geometry` (overridable).
164
+ */
165
+ export declare function compileQuery(query: Query, options: CompileOptions): CompiledSql;
166
+ /**
167
+ * Compile an {@link AggregationSpec} into a GROUP BY `SELECT`. Group-by fields
168
+ * are echoed in the projection (so the returned rows carry the group key),
169
+ * followed by each metric expression aliased to its `alias` (or `fn_field`).
170
+ */
171
+ export declare function compileAggregate(query: Query & {
172
+ aggregation: AggregationSpec;
173
+ }, options: CompileOptions): CompiledSql;
174
+ /**
175
+ * SQL that reads the parquet footer schema without scanning rows.
176
+ */
177
+ export declare function describeSql(sources: readonly string[]): string;
178
+ /**
179
+ * Cheap row-count estimate from the parquet footer (`num_rows` per row group),
180
+ * summed across all files. Avoids a full `count(*)` table scan on large
181
+ * Overture extracts.
182
+ */
183
+ export declare function rowEstimateSql(sources: readonly string[]): string;
184
+ /**
185
+ * SQL that reads the GeoParquet `geo` key-value metadata (the JSON blob that
186
+ * carries `primary_column`, per-column `encoding`, and `crs`). Returns zero
187
+ * rows for Parquet-native geometry files, which carry no `geo` metadata.
188
+ */
189
+ export declare function geoMetadataSql(sources: readonly string[]): string;
190
+ //# sourceMappingURL=geoparquet-sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geoparquet-sql.d.ts","sourceRoot":"","sources":["../../../src/core/geoparquet-sql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAiB,eAAe,EAAE,KAAK,EAAY,MAAM,sBAAsB,CAAC;AAC5F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIzD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKnD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKpD;AAID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAOjE;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,gBAAgB,GACxB,KAAK,GACL,QAAQ,GACR,SAAS,GACT,gBAAgB,GAChB,qBAAqB,GACrB,kBAAkB,GAClB,qBAAqB,GACrB,0BAA0B,GAC1B,uBAAuB,CAAC;AAE5B,mFAAmF;AACnF,MAAM,MAAM,8BAA8B,GAAG,OAAO,CAAC,gBAAgB,EAAE,YAAY,MAAM,EAAE,CAAC,CAAC;AAW7F,gGAAgG;AAChG,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,QAAQ,IAAI,8BAA8B,CAE/G;AAED,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC;CAC1C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAmB7D;AAID,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,CAkC7E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAW7E;AAID,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IACvC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,+EAA+E;IAC/E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AA0ED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,GAAG,WAAW,CAgB/E;AAsBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,GAAG;IAAE,WAAW,EAAE,eAAe,CAAA;CAAE,EAC/C,OAAO,EAAE,cAAc,GACtB,WAAW,CA2Bb;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAIjE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAIjE"}