@mailwoman/corpus 9.0.0 → 9.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (524) hide show
  1. package/README.md +3 -3
  2. package/data/PROVENANCE.md +227 -0
  3. package/data/reviewed-ve-postcode-tuples.json +74 -0
  4. package/data/sub-venue-lexicon.json +18269 -0
  5. package/out/src/adapters/ban/adapter.d.ts +1 -1
  6. package/out/src/adapters/ban/adapter.d.ts.map +1 -1
  7. package/out/src/adapters/ban/adapter.js +5 -4
  8. package/out/src/adapters/ban/adapter.js.map +1 -1
  9. package/out/src/adapters/fcc-bdc/adapter.d.ts +1 -1
  10. package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
  11. package/out/src/adapters/fcc-bdc/adapter.js +3 -3
  12. package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
  13. package/out/src/adapters/geonames/adapter.d.ts +1 -1
  14. package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
  15. package/out/src/adapters/geonames/adapter.js +2 -2
  16. package/out/src/adapters/geonames/adapter.js.map +1 -1
  17. package/out/src/adapters/geonames-postal/adapter.d.ts +1 -1
  18. package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
  19. package/out/src/adapters/geonames-postal/adapter.js +3 -3
  20. package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
  21. package/out/src/adapters/gnaf/adapter.d.ts +1 -1
  22. package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
  23. package/out/src/adapters/gnaf/adapter.js +2 -2
  24. package/out/src/adapters/gnaf/adapter.js.map +1 -1
  25. package/out/src/adapters/gnaf/assemble.js +1 -1
  26. package/out/src/adapters/gnaf/assemble.js.map +1 -1
  27. package/out/src/adapters/index.d.ts +1 -1
  28. package/out/src/adapters/index.d.ts.map +1 -1
  29. package/out/src/adapters/index.js +1 -1
  30. package/out/src/adapters/index.js.map +1 -1
  31. package/out/src/adapters/openaddresses/adapter.d.ts +1 -1
  32. package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
  33. package/out/src/adapters/openaddresses/adapter.js +3 -3
  34. package/out/src/adapters/openaddresses/adapter.js.map +1 -1
  35. package/out/src/adapters/overture/adapter.d.ts +1 -1
  36. package/out/src/adapters/overture/adapter.d.ts.map +1 -1
  37. package/out/src/adapters/overture/adapter.js +2 -2
  38. package/out/src/adapters/overture/adapter.js.map +1 -1
  39. package/out/src/adapters/state-hi-schools/adapter.d.ts +1 -1
  40. package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
  41. package/out/src/adapters/state-hi-schools/adapter.js +7 -6
  42. package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
  43. package/out/src/adapters/state-ia-contractors/adapter.d.ts +1 -1
  44. package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
  45. package/out/src/adapters/state-ia-contractors/adapter.js +12 -7
  46. package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
  47. package/out/src/adapters/state-ny-notaries/adapter.d.ts +1 -1
  48. package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
  49. package/out/src/adapters/state-ny-notaries/adapter.js +12 -18
  50. package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
  51. package/out/src/adapters/state-tx-notaries/adapter.d.ts +1 -1
  52. package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
  53. package/out/src/adapters/state-tx-notaries/adapter.js +12 -7
  54. package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
  55. package/out/src/adapters/synth-po-box/adapter.d.ts +3 -3
  56. package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
  57. package/out/src/adapters/synth-po-box/adapter.js +3 -3
  58. package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
  59. package/out/src/adapters/tiger/adapter.d.ts +1 -1
  60. package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
  61. package/out/src/adapters/tiger/adapter.js +2 -2
  62. package/out/src/adapters/tiger/adapter.js.map +1 -1
  63. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +1 -1
  64. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
  65. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +7 -6
  66. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
  67. package/out/src/adapters/usgov-imls-pls/adapter.d.ts +1 -1
  68. package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
  69. package/out/src/adapters/usgov-imls-pls/adapter.js +11 -7
  70. package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
  71. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +1 -1
  72. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
  73. package/out/src/adapters/usgov-irs-bmf/adapter.js +6 -5
  74. package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
  75. package/out/src/adapters/usgov-nad/adapter.d.ts +1 -1
  76. package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
  77. package/out/src/adapters/usgov-nad/adapter.js +8 -8
  78. package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
  79. package/out/src/adapters/usgov-nppes/adapter.d.ts +1 -1
  80. package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
  81. package/out/src/adapters/usgov-nppes/adapter.js +10 -10
  82. package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
  83. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +1 -1
  84. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
  85. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +7 -6
  86. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
  87. package/out/src/{adapter.d.ts → adapters/utils/index.d.ts} +8 -2
  88. package/out/src/adapters/utils/index.d.ts.map +1 -0
  89. package/out/src/{adapter.js → adapters/utils/index.js} +11 -3
  90. package/out/src/adapters/utils/index.js.map +1 -0
  91. package/out/src/adapters/wof-admin-jp/adapter.d.ts +1 -1
  92. package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
  93. package/out/src/adapters/wof-admin-jp/adapter.js +5 -5
  94. package/out/src/adapters/wof-admin-jp/adapter.js.map +1 -1
  95. package/out/src/adapters/wof-admin-json/adapter.d.ts +4 -15
  96. package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
  97. package/out/src/adapters/wof-admin-json/adapter.js +11 -35
  98. package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
  99. package/out/src/adapters/wof-json-rows.d.ts +32 -0
  100. package/out/src/adapters/wof-json-rows.d.ts.map +1 -0
  101. package/out/src/adapters/wof-json-rows.js +45 -0
  102. package/out/src/adapters/wof-json-rows.js.map +1 -0
  103. package/out/src/adapters/wof-postalcode-json/adapter.d.ts +4 -9
  104. package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
  105. package/out/src/adapters/wof-postalcode-json/adapter.js +12 -37
  106. package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
  107. package/out/src/build.d.ts +4 -4
  108. package/out/src/build.d.ts.map +1 -1
  109. package/out/src/build.js +7 -7
  110. package/out/src/build.js.map +1 -1
  111. package/out/src/index.d.ts +3 -17
  112. package/out/src/index.d.ts.map +1 -1
  113. package/out/src/index.js +3 -17
  114. package/out/src/index.js.map +1 -1
  115. package/out/src/name-prone-us-suffixes.d.ts +12 -0
  116. package/out/src/name-prone-us-suffixes.d.ts.map +1 -0
  117. package/out/src/name-prone-us-suffixes.js +12 -0
  118. package/out/src/name-prone-us-suffixes.js.map +1 -0
  119. package/out/src/parquet-wrapper/reader.d.ts.map +1 -1
  120. package/out/src/parquet-wrapper/reader.js +5 -0
  121. package/out/src/parquet-wrapper/reader.js.map +1 -1
  122. package/out/src/runner.d.ts +2 -2
  123. package/out/src/runner.d.ts.map +1 -1
  124. package/out/src/runner.js +1 -1
  125. package/out/src/runner.js.map +1 -1
  126. package/out/src/shard-recipes/anchor-absorption.d.ts.map +1 -1
  127. package/out/src/shard-recipes/anchor-absorption.js +4 -5
  128. package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
  129. package/out/src/shard-recipes/bare-country.d.ts +25 -0
  130. package/out/src/shard-recipes/bare-country.d.ts.map +1 -0
  131. package/out/src/shard-recipes/bare-country.js +87 -0
  132. package/out/src/shard-recipes/bare-country.js.map +1 -0
  133. package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
  134. package/out/src/shard-recipes/boundary-stress.js +2 -2
  135. package/out/src/shard-recipes/boundary-stress.js.map +1 -1
  136. package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
  137. package/out/src/shard-recipes/country-balanced.js +14 -21
  138. package/out/src/shard-recipes/country-balanced.js.map +1 -1
  139. package/out/src/shard-recipes/cz-pcfirst-preposition.d.ts.map +1 -1
  140. package/out/src/shard-recipes/cz-pcfirst-preposition.js +28 -10
  141. package/out/src/shard-recipes/cz-pcfirst-preposition.js.map +1 -1
  142. package/out/src/shard-recipes/fr-admin-split.d.ts.map +1 -1
  143. package/out/src/shard-recipes/fr-admin-split.js +4 -3
  144. package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
  145. package/out/src/shard-recipes/fr-bare-street.d.ts.map +1 -1
  146. package/out/src/shard-recipes/fr-bare-street.js +72 -11
  147. package/out/src/shard-recipes/fr-bare-street.js.map +1 -1
  148. package/out/src/shard-recipes/fr-lieudit.d.ts.map +1 -1
  149. package/out/src/shard-recipes/fr-lieudit.js +4 -3
  150. package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
  151. package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
  152. package/out/src/shard-recipes/fr-order.js +11 -20
  153. package/out/src/shard-recipes/fr-order.js.map +1 -1
  154. package/out/src/shard-recipes/german.d.ts.map +1 -1
  155. package/out/src/shard-recipes/german.js +8 -14
  156. package/out/src/shard-recipes/german.js.map +1 -1
  157. package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
  158. package/out/src/shard-recipes/house-venue.js +1 -1
  159. package/out/src/shard-recipes/house-venue.js.map +1 -1
  160. package/out/src/shard-recipes/index.d.ts.map +1 -1
  161. package/out/src/shard-recipes/index.js +8 -1
  162. package/out/src/shard-recipes/index.js.map +1 -1
  163. package/out/src/shard-recipes/intersection.d.ts.map +1 -1
  164. package/out/src/shard-recipes/intersection.js +7 -13
  165. package/out/src/shard-recipes/intersection.js.map +1 -1
  166. package/out/src/shard-recipes/locale.d.ts +5 -5
  167. package/out/src/shard-recipes/locale.d.ts.map +1 -1
  168. package/out/src/shard-recipes/locale.js +13 -20
  169. package/out/src/shard-recipes/locale.js.map +1 -1
  170. package/out/src/shard-recipes/no-street.d.ts.map +1 -1
  171. package/out/src/shard-recipes/no-street.js +1 -1
  172. package/out/src/shard-recipes/no-street.js.map +1 -1
  173. package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
  174. package/out/src/shard-recipes/po-box-cedex.js +60 -43
  175. package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
  176. package/out/src/shard-recipes/po-box.d.ts.map +1 -1
  177. package/out/src/shard-recipes/po-box.js +1 -1
  178. package/out/src/shard-recipes/po-box.js.map +1 -1
  179. package/out/src/shard-recipes/reviewed-postcode-tail.d.ts +47 -0
  180. package/out/src/shard-recipes/reviewed-postcode-tail.d.ts.map +1 -0
  181. package/out/src/shard-recipes/reviewed-postcode-tail.js +125 -0
  182. package/out/src/shard-recipes/reviewed-postcode-tail.js.map +1 -0
  183. package/out/src/shard-recipes/scaffold.d.ts +51 -23
  184. package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
  185. package/out/src/shard-recipes/scaffold.js +59 -23
  186. package/out/src/shard-recipes/scaffold.js.map +1 -1
  187. package/out/src/shard-recipes/street-affix.d.ts +54 -0
  188. package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
  189. package/out/src/shard-recipes/street-affix.js +203 -35
  190. package/out/src/shard-recipes/street-affix.js.map +1 -1
  191. package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
  192. package/out/src/shard-recipes/street-bare.js +3 -3
  193. package/out/src/shard-recipes/street-bare.js.map +1 -1
  194. package/out/src/shard-recipes/street.d.ts.map +1 -1
  195. package/out/src/shard-recipes/street.js +2 -2
  196. package/out/src/shard-recipes/street.js.map +1 -1
  197. package/out/src/shard-recipes/sub-venue-sources.d.ts +3 -6
  198. package/out/src/shard-recipes/sub-venue-sources.d.ts.map +1 -1
  199. package/out/src/shard-recipes/sub-venue-sources.js +4 -9
  200. package/out/src/shard-recipes/sub-venue-sources.js.map +1 -1
  201. package/out/src/shard-recipes/sub-venue.d.ts +2 -2
  202. package/out/src/shard-recipes/sub-venue.d.ts.map +1 -1
  203. package/out/src/shard-recipes/sub-venue.js +7 -6
  204. package/out/src/shard-recipes/sub-venue.js.map +1 -1
  205. package/out/src/shard-recipes/trailing-region.d.ts +74 -0
  206. package/out/src/shard-recipes/trailing-region.d.ts.map +1 -0
  207. package/out/src/shard-recipes/trailing-region.js +157 -0
  208. package/out/src/shard-recipes/trailing-region.js.map +1 -0
  209. package/out/src/shard-recipes/unit.d.ts.map +1 -1
  210. package/out/src/shard-recipes/unit.js +6 -12
  211. package/out/src/shard-recipes/unit.js.map +1 -1
  212. package/out/src/{synthesize-anchor-absorption.d.ts → synthesizers/anchor-absorption.d.ts} +1 -1
  213. package/out/src/synthesizers/anchor-absorption.d.ts.map +1 -0
  214. package/out/src/{synthesize-anchor-absorption.js → synthesizers/anchor-absorption.js} +1 -1
  215. package/out/src/synthesizers/anchor-absorption.js.map +1 -0
  216. package/out/src/{synthesize-boundary-stress.d.ts → synthesizers/boundary-stress.d.ts} +3 -3
  217. package/out/src/synthesizers/boundary-stress.d.ts.map +1 -0
  218. package/out/src/{synthesize-boundary-stress.js → synthesizers/boundary-stress.js} +2 -2
  219. package/out/src/synthesizers/boundary-stress.js.map +1 -0
  220. package/out/src/{synthesize-german.d.ts → synthesizers/german.d.ts} +2 -2
  221. package/out/src/synthesizers/german.d.ts.map +1 -0
  222. package/out/src/{synthesize-german.js → synthesizers/german.js} +2 -2
  223. package/out/src/synthesizers/german.js.map +1 -0
  224. package/out/src/{synthesize-house-venue.d.ts → synthesizers/house-venue.d.ts} +4 -4
  225. package/out/src/synthesizers/house-venue.d.ts.map +1 -0
  226. package/out/src/{synthesize-house-venue.js → synthesizers/house-venue.js} +20 -6
  227. package/out/src/synthesizers/house-venue.js.map +1 -0
  228. package/out/src/{synthesize-intersection.d.ts → synthesizers/intersection.d.ts} +2 -2
  229. package/out/src/synthesizers/intersection.d.ts.map +1 -0
  230. package/out/src/{synthesize-intersection.js → synthesizers/intersection.js} +1 -1
  231. package/out/src/synthesizers/intersection.js.map +1 -0
  232. package/out/src/{synthesize-no-street.d.ts → synthesizers/no-street.d.ts} +3 -3
  233. package/out/src/synthesizers/no-street.d.ts.map +1 -0
  234. package/out/src/{synthesize-no-street.js → synthesizers/no-street.js} +2 -2
  235. package/out/src/synthesizers/no-street.js.map +1 -0
  236. package/out/src/{synthesize-po-box.d.ts → synthesizers/po-box.d.ts} +2 -2
  237. package/out/src/synthesizers/po-box.d.ts.map +1 -0
  238. package/out/src/{synthesize-po-box.js → synthesizers/po-box.js} +1 -1
  239. package/out/src/synthesizers/po-box.js.map +1 -0
  240. package/out/src/{synthesize-street.d.ts → synthesizers/street.d.ts} +2 -2
  241. package/out/src/synthesizers/street.d.ts.map +1 -0
  242. package/out/src/{synthesize-street.js → synthesizers/street.js} +4 -3
  243. package/out/src/synthesizers/street.js.map +1 -0
  244. package/out/src/{synthesize.d.ts → synthesizers/utils.d.ts} +3 -3
  245. package/out/src/synthesizers/utils.d.ts.map +1 -0
  246. package/out/src/{synthesize.js → synthesizers/utils.js} +5 -4
  247. package/out/src/synthesizers/utils.js.map +1 -0
  248. package/out/src/tools/align-shard.d.ts.map +1 -1
  249. package/out/src/tools/align-shard.js +2 -2
  250. package/out/src/tools/align-shard.js.map +1 -1
  251. package/out/src/tools/fetch/ban.d.ts.map +1 -1
  252. package/out/src/tools/fetch/ban.js +2 -18
  253. package/out/src/tools/fetch/ban.js.map +1 -1
  254. package/out/src/tools/fetch/download.d.ts +12 -3
  255. package/out/src/tools/fetch/download.d.ts.map +1 -1
  256. package/out/src/tools/fetch/download.js +20 -4
  257. package/out/src/tools/fetch/download.js.map +1 -1
  258. package/out/src/tools/fetch/geonames-dump.d.ts +87 -0
  259. package/out/src/tools/fetch/geonames-dump.d.ts.map +1 -0
  260. package/out/src/tools/fetch/geonames-dump.js +178 -0
  261. package/out/src/tools/fetch/geonames-dump.js.map +1 -0
  262. package/out/src/tools/fetch/geonames-postal.d.ts +76 -0
  263. package/out/src/tools/fetch/geonames-postal.d.ts.map +1 -0
  264. package/out/src/tools/fetch/geonames-postal.js +125 -0
  265. package/out/src/tools/fetch/geonames-postal.js.map +1 -0
  266. package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
  267. package/out/src/tools/fetch/imls-pls.js +5 -17
  268. package/out/src/tools/fetch/imls-pls.js.map +1 -1
  269. package/out/src/tools/fetch/index.d.ts +11 -0
  270. package/out/src/tools/fetch/index.d.ts.map +1 -1
  271. package/out/src/tools/fetch/index.js +11 -0
  272. package/out/src/tools/fetch/index.js.map +1 -1
  273. package/out/src/tools/fetch/nad.d.ts.map +1 -1
  274. package/out/src/tools/fetch/nad.js +20 -11
  275. package/out/src/tools/fetch/nad.js.map +1 -1
  276. package/out/src/tools/fetch/nppes.d.ts.map +1 -1
  277. package/out/src/tools/fetch/nppes.js +17 -22
  278. package/out/src/tools/fetch/nppes.js.map +1 -1
  279. package/out/src/tools/fetch/openaddresses.d.ts.map +1 -1
  280. package/out/src/tools/fetch/openaddresses.js +18 -17
  281. package/out/src/tools/fetch/openaddresses.js.map +1 -1
  282. package/out/src/tools/fetch/ourairports.d.ts.map +1 -1
  283. package/out/src/tools/fetch/ourairports.js +7 -2
  284. package/out/src/tools/fetch/ourairports.js.map +1 -1
  285. package/out/src/tools/fetch/ppd.d.ts +0 -4
  286. package/out/src/tools/fetch/ppd.d.ts.map +1 -1
  287. package/out/src/tools/fetch/ppd.js +1 -1
  288. package/out/src/tools/fetch/ppd.js.map +1 -1
  289. package/out/src/tools/fetch/state-hi-schools.d.ts.map +1 -1
  290. package/out/src/tools/fetch/state-hi-schools.js +3 -19
  291. package/out/src/tools/fetch/state-hi-schools.js.map +1 -1
  292. package/out/src/tools/fetch/state-sources.d.ts +4 -0
  293. package/out/src/tools/fetch/state-sources.d.ts.map +1 -1
  294. package/out/src/tools/fetch/state-sources.js +1 -5
  295. package/out/src/tools/fetch/state-sources.js.map +1 -1
  296. package/out/src/tools/fetch/tiger-full.d.ts.map +1 -1
  297. package/out/src/tools/fetch/tiger-full.js +15 -21
  298. package/out/src/tools/fetch/tiger-full.js.map +1 -1
  299. package/out/src/tools/golden-expand.d.ts.map +1 -1
  300. package/out/src/tools/golden-expand.js +34 -25
  301. package/out/src/tools/golden-expand.js.map +1 -1
  302. package/out/src/tools/golden-relabel-street.d.ts.map +1 -1
  303. package/out/src/tools/golden-relabel-street.js +4 -77
  304. package/out/src/tools/golden-relabel-street.js.map +1 -1
  305. package/out/src/tools/index.d.ts +2 -2
  306. package/out/src/tools/index.d.ts.map +1 -1
  307. package/out/src/tools/index.js +2 -2
  308. package/out/src/tools/index.js.map +1 -1
  309. package/out/src/tools/ingest-csv.d.ts.map +1 -1
  310. package/out/src/tools/ingest-csv.js +0 -11
  311. package/out/src/tools/ingest-csv.js.map +1 -1
  312. package/out/src/tools/overlay-manifest.d.ts +4 -0
  313. package/out/src/tools/overlay-manifest.d.ts.map +1 -1
  314. package/out/src/tools/overlay-manifest.js +16 -6
  315. package/out/src/tools/overlay-manifest.js.map +1 -1
  316. package/out/src/tools/postcode-triples.d.ts +175 -0
  317. package/out/src/tools/postcode-triples.d.ts.map +1 -0
  318. package/out/src/tools/postcode-triples.js +304 -0
  319. package/out/src/tools/postcode-triples.js.map +1 -0
  320. package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
  321. package/out/src/tools/shard-kryptonite.js +1 -3
  322. package/out/src/tools/shard-kryptonite.js.map +1 -1
  323. package/out/src/tools/shard-translit.d.ts.map +1 -1
  324. package/out/src/tools/shard-translit.js +4 -27
  325. package/out/src/tools/shard-translit.js.map +1 -1
  326. package/out/src/tools/sub-venue/harvest.d.ts +100 -0
  327. package/out/src/tools/sub-venue/harvest.d.ts.map +1 -0
  328. package/out/src/tools/sub-venue/harvest.js +168 -0
  329. package/out/src/tools/sub-venue/harvest.js.map +1 -0
  330. package/out/src/tools/sub-venue/head-nouns.d.ts +50 -0
  331. package/out/src/tools/sub-venue/head-nouns.d.ts.map +1 -0
  332. package/out/src/tools/sub-venue/head-nouns.js +210 -0
  333. package/out/src/tools/sub-venue/head-nouns.js.map +1 -0
  334. package/out/src/tools/sub-venue/surfaces.d.ts +45 -0
  335. package/out/src/tools/sub-venue/surfaces.d.ts.map +1 -0
  336. package/out/src/tools/sub-venue/surfaces.js +77 -0
  337. package/out/src/tools/sub-venue/surfaces.js.map +1 -0
  338. package/out/src/tools/sub-venue/table.d.ts +229 -0
  339. package/out/src/tools/sub-venue/table.d.ts.map +1 -0
  340. package/out/src/tools/sub-venue/table.js +108 -0
  341. package/out/src/tools/sub-venue/table.js.map +1 -0
  342. package/out/src/tools/sub-venue/wikidata.d.ts +26 -0
  343. package/out/src/tools/sub-venue/wikidata.d.ts.map +1 -0
  344. package/out/src/tools/sub-venue/wikidata.js +62 -0
  345. package/out/src/tools/sub-venue/wikidata.js.map +1 -0
  346. package/out/src/tools/sub-venue-lexicon.d.ts +27 -378
  347. package/out/src/tools/sub-venue-lexicon.d.ts.map +1 -1
  348. package/out/src/tools/sub-venue-lexicon.js +30 -565
  349. package/out/src/tools/sub-venue-lexicon.js.map +1 -1
  350. package/out/src/{align.d.ts → utils/align.d.ts} +1 -1
  351. package/out/src/utils/align.d.ts.map +1 -0
  352. package/out/src/utils/align.js.map +1 -0
  353. package/out/src/utils/golden.d.ts.map +1 -0
  354. package/out/src/{golden.js → utils/golden.js} +2 -2
  355. package/out/src/utils/golden.js.map +1 -0
  356. package/out/src/utils/index.d.ts +14 -0
  357. package/out/src/utils/index.d.ts.map +1 -0
  358. package/out/src/utils/index.js +14 -0
  359. package/out/src/utils/index.js.map +1 -0
  360. package/out/src/utils/license.d.ts.map +1 -0
  361. package/out/src/{license.js → utils/license.js} +1 -1
  362. package/out/src/utils/license.js.map +1 -0
  363. package/out/src/{parquet.d.ts → utils/parquet.d.ts} +24 -5
  364. package/out/src/utils/parquet.d.ts.map +1 -0
  365. package/out/src/{parquet.js → utils/parquet.js} +6 -3
  366. package/out/src/utils/parquet.js.map +1 -0
  367. package/out/src/{split.d.ts → utils/split.d.ts} +1 -1
  368. package/out/src/utils/split.d.ts.map +1 -0
  369. package/out/src/{split.js → utils/split.js} +2 -2
  370. package/out/src/utils/split.js.map +1 -0
  371. package/out/src/utils/tokenize.d.ts.map +1 -0
  372. package/out/src/utils/tokenize.js.map +1 -0
  373. package/out/src/utils/wof-json.d.ts.map +1 -0
  374. package/out/src/utils/wof-json.js.map +1 -0
  375. package/package.json +287 -21
  376. package/src/adapters/ban/adapter.ts +7 -5
  377. package/src/adapters/fcc-bdc/adapter.ts +5 -4
  378. package/src/adapters/geonames/adapter.ts +3 -3
  379. package/src/adapters/geonames-postal/adapter.ts +4 -4
  380. package/src/adapters/gnaf/adapter.ts +3 -3
  381. package/src/adapters/gnaf/assemble.ts +1 -1
  382. package/src/adapters/index.ts +3 -2
  383. package/src/adapters/openaddresses/adapter.ts +4 -4
  384. package/src/adapters/overture/adapter.ts +3 -3
  385. package/src/adapters/state-hi-schools/adapter.ts +8 -7
  386. package/src/adapters/state-ia-contractors/adapter.ts +13 -8
  387. package/src/adapters/state-ny-notaries/adapter.ts +13 -32
  388. package/src/adapters/state-tx-notaries/adapter.ts +13 -8
  389. package/src/adapters/synth-po-box/adapter.ts +4 -4
  390. package/src/adapters/tiger/adapter.ts +5 -3
  391. package/src/adapters/usgov-hrsa-fqhc/adapter.ts +8 -7
  392. package/src/adapters/usgov-imls-pls/adapter.ts +12 -8
  393. package/src/adapters/usgov-irs-bmf/adapter.ts +7 -6
  394. package/src/adapters/usgov-nad/adapter.ts +9 -9
  395. package/src/adapters/usgov-nppes/adapter.ts +13 -12
  396. package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +8 -7
  397. package/src/{adapter.ts → adapters/utils/index.ts} +15 -3
  398. package/src/adapters/wof-admin-jp/adapter.ts +9 -12
  399. package/src/adapters/wof-admin-json/adapter.ts +15 -54
  400. package/src/adapters/wof-json-rows.ts +79 -0
  401. package/src/adapters/wof-postalcode-json/adapter.ts +16 -50
  402. package/src/build.ts +8 -8
  403. package/src/index.ts +3 -17
  404. package/src/name-prone-us-suffixes.ts +12 -0
  405. package/src/parquet-wrapper/reader.ts +9 -0
  406. package/src/runner.ts +2 -2
  407. package/src/shard-recipes/anchor-absorption.ts +5 -5
  408. package/src/shard-recipes/bare-country.ts +95 -0
  409. package/src/shard-recipes/boundary-stress.ts +3 -2
  410. package/src/shard-recipes/country-balanced.ts +16 -27
  411. package/src/shard-recipes/cz-pcfirst-preposition.ts +29 -10
  412. package/src/shard-recipes/fr-admin-split.ts +6 -4
  413. package/src/shard-recipes/fr-bare-street.ts +85 -10
  414. package/src/shard-recipes/fr-lieudit.ts +6 -4
  415. package/src/shard-recipes/fr-order.ts +13 -26
  416. package/src/shard-recipes/german.ts +9 -18
  417. package/src/shard-recipes/house-venue.ts +2 -1
  418. package/src/shard-recipes/index.ts +8 -1
  419. package/src/shard-recipes/intersection.ts +9 -17
  420. package/src/shard-recipes/locale.ts +16 -24
  421. package/src/shard-recipes/no-street.ts +2 -1
  422. package/src/shard-recipes/po-box-cedex.ts +76 -58
  423. package/src/shard-recipes/po-box.ts +2 -1
  424. package/src/shard-recipes/reviewed-postcode-tail.ts +189 -0
  425. package/src/shard-recipes/scaffold.ts +99 -24
  426. package/src/shard-recipes/street-affix.ts +284 -45
  427. package/src/shard-recipes/street-bare.ts +4 -3
  428. package/src/shard-recipes/street.ts +3 -2
  429. package/src/shard-recipes/sub-venue-sources.ts +13 -23
  430. package/src/shard-recipes/sub-venue.ts +11 -9
  431. package/src/shard-recipes/trailing-region.ts +183 -0
  432. package/src/shard-recipes/unit.ts +8 -17
  433. package/src/{synthesize-boundary-stress.ts → synthesizers/boundary-stress.ts} +2 -2
  434. package/src/{synthesize-german.ts → synthesizers/german.ts} +3 -2
  435. package/src/{synthesize-house-venue.ts → synthesizers/house-venue.ts} +20 -6
  436. package/src/{synthesize-intersection.ts → synthesizers/intersection.ts} +1 -1
  437. package/src/{synthesize-no-street.ts → synthesizers/no-street.ts} +2 -2
  438. package/src/{synthesize-po-box.ts → synthesizers/po-box.ts} +1 -1
  439. package/src/{synthesize-street.ts → synthesizers/street.ts} +5 -3
  440. package/src/{synthesize.ts → synthesizers/utils.ts} +6 -4
  441. package/src/tools/align-shard.ts +3 -2
  442. package/src/tools/fetch/ban.ts +2 -22
  443. package/src/tools/fetch/download.ts +22 -4
  444. package/src/tools/fetch/geonames-dump.ts +267 -0
  445. package/src/tools/fetch/geonames-postal.ts +180 -0
  446. package/src/tools/fetch/imls-pls.ts +6 -20
  447. package/src/tools/fetch/index.ts +11 -0
  448. package/src/tools/fetch/nad.ts +21 -10
  449. package/src/tools/fetch/nppes.ts +17 -23
  450. package/src/tools/fetch/openaddresses.ts +18 -22
  451. package/src/tools/fetch/ourairports.ts +7 -2
  452. package/src/tools/fetch/ppd.ts +1 -1
  453. package/src/tools/fetch/state-hi-schools.ts +3 -23
  454. package/src/tools/fetch/state-sources.ts +1 -1
  455. package/src/tools/fetch/tiger-full.ts +17 -24
  456. package/src/tools/golden-expand.ts +44 -33
  457. package/src/tools/golden-relabel-street.ts +5 -68
  458. package/src/tools/index.ts +2 -2
  459. package/src/tools/ingest-csv.ts +0 -13
  460. package/src/tools/overlay-manifest.ts +20 -8
  461. package/src/tools/postcode-triples.ts +375 -0
  462. package/src/tools/shard-kryptonite.ts +4 -5
  463. package/src/tools/shard-translit.ts +16 -35
  464. package/src/tools/sub-venue/harvest.ts +235 -0
  465. package/src/tools/sub-venue/head-nouns.ts +242 -0
  466. package/src/tools/sub-venue/surfaces.ts +95 -0
  467. package/src/tools/sub-venue/table.ts +281 -0
  468. package/src/tools/sub-venue/wikidata.ts +85 -0
  469. package/src/tools/sub-venue-lexicon.ts +67 -886
  470. package/src/{align.ts → utils/align.ts} +2 -1
  471. package/src/{golden.ts → utils/golden.ts} +2 -3
  472. package/src/utils/index.ts +14 -0
  473. package/src/{license.ts → utils/license.ts} +1 -1
  474. package/src/{parquet.ts → utils/parquet.ts} +22 -9
  475. package/src/{split.ts → utils/split.ts} +3 -3
  476. package/out/src/adapter.d.ts.map +0 -1
  477. package/out/src/adapter.js.map +0 -1
  478. package/out/src/align.d.ts.map +0 -1
  479. package/out/src/align.js.map +0 -1
  480. package/out/src/format.d.ts +0 -14
  481. package/out/src/format.d.ts.map +0 -1
  482. package/out/src/format.js +0 -14
  483. package/out/src/format.js.map +0 -1
  484. package/out/src/golden.d.ts.map +0 -1
  485. package/out/src/golden.js.map +0 -1
  486. package/out/src/license.d.ts.map +0 -1
  487. package/out/src/license.js.map +0 -1
  488. package/out/src/parquet.d.ts.map +0 -1
  489. package/out/src/parquet.js.map +0 -1
  490. package/out/src/split.d.ts.map +0 -1
  491. package/out/src/split.js.map +0 -1
  492. package/out/src/synthesize-anchor-absorption.d.ts.map +0 -1
  493. package/out/src/synthesize-anchor-absorption.js.map +0 -1
  494. package/out/src/synthesize-boundary-stress.d.ts.map +0 -1
  495. package/out/src/synthesize-boundary-stress.js.map +0 -1
  496. package/out/src/synthesize-german.d.ts.map +0 -1
  497. package/out/src/synthesize-german.js.map +0 -1
  498. package/out/src/synthesize-house-venue.d.ts.map +0 -1
  499. package/out/src/synthesize-house-venue.js.map +0 -1
  500. package/out/src/synthesize-intersection.d.ts.map +0 -1
  501. package/out/src/synthesize-intersection.js.map +0 -1
  502. package/out/src/synthesize-no-street.d.ts.map +0 -1
  503. package/out/src/synthesize-no-street.js.map +0 -1
  504. package/out/src/synthesize-po-box.d.ts.map +0 -1
  505. package/out/src/synthesize-po-box.js.map +0 -1
  506. package/out/src/synthesize-street.d.ts.map +0 -1
  507. package/out/src/synthesize-street.js.map +0 -1
  508. package/out/src/synthesize.d.ts.map +0 -1
  509. package/out/src/synthesize.js.map +0 -1
  510. package/out/src/tokenize.d.ts.map +0 -1
  511. package/out/src/tokenize.js.map +0 -1
  512. package/out/src/wof-json.d.ts.map +0 -1
  513. package/out/src/wof-json.js.map +0 -1
  514. package/src/format.ts +0 -14
  515. /package/out/src/{align.js → utils/align.js} +0 -0
  516. /package/out/src/{golden.d.ts → utils/golden.d.ts} +0 -0
  517. /package/out/src/{license.d.ts → utils/license.d.ts} +0 -0
  518. /package/out/src/{tokenize.d.ts → utils/tokenize.d.ts} +0 -0
  519. /package/out/src/{tokenize.js → utils/tokenize.js} +0 -0
  520. /package/out/src/{wof-json.d.ts → utils/wof-json.d.ts} +0 -0
  521. /package/out/src/{wof-json.js → utils/wof-json.js} +0 -0
  522. /package/src/{synthesize-anchor-absorption.ts → synthesizers/anchor-absorption.ts} +0 -0
  523. /package/src/{tokenize.ts → utils/tokenize.ts} +0 -0
  524. /package/src/{wof-json.ts → utils/wof-json.ts} +0 -0
@@ -20,9 +20,25 @@
20
20
  * run including this shard.
21
21
  */
22
22
 
23
+ import { FR_VOIE_TYPES } from "@mailwoman/codex/fr"
24
+
23
25
  import { decomposeFrStreet } from "../adapters/ban/street-decompose.ts"
24
26
  import { alignAndWrite, makeMulberry32, readTuples, type ShardRecipe, shardSourceID } from "./scaffold.ts"
25
27
 
28
+ /**
29
+ * Canonical voie type (lowercase, accent-kept) → its most common written abbreviation, from the codex table's first
30
+ * entry. Types with no attested abbreviation stay canonical in the abbreviated form.
31
+ */
32
+ const FR_VOIE_ABBREV: Record<string, string> = Object.fromEntries(
33
+ Object.entries(FR_VOIE_TYPES).flatMap(([canonical, abbrevs]) => (abbrevs[0] ? [[canonical, abbrevs[0]]] : []))
34
+ )
35
+
36
+ /**
37
+ * The order-cycle slot for the BARE-STREET-ONLY form (`«voie» «name»`, no number, no locality) — the absence
38
+ * counterweight to the locality-terminated comma-free forms (see the cycle comment).
39
+ */
40
+ const BARE_STREET_ONLY_FORM = 3
41
+
26
42
  /**
27
43
  * Shard recipe registered with the corpus builder — see the file header for the parse behaviour it exists to exercise,
28
44
  * and `description` below for the surface form it generates.
@@ -30,7 +46,7 @@ import { alignAndWrite, makeMulberry32, readTuples, type ShardRecipe, shardSourc
30
46
  export const frBareStreetRecipe: ShardRecipe = {
31
47
  name: "fr-bare-street",
32
48
  description:
33
- "FR bare comma-form street+city, NO postcode (#251): '<n> Rue <name>, <City>' — the postcode-anchoring lever",
49
+ "FR bare street+city, NO postcode (#251): comma / comma-free / abbreviated-voie surfaces over one label set",
34
50
  mode: "tuples",
35
51
  async run(opts, write) {
36
52
  // Seeded for parity with the other recipes; unused beyond reproducibility (the tuples drive the content).
@@ -53,23 +69,82 @@ export const frBareStreetRecipe: ShardRecipe = {
53
69
 
54
70
  const { prefix, street } = decomposeFrStreet(fullStreet)
55
71
 
56
- // The failing class is the prefix-led FR street; a no-prefix nom_voie ("La Ville Mois") isn't it.
72
+ // A no-prefix nom_voie ("La Ville Mois") is not the prefix-led class the numbered forms
73
+ // exercise — but as a BARE surface it is exactly the non-voie-led counterweight the v4.5.1
74
+ // probe showed missing ('Savile Row'-shaped spans still fell to the trailing-locality
75
+ // prior; the voie-led bare form protected only voie-led spans). Alternate rows emit the
76
+ // whole span as a bare street; the rest skip as before.
57
77
  if (!prefix || !street) {
78
+ if (read % 2 === 0 && fullStreet.split(" ").length >= 2) {
79
+ const bare = {
80
+ raw: fullStreet,
81
+ components: { street: fullStreet } as Record<string, string>,
82
+ country: "FR",
83
+ locale: "fr-FR",
84
+ source: "synth-fr-bare-street",
85
+ source_id: shardSourceID("synth-fr-bare-street", {
86
+ street: fullStreet,
87
+ f: "bare-nonvoie",
88
+ v: String(read),
89
+ }),
90
+ corpus_version: "0.9.4",
91
+ license:
92
+ "Synthetic — fr-bare-street; (street, number, city) from BAN (Base Adresse Nationale, Licence Ouverte)",
93
+ }
94
+
95
+ if (alignAndWrite(write, bare, "fr-bare-street")) {
96
+ emitted++
97
+ } else {
98
+ skipped++
99
+ }
100
+
101
+ continue
102
+ }
103
+
58
104
  skipped++
59
105
 
60
106
  continue
61
107
  }
62
108
 
63
- const components: Record<string, string> = {
64
- house_number: number,
65
- street_prefix: prefix,
66
- street,
67
- locality,
109
+ // Four surfaces over the same tuple, cycled deterministically. The comma form was the
110
+ // original lever; the COMMA-FREE form is the colloquial register users actually type
111
+ // ('12 rue de Rome Paris' — the street↔locality boundary with NO delimiter, the fr-fr
112
+ // panel's named loss); the ABBREVIATED form is the typeahead register the geocoder-tester
113
+ // FR slice attests at scale; and the BARE-STREET-ONLY form is the absence counterweight —
114
+ // without it, every delimiter-free surface in the mix ENDS in a locality, the model learns
115
+ // "trailing span = locality" as categorical, and bare street names across locales flip to
116
+ // locality wholesale (the v4.5.0 no-promote's measured erosion: 'Calle de Alcalá',
117
+ // 'Madison Square West', and COMER's fork all fell to that prior). Tags are identical
118
+ // where present; each component VALUE is the span as written (BIO alignment binds value
119
+ // to surface); the bare form carries NO number and NO locality because the surface has
120
+ // neither.
121
+ const form = read % 4
122
+ const prefixSurface = form >= 2 ? (FR_VOIE_ABBREV[prefix.toLowerCase()] ?? prefix) : prefix
123
+
124
+ const components: Record<string, string> =
125
+ form === BARE_STREET_ONLY_FORM
126
+ ? { street_prefix: prefix, street }
127
+ : { house_number: number, street_prefix: prefixSurface, street, locality }
128
+
129
+ // When the tuple carries a WOF-attested neighbourhood, the comma slot renders the
130
+ // THREE-slot middle surface — the dependent-locality counterweight (the v4.5.1 erosion's
131
+ // untouched half: the two-slot comma-free endings squeezed the middle tag out).
132
+ const hood = String(t.neighbourhood ?? "").trim()
133
+
134
+ if (form === 0 && hood) {
135
+ components.dependent_locality = hood
68
136
  }
69
137
 
70
- // BARE comma form, number-before (FR's dominant order), NO postcode — the whole point.
71
- const raw = `${number} ${prefix} ${street}, ${locality}`
72
- const source_id = shardSourceID("synth-fr-bare-street", { ...components, v: String(read) })
138
+ const raw =
139
+ form === 0
140
+ ? hood
141
+ ? `${number} ${prefix} ${street}, ${hood}, ${locality}`
142
+ : `${number} ${prefix} ${street}, ${locality}`
143
+ : form === BARE_STREET_ONLY_FORM
144
+ ? `${prefix} ${street}`
145
+ : `${number} ${prefixSurface} ${street} ${locality}`
146
+
147
+ const source_id = shardSourceID("synth-fr-bare-street", { ...components, f: String(form), v: String(read) })
73
148
 
74
149
  const canonical = {
75
150
  raw,
@@ -29,13 +29,15 @@ import { join } from "node:path"
29
29
 
30
30
  import { extractBANAddrPoints } from "@mailwoman/ban/sdk"
31
31
  import { COUNTRY_SURFACE_FORMS } from "@mailwoman/codex/country"
32
+ import { isPresent } from "@mailwoman/core/objects"
32
33
  import type { ComponentTag } from "@mailwoman/core/types"
33
34
  import { dataRootPath } from "@mailwoman/core/utils"
34
35
 
35
- import { stableSourceID } from "../adapter.ts"
36
+ import { stableSourceID } from "#adapters/utils"
37
+ import type { CanonicalRow } from "#types"
38
+ import { alignRow } from "#utils"
39
+
36
40
  import { decomposeFrStreet } from "../adapters/ban/street-decompose.ts"
37
- import { alignRow } from "../align.ts"
38
- import type { CanonicalRow } from "../types.ts"
39
41
  import { makeMulberry32, type ShardRecipe } from "./scaffold.ts"
40
42
 
41
43
  /**
@@ -156,7 +158,7 @@ function composeRaw(
156
158
  }
157
159
 
158
160
  lines.push(dependentLocality)
159
- const cityLine = [postcode, locality].filter(Boolean).join(" ").trim()
161
+ const cityLine = [postcode, locality].filter(isPresent).join(" ").trim()
160
162
 
161
163
  if (cityLine) {
162
164
  lines.push(cityLine)
@@ -30,15 +30,15 @@
30
30
  * inlined the variant logic and never called it).
31
31
  */
32
32
 
33
- import { spawnSync } from "node:child_process"
34
-
33
+ import { isPresent } from "@mailwoman/core/objects"
35
34
  import type { ComponentTag } from "@mailwoman/core/types"
36
35
  import { dataRootPath } from "@mailwoman/core/utils"
37
36
 
38
- import { stableSourceID } from "../adapter.ts"
39
- import { alignRow } from "../align.ts"
40
- import type { CanonicalRow } from "../types.ts"
41
- import { makeMulberry32, readCSVRecords, type ShardRecipe } from "./scaffold.ts"
37
+ import { stableSourceID } from "#adapters/utils"
38
+ import type { CanonicalRow } from "#types"
39
+ import { alignRow } from "#utils"
40
+
41
+ import { makeMulberry32, readZippedCSVRecords, type ShardRecipe } from "./scaffold.ts"
42
42
 
43
43
  /* oxlint-disable sister-software/no-unnamed-threshold -- the bare decimals below are weighted-sampler
44
44
  cutoffs, not thresholds: `const r = random()` followed by a cascade of `r < 0.4` branches IS the
@@ -72,28 +72,15 @@ interface FrTuple {
72
72
  }
73
73
 
74
74
  /**
75
- * Stream FR tuples out of the cached OA zip. The countrywide extract is GB-scale; cap with `head` so the whole file
76
- * never has to be held in memory. Only keeps rows with a house_number (the shard's core signal) and a postcode
77
- * (required for reversed-order rendering to be meaningful).
75
+ * Stream FR tuples out of the cached OA zip. The countrywide extract is GB-scale, so this reads only as far as `limit`
76
+ * distinct tuples — the `break` closes the reader and releases the archive. Only keeps rows with a house_number (the
77
+ * shard's core signal) and a postcode (required for reversed-order rendering to be meaningful).
78
78
  */
79
- function readTuples(limit: number): FrTuple[] {
80
- const maxLines = Math.max(limit * 8, 40_000) + 1
81
-
82
- const r = spawnSync("bash", ["-c", `unzip -p "${SOURCE.zip}" "${SOURCE.csv}" | head -n ${maxLines}`], {
83
- maxBuffer: 1024 * 1024 * 1024,
84
- encoding: "buffer",
85
- })
86
-
87
- if (r.status !== 0) {
88
- console.error(` WARN: unzip failed for ${SOURCE.zip} (status ${r.status})`)
89
-
90
- return []
91
- }
92
-
79
+ async function readTuples(limit: number): Promise<FrTuple[]> {
93
80
  const tuples: FrTuple[] = []
94
81
  const seen = new Set<string>()
95
82
 
96
- for (const row of readCSVRecords(r.stdout)) {
83
+ for await (const row of readZippedCSVRecords(SOURCE.zip, SOURCE.csv)) {
97
84
  if (tuples.length >= limit) break
98
85
  const street = row.street ?? ""
99
86
  const locality = row.city ?? ""
@@ -161,7 +148,7 @@ export const frOrderRecipe: ShardRecipe = {
161
148
 
162
149
  // Over-read from the CSV so the dedup + filter pass can fill `count` rows.
163
150
  const poolLimit = Math.max(count * 8, 40_000)
164
- const pool = readTuples(poolLimit)
151
+ const pool = await readTuples(poolLimit)
165
152
 
166
153
  console.error(` ${SOURCE.csv}: ${pool.length} unique tuples (capped read)`)
167
154
 
@@ -211,7 +198,7 @@ export const frOrderRecipe: ShardRecipe = {
211
198
  const { raw, components } = rendered
212
199
 
213
200
  // Safety check: every component must appear verbatim in raw (alignment precondition).
214
- const componentValues = Object.values(components).filter(Boolean) as string[]
201
+ const componentValues = Object.values(components).filter(isPresent)
215
202
 
216
203
  if (!componentValues.every((v) => raw.includes(v))) {
217
204
  skipped++
@@ -15,14 +15,13 @@
15
15
  * docs/articles/evals/resolver-geo/2026-06-06-anchor-pilot.md (the order-artifact correction).
16
16
  */
17
17
 
18
- import { spawnSync } from "node:child_process"
19
-
20
18
  import { dataRootPath } from "@mailwoman/core/utils"
21
19
 
22
- import { stableSourceID } from "../adapter.ts"
23
- import { alignRow } from "../align.ts"
24
- import { synthesizeGermanRow, type LocaleBaseTuple } from "../synthesize-german.ts"
25
- import { makeMulberry32, readCSVRecords, type ShardRecipe } from "./scaffold.ts"
20
+ import { stableSourceID } from "#adapters/utils"
21
+ import { synthesizeGermanRow, type LocaleBaseTuple } from "#synthesizers/german"
22
+ import { alignRow } from "#utils"
23
+
24
+ import { makeMulberry32, readZippedCSVRecords, type ShardRecipe } from "./scaffold.ts"
26
25
 
27
26
  /**
28
27
  * A German OA source (cached zip) + the Bundesland the file covers (OA's REGION column is empty for DE).
@@ -44,21 +43,13 @@ const SOURCES: GermanSource[] = [
44
43
  ]
45
44
 
46
45
  /**
47
- * Stream real German tuples out of a cached OA zip (buffered `unzip -p`).
46
+ * Stream real German tuples out of a cached OA zip.
48
47
  */
49
- function readGermanTuples(source: GermanSource): LocaleBaseTuple[] {
50
- const r = spawnSync("unzip", ["-p", source.zip, source.csv], { maxBuffer: 1024 * 1024 * 1024, encoding: "buffer" })
51
-
52
- if (r.status !== 0) {
53
- console.error(` WARN: unzip failed for ${source.zip} (status ${r.status})`)
54
-
55
- return []
56
- }
57
-
48
+ async function readGermanTuples(source: GermanSource): Promise<LocaleBaseTuple[]> {
58
49
  const tuples: LocaleBaseTuple[] = []
59
50
  const seen = new Set<string>()
60
51
 
61
- for (const row of readCSVRecords(r.stdout)) {
52
+ for await (const row of readZippedCSVRecords(source.zip, source.csv)) {
62
53
  const street = row.street ?? ""
63
54
  const locality = row.city ?? ""
64
55
 
@@ -102,7 +93,7 @@ export const germanRecipe: ShardRecipe = {
102
93
  const pool: LocaleBaseTuple[] = []
103
94
 
104
95
  for (const s of SOURCES) {
105
- const t = readGermanTuples(s)
96
+ const t = await readGermanTuples(s)
106
97
 
107
98
  console.error(` ${s.csv}: ${t.length} unique tuples`)
108
99
 
@@ -10,7 +10,8 @@
10
10
  * scripts/build-house-venue-shard.mjs.
11
11
  */
12
12
 
13
- import { synthesizeHouseVenueRow, type HouseVenueBaseTuple } from "../synthesize-house-venue.ts"
13
+ import { synthesizeHouseVenueRow, type HouseVenueBaseTuple } from "#synthesizers/house-venue"
14
+
14
15
  import { alignAndWrite, makeLcg, readTuples, shardSourceID, type ShardRecipe } from "./scaffold.ts"
15
16
 
16
17
  const LICENSE = "Synthetic — derived from CC-BY / public-domain input tuples"
@@ -9,6 +9,7 @@
9
9
  */
10
10
 
11
11
  import { anchorAbsorptionRecipe } from "./anchor-absorption.ts"
12
+ import { bareCountryRecipe } from "./bare-country.ts"
12
13
  import { boundaryStressRecipe } from "./boundary-stress.ts"
13
14
  import { countryBalancedRecipe } from "./country-balanced.ts"
14
15
  import { czPcFirstPrepositionRecipe } from "./cz-pcfirst-preposition.ts"
@@ -27,12 +28,14 @@ import { noStreetLedRecipe } from "./no-street-led.ts"
27
28
  import { noStreetRecipe } from "./no-street.ts"
28
29
  import { poBoxCedexRecipe } from "./po-box-cedex.ts"
29
30
  import { poBoxRecipe } from "./po-box.ts"
31
+ import { reviewedPostcodeTailRecipe } from "./reviewed-postcode-tail.ts"
30
32
  import type { ShardRecipe } from "./scaffold.ts"
31
33
  import { siBareVillageRecipe } from "./si-bare-village.ts"
32
- import { streetAffixRecipe } from "./street-affix.ts"
34
+ import { streetAffixRecipe, suffixBoundaryRecipe } from "./street-affix.ts"
33
35
  import { streetBareRecipe } from "./street-bare.ts"
34
36
  import { streetRecipe } from "./street.ts"
35
37
  import { subVenueRecipe } from "./sub-venue.ts"
38
+ import { trailingRegionRecipe } from "./trailing-region.ts"
36
39
  import { unitRecipe } from "./unit.ts"
37
40
 
38
41
  export * from "./scaffold.ts"
@@ -41,9 +44,13 @@ export * from "./scaffold.ts"
41
44
  * Every registered recipe, in display order.
42
45
  */
43
46
  const RECIPES: readonly ShardRecipe[] = [
47
+ bareCountryRecipe,
48
+ trailingRegionRecipe,
49
+ reviewedPostcodeTailRecipe,
44
50
  streetRecipe,
45
51
  streetBareRecipe,
46
52
  streetAffixRecipe,
53
+ suffixBoundaryRecipe,
47
54
  noStreetRecipe,
48
55
  houseVenueRecipe,
49
56
  poBoxRecipe,
@@ -34,18 +34,18 @@
34
34
  * - `$MAILWOMAN_DATA_ROOT/oa-cache/us__il__cook.zip` (ZIP→city tails)
35
35
  */
36
36
 
37
- import { spawnSync } from "node:child_process"
38
- import { existsSync, readFileSync, writeFileSync } from "node:fs"
37
+ import { existsSync, writeFileSync } from "node:fs"
39
38
 
40
39
  import type { DuckDBConnection } from "@duckdb/node-api"
41
40
  import type { ComponentTag } from "@mailwoman/core/types"
42
41
  import { dataRootPath, repoRootPath } from "@mailwoman/core/utils"
43
42
  import { JSONSpliterator } from "spliterator"
44
43
 
45
- import { stableSourceID } from "../adapter.ts"
46
- import { alignRow } from "../align.ts"
47
- import type { CanonicalRow, LabeledRow } from "../types.ts"
48
- import { makeMulberry32, readCSVRecords, type ShardRecipe } from "./scaffold.ts"
44
+ import { stableSourceID } from "#adapters/utils"
45
+ import type { CanonicalRow, LabeledRow } from "#types"
46
+ import { alignRow } from "#utils"
47
+
48
+ import { makeMulberry32, readZippedCSVRecords, type ShardRecipe } from "./scaffold.ts"
49
49
 
50
50
  interface County {
51
51
  fips: string
@@ -251,19 +251,11 @@ async function extractCrossings(
251
251
  /**
252
252
  * ZIP → majority city from the cached OA Cook-county CSV (real ZIP/city pairings).
253
253
  */
254
- function buildZipCityMap(): Map<string, string> {
255
- const r = spawnSync("unzip", ["-p", OA_COOK.zip, OA_COOK.csv], { maxBuffer: 1024 * 1024 * 1024, encoding: "buffer" })
256
-
257
- if (r.status !== 0) {
258
- console.error(` WARN: unzip failed for ${OA_COOK.zip} — city tails disabled`)
259
-
260
- return new Map()
261
- }
262
-
254
+ async function buildZipCityMap(): Promise<Map<string, string>> {
263
255
  const counts = new Map<string, Map<string, number>>()
264
256
 
265
257
  // zip → Map(city → n)
266
- for (const row of readCSVRecords(r.stdout)) {
258
+ for await (const row of readZippedCSVRecords(OA_COOK.zip, OA_COOK.csv)) {
267
259
  const city = row.city ?? ""
268
260
  const zip = row.postcode ?? ""
269
261
 
@@ -518,7 +510,7 @@ export const intersectionRecipe: ShardRecipe = {
518
510
  throw new Error(`No crossings found — are the TIGER EDGES shapefiles present in ${edgesDir}?`)
519
511
  }
520
512
 
521
- const zipCity = opts.golden ? new Map<string, string>() : buildZipCityMap()
513
+ const zipCity = opts.golden ? new Map<string, string>() : await buildZipCityMap()
522
514
 
523
515
  if (!opts.golden) {
524
516
  console.error(` zip→city map: ${zipCity.size} ZIPs (OA Cook)`)
@@ -7,7 +7,7 @@
7
7
  * OpenAddresses tuples for a `--country` (DE/FR/NL/IT/ES), renders each via
8
8
  * {@link synthesizeLocaleRow} in BOTH orders (`--intl-fraction`, default 0.4 international / the
9
9
  * rest country-native), aligns to BIO, and emits a labeled JSONL. Generate-mode: it STREAMS each
10
- * source CSV (`unzip -p` for cached zips, plain `createReadStream` for extracted CSVs) and
10
+ * source CSV (a streamed zip member for cached zips, plain `createReadStream` for extracted CSVs) and
11
11
  * reservoir-samples to {@link RESERVOIR_CAP} (so FR/ES countrywide work in bounded memory), then
12
12
  * draws `--count` rows from the pool with the passed `random`. Ported from
13
13
  * scripts/build-locale-shard.mjs.
@@ -25,21 +25,23 @@
25
25
  * country, so DE/FR emit streams are unchanged for a given seed.
26
26
  */
27
27
 
28
- import { spawn } from "node:child_process"
29
28
  import { createReadStream } from "node:fs"
30
29
 
31
30
  import { COUNTRY_SURFACE_FORMS } from "@mailwoman/codex/country"
31
+ import { readZipEntry } from "@mailwoman/core/fs/zip"
32
+ import { isPresent } from "@mailwoman/core/objects"
32
33
  import { dataRootPath } from "@mailwoman/core/utils"
33
34
  import { CSVSpliterator } from "spliterator"
34
35
 
35
- import { stableSourceID } from "../adapter.ts"
36
- import { alignRow } from "../align.ts"
37
- import { type LocaleBaseTuple, type SynthesizedLocaleRow, synthesizeLocaleRow } from "../synthesize-german.ts"
36
+ import { stableSourceID } from "#adapters/utils"
37
+ import { type LocaleBaseTuple, type SynthesizedLocaleRow, synthesizeLocaleRow } from "#synthesizers/german"
38
+ import { alignRow } from "#utils"
39
+
38
40
  import { makeMulberry32, type ShardRecipe } from "./scaffold.ts"
39
41
 
40
42
  /**
41
- * One per-country OA source part: either a cached `zip` + `csv` member (streamed via `unzip -p`) or an extracted plain
42
- * `path` (streamed via `createReadStream`). Both carry the standard OA header
43
+ * One per-country OA source part: either a cached `zip` + `csv` member (streamed out of the archive) or an extracted
44
+ * plain `path` (streamed via `createReadStream`). Both carry the standard OA header
43
45
  * (LON,LAT,NUMBER,STREET,UNIT,CITY,DISTRICT,REGION,POSTCODE,ID,HASH). An optional `region` fallback covers countries
44
46
  * whose REGION column is empty (DE — the Bundesland is implied by the per-state file).
45
47
  */
@@ -223,7 +225,7 @@ interface ColumnIndex {
223
225
 
224
226
  /**
225
227
  * Stream real tuples out of an OA source part and reservoir-sample to {@link RESERVOIR_CAP}. Reads the CSV row-by-row —
226
- * `unzip -p | CSVSpliterator` for zip parts, `createReadStream | CSVSpliterator` for extracted parts (both bounded
228
+ * `readZipEntry | CSVSpliterator` for zip parts, `createReadStream | CSVSpliterator` for extracted parts (both bounded
227
229
  * memory) — and keeps a uniform random sample (Algorithm R) seeded by `rng`, separate from the emit loop's PRNG. NO
228
230
  * global dedup (a 25M-key Set would OOM; OA rows are near-unique). The city passes through {@link cleanCityNoise}; the
229
231
  * region falls back to `part.region` when the row's REGION cell is empty (DE).
@@ -231,21 +233,11 @@ interface ColumnIndex {
231
233
  * Exported for {@link locale.test.ts} — the CSV read path (quote handling, CRLF, region fallback) has no other test.
232
234
  */
233
235
  export async function readTuples(part: LocalePart, rng: () => number): Promise<LocaleBaseTuple[]> {
234
- let input: NodeJS.ReadableStream
235
-
236
- if (part.path) {
237
- // No `encoding` — CSVSpliterator delimits raw bytes and decodes utf-8 itself; a string stream
238
- // (from `{ encoding: "utf8" }`) would defeat its byte-range scanner.
239
- input = createReadStream(part.path)
240
- } else {
241
- const child = spawn("unzip", ["-p", part.zip!, part.csv!])
242
-
243
- child.on("error", (err) => {
244
- console.error(` WARN: unzip failed for ${part.zip}: ${err.message}`)
245
- })
246
-
247
- input = child.stdout!
248
- }
236
+ // No `encoding` on the file path — CSVSpliterator delimits raw bytes and decodes utf-8 itself; a string stream
237
+ // (from `{ encoding: "utf8" }`) would defeat its byte-range scanner.
238
+ const input: NodeJS.ReadableStream | AsyncIterable<Uint8Array> = part.path
239
+ ? createReadStream(part.path)
240
+ : readZipEntry(part.zip!, part.csv!)
249
241
 
250
242
  const get = (cells: string[], i: number): string => (i >= 0 && i < cells.length ? (cells[i] ?? "").trim() : "")
251
243
  const reservoir: LocaleBaseTuple[] = []
@@ -302,7 +294,7 @@ export async function readTuples(part: LocalePart, rng: () => number): Promise<L
302
294
  // pre-joined STREET column, so `cols.tipoVial === -1` and this is a no-op there.
303
295
  const street =
304
296
  cols.tipoVial >= 0
305
- ? [get(cells, cols.tipoVial), get(cells, cols.street)].filter(Boolean).join(" ")
297
+ ? [get(cells, cols.tipoVial), get(cells, cols.street)].filter(isPresent).join(" ")
306
298
  : get(cells, cols.street)
307
299
 
308
300
  const rawCity = get(cells, cols.city)
@@ -10,7 +10,8 @@
10
10
  * scripts/build-no-street-shard.mjs.
11
11
  */
12
12
 
13
- import { synthesizeNoStreetRow, type NoStreetBaseTuple } from "../synthesize-no-street.ts"
13
+ import { synthesizeNoStreetRow, type NoStreetBaseTuple } from "#synthesizers/no-street"
14
+
14
15
  import { alignAndWrite, makeLcg, readTuples, shardSourceID, type ShardRecipe } from "./scaffold.ts"
15
16
 
16
17
  const LICENSE = "Synthetic — derived from CC-BY / public-domain input tuples"