@mailwoman/corpus 8.6.0 → 9.1.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/README.md +2 -2
- package/data/PROVENANCE.md +214 -0
- package/data/sub-venue-lexicon.json +18269 -0
- package/out/src/adapters/ban/adapter.d.ts +5 -4
- package/out/src/adapters/ban/adapter.d.ts.map +1 -1
- package/out/src/adapters/ban/adapter.js +62 -69
- package/out/src/adapters/ban/adapter.js.map +1 -1
- package/out/src/adapters/ban/street-decompose.d.ts.map +1 -1
- package/out/src/adapters/ban/street-decompose.js +18 -25
- package/out/src/adapters/ban/street-decompose.js.map +1 -1
- package/out/src/adapters/fcc-bdc/adapter.d.ts +1 -7
- package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
- package/out/src/adapters/fcc-bdc/adapter.js +4 -26
- package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
- package/out/src/adapters/geonames/adapter.d.ts +1 -1
- package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
- package/out/src/adapters/geonames/adapter.js +72 -78
- package/out/src/adapters/geonames/adapter.js.map +1 -1
- package/out/src/adapters/geonames-postal/adapter.d.ts +1 -1
- package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
- package/out/src/adapters/geonames-postal/adapter.js +46 -51
- package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
- package/out/src/adapters/gnaf/adapter.d.ts +1 -1
- package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
- package/out/src/adapters/gnaf/adapter.js +6 -9
- package/out/src/adapters/gnaf/adapter.js.map +1 -1
- package/out/src/adapters/gnaf/assemble.d.ts.map +1 -1
- package/out/src/adapters/gnaf/assemble.js +7 -12
- package/out/src/adapters/gnaf/assemble.js.map +1 -1
- package/out/src/adapters/index.d.ts +1 -1
- package/out/src/adapters/index.d.ts.map +1 -1
- package/out/src/adapters/index.js +1 -1
- package/out/src/adapters/index.js.map +1 -1
- package/out/src/adapters/openaddresses/adapter.d.ts +1 -1
- package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
- package/out/src/adapters/openaddresses/adapter.js +5 -10
- package/out/src/adapters/openaddresses/adapter.js.map +1 -1
- package/out/src/adapters/overture/adapter.d.ts +1 -1
- package/out/src/adapters/overture/adapter.d.ts.map +1 -1
- package/out/src/adapters/overture/adapter.js +5 -9
- package/out/src/adapters/overture/adapter.js.map +1 -1
- package/out/src/adapters/state-hi-schools/adapter.d.ts +1 -1
- package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-hi-schools/adapter.js +57 -75
- package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.d.ts +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.js +60 -78
- package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.d.ts +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.js +69 -87
- package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.d.ts +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.js +71 -89
- package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
- package/out/src/adapters/synth-po-box/adapter.d.ts +3 -3
- package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
- package/out/src/adapters/synth-po-box/adapter.js +10 -18
- package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
- package/out/src/adapters/tiger/adapter.d.ts +1 -1
- package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
- package/out/src/adapters/tiger/adapter.js +2 -2
- package/out/src/adapters/tiger/adapter.js.map +1 -1
- package/out/src/adapters/tiger/street-decompose.d.ts.map +1 -1
- package/out/src/adapters/tiger/street-decompose.js +18 -27
- package/out/src/adapters/tiger/street-decompose.js.map +1 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +4 -4
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +64 -82
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.js +62 -84
- package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.js +59 -66
- package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
- package/out/src/adapters/usgov-nad/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-nad/adapter.js +6 -9
- package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
- package/out/src/adapters/usgov-nppes/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-nppes/adapter.js +60 -78
- package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +53 -73
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
- package/out/src/{adapter.d.ts → adapters/utils/index.d.ts} +43 -2
- package/out/src/adapters/utils/index.d.ts.map +1 -0
- package/out/src/{adapter.js → adapters/utils/index.js} +47 -2
- package/out/src/adapters/utils/index.js.map +1 -0
- package/out/src/adapters/wof-admin-jp/adapter.d.ts +1 -1
- package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-admin-jp/adapter.js +24 -6
- package/out/src/adapters/wof-admin-jp/adapter.js.map +1 -1
- package/out/src/adapters/wof-admin-json/adapter.d.ts +2 -2
- package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-admin-json/adapter.js +2 -2
- package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
- package/out/src/adapters/wof-postalcode-json/adapter.d.ts +2 -2
- package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-postalcode-json/adapter.js +2 -2
- package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
- package/out/src/build.d.ts +3 -4
- package/out/src/build.d.ts.map +1 -1
- package/out/src/build.js +6 -8
- package/out/src/build.js.map +1 -1
- package/out/src/index.d.ts +3 -17
- package/out/src/index.d.ts.map +1 -1
- package/out/src/index.js +3 -17
- package/out/src/index.js.map +1 -1
- package/out/src/name-prone-us-suffixes.d.ts +12 -0
- package/out/src/name-prone-us-suffixes.d.ts.map +1 -0
- package/out/src/name-prone-us-suffixes.js +12 -0
- package/out/src/name-prone-us-suffixes.js.map +1 -0
- package/out/src/parquet-wrapper/reader.d.ts +8 -0
- package/out/src/parquet-wrapper/reader.d.ts.map +1 -1
- package/out/src/parquet-wrapper/reader.js +16 -0
- package/out/src/parquet-wrapper/reader.js.map +1 -1
- package/out/src/parquet-wrapper/schema.d.ts +4 -0
- package/out/src/parquet-wrapper/schema.d.ts.map +1 -1
- package/out/src/parquet-wrapper/schema.js.map +1 -1
- package/out/src/runner.d.ts +2 -2
- package/out/src/runner.d.ts.map +1 -1
- package/out/src/runner.js +1 -1
- package/out/src/runner.js.map +1 -1
- package/out/src/shard-recipes/anchor-absorption.d.ts.map +1 -1
- package/out/src/shard-recipes/anchor-absorption.js +5 -4
- package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
- package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
- package/out/src/shard-recipes/boundary-stress.js +2 -2
- package/out/src/shard-recipes/boundary-stress.js.map +1 -1
- package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
- package/out/src/shard-recipes/country-balanced.js +75 -75
- package/out/src/shard-recipes/country-balanced.js.map +1 -1
- package/out/src/shard-recipes/fr-admin-split.js +2 -2
- package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
- package/out/src/shard-recipes/fr-fragment.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-fragment.js +8 -5
- package/out/src/shard-recipes/fr-fragment.js.map +1 -1
- package/out/src/shard-recipes/fr-lieudit.js +2 -2
- package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
- package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-order.js +18 -72
- package/out/src/shard-recipes/fr-order.js.map +1 -1
- package/out/src/shard-recipes/german.d.ts.map +1 -1
- package/out/src/shard-recipes/german.js +17 -70
- package/out/src/shard-recipes/german.js.map +1 -1
- package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
- package/out/src/shard-recipes/house-venue.js +1 -1
- package/out/src/shard-recipes/house-venue.js.map +1 -1
- package/out/src/shard-recipes/index.d.ts.map +1 -1
- package/out/src/shard-recipes/index.js +4 -1
- package/out/src/shard-recipes/index.js.map +1 -1
- package/out/src/shard-recipes/intersection.d.ts +2 -2
- package/out/src/shard-recipes/intersection.d.ts.map +1 -1
- package/out/src/shard-recipes/intersection.js +28 -72
- package/out/src/shard-recipes/intersection.js.map +1 -1
- package/out/src/shard-recipes/locale.d.ts +5 -5
- package/out/src/shard-recipes/locale.d.ts.map +1 -1
- package/out/src/shard-recipes/locale.js +25 -35
- package/out/src/shard-recipes/locale.js.map +1 -1
- package/out/src/shard-recipes/no-fragment.d.ts.map +1 -1
- package/out/src/shard-recipes/no-fragment.js +8 -5
- package/out/src/shard-recipes/no-fragment.js.map +1 -1
- package/out/src/shard-recipes/no-street-led.d.ts.map +1 -1
- package/out/src/shard-recipes/no-street-led.js +8 -5
- package/out/src/shard-recipes/no-street-led.js.map +1 -1
- package/out/src/shard-recipes/no-street.d.ts.map +1 -1
- package/out/src/shard-recipes/no-street.js +1 -1
- package/out/src/shard-recipes/no-street.js.map +1 -1
- package/out/src/shard-recipes/po-box-cedex.d.ts +3 -3
- package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
- package/out/src/shard-recipes/po-box-cedex.js +101 -127
- package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
- package/out/src/shard-recipes/po-box.d.ts.map +1 -1
- package/out/src/shard-recipes/po-box.js +1 -1
- package/out/src/shard-recipes/po-box.js.map +1 -1
- package/out/src/shard-recipes/scaffold.d.ts +58 -9
- package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
- package/out/src/shard-recipes/scaffold.js +87 -29
- package/out/src/shard-recipes/scaffold.js.map +1 -1
- package/out/src/shard-recipes/street-affix.d.ts +54 -0
- package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
- package/out/src/shard-recipes/street-affix.js +253 -111
- package/out/src/shard-recipes/street-affix.js.map +1 -1
- package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
- package/out/src/shard-recipes/street-bare.js +3 -3
- package/out/src/shard-recipes/street-bare.js.map +1 -1
- package/out/src/shard-recipes/street.d.ts.map +1 -1
- package/out/src/shard-recipes/street.js +2 -2
- package/out/src/shard-recipes/street.js.map +1 -1
- package/out/src/shard-recipes/sub-venue-sources.d.ts +228 -0
- package/out/src/shard-recipes/sub-venue-sources.d.ts.map +1 -0
- package/out/src/shard-recipes/sub-venue-sources.js +664 -0
- package/out/src/shard-recipes/sub-venue-sources.js.map +1 -0
- package/out/src/shard-recipes/sub-venue.d.ts +269 -0
- package/out/src/shard-recipes/sub-venue.d.ts.map +1 -0
- package/out/src/shard-recipes/sub-venue.js +709 -0
- package/out/src/shard-recipes/sub-venue.js.map +1 -0
- package/out/src/shard-recipes/unit.d.ts +1 -1
- package/out/src/shard-recipes/unit.d.ts.map +1 -1
- package/out/src/shard-recipes/unit.js +26 -74
- package/out/src/shard-recipes/unit.js.map +1 -1
- package/out/src/{synthesize-anchor-absorption.d.ts → synthesizers/anchor-absorption.d.ts} +1 -1
- package/out/src/synthesizers/anchor-absorption.d.ts.map +1 -0
- package/out/src/{synthesize-anchor-absorption.js → synthesizers/anchor-absorption.js} +1 -1
- package/out/src/synthesizers/anchor-absorption.js.map +1 -0
- package/out/src/{synthesize-boundary-stress.d.ts → synthesizers/boundary-stress.d.ts} +3 -3
- package/out/src/synthesizers/boundary-stress.d.ts.map +1 -0
- package/out/src/{synthesize-boundary-stress.js → synthesizers/boundary-stress.js} +2 -2
- package/out/src/synthesizers/boundary-stress.js.map +1 -0
- package/out/src/{synthesize-german.d.ts → synthesizers/german.d.ts} +2 -2
- package/out/src/synthesizers/german.d.ts.map +1 -0
- package/out/src/{synthesize-german.js → synthesizers/german.js} +2 -2
- package/out/src/synthesizers/german.js.map +1 -0
- package/out/src/{synthesize-house-venue.d.ts → synthesizers/house-venue.d.ts} +4 -4
- package/out/src/synthesizers/house-venue.d.ts.map +1 -0
- package/out/src/{synthesize-house-venue.js → synthesizers/house-venue.js} +4 -4
- package/out/src/synthesizers/house-venue.js.map +1 -0
- package/out/src/{synthesize-intersection.d.ts → synthesizers/intersection.d.ts} +2 -2
- package/out/src/synthesizers/intersection.d.ts.map +1 -0
- package/out/src/{synthesize-intersection.js → synthesizers/intersection.js} +1 -1
- package/out/src/synthesizers/intersection.js.map +1 -0
- package/out/src/{synthesize-no-street.d.ts → synthesizers/no-street.d.ts} +3 -3
- package/out/src/synthesizers/no-street.d.ts.map +1 -0
- package/out/src/{synthesize-no-street.js → synthesizers/no-street.js} +2 -2
- package/out/src/synthesizers/no-street.js.map +1 -0
- package/out/src/{synthesize-po-box.d.ts → synthesizers/po-box.d.ts} +2 -2
- package/out/src/synthesizers/po-box.d.ts.map +1 -0
- package/out/src/{synthesize-po-box.js → synthesizers/po-box.js} +1 -1
- package/out/src/synthesizers/po-box.js.map +1 -0
- package/out/src/{synthesize-street.d.ts → synthesizers/street.d.ts} +2 -2
- package/out/src/synthesizers/street.d.ts.map +1 -0
- package/out/src/{synthesize-street.js → synthesizers/street.js} +2 -2
- package/out/src/synthesizers/street.js.map +1 -0
- package/out/src/{synthesize.d.ts → synthesizers/utils.d.ts} +3 -3
- package/out/src/synthesizers/utils.d.ts.map +1 -0
- package/out/src/{synthesize.js → synthesizers/utils.js} +4 -15
- package/out/src/synthesizers/utils.js.map +1 -0
- package/out/src/tools/align-shard.d.ts.map +1 -1
- package/out/src/tools/align-shard.js +4 -8
- package/out/src/tools/align-shard.js.map +1 -1
- package/out/src/tools/audit.d.ts.map +1 -1
- package/out/src/tools/audit.js +4 -4
- package/out/src/tools/audit.js.map +1 -1
- package/out/src/tools/corpus-stats.d.ts +2 -2
- package/out/src/tools/corpus-stats.d.ts.map +1 -1
- package/out/src/tools/corpus-stats.js +18 -31
- package/out/src/tools/corpus-stats.js.map +1 -1
- package/out/src/tools/fetch/download.d.ts.map +1 -1
- package/out/src/tools/fetch/download.js +5 -6
- package/out/src/tools/fetch/download.js.map +1 -1
- package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
- package/out/src/tools/fetch/imls-pls.js +3 -15
- package/out/src/tools/fetch/imls-pls.js.map +1 -1
- package/out/src/tools/fetch/index.d.ts +14 -1
- package/out/src/tools/fetch/index.d.ts.map +1 -1
- package/out/src/tools/fetch/index.js +14 -1
- package/out/src/tools/fetch/index.js.map +1 -1
- package/out/src/tools/fetch/nad.d.ts +1 -1
- package/out/src/tools/fetch/nad.js +1 -1
- package/out/src/tools/fetch/nppes.d.ts.map +1 -1
- package/out/src/tools/fetch/nppes.js +8 -14
- package/out/src/tools/fetch/nppes.js.map +1 -1
- package/out/src/tools/fetch/openaddresses.d.ts +1 -1
- package/out/src/tools/fetch/openaddresses.js +1 -1
- package/out/src/tools/fetch/ourairports.d.ts +45 -0
- package/out/src/tools/fetch/ourairports.d.ts.map +1 -0
- package/out/src/tools/fetch/ourairports.js +123 -0
- package/out/src/tools/fetch/ourairports.js.map +1 -0
- package/out/src/tools/fetch/wikidata-subvenue.d.ts +171 -0
- package/out/src/tools/fetch/wikidata-subvenue.d.ts.map +1 -0
- package/out/src/tools/fetch/wikidata-subvenue.js +275 -0
- package/out/src/tools/fetch/wikidata-subvenue.js.map +1 -0
- package/out/src/tools/golden-expand.d.ts.map +1 -1
- package/out/src/tools/golden-expand.js +18 -16
- package/out/src/tools/golden-expand.js.map +1 -1
- package/out/src/tools/golden-promote.d.ts.map +1 -1
- package/out/src/tools/golden-promote.js +12 -6
- package/out/src/tools/golden-promote.js.map +1 -1
- package/out/src/tools/golden-relabel-street.d.ts +196 -0
- package/out/src/tools/golden-relabel-street.d.ts.map +1 -0
- package/out/src/tools/golden-relabel-street.js +440 -0
- package/out/src/tools/golden-relabel-street.js.map +1 -0
- package/out/src/tools/index.d.ts +4 -0
- package/out/src/tools/index.d.ts.map +1 -1
- package/out/src/tools/index.js +4 -0
- package/out/src/tools/index.js.map +1 -1
- package/out/src/tools/jsonl-to-parquet.d.ts.map +1 -1
- package/out/src/tools/jsonl-to-parquet.js +3 -2
- package/out/src/tools/jsonl-to-parquet.js.map +1 -1
- package/out/src/tools/lint-shard-vocab.d.ts.map +1 -1
- package/out/src/tools/lint-shard-vocab.js +3 -2
- package/out/src/tools/lint-shard-vocab.js.map +1 -1
- package/out/src/tools/lint-shard.d.ts +3 -3
- package/out/src/tools/lint-shard.d.ts.map +1 -1
- package/out/src/tools/lint-shard.js +23 -32
- package/out/src/tools/lint-shard.js.map +1 -1
- package/out/src/tools/overlay-manifest.d.ts.map +1 -1
- package/out/src/tools/overlay-manifest.js +2 -1
- package/out/src/tools/overlay-manifest.js.map +1 -1
- package/out/src/tools/overture-subvenue.d.ts +112 -0
- package/out/src/tools/overture-subvenue.d.ts.map +1 -0
- package/out/src/tools/overture-subvenue.js +144 -0
- package/out/src/tools/overture-subvenue.js.map +1 -0
- package/out/src/tools/shard-kryptonite.d.ts +1 -1
- package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
- package/out/src/tools/shard-kryptonite.js +6 -6
- package/out/src/tools/shard-kryptonite.js.map +1 -1
- package/out/src/tools/shard-translit.d.ts +6 -3
- package/out/src/tools/shard-translit.d.ts.map +1 -1
- package/out/src/tools/shard-translit.js +9 -8
- package/out/src/tools/shard-translit.js.map +1 -1
- package/out/src/tools/sub-venue-lexicon.d.ts +507 -0
- package/out/src/tools/sub-venue-lexicon.d.ts.map +1 -0
- package/out/src/tools/sub-venue-lexicon.js +817 -0
- package/out/src/tools/sub-venue-lexicon.js.map +1 -0
- package/out/src/tools/sub-venue-promotions.d.ts +94 -0
- package/out/src/tools/sub-venue-promotions.d.ts.map +1 -0
- package/out/src/tools/sub-venue-promotions.js +266 -0
- package/out/src/tools/sub-venue-promotions.js.map +1 -0
- package/out/src/{align.d.ts → utils/align.d.ts} +1 -1
- package/out/src/utils/align.d.ts.map +1 -0
- package/out/src/utils/align.js.map +1 -0
- package/out/src/{golden.d.ts → utils/golden.d.ts} +5 -0
- package/out/src/utils/golden.d.ts.map +1 -0
- package/out/src/{golden.js → utils/golden.js} +24 -10
- package/out/src/utils/golden.js.map +1 -0
- package/out/src/utils/index.d.ts +14 -0
- package/out/src/utils/index.d.ts.map +1 -0
- package/out/src/utils/index.js +14 -0
- package/out/src/utils/index.js.map +1 -0
- package/out/src/utils/license.d.ts.map +1 -0
- package/out/src/utils/license.js.map +1 -0
- package/out/src/{parquet.d.ts → utils/parquet.d.ts} +2 -2
- package/out/src/utils/parquet.d.ts.map +1 -0
- package/out/src/{parquet.js → utils/parquet.js} +3 -15
- package/out/src/utils/parquet.js.map +1 -0
- package/out/src/{split.d.ts → utils/split.d.ts} +8 -1
- package/out/src/utils/split.d.ts.map +1 -0
- package/out/src/{split.js → utils/split.js} +7 -0
- package/out/src/utils/split.js.map +1 -0
- package/out/src/utils/tokenize.d.ts.map +1 -0
- package/out/src/utils/tokenize.js.map +1 -0
- package/out/src/{wof-json.d.ts → utils/wof-json.d.ts} +2 -2
- package/out/src/utils/wof-json.d.ts.map +1 -0
- package/out/src/{wof-json.js → utils/wof-json.js} +5 -8
- package/out/src/utils/wof-json.js.map +1 -0
- package/package.json +66 -20
- package/src/adapters/ban/adapter.ts +58 -68
- package/src/adapters/ban/street-decompose.ts +17 -25
- package/src/adapters/fcc-bdc/adapter.ts +5 -36
- package/src/adapters/geonames/adapter.ts +67 -76
- package/src/adapters/geonames-postal/adapter.ts +45 -54
- package/src/adapters/gnaf/adapter.ts +7 -11
- package/src/adapters/gnaf/assemble.ts +7 -11
- package/src/adapters/index.ts +3 -2
- package/src/adapters/openaddresses/adapter.ts +6 -12
- package/src/adapters/overture/adapter.ts +6 -10
- package/src/adapters/state-hi-schools/adapter.ts +53 -77
- package/src/adapters/state-ia-contractors/adapter.ts +55 -80
- package/src/adapters/state-ny-notaries/adapter.ts +64 -89
- package/src/adapters/state-tx-notaries/adapter.ts +63 -88
- package/src/adapters/synth-po-box/adapter.ts +12 -23
- package/src/adapters/tiger/adapter.ts +4 -3
- package/src/adapters/tiger/street-decompose.ts +21 -31
- package/src/adapters/usgov-hrsa-fqhc/adapter.ts +64 -88
- package/src/adapters/usgov-imls-pls/adapter.ts +57 -86
- package/src/adapters/usgov-irs-bmf/adapter.ts +55 -66
- package/src/adapters/usgov-nad/adapter.ts +7 -11
- package/src/adapters/usgov-nppes/adapter.ts +54 -79
- package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +48 -75
- package/src/{adapter.ts → adapters/utils/index.ts} +59 -3
- package/src/adapters/wof-admin-jp/adapter.ts +35 -9
- package/src/adapters/wof-admin-json/adapter.ts +3 -4
- package/src/adapters/wof-postalcode-json/adapter.ts +3 -4
- package/src/build.ts +12 -11
- package/src/index.ts +3 -17
- package/src/name-prone-us-suffixes.ts +12 -0
- package/src/parquet-wrapper/reader.ts +19 -0
- package/src/parquet-wrapper/schema.ts +4 -0
- package/src/runner.ts +7 -2
- package/src/shard-recipes/anchor-absorption.ts +5 -4
- package/src/shard-recipes/boundary-stress.ts +6 -2
- package/src/shard-recipes/country-balanced.ts +77 -91
- package/src/shard-recipes/fr-admin-split.ts +3 -3
- package/src/shard-recipes/fr-fragment.ts +10 -7
- package/src/shard-recipes/fr-lieudit.ts +3 -3
- package/src/shard-recipes/fr-order.ts +18 -83
- package/src/shard-recipes/german.ts +17 -80
- package/src/shard-recipes/house-venue.ts +2 -1
- package/src/shard-recipes/index.ts +4 -1
- package/src/shard-recipes/intersection.ts +37 -74
- package/src/shard-recipes/locale.ts +31 -39
- package/src/shard-recipes/no-fragment.ts +10 -7
- package/src/shard-recipes/no-street-led.ts +10 -7
- package/src/shard-recipes/no-street.ts +2 -1
- package/src/shard-recipes/po-box-cedex.ts +127 -161
- package/src/shard-recipes/po-box.ts +6 -1
- package/src/shard-recipes/scaffold.ts +125 -27
- package/src/shard-recipes/street-affix.ts +335 -134
- package/src/shard-recipes/street-bare.ts +4 -3
- package/src/shard-recipes/street.ts +3 -2
- package/src/shard-recipes/sub-venue-sources.ts +895 -0
- package/src/shard-recipes/sub-venue.ts +982 -0
- package/src/shard-recipes/unit.ts +27 -85
- package/src/{synthesize-boundary-stress.ts → synthesizers/boundary-stress.ts} +2 -2
- package/src/{synthesize-german.ts → synthesizers/german.ts} +2 -2
- package/src/{synthesize-house-venue.ts → synthesizers/house-venue.ts} +4 -4
- package/src/{synthesize-intersection.ts → synthesizers/intersection.ts} +1 -1
- package/src/{synthesize-no-street.ts → synthesizers/no-street.ts} +2 -2
- package/src/{synthesize-po-box.ts → synthesizers/po-box.ts} +1 -1
- package/src/{synthesize-street.ts → synthesizers/street.ts} +2 -2
- package/src/{synthesize.ts → synthesizers/utils.ts} +4 -18
- package/src/tools/align-shard.ts +4 -7
- package/src/tools/audit.ts +6 -5
- package/src/tools/corpus-stats.ts +25 -33
- package/src/tools/fetch/download.ts +7 -5
- package/src/tools/fetch/imls-pls.ts +4 -18
- package/src/tools/fetch/index.ts +14 -1
- package/src/tools/fetch/nad.ts +1 -1
- package/src/tools/fetch/nppes.ts +9 -16
- package/src/tools/fetch/openaddresses.ts +1 -1
- package/src/tools/fetch/ourairports.ts +166 -0
- package/src/tools/fetch/wikidata-subvenue.ts +386 -0
- package/src/tools/golden-expand.ts +18 -13
- package/src/tools/golden-promote.ts +15 -6
- package/src/tools/golden-relabel-street.ts +685 -0
- package/src/tools/index.ts +4 -0
- package/src/tools/jsonl-to-parquet.ts +3 -2
- package/src/tools/lint-shard-vocab.ts +3 -2
- package/src/tools/lint-shard.ts +33 -36
- package/src/tools/overlay-manifest.ts +2 -1
- package/src/tools/overture-subvenue.ts +215 -0
- package/src/tools/shard-kryptonite.ts +8 -9
- package/src/tools/shard-translit.ts +22 -11
- package/src/tools/sub-venue-lexicon.ts +1250 -0
- package/src/tools/sub-venue-promotions.ts +330 -0
- package/src/{align.ts → utils/align.ts} +1 -1
- package/src/{golden.ts → utils/golden.ts} +25 -11
- package/src/utils/index.ts +14 -0
- package/src/{parquet.ts → utils/parquet.ts} +5 -19
- package/src/{split.ts → utils/split.ts} +8 -2
- package/src/{wof-json.ts → utils/wof-json.ts} +5 -8
- package/out/src/adapter.d.ts.map +0 -1
- package/out/src/adapter.js.map +0 -1
- package/out/src/align.d.ts.map +0 -1
- package/out/src/align.js.map +0 -1
- package/out/src/format.d.ts +0 -14
- package/out/src/format.d.ts.map +0 -1
- package/out/src/format.js +0 -14
- package/out/src/format.js.map +0 -1
- package/out/src/golden.d.ts.map +0 -1
- package/out/src/golden.js.map +0 -1
- package/out/src/license.d.ts.map +0 -1
- package/out/src/license.js.map +0 -1
- package/out/src/parquet.d.ts.map +0 -1
- package/out/src/parquet.js.map +0 -1
- package/out/src/split.d.ts.map +0 -1
- package/out/src/split.js.map +0 -1
- package/out/src/synthesize-anchor-absorption.d.ts.map +0 -1
- package/out/src/synthesize-anchor-absorption.js.map +0 -1
- package/out/src/synthesize-boundary-stress.d.ts.map +0 -1
- package/out/src/synthesize-boundary-stress.js.map +0 -1
- package/out/src/synthesize-german.d.ts.map +0 -1
- package/out/src/synthesize-german.js.map +0 -1
- package/out/src/synthesize-house-venue.d.ts.map +0 -1
- package/out/src/synthesize-house-venue.js.map +0 -1
- package/out/src/synthesize-intersection.d.ts.map +0 -1
- package/out/src/synthesize-intersection.js.map +0 -1
- package/out/src/synthesize-no-street.d.ts.map +0 -1
- package/out/src/synthesize-no-street.js.map +0 -1
- package/out/src/synthesize-po-box.d.ts.map +0 -1
- package/out/src/synthesize-po-box.js.map +0 -1
- package/out/src/synthesize-street.d.ts.map +0 -1
- package/out/src/synthesize-street.js.map +0 -1
- package/out/src/synthesize.d.ts.map +0 -1
- package/out/src/synthesize.js.map +0 -1
- package/out/src/tokenize.d.ts.map +0 -1
- package/out/src/tokenize.js.map +0 -1
- package/out/src/wof-json.d.ts.map +0 -1
- package/out/src/wof-json.js.map +0 -1
- package/src/format.ts +0 -14
- /package/out/src/{align.js → utils/align.js} +0 -0
- /package/out/src/{license.d.ts → utils/license.d.ts} +0 -0
- /package/out/src/{license.js → utils/license.js} +0 -0
- /package/out/src/{tokenize.d.ts → utils/tokenize.d.ts} +0 -0
- /package/out/src/{tokenize.js → utils/tokenize.js} +0 -0
- /package/src/{synthesize-anchor-absorption.ts → synthesizers/anchor-absorption.ts} +0 -0
- /package/src/{license.ts → utils/license.ts} +0 -0
- /package/src/{tokenize.ts → utils/tokenize.ts} +0 -0
|
@@ -15,14 +15,11 @@
|
|
|
15
15
|
* License: stamped `"Public Domain"` per Texas state government open-data terms.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
import {
|
|
23
|
-
import { lookupStateAbbreviation } from "../../codex/us-fips-state.ts"
|
|
24
|
-
import { reconcileComponents } from "../../format.ts"
|
|
25
|
-
import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
|
|
18
|
+
import { splitStreetLine, stableSourceID } from "@mailwoman/corpus/adapters/utils"
|
|
19
|
+
import { lookupStateAbbreviation } from "@mailwoman/corpus/codex/us-fips-state"
|
|
20
|
+
import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
|
|
21
|
+
import { reconcileComponents } from "@mailwoman/formatter"
|
|
22
|
+
import { CSVSpliterator } from "spliterator"
|
|
26
23
|
|
|
27
24
|
/**
|
|
28
25
|
* Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
|
|
@@ -35,8 +32,6 @@ export const STATE_TX_NOTARIES_ADAPTER_ID = "state-tx-notaries"
|
|
|
35
32
|
*/
|
|
36
33
|
export const STATE_TX_NOTARIES_DEFAULT_LICENSE = "Public Domain"
|
|
37
34
|
|
|
38
|
-
const HOUSE_NUMBER_PREFIX = /^(\d+(?:-\d+)?[A-Za-z]?)\s+(.+)$/
|
|
39
|
-
|
|
40
35
|
/**
|
|
41
36
|
* Match trailing "CITY, ST ZIP" or "CITY, ST" at the end of an address line.
|
|
42
37
|
*/
|
|
@@ -49,17 +44,6 @@ interface TxNotaryRow {
|
|
|
49
44
|
Address: string
|
|
50
45
|
}
|
|
51
46
|
|
|
52
|
-
function splitAddress(address: string): { house_number?: string; street: string } | null {
|
|
53
|
-
const trimmed = address.trim()
|
|
54
|
-
|
|
55
|
-
if (!trimmed) return null
|
|
56
|
-
const m = HOUSE_NUMBER_PREFIX.exec(trimmed)
|
|
57
|
-
|
|
58
|
-
if (m) return { house_number: m[1], street: m[2]!.trim() }
|
|
59
|
-
|
|
60
|
-
return { street: trimmed }
|
|
61
|
-
}
|
|
62
|
-
|
|
63
47
|
export function createStateTxNotariesAdapter(): CorpusAdapter {
|
|
64
48
|
return {
|
|
65
49
|
id: STATE_TX_NOTARIES_ADAPTER_ID,
|
|
@@ -72,99 +56,90 @@ export function createStateTxNotariesAdapter(): CorpusAdapter {
|
|
|
72
56
|
throw new Error(`state-tx-notaries adapter: only US supported, got country=${opts.country}`)
|
|
73
57
|
}
|
|
74
58
|
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
skip_empty_lines: true,
|
|
81
|
-
relax_quotes: true,
|
|
82
|
-
relax_column_count: true,
|
|
83
|
-
})
|
|
84
|
-
)
|
|
59
|
+
const rows = CSVSpliterator.fromAsync(opts.inputPath, {
|
|
60
|
+
mode: "object",
|
|
61
|
+
normalizeKeys: false,
|
|
62
|
+
enableQuoteHandling: true,
|
|
63
|
+
})
|
|
85
64
|
|
|
86
65
|
let emitted = 0
|
|
87
66
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (opts.signal?.aborted) break
|
|
67
|
+
for await (const record of rows as AsyncIterable<TxNotaryRow>) {
|
|
68
|
+
if (opts.signal?.aborted) break
|
|
91
69
|
|
|
92
|
-
|
|
70
|
+
if (opts.limit !== undefined && emitted >= opts.limit) break
|
|
93
71
|
|
|
94
|
-
|
|
72
|
+
const rawAddress = (record.Address ?? "").trim()
|
|
95
73
|
|
|
96
|
-
|
|
74
|
+
if (!rawAddress) continue
|
|
97
75
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
76
|
+
const firstName = (record["First Name"] ?? "").trim()
|
|
77
|
+
const lastName = (record["Last Name"] ?? "").trim()
|
|
78
|
+
const notaryID = (record["Notary ID"] ?? "").trim()
|
|
101
79
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
80
|
+
// Parse embedded city/state/zip from the trailing portion of the address.
|
|
81
|
+
// Addresses look like: "1215 MCMILLAN DR\nCEDAR HILL, TX 75104"
|
|
82
|
+
const addrSingleLine = rawAddress.replaceAll("\n", ", ")
|
|
83
|
+
const cszMatch = CITY_STATE_ZIP_SUFFIX.exec(addrSingleLine)
|
|
106
84
|
|
|
107
|
-
|
|
85
|
+
if (!cszMatch) continue
|
|
108
86
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
87
|
+
const city = (cszMatch[1] ?? "").trim()
|
|
88
|
+
const stateAbbr = (cszMatch[2] ?? "").trim()
|
|
89
|
+
const zip = (cszMatch[3] ?? "").trim()
|
|
112
90
|
|
|
113
|
-
|
|
91
|
+
if (!city || !stateAbbr) continue
|
|
114
92
|
|
|
115
|
-
|
|
93
|
+
const state = lookupStateAbbreviation(stateAbbr)
|
|
116
94
|
|
|
117
|
-
|
|
95
|
+
if (!state) continue
|
|
118
96
|
|
|
119
|
-
|
|
120
|
-
|
|
97
|
+
// Extract the street portion (everything before the city/state/zip)
|
|
98
|
+
const streetPortion = addrSingleLine.slice(0, cszMatch.index).replace(/,\s*$/, "").trim()
|
|
121
99
|
|
|
122
|
-
|
|
100
|
+
if (!streetPortion) continue
|
|
123
101
|
|
|
124
|
-
|
|
102
|
+
const split = splitStreetLine(streetPortion)
|
|
125
103
|
|
|
126
|
-
|
|
104
|
+
if (!split) continue
|
|
127
105
|
|
|
128
|
-
|
|
106
|
+
const venue = [firstName, lastName].filter(Boolean).join(" ") || undefined
|
|
129
107
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const streetPart = [split.house_number, split.street].filter(Boolean).join(" ").trim()
|
|
108
|
+
const components: CanonicalRow["components"] = {
|
|
109
|
+
...(venue ? { venue } : {}),
|
|
110
|
+
...(split.house_number ? { house_number: split.house_number } : {}),
|
|
111
|
+
street: split.street,
|
|
112
|
+
locality: city,
|
|
113
|
+
region: state.abbreviation,
|
|
114
|
+
...(zip ? { postcode: zip } : {}),
|
|
115
|
+
}
|
|
140
116
|
|
|
141
|
-
|
|
142
|
-
.filter(Boolean)
|
|
143
|
-
.join(", ")
|
|
117
|
+
const streetPart = [split.house_number, split.street].filter(Boolean).join(" ").trim()
|
|
144
118
|
|
|
145
|
-
|
|
119
|
+
const raw = [venue, streetPart, [city, [stateAbbr, zip].filter(Boolean).join(" ")].filter(Boolean).join(", ")]
|
|
120
|
+
.filter(Boolean)
|
|
121
|
+
.join(", ")
|
|
146
122
|
|
|
147
|
-
|
|
123
|
+
const aligned = reconcileComponents(components, raw)
|
|
148
124
|
|
|
149
|
-
|
|
150
|
-
? `${STATE_TX_NOTARIES_ADAPTER_ID}-${notaryID}`
|
|
151
|
-
: stableSourceID(STATE_TX_NOTARIES_ADAPTER_ID, aligned)
|
|
125
|
+
if (Object.keys(aligned).length <= 2) continue
|
|
152
126
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
country: "US",
|
|
157
|
-
locale: "en-US",
|
|
158
|
-
source: STATE_TX_NOTARIES_ADAPTER_ID,
|
|
159
|
-
source_id: sourceID,
|
|
160
|
-
corpus_version: "",
|
|
161
|
-
license: STATE_TX_NOTARIES_DEFAULT_LICENSE,
|
|
162
|
-
}
|
|
127
|
+
const sourceID = notaryID
|
|
128
|
+
? `${STATE_TX_NOTARIES_ADAPTER_ID}-${notaryID}`
|
|
129
|
+
: stableSourceID(STATE_TX_NOTARIES_ADAPTER_ID, aligned)
|
|
163
130
|
|
|
164
|
-
|
|
131
|
+
yield {
|
|
132
|
+
raw,
|
|
133
|
+
components: aligned,
|
|
134
|
+
country: "US",
|
|
135
|
+
locale: "en-US",
|
|
136
|
+
source: STATE_TX_NOTARIES_ADAPTER_ID,
|
|
137
|
+
source_id: sourceID,
|
|
138
|
+
corpus_version: "",
|
|
139
|
+
license: STATE_TX_NOTARIES_DEFAULT_LICENSE,
|
|
165
140
|
}
|
|
166
|
-
|
|
167
|
-
|
|
141
|
+
|
|
142
|
+
emitted++
|
|
168
143
|
}
|
|
169
144
|
},
|
|
170
145
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Consumes a JSONL stream of (locality, region, postcode, country) tuples — typically extracted
|
|
9
9
|
* from existing corpus output (TIGER/NAD/BAN/WOF) — and emits synthetic PO box training rows. See
|
|
10
|
-
*
|
|
10
|
+
* `@mailwoman/corpus/synthesizers/po-box` for the per-locale templates and number-noise logic.
|
|
11
11
|
*
|
|
12
12
|
* Why an adapter and not an augmenter:
|
|
13
13
|
*
|
|
@@ -20,17 +20,18 @@
|
|
|
20
20
|
* carries a `street` field.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
import { stableSourceID } from "
|
|
23
|
+
import { tryParsingJSON } from "@mailwoman/core/objects"
|
|
24
|
+
import { makeLcg } from "@mailwoman/core/utils"
|
|
25
|
+
import { stableSourceID } from "@mailwoman/corpus/adapters/utils"
|
|
26
26
|
import {
|
|
27
27
|
countryToLocale,
|
|
28
28
|
REGION_OPTIONAL_LOCALES,
|
|
29
29
|
synthesizeMilitaryPoBoxRow,
|
|
30
30
|
synthesizePoBoxRow,
|
|
31
31
|
type PoBoxBaseTuple,
|
|
32
|
-
} from "
|
|
33
|
-
import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "
|
|
32
|
+
} from "@mailwoman/corpus/synthesizers/po-box"
|
|
33
|
+
import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
|
|
34
|
+
import { TextSpliterator } from "spliterator"
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
37
|
* Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
|
|
@@ -73,16 +74,6 @@ export interface SynthPoBoxAdapterOptions {
|
|
|
73
74
|
militaryRatio?: number
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
function makeRandom(seed: number): () => number {
|
|
77
|
-
let s = seed
|
|
78
|
-
|
|
79
|
-
return () => {
|
|
80
|
-
s = (s * 1_664_525 + 1_013_904_223) % 4_294_967_296
|
|
81
|
-
|
|
82
|
-
return s / 4_294_967_296
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
77
|
export function createSynthPoBoxAdapter(opts: SynthPoBoxAdapterOptions = {}): CorpusAdapter {
|
|
87
78
|
const variantsPerInput = opts.variantsPerInput ?? 1
|
|
88
79
|
const pmbRatio = opts.pmbRatio ?? 0.15
|
|
@@ -95,10 +86,10 @@ export function createSynthPoBoxAdapter(opts: SynthPoBoxAdapterOptions = {}): Co
|
|
|
95
86
|
"Synthetic PO box / PMB / Apartado / Boîte Postale rows. Consumes JSONL of (locality, region, postcode, country) tuples and emits locale-appropriate PO box variants.",
|
|
96
87
|
|
|
97
88
|
async *rows(options: AdapterOptions): AsyncIterable<CanonicalRow> {
|
|
98
|
-
const random =
|
|
89
|
+
const random = makeLcg(opts.seed ?? Date.now())
|
|
99
90
|
|
|
100
|
-
// TextSpliterator streams string lines; the per-line
|
|
101
|
-
// tolerant of malformed rows (skipped++), so TextSpliterator +
|
|
91
|
+
// TextSpliterator streams string lines; the per-line tryParsingJSON below keeps this reader
|
|
92
|
+
// tolerant of malformed rows (skipped++), so TextSpliterator + a non-throwing parse — not
|
|
102
93
|
// JSONSpliterator, which would throw on the first bad line.
|
|
103
94
|
const lines = TextSpliterator.fromAsync(options.inputPath)
|
|
104
95
|
|
|
@@ -115,11 +106,9 @@ export function createSynthPoBoxAdapter(opts: SynthPoBoxAdapterOptions = {}): Co
|
|
|
115
106
|
|
|
116
107
|
if (!trimmed) continue
|
|
117
108
|
|
|
118
|
-
|
|
109
|
+
const input = tryParsingJSON<PoBoxInputRow>(trimmed)
|
|
119
110
|
|
|
120
|
-
|
|
121
|
-
input = JSON.parse(trimmed) as PoBoxInputRow
|
|
122
|
-
} catch {
|
|
111
|
+
if (input === null) {
|
|
123
112
|
skipped++
|
|
124
113
|
|
|
125
114
|
continue
|
|
@@ -36,9 +36,10 @@
|
|
|
36
36
|
|
|
37
37
|
import { DatabaseSync } from "node:sqlite"
|
|
38
38
|
|
|
39
|
-
import { lookupFipsState } from "
|
|
40
|
-
import {
|
|
41
|
-
import
|
|
39
|
+
import { lookupFipsState } from "@mailwoman/corpus/codex/us-fips-state"
|
|
40
|
+
import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
|
|
41
|
+
import { formatAddress, reconcileComponents } from "@mailwoman/formatter"
|
|
42
|
+
|
|
42
43
|
import { decomposeStreet } from "./street-decompose.ts"
|
|
43
44
|
|
|
44
45
|
/**
|
|
@@ -17,45 +17,35 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { readFileSync } from "node:fs"
|
|
20
|
-
import { resolve } from "node:path"
|
|
21
20
|
|
|
22
21
|
import { resourceDictionaryPath } from "@mailwoman/core/utils"
|
|
22
|
+
import { TextSpliterator } from "spliterator"
|
|
23
23
|
|
|
24
24
|
function loadDictionary(filename: string): Set<string> {
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
for (const line of text.split("\n")) {
|
|
38
|
-
const trimmed = line.trim()
|
|
39
|
-
|
|
40
|
-
if (!trimmed || trimmed.startsWith("#")) continue
|
|
41
|
-
|
|
42
|
-
// libpostal format: canonical|abbr|abbr|... — index all forms
|
|
43
|
-
for (const form of trimmed.split("|")) {
|
|
44
|
-
const f = form.trim().toLowerCase()
|
|
45
|
-
|
|
46
|
-
if (f) {
|
|
47
|
-
set.add(f)
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
25
|
+
// `resourceDictionaryPath` already resolves both layouts — `core/data/...` from source and from the
|
|
26
|
+
// packaged `out/` tree. The candidate list this replaced named it TWICE and then guessed a third path
|
|
27
|
+
// off `process.cwd()`, and swallowed every error while probing, so a corrupt dictionary reported as a
|
|
28
|
+
// missing one.
|
|
29
|
+
const text = readFileSync(resourceDictionaryPath("libpostal", "en", filename), "utf8")
|
|
30
|
+
const set = new Set<string>()
|
|
31
|
+
|
|
32
|
+
// The largest libpostal dictionary is 8.4 KB, and this runs once per process at module load.
|
|
33
|
+
for (const line of TextSpliterator.from(text)) {
|
|
34
|
+
const trimmed = line.trim()
|
|
35
|
+
|
|
36
|
+
if (!trimmed || trimmed.startsWith("#")) continue
|
|
51
37
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
38
|
+
// libpostal format: canonical|abbr|abbr|... — index all forms
|
|
39
|
+
for (const form of trimmed.split("|")) {
|
|
40
|
+
const f = form.trim().toLowerCase()
|
|
41
|
+
|
|
42
|
+
if (f) {
|
|
43
|
+
set.add(f)
|
|
44
|
+
}
|
|
55
45
|
}
|
|
56
46
|
}
|
|
57
47
|
|
|
58
|
-
|
|
48
|
+
return set
|
|
59
49
|
}
|
|
60
50
|
|
|
61
51
|
const DIRECTIONALS = loadDictionary("directionals.txt")
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* Federally Qualified Health Centers (FQHCs) are HRSA-funded community health programs that
|
|
9
9
|
* self-report site addresses to the HRSA Data Warehouse. The published CSV (`data.hrsa.gov`)
|
|
10
10
|
* carries the site name, the postal-formatted street address, and the locality/region/postcode
|
|
11
|
-
* quad.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* quad. The source earns its place on adversarial-value-per-row (#22): every facility name is a
|
|
12
|
+
* human-typed venue string and the addresses pass through enough hands to accumulate the
|
|
13
|
+
* abbreviation drift + suite designator chaos that pure gazetteer data does not.
|
|
14
14
|
*
|
|
15
15
|
* The adapter consumes a CSV file the operator pre-downloads. The HRSA data is published as a
|
|
16
16
|
* single national CSV (~10K rows), small enough that the operator can re-fetch on every corpus
|
|
@@ -29,14 +29,11 @@
|
|
|
29
29
|
* terms.
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
import {
|
|
33
|
-
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
import {
|
|
37
|
-
import { lookupStateAbbreviation } from "../../codex/us-fips-state.ts"
|
|
38
|
-
import { reconcileComponents } from "../../format.ts"
|
|
39
|
-
import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
|
|
32
|
+
import { splitStreetLine, stableSourceID } from "@mailwoman/corpus/adapters/utils"
|
|
33
|
+
import { lookupStateAbbreviation } from "@mailwoman/corpus/codex/us-fips-state"
|
|
34
|
+
import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
|
|
35
|
+
import { reconcileComponents } from "@mailwoman/formatter"
|
|
36
|
+
import { CSVSpliterator } from "spliterator"
|
|
40
37
|
|
|
41
38
|
/**
|
|
42
39
|
* Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
|
|
@@ -70,23 +67,11 @@ interface HrsaSiteRow {
|
|
|
70
67
|
* Split a "123 Main St Suite 4" surface form into `(house_number, street)`. The regex tolerates one trailing letter on
|
|
71
68
|
* the number (`"123A Main St"`) and a hyphenated form (`"40-12 Bell Blvd"`); anything else falls back to street-only.
|
|
72
69
|
*
|
|
73
|
-
* Suite / Apt / Unit designators stay on `street`
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
70
|
+
* Suite / Apt / Unit designators stay on `street` — Mailwoman's `unit` component exists but the address-formatter does
|
|
71
|
+
* not have a clean slot for it, and HRSA addresses do not separate the suite into its own column. Leaving the surface
|
|
72
|
+
* form intact in `street` preserves the adversarial training signal (the model learns that a trailing "Suite 4" is part
|
|
73
|
+
* of the road line in this distribution).
|
|
77
74
|
*/
|
|
78
|
-
const HOUSE_NUMBER_PREFIX = /^(\d+(?:-\d+)?[A-Za-z]?)\s+(.+)$/
|
|
79
|
-
|
|
80
|
-
function splitAddress(address: string): { house_number?: string; street: string } | null {
|
|
81
|
-
const trimmed = address.trim()
|
|
82
|
-
|
|
83
|
-
if (!trimmed) return null
|
|
84
|
-
const m = HOUSE_NUMBER_PREFIX.exec(trimmed)
|
|
85
|
-
|
|
86
|
-
if (m) return { house_number: m[1], street: m[2]!.trim() }
|
|
87
|
-
|
|
88
|
-
return { street: trimmed }
|
|
89
|
-
}
|
|
90
75
|
|
|
91
76
|
/**
|
|
92
77
|
* Compose the raw envelope-style address line. Format:
|
|
@@ -122,78 +107,69 @@ export function createUsgovHrsaFqhcAdapter(): CorpusAdapter {
|
|
|
122
107
|
throw new Error(`usgov-hrsa-fqhc adapter: only US supported, got country=${opts.country}`)
|
|
123
108
|
}
|
|
124
109
|
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
skip_empty_lines: true,
|
|
131
|
-
relax_quotes: true,
|
|
132
|
-
relax_column_count: true,
|
|
133
|
-
})
|
|
134
|
-
)
|
|
110
|
+
const rows = CSVSpliterator.fromAsync(opts.inputPath, {
|
|
111
|
+
mode: "object",
|
|
112
|
+
normalizeKeys: false,
|
|
113
|
+
enableQuoteHandling: true,
|
|
114
|
+
})
|
|
135
115
|
|
|
136
116
|
let emitted = 0
|
|
137
117
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const raw = composeRaw(venue, split.house_number, split.street, city, state.abbreviation, postcode)
|
|
118
|
+
for await (const record of rows as AsyncIterable<HrsaSiteRow>) {
|
|
119
|
+
if (opts.signal?.aborted) break
|
|
120
|
+
|
|
121
|
+
if (opts.limit !== undefined && emitted >= opts.limit) break
|
|
122
|
+
|
|
123
|
+
const venue = (record["Site Name"] ?? "").trim()
|
|
124
|
+
const split = splitStreetLine(record["Site Address"] ?? "")
|
|
125
|
+
const city = (record["Site City"] ?? "").trim()
|
|
126
|
+
const stateAbbr = (record["Site State Abbreviation"] ?? "").trim()
|
|
127
|
+
const postcode = (record["Site Postal Code"] ?? "").trim()
|
|
128
|
+
|
|
129
|
+
if (!venue || !split || !city || !postcode) continue
|
|
130
|
+
const state = lookupStateAbbreviation(stateAbbr)
|
|
131
|
+
|
|
132
|
+
if (!state) continue
|
|
133
|
+
|
|
134
|
+
// Insertion order matters here. `venue` first so alignment claims its span
|
|
135
|
+
// (which may contain a token like "Buffalo") before `locality` runs its
|
|
136
|
+
// search — the kryptonite case `Buffalo Health Clinic, Buffalo NY`
|
|
137
|
+
// otherwise mis-labels the venue's "Buffalo" as locality.
|
|
138
|
+
const components: CanonicalRow["components"] = {
|
|
139
|
+
venue,
|
|
140
|
+
...(split.house_number ? { house_number: split.house_number } : {}),
|
|
141
|
+
street: split.street,
|
|
142
|
+
locality: city,
|
|
143
|
+
region: state.abbreviation,
|
|
144
|
+
postcode,
|
|
145
|
+
}
|
|
169
146
|
|
|
170
|
-
|
|
147
|
+
const raw = composeRaw(venue, split.house_number, split.street, city, state.abbreviation, postcode)
|
|
171
148
|
|
|
172
|
-
|
|
149
|
+
if (!raw) continue
|
|
173
150
|
|
|
174
|
-
|
|
151
|
+
const aligned = reconcileComponents(components, raw)
|
|
175
152
|
|
|
176
|
-
|
|
153
|
+
if (!Object.keys(aligned).length) continue
|
|
177
154
|
|
|
178
|
-
|
|
179
|
-
? `${USGOV_HRSA_FQHC_ADAPTER_ID}-${siteID}`
|
|
180
|
-
: stableSourceID(USGOV_HRSA_FQHC_ADAPTER_ID, aligned)
|
|
155
|
+
const siteID = (record["Site ID"] ?? "").trim()
|
|
181
156
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
country: "US",
|
|
186
|
-
locale: "en-US",
|
|
187
|
-
source: USGOV_HRSA_FQHC_ADAPTER_ID,
|
|
188
|
-
source_id: sourceID,
|
|
189
|
-
corpus_version: "",
|
|
190
|
-
license: USGOV_HRSA_FQHC_DEFAULT_LICENSE,
|
|
191
|
-
}
|
|
157
|
+
const sourceID = siteID
|
|
158
|
+
? `${USGOV_HRSA_FQHC_ADAPTER_ID}-${siteID}`
|
|
159
|
+
: stableSourceID(USGOV_HRSA_FQHC_ADAPTER_ID, aligned)
|
|
192
160
|
|
|
193
|
-
|
|
161
|
+
yield {
|
|
162
|
+
raw,
|
|
163
|
+
components: aligned,
|
|
164
|
+
country: "US",
|
|
165
|
+
locale: "en-US",
|
|
166
|
+
source: USGOV_HRSA_FQHC_ADAPTER_ID,
|
|
167
|
+
source_id: sourceID,
|
|
168
|
+
corpus_version: "",
|
|
169
|
+
license: USGOV_HRSA_FQHC_DEFAULT_LICENSE,
|
|
194
170
|
}
|
|
195
|
-
|
|
196
|
-
|
|
171
|
+
|
|
172
|
+
emitted++
|
|
197
173
|
}
|
|
198
174
|
},
|
|
199
175
|
}
|