@mailwoman/resolver-wof-sqlite 4.16.2 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/address-point-interpolation.d.ts.map +1 -1
- package/out/address-point-interpolation.js +6 -6
- package/out/address-point-interpolation.js.map +1 -1
- package/out/address-point-schema.d.ts +5 -6
- package/out/address-point-schema.d.ts.map +1 -1
- package/out/address-point-schema.js +7 -2
- package/out/address-point-schema.js.map +1 -1
- package/out/address-point.d.ts +22 -8
- package/out/address-point.d.ts.map +1 -1
- package/out/address-point.js +29 -13
- package/out/address-point.js.map +1 -1
- package/out/ancestry-backfill.d.ts +53 -0
- package/out/ancestry-backfill.d.ts.map +1 -0
- package/out/ancestry-backfill.js +150 -0
- package/out/ancestry-backfill.js.map +1 -0
- package/out/ancestry.d.ts +6 -6
- package/out/ancestry.d.ts.map +1 -1
- package/out/ancestry.js +6 -6
- package/out/ancestry.js.map +1 -1
- package/out/build-candidate-cli.d.ts.map +1 -1
- package/out/build-candidate-cli.js.map +1 -1
- package/out/build-candidate.d.ts +4 -5
- package/out/build-candidate.d.ts.map +1 -1
- package/out/build-candidate.js +15 -14
- package/out/build-candidate.js.map +1 -1
- package/out/build-coincident-roles-cli.d.ts.map +1 -1
- package/out/build-coincident-roles-cli.js.map +1 -1
- package/out/build-fts-cli.d.ts +1 -1
- package/out/build-fts-cli.d.ts.map +1 -1
- package/out/build-fts-cli.js +6 -6
- package/out/build-fts-cli.js.map +1 -1
- package/out/build-slim-cli.d.ts +1 -1
- package/out/build-slim-cli.d.ts.map +1 -1
- package/out/build-slim-cli.js +3 -3
- package/out/build-slim-cli.js.map +1 -1
- package/out/build-slim.d.ts +7 -8
- package/out/build-slim.d.ts.map +1 -1
- package/out/build-slim.js +9 -9
- package/out/build-slim.js.map +1 -1
- package/out/candidate-fts.d.ts +5 -7
- package/out/candidate-fts.d.ts.map +1 -1
- package/out/candidate-fts.js +5 -7
- package/out/candidate-fts.js.map +1 -1
- package/out/candidate-lookup.d.ts +7 -7
- package/out/candidate-lookup.d.ts.map +1 -1
- package/out/candidate-lookup.js +31 -35
- package/out/candidate-lookup.js.map +1 -1
- package/out/candidate-schema.d.ts +13 -14
- package/out/candidate-schema.d.ts.map +1 -1
- package/out/candidate-schema.js +9 -9
- package/out/candidate-schema.js.map +1 -1
- package/out/coincident-roles.d.ts +9 -11
- package/out/coincident-roles.d.ts.map +1 -1
- package/out/coincident-roles.js +7 -7
- package/out/coincident-roles.js.map +1 -1
- package/out/convention.d.ts +30 -35
- package/out/convention.d.ts.map +1 -1
- package/out/convention.js +19 -21
- package/out/convention.js.map +1 -1
- package/out/fst-autocomplete.d.ts +5 -5
- package/out/fst-autocomplete.d.ts.map +1 -1
- package/out/fst-autocomplete.js +12 -13
- package/out/fst-autocomplete.js.map +1 -1
- package/out/fst-builder.d.ts +7 -7
- package/out/fst-builder.d.ts.map +1 -1
- package/out/fst-builder.js +9 -9
- package/out/fst-builder.js.map +1 -1
- package/out/fst-deserialize-web.d.ts +4 -4
- package/out/fst-deserialize-web.d.ts.map +1 -1
- package/out/fst-deserialize-web.js +4 -4
- package/out/fst-deserialize-web.js.map +1 -1
- package/out/fst-matcher.d.ts +12 -12
- package/out/fst-matcher.d.ts.map +1 -1
- package/out/fst-matcher.js +25 -25
- package/out/fst-matcher.js.map +1 -1
- package/out/fst-serialize.d.ts +5 -5
- package/out/fst-serialize.d.ts.map +1 -1
- package/out/fst-serialize.js +7 -6
- package/out/fst-serialize.js.map +1 -1
- package/out/fst-types.d.ts +13 -13
- package/out/fts.d.ts +74 -80
- package/out/fts.d.ts.map +1 -1
- package/out/fts.js +65 -71
- package/out/fts.js.map +1 -1
- package/out/geo.d.ts +14 -15
- package/out/geo.d.ts.map +1 -1
- package/out/geo.js +8 -8
- package/out/geo.js.map +1 -1
- package/out/geonames-aliases.d.ts +18 -9
- package/out/geonames-aliases.d.ts.map +1 -1
- package/out/geonames-aliases.js +70 -12
- package/out/geonames-aliases.js.map +1 -1
- package/out/index.d.ts +9 -9
- package/out/index.js +7 -7
- package/out/interpolation.d.ts +8 -10
- package/out/interpolation.d.ts.map +1 -1
- package/out/interpolation.js +6 -6
- package/out/interpolation.js.map +1 -1
- package/out/lookup.d.ts +74 -81
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +114 -128
- package/out/lookup.js.map +1 -1
- package/out/postal-city-alias-lookup.d.ts +9 -10
- package/out/postal-city-alias-lookup.d.ts.map +1 -1
- package/out/postal-city-alias-lookup.js +13 -14
- package/out/postal-city-alias-lookup.js.map +1 -1
- package/out/postal-city-alias-schema.d.ts +5 -6
- package/out/postal-city-alias-schema.d.ts.map +1 -1
- package/out/postal-city-alias-schema.js +3 -4
- package/out/postal-city-alias-schema.js.map +1 -1
- package/out/postal-city-candidate-schema.d.ts +7 -10
- package/out/postal-city-candidate-schema.d.ts.map +1 -1
- package/out/postal-city-candidate-schema.js +4 -6
- package/out/postal-city-candidate-schema.js.map +1 -1
- package/out/postcode-point-lookup.d.ts +3 -4
- package/out/postcode-point-lookup.d.ts.map +1 -1
- package/out/postcode-point-lookup.js +2 -2
- package/out/postcode-point-lookup.js.map +1 -1
- package/out/reverse.d.ts +26 -29
- package/out/reverse.d.ts.map +1 -1
- package/out/reverse.js +36 -38
- package/out/reverse.js.map +1 -1
- package/out/schema.d.ts +32 -33
- package/out/schema.d.ts.map +1 -1
- package/out/sharding.d.ts +26 -28
- package/out/sharding.d.ts.map +1 -1
- package/out/sharding.js +16 -16
- package/out/sharding.js.map +1 -1
- package/out/sqlite-convention-source.d.ts +3 -3
- package/out/sqlite-convention-source.d.ts.map +1 -1
- package/out/sqlite-convention-source.js +6 -6
- package/out/sqlite-convention-source.js.map +1 -1
- package/out/sqlite-utils.d.ts +4 -5
- package/out/sqlite-utils.d.ts.map +1 -1
- package/out/sqlite-utils.js +4 -5
- package/out/sqlite-utils.js.map +1 -1
- package/out/street-morphology-fst-builder.d.ts +15 -18
- package/out/street-morphology-fst-builder.d.ts.map +1 -1
- package/out/street-morphology-fst-builder.js +17 -17
- package/out/street-morphology-fst-builder.js.map +1 -1
- package/out/street-normalize.d.ts +43 -28
- package/out/street-normalize.d.ts.map +1 -1
- package/out/street-normalize.js +96 -34
- package/out/street-normalize.js.map +1 -1
- package/out/street-segment-schema.d.ts +5 -5
- package/out/street-segment-schema.js +2 -2
- package/out/types.d.ts +42 -47
- package/out/types.d.ts.map +1 -1
- package/out/types.js +1 -1
- package/out/unified-schema.d.ts +6 -6
- package/out/unified-schema.d.ts.map +1 -1
- package/out/unified-schema.js +10 -10
- package/out/unified-schema.js.map +1 -1
- package/package.json +26 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point-interpolation.d.ts","sourceRoot":"","sources":["../address-point-interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAG9D,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AA2BjG,qBAAa,wBAAyB,YAAW,mBAAmB;;gBAMvD,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;QAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;KAAE;
|
|
1
|
+
{"version":3,"file":"address-point-interpolation.d.ts","sourceRoot":"","sources":["../address-point-interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAG9D,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AA2BjG,qBAAa,wBAAyB,YAAW,mBAAmB;;gBAMvD,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;QAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;KAAE;IA2B7F,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,GAAG,IAAI;IAgBvD,KAAK,IAAI,IAAI;CAGb"}
|
|
@@ -37,23 +37,23 @@ import { haversineKm } from "./geo.js";
|
|
|
37
37
|
import { hasTable } from "./sqlite-utils.js";
|
|
38
38
|
import { canonicalizeRouteKey, normalizeStreetForKey } from "./street-normalize.js";
|
|
39
39
|
/**
|
|
40
|
-
* Extrapolation cap for a single-sided bracket: at most one pair-span beyond the nearest known
|
|
41
|
-
*
|
|
40
|
+
* Extrapolation cap for a single-sided bracket: at most one pair-span beyond the nearest known point (`t = 2`). Past
|
|
41
|
+
* it, the two-point line carries no evidence about the query number.
|
|
42
42
|
*/
|
|
43
43
|
const MAX_EXTRAPOLATION_T = 2;
|
|
44
44
|
export class AddressPointInterpolator {
|
|
45
45
|
#db;
|
|
46
|
-
#
|
|
46
|
+
#ownsDB;
|
|
47
47
|
#fallback;
|
|
48
48
|
#byPostcode;
|
|
49
49
|
constructor(opts) {
|
|
50
50
|
if (opts.database) {
|
|
51
51
|
this.#db = opts.database;
|
|
52
|
-
this.#
|
|
52
|
+
this.#ownsDB = false;
|
|
53
53
|
}
|
|
54
54
|
else if (opts.dbPath) {
|
|
55
55
|
this.#db = new DatabaseSync(opts.dbPath, { readOnly: true });
|
|
56
|
-
this.#
|
|
56
|
+
this.#ownsDB = true;
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
59
|
throw new Error("AddressPointInterpolator: one of dbPath or database is required");
|
|
@@ -85,7 +85,7 @@ export class AddressPointInterpolator {
|
|
|
85
85
|
return hit ?? this.#fallback?.find(query) ?? null;
|
|
86
86
|
}
|
|
87
87
|
close() {
|
|
88
|
-
if (this.#
|
|
88
|
+
if (this.#ownsDB)
|
|
89
89
|
this.#db.close();
|
|
90
90
|
}
|
|
91
91
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point-interpolation.js","sourceRoot":"","sources":["../address-point-interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI1C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAEnF;;;GAGG;AACH,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAmB7B,MAAM,OAAO,wBAAwB;IAC3B,GAAG,CAAc;IACjB,OAAO,CAAS;IAChB,SAAS,CAAgC;IACzC,WAAW,CAAiD;IAErE,YAAY,IAAiF;QAC5F,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAA;YACxB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACrB,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;YAC5D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACpB,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;QACnF,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"address-point-interpolation.js","sourceRoot":"","sources":["../address-point-interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI1C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAEnF;;;GAGG;AACH,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAmB7B,MAAM,OAAO,wBAAwB;IAC3B,GAAG,CAAc;IACjB,OAAO,CAAS;IAChB,SAAS,CAAgC;IACzC,WAAW,CAAiD;IAErE,YAAY,IAAiF;QAC5F,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAA;YACxB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACrB,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;YAC5D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACpB,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;QACnF,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAA;QAE9B,iGAAiG;QACjG,sFAAsF;QACtF,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,CAAC;YACzC,uFAAuF;YACvF,yFAAyF;YACzF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAClC;;;;sCAIkC,CAClC,CAAA;QACF,CAAC;IACF,CAAC;IAED,IAAI,CAAC,KAAyB;QAC7B,MAAM,SAAS,GAAG,oBAAoB,CAAC,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;QAC3E,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;QAErC,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAA;QACvD,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;QAE3B,+FAA+F;QAC/F,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAA;QAEpF,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAA0B,CAAA;QAC/F,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAEvE,OAAO,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAA;IAClD,CAAC;IAED,KAAK;QACJ,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAA;IACnC,CAAC;CACD;AAED,wFAAwF;AACxF,SAAS,eAAe,CAAC,IAAyB;IACjD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsB,CAAA;IAEzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAE5B,IAAI,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;;YACrB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IAC3B,CAAC;IAED,OAAO,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;SACvB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QACrB,CAAC;QACD,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM;QAC5D,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM;QAC5D,MAAM,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,MAAM;QACxB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,OAAO;KAC1B,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5B,CAAC;AAED,SAAS,wBAAwB,CAAC,IAAyB,EAAE,CAAS;IACrE,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;IAErC,oFAAoF;IACpF,IAAI,KAA+B,CAAA;IACnC,IAAI,KAA+B,CAAA;IAEnC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC;YAAE,KAAK,GAAG,MAAM,CAAA;aAC3B,CAAC;YACL,KAAK,GAAG,MAAM,CAAA;YACd,MAAK;QACN,CAAC;IACF,CAAC;IAED,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAC7C,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;QAE5E,OAAO;YACN,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAC5C,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAC5C,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,eAAe;YACvB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;YACnC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,OAAO,EAAE,KAAK,CAAC,OAAO;SACtB,CAAA;IACF,CAAC;IAED,uFAAuF;IACvF,oFAAoF;IACpF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAE5D,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAChC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,CAAA;IACvE,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;IAExC,IAAI,CAAC,GAAG,mBAAmB;QAAE,OAAO,IAAI,CAAA;IAExC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC9C,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACtE,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IAEnE,OAAO;QACN,GAAG;QACH,GAAG;QACH,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,eAAe;QACvB,OAAO,EAAE,QAAQ;QACjB,wFAAwF;QACxF,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC;QAC5C,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;KACrB,CAAA;AACF,CAAC"}
|
|
@@ -17,10 +17,9 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { Kysely } from "kysely";
|
|
19
19
|
/**
|
|
20
|
-
* One rooftop address point. `(street_norm, number)` within a `postcode` (preferred) or
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* are nullable (not every source carries all three).
|
|
20
|
+
* One rooftop address point. `(street_norm, number)` within a `postcode` (preferred) or `locality_norm` scope is the
|
|
21
|
+
* lookup; `street_key` is the #483 route-fold key for interpolation. Coordinates are non-null (the builder drops
|
|
22
|
+
* non-finite coords). `unit`/`postcode`/`locality_norm` are nullable (not every source carries all three).
|
|
24
23
|
*/
|
|
25
24
|
export interface AddressPointTable {
|
|
26
25
|
/** Shared {@link normalizeStreetForKey} of the street — the build/query-consistent probe key. */
|
|
@@ -47,8 +46,8 @@ export interface AddressPointDatabase {
|
|
|
47
46
|
address_point: AddressPointTable;
|
|
48
47
|
}
|
|
49
48
|
/**
|
|
50
|
-
* The `address_point` columns in INSERT order. The builder's positional prepared statement derives
|
|
51
|
-
*
|
|
49
|
+
* The `address_point` columns in INSERT order. The builder's positional prepared statement derives its placeholder list
|
|
50
|
+
* from this, so the positional order can't drift from the DDL / the reader.
|
|
52
51
|
*/
|
|
53
52
|
export declare const ADDRESS_POINT_COLUMNS: readonly ["street_norm", "street_key", "number", "unit", "postcode", "locality_norm", "street_raw", "lat", "lon", "source", "release"];
|
|
54
53
|
/** Create the `address_point` table — called before the streaming bulk load. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point-schema.d.ts","sourceRoot":"","sources":["../address-point-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC
|
|
1
|
+
{"version":3,"file":"address-point-schema.d.ts","sourceRoot":"","sources":["../address-point-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAA;IACnB,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAA;IAClB,wFAAwF;IACxF,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,mFAAmF;IACnF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAA;CACf;AAED,6FAA6F;AAC7F,MAAM,WAAW,oBAAoB;IACpC,aAAa,EAAE,iBAAiB,CAAA;CAChC;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,wIAYxB,CAAA;AAEV,gFAAgF;AAChF,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,MAAM,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB7F;AAED,uGAAuG;AACvG,wBAAsB,yBAAyB,CAAC,EAAE,EAAE,MAAM,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB/F"}
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
* schema guards the contract; positional inserts keep the speed.)
|
|
17
17
|
*/
|
|
18
18
|
/**
|
|
19
|
-
* The `address_point` columns in INSERT order. The builder's positional prepared statement derives
|
|
20
|
-
*
|
|
19
|
+
* The `address_point` columns in INSERT order. The builder's positional prepared statement derives its placeholder list
|
|
20
|
+
* from this, so the positional order can't drift from the DDL / the reader.
|
|
21
21
|
*/
|
|
22
22
|
export const ADDRESS_POINT_COLUMNS = [
|
|
23
23
|
"street_norm",
|
|
@@ -63,5 +63,10 @@ export async function createAddressPointIndexes(db) {
|
|
|
63
63
|
.columns(["locality_norm", "street_norm", "number"])
|
|
64
64
|
.execute();
|
|
65
65
|
await db.schema.createIndex("idx_ap_streetkey").on("address_point").columns(["postcode", "street_key"]).execute();
|
|
66
|
+
// Street-first index for the BBOX scope (#247): OSM points often carry no postcode/locality, so the
|
|
67
|
+
// reader scopes a `(street_norm, number)` probe by the resolved locality's bbox (lat/lon BETWEEN). The
|
|
68
|
+
// postcode/locality indexes lead with their scope column and can't serve this; US situs never probes by
|
|
69
|
+
// bbox so it simply carries one extra (cheap) index on a future rebuild.
|
|
70
|
+
await db.schema.createIndex("idx_ap_street").on("address_point").columns(["street_norm", "number"]).execute();
|
|
66
71
|
}
|
|
67
72
|
//# sourceMappingURL=address-point-schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point-schema.js","sourceRoot":"","sources":["../address-point-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"address-point-schema.js","sourceRoot":"","sources":["../address-point-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAmCH;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACpC,aAAa;IACb,YAAY;IACZ,QAAQ;IACR,MAAM;IACN,UAAU;IACV,eAAe;IACf,YAAY;IACZ,KAAK;IACL,KAAK;IACL,QAAQ;IACR,SAAS;CACA,CAAA;AAEV,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,EAAgC;IAC7E,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,eAAe,CAAC;SAC5B,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACrD,wFAAwF;SACvF,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACnD,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;SACzB,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC;SAC7B,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC;SAClC,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACnD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC5C,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC5C,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/C,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAChD,OAAO,EAAE,CAAA;AACZ,CAAC;AAED,uGAAuG;AACvG,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,EAAgC;IAC/E,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,iBAAiB,CAAC;SAC9B,EAAE,CAAC,eAAe,CAAC;SACnB,OAAO,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;SAC9C,OAAO,EAAE,CAAA;IACX,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,iBAAiB,CAAC;SAC9B,EAAE,CAAC,eAAe,CAAC;SACnB,OAAO,CAAC,CAAC,eAAe,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;SACnD,OAAO,EAAE,CAAA;IACX,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;IACjH,oGAAoG;IACpG,uGAAuG;IACvG,wGAAwG;IACxG,yEAAyE;IACzE,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;AAC9G,CAAC"}
|
package/out/address-point.d.ts
CHANGED
|
@@ -4,25 +4,39 @@
|
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
6
|
* SQLite implementation of core's `AddressPointLookup` (#476): exact `(street, number)` within a
|
|
7
|
-
* postcode (preferred) or
|
|
8
|
-
*
|
|
9
|
-
* (`street-normalize.ts`)
|
|
7
|
+
* postcode (preferred), locality, or — for shards whose points carry no scope tag (OSM, #247) —
|
|
8
|
+
* the resolved locality's BBOX. Query-side normalization is THE shared normalizer
|
|
9
|
+
* (`street-normalize.ts`), selected per the shard's `streetLocale` so build-side and probe-side
|
|
10
|
+
* stay identical by construction (US delegates to the USPS pipeline; FR/DE/NL use the locale rules).
|
|
10
11
|
*
|
|
11
12
|
* Matching is exact-after-normalization only — no fuzzy street matching in this tier (measure how
|
|
12
|
-
* far exact gets first; fuzz is a later, separate decision).
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* building for tier purposes.
|
|
13
|
+
* far exact gets first; fuzz is a later, separate decision). Scope order is most-selective first:
|
|
14
|
+
* postcode, then locality, then the bbox fall-through (only when a bbox is supplied AND the prior
|
|
15
|
+
* scopes missed). Multiple hits return the first by rowid — unit siblings share the building coord.
|
|
16
16
|
*/
|
|
17
17
|
import type { AddressPointHit, AddressPointLookup } from "@mailwoman/resolver";
|
|
18
|
+
import { type StreetLocale } from "./street-normalize.js";
|
|
18
19
|
export declare class AddressPointSqliteLookup implements AddressPointLookup {
|
|
19
20
|
#private;
|
|
20
|
-
|
|
21
|
+
/**
|
|
22
|
+
* @param dbPath Shard path.
|
|
23
|
+
* @param opts.streetLocale The street-normalization locale this shard was BUILT with — must match, or every key
|
|
24
|
+
* misses. Defaults to `"us"` (the situs tier), so existing callers are unchanged.
|
|
25
|
+
*/
|
|
26
|
+
constructor(dbPath: string, opts?: {
|
|
27
|
+
streetLocale?: StreetLocale;
|
|
28
|
+
});
|
|
21
29
|
find(query: {
|
|
22
30
|
street: string;
|
|
23
31
|
number: string;
|
|
24
32
|
postcode?: string;
|
|
25
33
|
locality?: string;
|
|
34
|
+
bbox?: {
|
|
35
|
+
minLat: number;
|
|
36
|
+
maxLat: number;
|
|
37
|
+
minLon: number;
|
|
38
|
+
maxLon: number;
|
|
39
|
+
};
|
|
26
40
|
}): AddressPointHit | null;
|
|
27
41
|
close(): void;
|
|
28
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point.d.ts","sourceRoot":"","sources":["../address-point.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"address-point.d.ts","sourceRoot":"","sources":["../address-point.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAI9E,OAAO,EAAwD,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAc/G,qBAAa,wBAAyB,YAAW,kBAAkB;;IAOlE;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,YAAY,CAAC,EAAE,YAAY,CAAA;KAAO;IAsBtE,IAAI,CAAC,KAAK,EAAE;QACX,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,IAAI,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KACzE,GAAG,eAAe,GAAG,IAAI;IA+B1B,KAAK,IAAI,IAAI;CAGb"}
|
package/out/address-point.js
CHANGED
|
@@ -4,30 +4,38 @@
|
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
6
|
* SQLite implementation of core's `AddressPointLookup` (#476): exact `(street, number)` within a
|
|
7
|
-
* postcode (preferred) or
|
|
8
|
-
*
|
|
9
|
-
* (`street-normalize.ts`)
|
|
7
|
+
* postcode (preferred), locality, or — for shards whose points carry no scope tag (OSM, #247) —
|
|
8
|
+
* the resolved locality's BBOX. Query-side normalization is THE shared normalizer
|
|
9
|
+
* (`street-normalize.ts`), selected per the shard's `streetLocale` so build-side and probe-side
|
|
10
|
+
* stay identical by construction (US delegates to the USPS pipeline; FR/DE/NL use the locale rules).
|
|
10
11
|
*
|
|
11
12
|
* Matching is exact-after-normalization only — no fuzzy street matching in this tier (measure how
|
|
12
|
-
* far exact gets first; fuzz is a later, separate decision).
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* building for tier purposes.
|
|
13
|
+
* far exact gets first; fuzz is a later, separate decision). Scope order is most-selective first:
|
|
14
|
+
* postcode, then locality, then the bbox fall-through (only when a bbox is supplied AND the prior
|
|
15
|
+
* scopes missed). Multiple hits return the first by rowid — unit siblings share the building coord.
|
|
16
16
|
*/
|
|
17
17
|
import { DatabaseSync } from "node:sqlite";
|
|
18
18
|
import { hasTable } from "./sqlite-utils.js";
|
|
19
|
-
import { normalizeLocalityForKey,
|
|
19
|
+
import { normalizeLocalityForKey, normalizeStreetForKeyLocale } from "./street-normalize.js";
|
|
20
20
|
/**
|
|
21
|
-
* The 4 columns the reader SELECTs, in the schema's order — referenced by the prepared SELECTs so
|
|
22
|
-
*
|
|
21
|
+
* The 4 columns the reader SELECTs, in the schema's order — referenced by the prepared SELECTs so the projected
|
|
22
|
+
* `AddressPointRow` stays in lockstep with the shared schema.
|
|
23
23
|
*/
|
|
24
24
|
const SELECT_COLS = "lat, lon, source, release";
|
|
25
25
|
export class AddressPointSqliteLookup {
|
|
26
26
|
#db;
|
|
27
|
+
#locale;
|
|
27
28
|
#byPostcode;
|
|
28
29
|
#byLocality;
|
|
29
|
-
|
|
30
|
+
#byBbox;
|
|
31
|
+
/**
|
|
32
|
+
* @param dbPath Shard path.
|
|
33
|
+
* @param opts.streetLocale The street-normalization locale this shard was BUILT with — must match, or every key
|
|
34
|
+
* misses. Defaults to `"us"` (the situs tier), so existing callers are unchanged.
|
|
35
|
+
*/
|
|
36
|
+
constructor(dbPath, opts = {}) {
|
|
30
37
|
this.#db = new DatabaseSync(dbPath, { readOnly: true });
|
|
38
|
+
this.#locale = opts.streetLocale ?? "us";
|
|
31
39
|
// Degrade gracefully on an empty/tableless shard (interrupted build, stray 0-byte file): with no
|
|
32
40
|
// `address_point` table this lookup is a no-op miss, not a crash that loses the whole state (#568).
|
|
33
41
|
if (hasTable(this.#db, "address_point")) {
|
|
@@ -35,12 +43,14 @@ export class AddressPointSqliteLookup {
|
|
|
35
43
|
WHERE postcode = ? AND street_norm = ? AND number = ? LIMIT 1`);
|
|
36
44
|
this.#byLocality = this.#db.prepare(`SELECT ${SELECT_COLS} FROM address_point
|
|
37
45
|
WHERE locality_norm = ? AND street_norm = ? AND number = ? LIMIT 1`);
|
|
46
|
+
this.#byBbox = this.#db.prepare(`SELECT ${SELECT_COLS} FROM address_point
|
|
47
|
+
WHERE street_norm = ? AND number = ? AND lat BETWEEN ? AND ? AND lon BETWEEN ? AND ? LIMIT 1`);
|
|
38
48
|
}
|
|
39
49
|
}
|
|
40
50
|
find(query) {
|
|
41
|
-
if (!this.#byPostcode || !this.#byLocality)
|
|
51
|
+
if (!this.#byPostcode || !this.#byLocality || !this.#byBbox)
|
|
42
52
|
return null;
|
|
43
|
-
const streetNorm =
|
|
53
|
+
const streetNorm = normalizeStreetForKeyLocale(query.street, this.#locale);
|
|
44
54
|
const number = query.number.trim().toLowerCase();
|
|
45
55
|
if (!streetNorm || !number)
|
|
46
56
|
return null;
|
|
@@ -51,6 +61,12 @@ export class AddressPointSqliteLookup {
|
|
|
51
61
|
if (!row && query.locality) {
|
|
52
62
|
row = this.#byLocality.get(normalizeLocalityForKey(query.locality), streetNorm, number);
|
|
53
63
|
}
|
|
64
|
+
// Bbox fall-through (#247): the point carries no postcode/locality of its own, but its coordinate falls
|
|
65
|
+
// inside the resolved locality's box. Only reached when the scoped probes missed AND a bbox was supplied.
|
|
66
|
+
if (!row && query.bbox) {
|
|
67
|
+
const b = query.bbox;
|
|
68
|
+
row = this.#byBbox.get(streetNorm, number, b.minLat, b.maxLat, b.minLon, b.maxLon);
|
|
69
|
+
}
|
|
54
70
|
if (!row)
|
|
55
71
|
return null;
|
|
56
72
|
return { lat: row.lat, lon: row.lon, source: row.source, release: row.release };
|
package/out/address-point.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point.js","sourceRoot":"","sources":["../address-point.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK1C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,uBAAuB,EAAE,
|
|
1
|
+
{"version":3,"file":"address-point.js","sourceRoot":"","sources":["../address-point.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* Repair the only-self ancestry that {@link populateAncestors} (the parent_id closure in
|
|
7
|
+
* unified-schema.ts) leaves for places whose `wof:parent_id` is the WOF `-4` "ambiguous /
|
|
8
|
+
* multi-parent" sentinel.
|
|
9
|
+
*
|
|
10
|
+
* Root cause (#440 / #832): a place that straddles multiple parents — New York City spans five
|
|
11
|
+
* counties (its boroughs), London 30+ — carries `wof:parent_id = -4`, so the parent_id closure
|
|
12
|
+
* dead-ends and the place gets NO region/county/country ancestry. The resolver's region-descendant
|
|
13
|
+
* filter then can't reach it: given "New York, NY", NYC (with no NY-state ancestor) is excluded and
|
|
14
|
+
* a correctly-parented namesake ("New York Mills", pop 3,190) wins over NYC's 8.8M. The same defect
|
|
15
|
+
* orphans London, Singapore, and ~2,850 other localities — the most demo-visible queries.
|
|
16
|
+
*
|
|
17
|
+
* The authoritative hierarchy IS in the source geojson: `wof:hierarchy` is an array of branches,
|
|
18
|
+
* each a `<placetype>_id` → id map (region_id, county_id, country_id, …), fully populated even when
|
|
19
|
+
* parent_id is -4. This reads it for every only-self place and inserts the missing ancestor rows
|
|
20
|
+
* (one per distinct ancestor across branches).
|
|
21
|
+
*
|
|
22
|
+
* MUST run AFTER populateAncestors and BEFORE the build freezes (VACUUM INTO), so the rows land in
|
|
23
|
+
* the shipped artifact — `scripts/build-unified-wof.ts` Phase 3 calls it inline. The standalone
|
|
24
|
+
* `scripts/backfill-ancestors-from-hierarchy.ts` is a thin CLI over the same function for ad-hoc
|
|
25
|
+
* repair of an already-built DB. Idempotent: only touches places with <= 1 ancestor row (self), and
|
|
26
|
+
* inserts each (id, ancestor_id) at most once.
|
|
27
|
+
*/
|
|
28
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
29
|
+
export interface AncestryBackfillResult {
|
|
30
|
+
/** Places that gained at least one ancestor row. */
|
|
31
|
+
placesFixed: number;
|
|
32
|
+
/** Total ancestor rows inserted. */
|
|
33
|
+
rowsAdded: number;
|
|
34
|
+
/**
|
|
35
|
+
* Only-self candidates whose source geojson could not be found (non-WOF backfilled places, or repos not present
|
|
36
|
+
* locally) — skipped, not an error.
|
|
37
|
+
*/
|
|
38
|
+
noGeojson: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Discover the `data` directories under a WOF repos root that hold sharded geojson, e.g.
|
|
42
|
+
* `<root>/whosonfirst-data/whosonfirst-data-admin-us/data`. Resolves an id to its geojson via these roots. Accepts both
|
|
43
|
+
* the nested lab layout (a `whosonfirst-data` group dir holding the admin repos) and a flat layout (admin repos
|
|
44
|
+
* directly under the root); searches at most two directory levels deep.
|
|
45
|
+
*/
|
|
46
|
+
export declare function discoverAdminDataRoots(reposRoot: string): string[];
|
|
47
|
+
/**
|
|
48
|
+
* Insert missing ancestor rows for only-self places by reading `wof:hierarchy` from their source geojson under
|
|
49
|
+
* `geojsonRoots` (see {@link discoverAdminDataRoots}). Runs inside a single transaction; caller owns connection
|
|
50
|
+
* lifecycle (open, WAL checkpoint, close).
|
|
51
|
+
*/
|
|
52
|
+
export declare function backfillAncestorsFromHierarchy(db: DatabaseSync, geojsonRoots: readonly string[]): AncestryBackfillResult;
|
|
53
|
+
//# sourceMappingURL=ancestry-backfill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ancestry-backfill.d.ts","sourceRoot":"","sources":["../ancestry-backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK/C,MAAM,WAAW,sBAAsB;IACtC,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CA8BlE;AAmCD;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC7C,EAAE,EAAE,YAAY,EAChB,YAAY,EAAE,SAAS,MAAM,EAAE,GAC7B,sBAAsB,CA8DxB"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* Repair the only-self ancestry that {@link populateAncestors} (the parent_id closure in
|
|
7
|
+
* unified-schema.ts) leaves for places whose `wof:parent_id` is the WOF `-4` "ambiguous /
|
|
8
|
+
* multi-parent" sentinel.
|
|
9
|
+
*
|
|
10
|
+
* Root cause (#440 / #832): a place that straddles multiple parents — New York City spans five
|
|
11
|
+
* counties (its boroughs), London 30+ — carries `wof:parent_id = -4`, so the parent_id closure
|
|
12
|
+
* dead-ends and the place gets NO region/county/country ancestry. The resolver's region-descendant
|
|
13
|
+
* filter then can't reach it: given "New York, NY", NYC (with no NY-state ancestor) is excluded and
|
|
14
|
+
* a correctly-parented namesake ("New York Mills", pop 3,190) wins over NYC's 8.8M. The same defect
|
|
15
|
+
* orphans London, Singapore, and ~2,850 other localities — the most demo-visible queries.
|
|
16
|
+
*
|
|
17
|
+
* The authoritative hierarchy IS in the source geojson: `wof:hierarchy` is an array of branches,
|
|
18
|
+
* each a `<placetype>_id` → id map (region_id, county_id, country_id, …), fully populated even when
|
|
19
|
+
* parent_id is -4. This reads it for every only-self place and inserts the missing ancestor rows
|
|
20
|
+
* (one per distinct ancestor across branches).
|
|
21
|
+
*
|
|
22
|
+
* MUST run AFTER populateAncestors and BEFORE the build freezes (VACUUM INTO), so the rows land in
|
|
23
|
+
* the shipped artifact — `scripts/build-unified-wof.ts` Phase 3 calls it inline. The standalone
|
|
24
|
+
* `scripts/backfill-ancestors-from-hierarchy.ts` is a thin CLI over the same function for ad-hoc
|
|
25
|
+
* repair of an already-built DB. Idempotent: only touches places with <= 1 ancestor row (self), and
|
|
26
|
+
* inserts each (id, ancestor_id) at most once.
|
|
27
|
+
*/
|
|
28
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
29
|
+
import { join } from "node:path";
|
|
30
|
+
/** Genuinely top-level placetypes — they never have (or need) an ancestor, so skip them. */
|
|
31
|
+
const TOP_PLACETYPES = new Set(["country", "continent", "empire", "ocean", "marinearea", "planet"]);
|
|
32
|
+
/**
|
|
33
|
+
* Discover the `data` directories under a WOF repos root that hold sharded geojson, e.g.
|
|
34
|
+
* `<root>/whosonfirst-data/whosonfirst-data-admin-us/data`. Resolves an id to its geojson via these roots. Accepts both
|
|
35
|
+
* the nested lab layout (a `whosonfirst-data` group dir holding the admin repos) and a flat layout (admin repos
|
|
36
|
+
* directly under the root); searches at most two directory levels deep.
|
|
37
|
+
*/
|
|
38
|
+
export function discoverAdminDataRoots(reposRoot) {
|
|
39
|
+
const roots = [];
|
|
40
|
+
const visit = (dir, depth) => {
|
|
41
|
+
if (depth > 2)
|
|
42
|
+
return;
|
|
43
|
+
let names;
|
|
44
|
+
try {
|
|
45
|
+
names = readdirSync(dir, { withFileTypes: true })
|
|
46
|
+
.filter((e) => e.isDirectory())
|
|
47
|
+
.map((e) => e.name);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
for (const name of names) {
|
|
53
|
+
const child = join(dir, name);
|
|
54
|
+
if (name === "data") {
|
|
55
|
+
roots.push(child);
|
|
56
|
+
}
|
|
57
|
+
else if (name.startsWith("whosonfirst-data")) {
|
|
58
|
+
visit(child, depth + 1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
visit(reposRoot, 0);
|
|
63
|
+
return roots;
|
|
64
|
+
}
|
|
65
|
+
/** WOF geojson lives sharded: an id resolves to `<3-char chunks>/<id>.geojson` under each data root. */
|
|
66
|
+
function geojsonForID(id, roots) {
|
|
67
|
+
const s = String(id);
|
|
68
|
+
const chunks = [];
|
|
69
|
+
for (let i = 0; i < s.length; i += 3)
|
|
70
|
+
chunks.push(s.slice(i, i + 3));
|
|
71
|
+
const rel = join(chunks.join("/"), `${s}.geojson`);
|
|
72
|
+
for (const root of roots) {
|
|
73
|
+
const fp = join(root, rel);
|
|
74
|
+
if (existsSync(fp)) {
|
|
75
|
+
try {
|
|
76
|
+
return JSON.parse(readFileSync(fp, "utf8"));
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
// `<placetype>_id` key → ancestor placetype. WOF hierarchy keys are e.g. region_id, county_id. Self
|
|
86
|
+
// is filtered downstream by the `aid === id` check, so we do NOT special-case locality here: for a
|
|
87
|
+
// locality candidate `locality_id` IS self (dropped by aid===id), but for a neighbourhood candidate
|
|
88
|
+
// `locality_id` is its PARENT locality — a real ancestor we must keep.
|
|
89
|
+
function placetypeFromKey(key) {
|
|
90
|
+
if (!key.endsWith("_id"))
|
|
91
|
+
return null;
|
|
92
|
+
return key.slice(0, -3);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Insert missing ancestor rows for only-self places by reading `wof:hierarchy` from their source geojson under
|
|
96
|
+
* `geojsonRoots` (see {@link discoverAdminDataRoots}). Runs inside a single transaction; caller owns connection
|
|
97
|
+
* lifecycle (open, WAL checkpoint, close).
|
|
98
|
+
*/
|
|
99
|
+
export function backfillAncestorsFromHierarchy(db, geojsonRoots) {
|
|
100
|
+
const candidates = db
|
|
101
|
+
.prepare(`SELECT s.id AS id, s.placetype AS placetype FROM spr s
|
|
102
|
+
WHERE (SELECT count(*) FROM ancestors a WHERE a.id = s.id) <= 1`)
|
|
103
|
+
.all();
|
|
104
|
+
const insert = db.prepare("INSERT INTO ancestors (id, ancestor_id, ancestor_placetype, lastmodified) VALUES (?, ?, ?, 0)");
|
|
105
|
+
const hasRow = db.prepare("SELECT 1 FROM ancestors WHERE id = ? AND ancestor_id = ? LIMIT 1");
|
|
106
|
+
let placesFixed = 0;
|
|
107
|
+
let rowsAdded = 0;
|
|
108
|
+
let noGeojson = 0;
|
|
109
|
+
db.exec("BEGIN");
|
|
110
|
+
for (const { id, placetype } of candidates) {
|
|
111
|
+
if (TOP_PLACETYPES.has(placetype))
|
|
112
|
+
continue;
|
|
113
|
+
const gj = geojsonForID(id, geojsonRoots);
|
|
114
|
+
const props = (gj?.["properties"] ?? null);
|
|
115
|
+
const hierarchy = (props?.["wof:hierarchy"] ?? null);
|
|
116
|
+
if (!hierarchy || hierarchy.length === 0) {
|
|
117
|
+
if (!gj)
|
|
118
|
+
noGeojson++;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// Collect distinct (ancestor_id, placetype) across all hierarchy branches, excluding self.
|
|
122
|
+
const seen = new Map();
|
|
123
|
+
for (const branch of hierarchy) {
|
|
124
|
+
for (const [key, val] of Object.entries(branch)) {
|
|
125
|
+
const pt = placetypeFromKey(key);
|
|
126
|
+
if (!pt)
|
|
127
|
+
continue;
|
|
128
|
+
const aid = Number(val);
|
|
129
|
+
if (!Number.isFinite(aid) || aid <= 0 || aid === id)
|
|
130
|
+
continue;
|
|
131
|
+
if (!seen.has(aid))
|
|
132
|
+
seen.set(aid, pt);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
let added = 0;
|
|
136
|
+
for (const [aid, pt] of seen) {
|
|
137
|
+
if (hasRow.get(id, aid))
|
|
138
|
+
continue;
|
|
139
|
+
insert.run(id, aid, pt);
|
|
140
|
+
added++;
|
|
141
|
+
}
|
|
142
|
+
if (added > 0) {
|
|
143
|
+
placesFixed++;
|
|
144
|
+
rowsAdded += added;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
db.exec("COMMIT");
|
|
148
|
+
return { placesFixed, rowsAdded, noGeojson };
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=ancestry-backfill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ancestry-backfill.js","sourceRoot":"","sources":["../ancestry-backfill.ts"],"names":[],"mappings":"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"}
|
package/out/ancestry.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* joined with `spr` for canonical names + centroids, ordered NEAREST-FIRST (deepest placetype
|
|
8
8
|
* first, country last).
|
|
9
9
|
*
|
|
10
|
-
* Factored out of `
|
|
10
|
+
* Factored out of `WOFSqlitePlaceLookup.ancestors()` (#404) so the reverse geocoder (`reverse.ts`,
|
|
11
11
|
* #484) reuses the SAME walk instead of growing a second one. The placetype-specificity ordering
|
|
12
12
|
* lives here as `PLACETYPE_DEPTH` — a single TS map instead of the previous SQL CASE, and
|
|
13
13
|
* extended below `localadmin` (locality/borough/neighbourhood/microhood now rank correctly
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import type { DatabaseSync } from "node:sqlite";
|
|
18
18
|
/**
|
|
19
|
-
* WOF placetype → containment depth, coarsest = 1. Higher = finer. Placetypes we never resolve
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* WOF placetype → containment depth, coarsest = 1. Higher = finer. Placetypes we never resolve (continent, empire, …)
|
|
20
|
+
* map to 0 and sort last. NOT the same table as the FST's `PLACETYPE_ORDER` (fst-serialize.ts) — that one is a
|
|
21
|
+
* serialization order, this one is containment depth.
|
|
22
22
|
*/
|
|
23
23
|
export declare const PLACETYPE_DEPTH: Readonly<Record<string, number>>;
|
|
24
24
|
/** Containment depth for a placetype — 0 (sorts coarsest) when unknown. */
|
|
@@ -33,8 +33,8 @@ export interface AncestorPlaceRow {
|
|
|
33
33
|
lon: number;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* The ancestor lineage of `id` — self excluded, nearest-first. Returns `[]` when the place has no
|
|
37
|
-
*
|
|
36
|
+
* The ancestor lineage of `id` — self excluded, nearest-first. Returns `[]` when the place has no recorded ancestry.
|
|
37
|
+
* NOT memoized here; `WOFSqlitePlaceLookup` keeps its own per-id cache.
|
|
38
38
|
*/
|
|
39
39
|
export declare function ancestorLineage(db: DatabaseSync, id: number, schemaName?: string): AncestorPlaceRow[];
|
|
40
40
|
//# sourceMappingURL=ancestry.d.ts.map
|
package/out/ancestry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ancestry.d.ts","sourceRoot":"","sources":["../ancestry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY5D,CAAA;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;CACX;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,SAAS,GAAG,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"ancestry.d.ts","sourceRoot":"","sources":["../ancestry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY5D,CAAA;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;CACX;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,SAAS,GAAG,gBAAgB,EAAE,CAYrG"}
|
package/out/ancestry.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* joined with `spr` for canonical names + centroids, ordered NEAREST-FIRST (deepest placetype
|
|
8
8
|
* first, country last).
|
|
9
9
|
*
|
|
10
|
-
* Factored out of `
|
|
10
|
+
* Factored out of `WOFSqlitePlaceLookup.ancestors()` (#404) so the reverse geocoder (`reverse.ts`,
|
|
11
11
|
* #484) reuses the SAME walk instead of growing a second one. The placetype-specificity ordering
|
|
12
12
|
* lives here as `PLACETYPE_DEPTH` — a single TS map instead of the previous SQL CASE, and
|
|
13
13
|
* extended below `localadmin` (locality/borough/neighbourhood/microhood now rank correctly
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* geocoding always does).
|
|
16
16
|
*/
|
|
17
17
|
/**
|
|
18
|
-
* WOF placetype → containment depth, coarsest = 1. Higher = finer. Placetypes we never resolve
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* WOF placetype → containment depth, coarsest = 1. Higher = finer. Placetypes we never resolve (continent, empire, …)
|
|
19
|
+
* map to 0 and sort last. NOT the same table as the FST's `PLACETYPE_ORDER` (fst-serialize.ts) — that one is a
|
|
20
|
+
* serialization order, this one is containment depth.
|
|
21
21
|
*/
|
|
22
22
|
export const PLACETYPE_DEPTH = {
|
|
23
23
|
country: 1,
|
|
@@ -37,8 +37,8 @@ export function placetypeDepth(placetype) {
|
|
|
37
37
|
return PLACETYPE_DEPTH[placetype] ?? 0;
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
* The ancestor lineage of `id` — self excluded, nearest-first. Returns `[]` when the place has no
|
|
41
|
-
*
|
|
40
|
+
* The ancestor lineage of `id` — self excluded, nearest-first. Returns `[]` when the place has no recorded ancestry.
|
|
41
|
+
* NOT memoized here; `WOFSqlitePlaceLookup` keeps its own per-id cache.
|
|
42
42
|
*/
|
|
43
43
|
export function ancestorLineage(db, id, schemaName = "main") {
|
|
44
44
|
const rows = db
|
package/out/ancestry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ancestry.js","sourceRoot":"","sources":["../ancestry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqC;IAChE,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,aAAa,EAAE,EAAE;IACjB,SAAS,EAAE,EAAE;CACb,CAAA;AAED,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC/C,OAAO,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;AACvC,CAAC;AAYD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAAgB,EAAE,EAAU,EAAE,UAAU,GAAG,MAAM;IAChF,MAAM,IAAI,GAAG,EAAE;SACb,OAAO,CACP;;UAEO,UAAU,qBAAqB,UAAU;4CACP,CACzC;SACA,GAAG,CAAC,EAAE,CAAkC,CAAA;IAC1C,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"ancestry.js","sourceRoot":"","sources":["../ancestry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqC;IAChE,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,aAAa,EAAE,EAAE;IACjB,SAAS,EAAE,EAAE;CACb,CAAA;AAED,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC/C,OAAO,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;AACvC,CAAC;AAYD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAAgB,EAAE,EAAU,EAAE,UAAU,GAAG,MAAM;IAChF,MAAM,IAAI,GAAG,EAAE;SACb,OAAO,CACP;;UAEO,UAAU,qBAAqB,UAAU;4CACP,CACzC;SACA,GAAG,CAAC,EAAE,CAAkC,CAAA;IAC1C,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;IAE9E,OAAO,IAAI,CAAA;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-candidate-cli.d.ts","sourceRoot":"","sources":["../build-candidate-cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"build-candidate-cli.d.ts","sourceRoot":"","sources":["../build-candidate-cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AAsDH,wBAAsB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkB7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-candidate-cli.js","sourceRoot":"","sources":["../build-candidate-cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAQ1D,SAAS,iBAAiB,CAAC,IAAY;IACtC,MAAM,CAAC,KAAK,CACX;QACC,oGAAoG;QACpG,EAAE;QACF,0FAA0F;QAC1F,0FAA0F;QAC1F,iGAAiG;QACjG,yFAAyF;QACzF,sDAAsD;QACtD,EAAE;KACF,CAAC,IAAI,CAAC,IAAI,CAAC,CACZ,CAAA;IACD,IAAI,CAAC,IAAI,CAAC,CAAA;AACX,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAChC,IAAI,KAAyB,CAAA;IAC7B,IAAI,MAA0B,CAAA;IAC9B,MAAM,SAAS,GAAa,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"build-candidate-cli.js","sourceRoot":"","sources":["../build-candidate-cli.ts"],"names":[],"mappings":"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"}
|