Compare commits
127 Commits
7abd3e2d95
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 976d2e5ac1 | |||
| 343c9fa98a | |||
| f206a18027 | |||
| 3dc1cf82f1 | |||
| 0d627d2b11 | |||
| ce8ea550a3 | |||
| 1035f8bb2a | |||
| ce59653ccd | |||
| ea9c1ad436 | |||
| e09e92ff03 | |||
| 81cf04ae8b | |||
| 5715e516aa | |||
| 621e6f4548 | |||
| 839b7bd164 | |||
| d081ec85d0 | |||
| 474f73444b | |||
| edce645f34 | |||
| b581daf0ab | |||
| 815a24c186 | |||
| 878cab95e7 | |||
| e7a81459cd | |||
| 15af49e618 | |||
| b3be1ee137 | |||
| 5083b79730 | |||
| b3ead0ca5e | |||
| 78d7e513f9 | |||
| 4472c8d92b | |||
| caec22001d | |||
| e7a906debf | |||
| df8d15aeb6 | |||
| 93d216616b | |||
| c93281b8cc | |||
| f081fa1433 | |||
| baed259802 | |||
| ec6f0e2edb | |||
| d1fbc96a34 | |||
| 2016a7408c | |||
| 9feadf4d15 | |||
| ad57bf0c54 | |||
| ceb7f81a1f | |||
| daabf8c91f | |||
| af20cec9c3 | |||
| 2dbfb0a622 | |||
| 3f5f754189 | |||
| d366a80629 | |||
| d98571dfb3 | |||
| 29e471ef0f | |||
| 710b6b0261 | |||
| 85d4760cde | |||
| 784a2f0c0c | |||
| 2ad00b3569 | |||
| 8a17fb1548 | |||
| 0910ab7d1a | |||
| 604bcb1878 | |||
| 97c4e17671 | |||
| 66d11ce1c7 | |||
| b0db82f2f1 | |||
| e9d8603611 | |||
| 17d1703806 | |||
| ecc0b475ae | |||
| 69d0db9431 | |||
| 9beb42f1ca | |||
| 8432a7c4ae | |||
| 3e1d3914c2 | |||
| cddf81e6a5 | |||
| 35dc998b03 | |||
| 57b2d182c7 | |||
| fb5a5ff38f | |||
| c326683ada | |||
| 9c719c83a6 | |||
| dd913a17e3 | |||
| c8a4ffa764 | |||
| 9db8d35a49 | |||
| 5fb5e5f4c8 | |||
| c232e65001 | |||
| a851b5f5fd | |||
| 9497824350 | |||
| 1a818ff9b4 | |||
| d8bf86f0c8 | |||
| d5d9c2655e | |||
| 2d08bf4b32 | |||
| 6b0a2a60a8 | |||
| 7eb891dd80 | |||
| b6e1927468 | |||
| 93e17c1770 | |||
| 9d63943237 | |||
| bb43345d63 | |||
| c9c756e2c4 | |||
| 98938e6126 | |||
| 396ae3bcd2 | |||
| 86eb55d564 | |||
| 0c6ab0937a | |||
| 02eb95b94b | |||
| 7d50f43d0b | |||
| 2dcc31fa63 | |||
| 33c441f85a | |||
| 63f4bf7c0a | |||
| 7e25c6de44 | |||
| 7a394ee2f2 | |||
| a136be6059 | |||
| 289d5edc31 | |||
| 7ff817d5ae | |||
| b6219bf76a | |||
| e5711cbdb4 | |||
| 6adc086b7e | |||
| 8c2b51ebed | |||
| 8e30d05a0e | |||
| 8cef7a9c00 | |||
| 92f58edc2d | |||
| 9e37f3dc51 | |||
| db271f82ee | |||
| 1029b789b5 | |||
| 7993e04d95 | |||
| 8c005070ec | |||
| 42c74b9b43 | |||
| 2127b3277c | |||
| f7403f0cfb | |||
| 08d996301b | |||
| c314f9cb57 | |||
| aea7b72e4b | |||
| 1d4a0f673f | |||
| 60b9922c7e | |||
| fb0480e741 | |||
| 66cb5937cc | |||
| d8c348d07b | |||
| 1ab3bbce30 | |||
| 6b06445c32 |
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
.claude
|
.claude
|
||||||
*.out
|
*.out
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
data-import/cache/
|
||||||
|
|||||||
@@ -1,11 +1,27 @@
|
|||||||
# Rules
|
# Rules
|
||||||
|
|
||||||
- Go runs only through `docker compose run --rm <test|vet|fmt|build>`; the merge gate is `docker build .` plus CI's changelog check.
|
- Go runs only through `docker compose run --rm <test|vet|fmt|build|cyclo>`; the merge gate is `docker build .` plus CI's changelog check.
|
||||||
- Tests first, in their own commit; the implementation follows in the next. A re-pin of seeded output or of `testdata/shipped_shape.txt` is its own commit.
|
- Tests first, in their own commit; the implementation follows in the next. A re-pin of seeded output or of `testdata/shipped_shape.txt` is its own commit.
|
||||||
- A change under `data/` or to the shape pin adds its `CHANGELOG.md` entry under `Unreleased` in the same PR, and so does a change to a flag, an exit code, an exported name, a fence, a builtin or the lowest Go; what is major is the README's Versioning table.
|
- A change under `data/` or to the shape pin adds its `CHANGELOG.md` entry under `Unreleased` in the same PR, and so does a change to a flag, an exit code, an exported name, a fence, a builtin or the lowest Go; what is major is the README's Versioning table.
|
||||||
- One-line commit messages: no ticket prefix, no repo name, no authorship trailers.
|
- One-line commit messages: no ticket prefix, no repo name, no authorship trailers.
|
||||||
|
- Merges are fast-forward only, which `tea pr merge` cannot spell — every style it
|
||||||
|
offers fails with "is it still open?", as does a merge whose required checks are
|
||||||
|
still pending, so read the checks before believing the style is the problem. Use
|
||||||
|
`tea api /repos/{owner}/{repo}/pulls/<n>/merge -f Do=fast-forward-only`.
|
||||||
|
- Gitea queues Actions runs that `/repos/{owner}/{repo}/actions/tasks` does not
|
||||||
|
list, so an empty task list says nothing about whether CI ran; read
|
||||||
|
`/repos/{owner}/{repo}/commits/<sha>/status`.
|
||||||
|
- README goal 2 is gated at 7.0 on the `comprehension-panel` skill, and below it
|
||||||
|
nothing else merges — no feature, no category, no data — bar a security fix and a
|
||||||
|
dependency bump. `todo.md` carries the round: the nine-seat findings run at depth 1,
|
||||||
|
a PR per item it names, then the run again, until the score passes. At or above 7.0
|
||||||
|
every pull request scores with the four-seat run and answers it in one run. No merge
|
||||||
|
lowers the last score.
|
||||||
- Hard tabs. No comment by default; delete a restatement, a rationale, history, or a file preamble.
|
- Hard tabs. No comment by default; delete a restatement, a rationale, history, or a file preamble.
|
||||||
- One spelling per result: reject the other at `New`, and let the error name the spelling to use.
|
- One spelling per result: reject the other at `New`, and let the error name the spelling to use.
|
||||||
- A standing choice a reader would relitigate goes under Decisions in the README, not in a comment.
|
- A standing choice a reader would relitigate goes under Decisions in the README, not in a comment.
|
||||||
|
- Prose naming a source states what that source states: read the register's own field
|
||||||
|
before paraphrasing it, and name the register you read before claiming none
|
||||||
|
publishes a spelling.
|
||||||
- A README example is a `json` block that loads and renders as a category; `readme_test.go` runs every one.
|
- A README example is a `json` block that loads and renders as a category; `readme_test.go` runs every one.
|
||||||
- Cyclomatic complexity is gated at 14: the table-shaped dispatches (`eachToken`, `calc.factor`, `walkPath`) sit at 13–14 and stay whole; anything else that reaches 14 is decomposed.
|
- Cyclomatic complexity is gated at 14: the table-shaped dispatches (`linkParent`, `compileTemplate`, `renderEdges`) sit at it and stay whole; a function that would pass it is decomposed.
|
||||||
|
|||||||
+72
-8
@@ -11,18 +11,82 @@ replacement, and each removed path, column or flag.
|
|||||||
- First release: the CLI, the library and the shipped data set.
|
- First release: the CLI, the library and the shipped data set.
|
||||||
- Table categories: a category JSON naming a `rows` TSV beside it, with the options
|
- Table categories: a category JSON naming a `rows` TSV beside it, with the options
|
||||||
`key`, `name`, `weight` and `parent`; a path selects a row by key or name,
|
`key`, `name`, `weight` and `parent`; a path selects a row by key or name,
|
||||||
`misc.country[SE]`, and descends to a linked table by name; linked tables draw
|
`misc.territory[SE]`, and descends to a linked table by name; linked tables draw
|
||||||
consistently within one render and draw group. `rows` is an option, so no
|
consistently within one render and draw group. `rows` is an option, so no
|
||||||
template may carry a field of that name. Refused at `New`: a `name` without a
|
template may carry a field of that name. A `name` without a `key` resolves
|
||||||
`key`, a name spelling another row's key, a table named like a column of any
|
inside the table's `parent`. Refused at `New`: a `name` without a `key` or a
|
||||||
|
`parent`, a name repeating inside one parent row, a name spelling another row's key, a table named like a column of any
|
||||||
table above it, a table whose format or cell references its own family, and,
|
table above it, a table whose format or cell references its own family, and,
|
||||||
within one render and draw group, a path drawing a table another path selects a
|
within one render and draw group, a path drawing a table another path selects a
|
||||||
row of, or two paths pinning different rows of one table.
|
row of, or two paths pinning different rows of one table.
|
||||||
- `New` refuses a root choice of templates sharing one format and one set of string
|
- `New` refuses a root choice of templates sharing one format and one set of string
|
||||||
fields, naming the rows TSV to write instead.
|
fields, naming the rows TSV to write instead.
|
||||||
- `misc.country`, `misc.currency`, `misc.language`, `misc.httpstatus` and
|
- `misc.territory`, `misc.currency`, `misc.language`, `misc.httpstatus` and
|
||||||
`misc.mimetype` are tables. `misc.country` is every ISO 3166 country that has a
|
`misc.mimetype` are tables. `misc.territory` is every ISO 3166-1 territory that has
|
||||||
capital, a currency and a TLD, with the columns `calling-code`, `capital`,
|
a capital, a currency and a TLD, with the columns `calling-code`, `capital`,
|
||||||
`currency`, `flag`, `languages`, `numeric` and `tld` added; `misc.currency` the
|
`country`, `currency`, `flag`, `languages`, `numeric` and `tld` added, `country`
|
||||||
|
holding the alpha-2 code of the sovereign state it belongs to and its own where it
|
||||||
|
is one; `misc.currency` the
|
||||||
current ISO 4217 currencies with a minor unit, with `decimals` and `numeric`
|
current ISO 4217 currencies with a minor unit, with `decimals` and `numeric`
|
||||||
added, and its symbols from CLDR. `DATA-LICENSES.md` lists each source.
|
added, and its symbols from CLDR; `misc.language` every ISO 639-2 entry carrying a
|
||||||
|
639-1 code, with a `code3` column holding its 639-2/T code; `misc.httpstatus` each
|
||||||
|
code the IANA registry lists with a plain reason phrase; and `misc.mimetype` each
|
||||||
|
type mime-db records as IANA-registered and gives a filename extension.
|
||||||
|
`DATA-LICENSES.md` lists each source.
|
||||||
|
- `misc.timezone`, `misc.car` and `misc.useragent` are tables too. `misc.timezone`
|
||||||
|
is every zone tzdb `zone.tab` gives a shipped territory, with `offset` holding the
|
||||||
|
zone's standard UTC offset and `territory` linking to `misc.territory`, so
|
||||||
|
`misc.territory[SE].timezone` draws `Europe/Stockholm`; zones of a territory
|
||||||
|
`misc.territory` does not ship, Antarctica's among them, and the constant `UTC`
|
||||||
|
are gone; spell that one as the text `"UTC"`. A `weight` column carries the
|
||||||
|
population GeoNames records in each zone, so a draw favours the zones people live
|
||||||
|
in. `misc.useragent` is the top-user-agents desktop and mobile lists with `browser`,
|
||||||
|
`device` and `os` columns. `misc.car` keeps its makes and models in a `make` and a
|
||||||
|
`model` column.
|
||||||
|
- `misc.httpmethod`, `misc.protocol` and `misc.port` are IANA's registries as tables.
|
||||||
|
`misc.httpmethod` is the eight methods RFC 9110 defines and PATCH, carrying
|
||||||
|
`safe` and `idempotent` as `true` or `false`; `misc.protocol` the keyword, its
|
||||||
|
`number` and its `name`, selectable by either; `misc.port` renders a TCP port number,
|
||||||
|
with the IANA `service` name beside it, keeping the first service the registry
|
||||||
|
describes for a port so a number selects one row.
|
||||||
|
- `misc.tld` is the IANA root zone as a table: every delegated TLD keyed with its
|
||||||
|
leading dot, `.se` and `.xn--p1ai`, the register's `type` beside it, and a `unicode`
|
||||||
|
column holding the form the register displays, so `misc.tld[.рф]` selects the row
|
||||||
|
`.xn--p1ai` renders. A delegation the register marks "Not assigned" does not ship.
|
||||||
|
- `misc.loglevel` is the eight syslog severities: the `keyword` a configuration writes,
|
||||||
|
`err` and `info`, keyed by the numerical `code` a PRI encodes and selectable by
|
||||||
|
either, with the `severity` RFC 5424 spells beside it.
|
||||||
|
- `geo.SE` and `geo.US`: five linked tables per country, `region`, `municipality`,
|
||||||
|
`locality`, `postal-code` and `street`, weighted by population and address counts
|
||||||
|
and built from SCB, GeoNames, Trafikverket NVDB and the US Census Bureau, and an
|
||||||
|
`address` record over one consistent draw of them. `sv_SE.address` and
|
||||||
|
`en_US.address` read those records, so `en_US.address.street` no longer carries
|
||||||
|
`name` and `suffix`, and a locale folder loads only beside `geo`.
|
||||||
|
- `{date(from,to,'layout')}` and `{time('layout')}`: a second between two days, or
|
||||||
|
within one, in a single-quoted Go layout, drawn in UTC; `from` may equal `to`.
|
||||||
|
`sv_SE.date`, `en_US.date`, `sv_SE.time` and `en_US.time` render through them, so
|
||||||
|
`date.year`, `date.month`, `date.day`, `time.hour`, `time.minute`, `time.minute.t`,
|
||||||
|
`time.sec` and `time.ampm` are no longer paths — a part of a date is now its own
|
||||||
|
`{date(…,'2006')}`. `misc.datetime` is an RFC 3339 instant.
|
||||||
|
- `sex`, `first-name` and `last-name` tables in `sv_SE` and `en_US`, weighted by
|
||||||
|
bearers from SCB, the SSA and the Census Bureau; `first-name` links to `sex`, and a
|
||||||
|
name both sexes carry is a row under each. `person` reads them, so its columns are
|
||||||
|
`first`, `last`, `prefix` and `sex`; `person.femalefirst` and `person.malefirst` are
|
||||||
|
no longer paths — draw `sex[f].first-name` and `sex[m].first-name` instead.
|
||||||
|
`en_US.title` links to `sex` as well, so `en_US.person.prefix` draws `Mr` or `Ms`
|
||||||
|
without contradicting the record's `sex`; `sv_SE.title` is an unsexed table of the
|
||||||
|
same shape.
|
||||||
|
- `sv_SE.personnummer` and `sv_SE.samordningsnummer`, Skatteverket's test series
|
||||||
|
from a `sv_SE.birth-number` table under `sex`, in place of `sv_SE.ssn`, whose
|
||||||
|
`ssn.mmdd`, `ssn.mmdd.m` and `ssn.mmdd.d` go with it. `en_US.ssn` now draws the
|
||||||
|
ranges the SSA assigns and carries the columns `area`, `group` and `serial`, so
|
||||||
|
`--format csv en_US.ssn` writes a header where it used to fail; `en_US.itin` is new
|
||||||
|
and carries the same three. `person.prefix` is null where a person has no title,
|
||||||
|
where it used to be an empty string, so `--format sql` writes `NULL` and a `string`
|
||||||
|
struct field reading it becomes `*string`.
|
||||||
|
- `ErrNoColumns` is exported, so a caller can tell the one record fence a path can
|
||||||
|
answer from the rest.
|
||||||
|
- An error names a spelling that runs: a layout is named single-quoted and free of
|
||||||
|
its own quotes, a row of a table with no key is named as the path that selects it,
|
||||||
|
`sv_SE.sex[f].first-name[Kim]`, and a category with no columns names the record
|
||||||
|
that gives it one.
|
||||||
|
|||||||
+23
-6
@@ -1,14 +1,31 @@
|
|||||||
# Data licenses
|
# Data licenses
|
||||||
|
|
||||||
Every shipped dataset, its source, its licence and the attribution it asks for. A
|
Every shipped dataset, its source, its licence and the attribution it asks for. A
|
||||||
`data-import/` script rebuilds each sourced table; a curated one is hand-written.
|
`data-import/` script rebuilds each sourced table, run as the README's
|
||||||
|
[Development](README.md#development) section says; a curated one is hand-written.
|
||||||
|
|
||||||
| Table | Source | Licence | Attribution | Rebuild |
|
| Table | Source | Licence | Attribution | Rebuild |
|
||||||
|-------|--------|---------|-------------|---------|
|
|-------|--------|---------|-------------|---------|
|
||||||
| `misc/country.tsv` | [datasets/country-codes](https://github.com/datasets/country-codes) | [PDDL 1.0](https://opendatacommons.org/licenses/pddl/1-0/) | none required | `data-import/country.py` |
|
| `geo/SE/locality.tsv`, `postal-code.tsv` | [GeoNames](https://www.geonames.org/) postal codes for SE; populations from SCB tätorter 2023 | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/); CC0 1.0 | "Postal codes from GeoNames, www.geonames.org" | `data-import/geo-se.py` |
|
||||||
|
| `geo/SE/region.tsv`, `municipality.tsv` | [SCB](https://www.scb.se/) län and kommun codes 2026 and population 2024 | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) | none required | `data-import/geo-se.py` |
|
||||||
|
| `geo/SE/street.tsv` | [Trafikverket NVDB](https://www.trafikverket.se/) Gatunamn, through the open API | CC0 1.0 | none required | `data-import/geo-se.py` |
|
||||||
|
| `geo/US/region.tsv`, `municipality.tsv`, `locality.tsv` | [Census Bureau](https://www.census.gov/) Gazetteer 2026 and population estimates 2025 | [public domain](https://www.usa.gov/government-works) | none required | `data-import/geo-us.py` |
|
||||||
|
| `geo/US/postal-code.tsv`, `street.tsv` | Census Bureau ZCTA to place relationships 2020 and TIGER/Line 2025 address ranges and feature names | public domain | none required | `data-import/geo-us.py` |
|
||||||
|
| `sv_SE/first-name.tsv`, `last-name.tsv` | [SCB](https://www.scb.se/) names with at least two bearers, 31 December 2022 | CC0 1.0 | "Källa: SCB" | `data-import/names-se.py` |
|
||||||
|
| `en_US/first-name.tsv` | [SSA](https://www.ssa.gov/oact/babynames/) baby names, births 1930 to 2020, through [hackerb9/ssa-baby-names](https://github.com/hackerb9/ssa-baby-names) | public domain | none required | `data-import/names-us.py` |
|
||||||
|
| `en_US/last-name.tsv` | Census Bureau surnames occurring 100 or more times, 2010 | public domain | none required | `data-import/names-us.py` |
|
||||||
|
| `sv_SE/sex.tsv`, `sv_SE/birth-number.tsv`, `sv_SE/title.tsv`, `en_US/sex.tsv`, `en_US/title.tsv`, `misc/car.tsv` | curated; Skatteverket's test birth numbers are facts, and `car.tsv` waits for an international source (goal 12) | — | — | — |
|
||||||
| `misc/currency.tsv` | [datasets/currency-codes](https://github.com/datasets/currency-codes); symbols from [Unicode CLDR](https://github.com/unicode-org/cldr) `en.xml` and `root.xml` | PDDL 1.0; [Unicode License v3](https://www.unicode.org/license.txt) | CLDR: "Copyright © 1991-2025 Unicode, Inc. Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the United States and other countries." | `data-import/currency.py` |
|
| `misc/currency.tsv` | [datasets/currency-codes](https://github.com/datasets/currency-codes); symbols from [Unicode CLDR](https://github.com/unicode-org/cldr) `en.xml` and `root.xml` | PDDL 1.0; [Unicode License v3](https://www.unicode.org/license.txt) | CLDR: "Copyright © 1991-2025 Unicode, Inc. Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the United States and other countries." | `data-import/currency.py` |
|
||||||
| `misc/httpstatus.tsv` | curated (IANA HTTP status codes are facts) | — | — | — |
|
| `misc/httpmethod.tsv` | [IANA HTTP Method Registry](https://www.iana.org/assignments/http-methods/) | [public domain](https://www.iana.org/help/licensing-terms) | none required | `data-import/httpmethod.py` |
|
||||||
| `misc/language.tsv` | curated (ISO 639-1 codes are facts) | — | — | — |
|
| `misc/httpstatus.tsv` | [IANA HTTP Status Code Registry](https://www.iana.org/assignments/http-status-codes/) | [public domain](https://www.iana.org/help/licensing-terms) | none required | `data-import/httpstatus.py` |
|
||||||
| `misc/mimetype.tsv` | curated (IANA media types are facts) | — | — | — |
|
| `misc/language.tsv` | [datasets/language-codes](https://github.com/datasets/language-codes), the [Library of Congress](https://www.loc.gov/standards/iso639-2/) ISO 639-2 register | [PDDL 1.0](https://opendatacommons.org/licenses/pddl/1-0/) | none required | `data-import/language.py` |
|
||||||
|
| `misc/loglevel.tsv` | [RFC 5424](https://www.rfc-editor.org/rfc/rfc5424.txt) Table 2, the syslog message severities; keywords from the [POSIX](https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/syslog.h.html) `<syslog.h>` severity macros | facts | none required | `data-import/loglevel.py` |
|
||||||
|
| `misc/mimetype.tsv` | [mime-db](https://github.com/jshttp/mime-db), the IANA media type registry with filename extensions | [MIT](https://github.com/jshttp/mime-db/blob/master/LICENSE) | "Copyright (c) 2014 Jonathan Ong, Copyright (c) 2015-2022 Douglas Christopher Wilson" | `data-import/mimetype.py` |
|
||||||
|
| `misc/port.tsv` | [IANA Service Name and Transport Protocol Port Number Registry](https://www.iana.org/assignments/service-names-port-numbers/) | [public domain](https://www.iana.org/help/licensing-terms) | none required | `data-import/port.py` |
|
||||||
|
| `misc/protocol.tsv` | [IANA Protocol Numbers](https://www.iana.org/assignments/protocol-numbers/) | [public domain](https://www.iana.org/help/licensing-terms) | none required | `data-import/protocol.py` |
|
||||||
|
| `misc/territory.tsv` | [datasets/country-codes](https://github.com/datasets/country-codes) | [PDDL 1.0](https://opendatacommons.org/licenses/pddl/1-0/) | none required | `data-import/territory.py` |
|
||||||
|
| `misc/timezone.tsv` | [IANA tzdb](https://www.iana.org/time-zones) 2026d `zone.tab` and the standard offset of each zone; weights from [GeoNames](https://www.geonames.org/) `cities15000` populations | [public domain](https://data.iana.org/time-zones/tzdb/LICENSE); [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | "Populations from GeoNames, www.geonames.org" | `data-import/timezone.py` |
|
||||||
|
| `misc/tld.tsv` | [IANA Root Zone Database](https://www.iana.org/domains/root/db), checked against the root zone's [TLD list](https://data.iana.org/TLD/tlds-alpha-by-domain.txt) | [public domain](https://www.iana.org/help/licensing-terms) | none required | `data-import/tld.py` |
|
||||||
|
| `misc/useragent.tsv` | [top-user-agents](https://github.com/microlinkhq/top-user-agents) desktop and mobile lists | [MIT](https://github.com/microlinkhq/top-user-agents/blob/master/LICENSE.md) | "Copyright © 2020 Kiko Beats" | `data-import/useragent.py` |
|
||||||
|
|
||||||
Every other category is hand-written JSON under [`data/`](data), MIT like the code.
|
Every other category is hand-written under [`data/`](data), MIT like the code.
|
||||||
|
|||||||
@@ -17,10 +17,12 @@ fejkdata sv_SE.person.last # Eriksson
|
|||||||
fejkdata --seed 42 sv_SE.address # the same address every run
|
fejkdata --seed 42 sv_SE.address # the same address every run
|
||||||
fejkdata -n 3 --separator ', ' sv_SE.word # nät, barn, sol
|
fejkdata -n 3 --separator ', ' sv_SE.word # nät, barn, sol
|
||||||
fejkdata --list # every path the data offers
|
fejkdata --list # every path the data offers
|
||||||
fejkdata 'misc.country[SE].capital' # Stockholm — a table's row, selected by key or name
|
fejkdata 'misc.territory[SE].capital' # Stockholm — a table's row, selected by key or name
|
||||||
|
fejkdata 'geo.SE.locality[Lund].street' # Fjelievägen — a linked table, drawn inside the row
|
||||||
fejkdata --data-path ./mydata sv_SE.word # layer a directory over the shipped data
|
fejkdata --data-path ./mydata sv_SE.word # layer a directory over the shipped data
|
||||||
fejkdata --no-shipped-data -d ./mydata --list # only your data
|
fejkdata --no-shipped-data -d ./mydata --list # only your data
|
||||||
fejkdata 'name: {/sv_SE.person.last}' # name: <a surname> — an inline template
|
fejkdata 'name: {/sv_SE.person.last}' # name: <a surname> — an inline template
|
||||||
|
fejkdata "{date(1990-01-01,2010-12-31,'2006-01-02')}" # 2003-11-27 — the argument in "…", the layout in '…'
|
||||||
fejkdata '{"format":"name: {x}","x":["bosse","lina"]}' # name: bosse or name: lina
|
fejkdata '{"format":"name: {x}","x":["bosse","lina"]}' # name: bosse or name: lina
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -31,11 +33,9 @@ a JSON object, array or string, or that carries a `{` token, is instead an
|
|||||||
**inline template**: a format string or a JSON value compiled and rendered on the
|
**inline template**: a format string or a JSON value compiled and rendered on the
|
||||||
spot. Its tokens reach the data by reference from the root —
|
spot. Its tokens reach the data by reference from the root —
|
||||||
`{/sv_SE.person.last}`, so shipped and `--data-path` categories are alike
|
`{/sv_SE.person.last}`, so shipped and `--data-path` categories are alike
|
||||||
available. An inline template sits in no folder, so the folder-relative `{.name}`
|
available. A path never contains a brace or a quote, and a bracket only as a selector
|
||||||
and `{..name}` are rejected naming the root spelling, and one reference alone —
|
after a name, so the two spellings cannot collide; which spellings an inline template
|
||||||
`{/sv_SE.person}` — is the path written as a template, rejected naming the path, as is
|
rejects, and what each names instead, is under [Decisions](#decisions).
|
||||||
a path written `/sv_SE.person`. A path never contains a brace or a quote, and a
|
|
||||||
bracket only as a selector after a name, so the two cannot collide (see [Decisions](#decisions)).
|
|
||||||
|
|
||||||
| Flag | |
|
| Flag | |
|
||||||
|------|--|
|
|------|--|
|
||||||
@@ -113,6 +113,12 @@ the template itself, which composes the format into one string rather than
|
|||||||
projecting columns — ask for more records with `--repeat`. A `repeat` on a column
|
projecting columns — ask for more records with `--repeat`. A `repeat` on a column
|
||||||
is fine.
|
is fine.
|
||||||
|
|
||||||
|
Columns are written in name order, whatever order the fields appear in. A category
|
||||||
|
whose fields are the parts of one value — `sv_SE.price`, `sv_SE.version`, `misc.uuid` —
|
||||||
|
projects those parts rather than the value, so for one column holding what `Fake`
|
||||||
|
renders, write `{"format":"","price":"{/sv_SE.price}"}` as a fieldless category asks
|
||||||
|
for.
|
||||||
|
|
||||||
A column carrying a newline keeps it inside the quoted CSV field or the SQL string
|
A column carrying a newline keeps it inside the quoted CSV field or the SQL string
|
||||||
literal, so a row can span physical lines: read the stream with a CSV or SQL
|
literal, so a row can span physical lines: read the stream with a CSV or SQL
|
||||||
parser rather than splitting it on newlines.
|
parser rather than splitting it on newlines.
|
||||||
@@ -140,6 +146,119 @@ a value two fields share in its own category and reference that. A field hold, t
|
|||||||
operand ties fields together within one column as always (see
|
operand ties fields together within one column as always (see
|
||||||
[Correlated fields](#correlated-fields) and [Decisions](#decisions)).
|
[Correlated fields](#correlated-fields) and [Decisions](#decisions)).
|
||||||
|
|
||||||
|
## Data
|
||||||
|
|
||||||
|
The shipped set under [`data/`](data) — one folder per locale (`en_US`, `sv_SE`)
|
||||||
|
plus a locale-neutral `misc` folder — is embedded, so the CLI and the library
|
||||||
|
work with no data on disk. A directory is a namespace: each JSON file is a
|
||||||
|
category named after the file, each subdirectory a dot-path segment, so
|
||||||
|
`mydata/sv_SE/person.json` is `sv_SE.person` and replaces the shipped one.
|
||||||
|
Sources merge in order; matching folders combine, any other clash is won by the
|
||||||
|
last loaded. Names may not use `.`, `|`, `(`, `{`, `}`, `[`, `]`, `"` or `/`, nor be
|
||||||
|
`-`, which a struct tag reserves; dot-prefixed entries are skipped, so a data directory can also be a checkout.
|
||||||
|
|
||||||
|
Each locale carries `address`, `color`, `company`, `date`, `email`, `first-name`,
|
||||||
|
`ip`, `last-name`, `person`, `phone`, `price`, `sentence`, `sex`, `time`, `url`,
|
||||||
|
`username`, `version` and `word`, formatted per locale; `sv_SE` adds
|
||||||
|
`personnummer` and `samordningsnummer`, `en_US` adds `ssn` and `itin`. `misc`
|
||||||
|
carries `car`, `coordinate`, `creditcard` (Luhn-valid), `currency` (ISO 4217),
|
||||||
|
`datetime` (RFC 3339), `emoji`, `httpmethod`, `httpstatus`, `language` (ISO 639-1,
|
||||||
|
with its 639-2/T code), `loglevel` (syslog severity), `mac`, `mimetype`, `objectid`,
|
||||||
|
`port`, `protocol`, `territory` (ISO 3166-1), `timezone` (IANA), `tld` (IANA root
|
||||||
|
zone), `useragent` and `uuid` (v4). Many carry sub-fields — `misc.currency.symbol`,
|
||||||
|
`misc.territory.alpha2`, `misc.httpstatus.code` — which `--list` shows. `car`,
|
||||||
|
`currency`, `httpmethod`, `httpstatus`, `language`, `loglevel`, `mimetype`, `port`,
|
||||||
|
`protocol`, `territory`, `timezone`, `tld` and `useragent` are [tables](#table), so
|
||||||
|
`misc.territory[SE].capital` and `misc.currency[Euro].symbol` select a row; `car` and
|
||||||
|
`useragent` carry no key or name, so they are drawn from rather than selected in.
|
||||||
|
|
||||||
|
`misc.httpmethod`, `misc.protocol` and `misc.port` are IANA's registries.
|
||||||
|
`misc.httpmethod` is the eight methods RFC 9110 defines and PATCH; the register's
|
||||||
|
other entries, WebDAV and DeltaV among them, do not ship. Its `safe` and
|
||||||
|
`idempotent` are `true` or `false`, so a Go `bool` reads them, though `--format json`
|
||||||
|
and `sql` write them as text, a table column carrying no datatype. `misc.protocol`
|
||||||
|
carries a `number` and a `name`, the keyword itself where the register spells none out,
|
||||||
|
and selects by either spelling.
|
||||||
|
`misc.port` is the TCP assignments, rendering the number a port field holds with the
|
||||||
|
IANA `service` beside it, and selecting by number alone. A draw spans the whole
|
||||||
|
register, so pin `misc.port[443]` where a fixture needs a port a reader recognises;
|
||||||
|
it stops at 49150, IANA assigning nothing above, so an ephemeral source port is
|
||||||
|
`{int(49152,65535)}`.
|
||||||
|
`misc.tld` is the root zone's delegated TLDs, keyed with the leading dot
|
||||||
|
`misc.territory.tld` already carries, `.se`. Its `type` is the register's —
|
||||||
|
`country-code`, `generic`, `generic-restricted`, `infrastructure` or `sponsored` — and
|
||||||
|
its `unicode` the form the register displays, `.рф` for `.xn--p1ai` and the key itself
|
||||||
|
for an ASCII one, which selects the row too, so `misc.tld[.рф]` renders `.xn--p1ai`. A
|
||||||
|
draw spans the whole zone, `.arpa` and `.zuerich` alike, so pin `misc.tld[.com]` where
|
||||||
|
a fixture needs one a reader recognises.
|
||||||
|
`misc.loglevel` is the eight syslog severities, rendering the keyword a configuration
|
||||||
|
writes, `err` and `info`, keyed by the numerical code a PRI encodes and selectable by
|
||||||
|
either, so `misc.loglevel[3]` and `misc.loglevel[err]` are one row.
|
||||||
|
`misc.loglevel.severity` is the name RFC 5424 spells, `Error` beside `err`; it
|
||||||
|
selects nothing, the code and the keyword do.
|
||||||
|
[`DATA-LICENSES.md`](DATA-LICENSES.md) names each table's source and licence.
|
||||||
|
|
||||||
|
`misc.timezone` is every zone tzdb gives a shipped territory, from one apiece for most
|
||||||
|
of them to dozens for the largest, weighted by the population GeoNames records in each,
|
||||||
|
so `misc.territory[US].timezone` draws `America/New_York` far more often than
|
||||||
|
`America/Nome`. It links to `misc.territory`, so `misc.territory[SE].timezone` is
|
||||||
|
`Europe/Stockholm` and a drawn territory and zone agree. Its `offset` is the zone's
|
||||||
|
*standard* offset, so do not pair it with a drawn `misc.datetime`: in a zone that
|
||||||
|
observes DST it is the wrong one half the year, which is what storing a zone name
|
||||||
|
avoids. A zone tzdb named recently — `Europe/Kyiv`, `America/Ciudad_Juarez` — is
|
||||||
|
rejected outright by a consumer resolving it against older tzdata, so where the
|
||||||
|
consumer validates the zone, pin one rather than draw it. There is no `UTC` row, tzdb
|
||||||
|
giving that name no territory — spell it as the text `"UTC"`. `misc.useragent` carries
|
||||||
|
`browser`, `device` and `os` beside the string, and `misc.car` a `make` and a `model`,
|
||||||
|
until an international source replaces them.
|
||||||
|
|
||||||
|
ISO 3166-1 codes territories, not sovereign states, so that is what the table is
|
||||||
|
called: Greenland and Åland have codes of their own, and `misc.territory.country`
|
||||||
|
names the state each belongs to — `DK` for Greenland, `FI` for Åland, and its own
|
||||||
|
code for a sovereign one, or for one the register names no state for.
|
||||||
|
|
||||||
|
`sex`, `first-name` and `last-name` are tables weighted by bearers, from SCB, the
|
||||||
|
SSA and the Census Bureau. `first-name` links to `sex`, so `sv_SE.sex[f].first-name`
|
||||||
|
draws a woman's name, and a name both sexes carry is a row under each, so
|
||||||
|
`en_US.sex[m].first-name[Taylor]` names the one a `first-name[Taylor]` alone cannot.
|
||||||
|
`person` reads one draw of the three, so its `first` and `sex` columns agree, and so
|
||||||
|
does a `personnummer` in the same render: its birth number, `sv_SE.birth-number`
|
||||||
|
under `sex`, is Skatteverket's test series, 238 for a woman and 239 for a man, which no
|
||||||
|
real person is ever given. `en_US.title` links to `sex` too, so a person's prefix
|
||||||
|
never contradicts it.
|
||||||
|
|
||||||
|
A person of a chosen sex is assembled from the tables — `sex[f].first-name` beside
|
||||||
|
`last-name` — while a shipped `personnummer` agrees with the sex its own render
|
||||||
|
*drew*, not with one a path selects. That test series is also small: a personnummer
|
||||||
|
is one of about 70,000 values, a day in 1930–2025 against the two birth numbers, so a
|
||||||
|
fixture past a few hundred rows repeats one and a `UNIQUE` column needs a category of
|
||||||
|
your own. `sv_SE.date` and `en_US.date` are uniform over 1970-01-01 to 2029-12-31,
|
||||||
|
`misc.datetime` over 2000-01-01 to 2029-12-31. What the two locales do not share:
|
||||||
|
`en_US.address` carries a `region` column the Swedish one has no use for, and
|
||||||
|
`sv_SE.title` has no `parent`, so it is selected as `sv_SE.title[dr]` rather than
|
||||||
|
inside a sex.
|
||||||
|
|
||||||
|
A `geo` folder holds one tree per country under its alpha-2 code: five
|
||||||
|
[linked tables](#linked-tables) named alike, and an `address` record over one
|
||||||
|
consistent draw of them, which the locale's `address` reads.
|
||||||
|
|
||||||
|
| Table | `geo.SE` | `geo.US` | Weight |
|
||||||
|
|-------|----------|----------|--------|
|
||||||
|
| `region` | län, by code or name | state, by USPS abbreviation or name; `code` is the FIPS code | population |
|
||||||
|
| `municipality` | kommun, by code or name | county, by FIPS code or name | population |
|
||||||
|
| `locality` | postort, by name | incorporated place of 25,000 people or more with a postal code of its own, by GEOID or name; Hawaii has none | tätort population, the kommun's where the postort names it, else 200; place population |
|
||||||
|
| `postal-code` | postnummer with street delivery, by code | ZCTA, by code | one; address ranges |
|
||||||
|
| `street` | gatunamn, the ten with most road segments per postort | street name, the ten with most address ranges per place | segments; address ranges |
|
||||||
|
|
||||||
|
`geo.SE.region[Skåne län].municipality` draws a kommun in Skåne,
|
||||||
|
`geo.SE.locality[Lund].street` a street in Lund, and
|
||||||
|
`geo.US.region[IL].locality[Springfield]` settles which Springfield. A region row
|
||||||
|
carries its `timezone`, the state's predominant zone, and a locality its `lat` and
|
||||||
|
`lon`. What ports across countries is the five table names, the `name` column,
|
||||||
|
selection by name, and the `address` record's columns `street`, `street-number`,
|
||||||
|
`postal-code` and `locality`; every other column is the country's own, `code` on a
|
||||||
|
Swedish region but `abbr` on a US one.
|
||||||
|
|
||||||
## Library
|
## Library
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -151,7 +270,7 @@ f, err := fejkdata.New(fejkdata.WithSeed(42))
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
v, err := f.Fake("sv_SE.address") // "Kungsvägen 68\n379 17 Stockholm"
|
v, err := f.Fake("sv_SE.address") // "Järvedsvägen 43\n891 77 Järved"
|
||||||
paths := f.List() // every path Fake accepts, sorted
|
paths := f.List() // every path Fake accepts, sorted
|
||||||
v, err = f.FakeTemplate("name: {/sv_SE.person.last}") // compile + render in one call
|
v, err = f.FakeTemplate("name: {/sv_SE.person.last}") // compile + render in one call
|
||||||
t, err := f.NewTemplate(`{"format":"name: {x}","x":["bosse","lina"]}`) // compile once
|
t, err := f.NewTemplate(`{"format":"name: {x}","x":["bosse","lina"]}`) // compile once
|
||||||
@@ -205,28 +324,6 @@ A `*Generator` is safe for concurrent use; a seeded sequence is reproducible onl
|
|||||||
when drawn from one goroutine. Changing how a value is composed shifts the seeded
|
when drawn from one goroutine. Changing how a value is composed shifts the seeded
|
||||||
stream for that value and everything drawn after it.
|
stream for that value and everything drawn after it.
|
||||||
|
|
||||||
## Data
|
|
||||||
|
|
||||||
The shipped set under [`data/`](data) — one folder per locale (`en_US`, `sv_SE`)
|
|
||||||
plus a locale-neutral `misc` folder — is embedded, so the CLI and the library
|
|
||||||
work with no data on disk. A directory is a namespace: each JSON file is a
|
|
||||||
category named after the file, each subdirectory a dot-path segment, so
|
|
||||||
`mydata/sv_SE/person.json` is `sv_SE.person` and replaces the shipped one.
|
|
||||||
Sources merge in order; matching folders combine, any other clash is won by the
|
|
||||||
last loaded. Names may not use `.`, `|`, `(`, `{`, `}`, `[`, `]`, `"` or `/`, nor be
|
|
||||||
`-`, which a struct tag reserves; dot-prefixed entries are skipped, so a data directory can also be a checkout.
|
|
||||||
|
|
||||||
Each locale carries `address`, `color`, `company`, `date`, `email`, `ip`,
|
|
||||||
`person`, `phone`, `price`, `sentence`, `ssn`, `time`, `url`, `username`,
|
|
||||||
`version` and `word`, formatted per locale. `misc` carries `car`, `coordinate`,
|
|
||||||
`country` (ISO 3166), `creditcard` (Luhn-valid), `currency` (ISO 4217), `emoji`,
|
|
||||||
`httpstatus`, `language` (ISO 639), `mac`, `mimetype`, `objectid`, `timezone`
|
|
||||||
(IANA), `useragent` and `uuid` (v4). Many carry sub-fields — `misc.currency.symbol`,
|
|
||||||
`misc.country.alpha2`, `misc.httpstatus.code` — which `--list` shows. `country`,
|
|
||||||
`currency`, `httpstatus`, `language` and `mimetype` are [tables](#table), so
|
|
||||||
`misc.country[SE].capital` and `misc.currency[Euro].symbol` select a row;
|
|
||||||
[`DATA-LICENSES.md`](DATA-LICENSES.md) names each table's source and licence.
|
|
||||||
|
|
||||||
## Data format
|
## Data format
|
||||||
|
|
||||||
Every value is a **node**, nestable without limit:
|
Every value is a **node**, nestable without limit:
|
||||||
@@ -378,12 +475,16 @@ numbers that skews the draw, and `parent` the table a column links to
|
|||||||
columns are the [record](#records)'s columns, so `--format csv` writes the rows and
|
columns are the [record](#records)'s columns, so `--format csv` writes the rows and
|
||||||
`--list` shows `country.alpha2`. A cell is a string node: `1{digits(2)} {digits(2)}`
|
`--list` shows `country.alpha2`. A cell is a string node: `1{digits(2)} {digits(2)}`
|
||||||
in a cell draws digits and `{/misc.uuid}` reads a reference, while `{name}` in a cell
|
in a cell draws digits and `{/misc.uuid}` reads a reference, while `{name}` in a cell
|
||||||
is refused, since a cell has no sibling. `New` proves the header, the options and every
|
is refused, since a cell has no sibling. Each cell may select its own row of another
|
||||||
|
table, `{/misc.currency[SEK].symbol}` on one row and `{/misc.currency[EUR].symbol}`
|
||||||
|
on the next, since only one row renders. `New` proves the header, the options and every
|
||||||
cell token, and refuses a TSV no category names, a key that is empty or repeats, a
|
cell token, and refuses a TSV no category names, a key that is empty or repeats, a
|
||||||
weight that is not a positive number, and a key or name holding `[`, `]`, `{`, `}`,
|
weight that is not a positive number, and a key or name holding `[`, `]`, `{`, `}`,
|
||||||
`"` or `|`, which a selector cannot spell; the rows are indexed on the first draw that
|
`"` or `|`, which a selector cannot spell; the rows are indexed on the first draw that
|
||||||
selects one. A `name` needs a `key`, since a name naming several rows is reported by
|
selects one. A `name` needs a `key`, since a name naming several rows is reported by
|
||||||
their keys, and a name spelling another row's key is refused, since the key would
|
their keys, or a `parent`, inside whose row a name names one row, so `first-name[Kim]`
|
||||||
|
is settled by the `sex` selected before it and a name repeating inside one parent row
|
||||||
|
is refused; a name spelling another row's key is refused, since the key would
|
||||||
select first and the name never. The table's options are its own — `rows`, `key`,
|
select first and the name never. The table's options are its own — `rows`, `key`,
|
||||||
`name`, `weight` and `parent` — so a column may be named `name`, as one usually is.
|
`name`, `weight` and `parent` — so a column may be named `name`, as one usually is.
|
||||||
|
|
||||||
@@ -393,11 +494,11 @@ inline template has no file beside it, so there it stays a choice.
|
|||||||
|
|
||||||
### Row selection
|
### Row selection
|
||||||
|
|
||||||
`[key]` or `[name]` after a table's name selects one row: `misc.country[SE]` and
|
`[key]` or `[name]` after a table's name selects one row: `misc.territory[SE]` and
|
||||||
`misc.country[Sweden]` name one row, and `misc.country[SE].capital` reads its column.
|
`misc.territory[Sweden]` name one row, and `misc.territory[SE].capital` reads its column.
|
||||||
A name naming several rows is an error listing their keys, unless a row selected
|
A name naming several rows is an error listing their keys, unless a row selected
|
||||||
before it settles which ([Linked tables](#linked-tables)). A selector is part of the path, so it works
|
before it settles which ([Linked tables](#linked-tables)). A selector is part of the path, so it works
|
||||||
wherever a path does: `Fake`, `FakeRecord`, a `{/misc.country[SE].capital}` reference
|
wherever a path does: `Fake`, `FakeRecord`, a `{/misc.territory[SE].capital}` reference
|
||||||
and a struct tag. A dot inside the brackets belongs to the key or name, so
|
and a struct tag. A dot inside the brackets belongs to the key or name, so
|
||||||
`city[St. Louis]` selects it. A path starts with a name, and `[` still opens a JSON
|
`city[St. Louis]` selects it. A path starts with a name, and `[` still opens a JSON
|
||||||
array at the start of a CLI argument, so `'[SE]'` alone names nothing.
|
array at the start of a CLI argument, so `'[SE]'` alone names nothing.
|
||||||
@@ -442,9 +543,10 @@ table another path in the group selects a row of, `{/city.name}` beside
|
|||||||
`{/country[SE].name}`, which the first token rendered would otherwise decide. `New`
|
`{/country[SE].name}`, which the first token rendered would otherwise decide. `New`
|
||||||
also refuses a link cell that is no key of the parent, a parent row no child links
|
also refuses a link cell that is no key of the parent, a parent row no child links
|
||||||
to, a chain of parents that closes, a table named like a column of any table above
|
to, a chain of parents that closes, a table named like a column of any table above
|
||||||
it, and a cell or format of a table that references a table of its own family, since
|
it, and a cell or format of a table that references a table of its own family, through
|
||||||
a row rendered whole would draw the family apart from itself: read the family from a
|
any template, a `repeat` or a `drawGroup` included, since a row rendered whole would
|
||||||
template beside it, or add the value as a column.
|
draw the family apart from itself: read the family from a template beside it, or add
|
||||||
|
the value as a column.
|
||||||
|
|
||||||
### Options and fields
|
### Options and fields
|
||||||
|
|
||||||
@@ -480,21 +582,34 @@ stays reproducible.
|
|||||||
| `{ulid()}` | sample | ULID, 26 Crockford base32 chars |
|
| `{ulid()}` | sample | ULID, 26 Crockford base32 chars |
|
||||||
| `{nanoid(n)}` | sample | URL-safe Nano ID, `n` chars |
|
| `{nanoid(n)}` | sample | URL-safe Nano ID, `n` chars |
|
||||||
| `{iban(CC)}` | sample | length- and mod-97-valid IBAN for BE, DE, DK, ES, FI, NO or SE |
|
| `{iban(CC)}` | sample | length- and mod-97-valid IBAN for BE, DE, DK, ES, FI, NO or SE |
|
||||||
|
| `{date(from,to,'layout')}` | sample | a second between two `YYYY-MM-DD` days, both included, in a quoted Go layout: `'2006-01-02'`, `'January 2, 2006'`, `'060102'`, `'2006-01-02T15:04:05Z'` |
|
||||||
|
| `{time('layout')}` | sample | a second within a day: `'15:04'`, `'3:04 PM'` |
|
||||||
| `{seq()}`, `{seq(name)}` | counter | next integer from 1 in this generator; `name` selects an independent counter |
|
| `{seq()}`, `{seq(name)}` | counter | next integer from 1 in this generator; `name` selects an independent counter |
|
||||||
| `{calc(expr)}`, `{calc(expr,dp)}` | computation | an arithmetic expression over sibling fields ([Computation](#computation)) |
|
| `{calc(expr)}`, `{calc(expr,dp)}` | computation | an arithmetic expression over sibling fields ([Computation](#computation)) |
|
||||||
| `{lowercase(x)}`, `{uppercase(x)}`, `{ascii(x)}` | transform | a field's value rewritten ([Transforms](#transforms)) |
|
| `{lowercase(x)}`, `{uppercase(x)}`, `{ascii(x)}` | transform | a field's value rewritten ([Transforms](#transforms)) |
|
||||||
|
|
||||||
A derivation reads what is to its left, so place it after its payload; the
|
A derivation reads what is to its left, so place it after its payload; the
|
||||||
buffer is per expansion, so a nested template keeps fixed parts out of the sum. A
|
buffer is per expansion, so a nested template keeps fixed parts out of the sum. A
|
||||||
Swedish personnummer is a Luhn checksum over the nine digits before it:
|
Swedish personnummer is a Luhn checksum over the nine digits before it, six of
|
||||||
|
them a birthdate:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{ "format": "{century}{core}", "century": ["19", "20"],
|
{ "format": "{date(1930-01-01,2010-12-31,'060102')}-{birth}{luhn()}", "birth": ["238", "239"] }
|
||||||
"core": { "format": "{digits(2)}{mmdd}-{digits(3)}{luhn()}", "mmdd": ["0115", "0704", "1218"] } }
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Renders e.g. `19811218-9876`. `{seq()}` spans `Fake` calls and `repeat`, resets
|
Renders e.g. `811218-2389`. A layout is Go's: the reference time `Mon Jan 2
|
||||||
with a new generator, and is the natural primary key for the SQL example above.
|
15:04:05 MST 2006` spelled as the output should look, quoted, since a layout may
|
||||||
|
carry the comma that separates arguments, with English names. Every second
|
||||||
|
between the two days is reachable, so a layout with a clock draws the time too, and
|
||||||
|
`from` may equal `to`, which is that one day. The instant is UTC, so a zone in the
|
||||||
|
layout prints `UTC` or `Z`.
|
||||||
|
The quotes delimit a layout outside a selector only, so `[O'Fallon]` in an
|
||||||
|
argument stays a name. Rejected at `New`: a bound that is no calendar date, or not
|
||||||
|
before the other; an unquoted layout, naming the single-quoted one; a layout naming no field, which is
|
||||||
|
text, as is one day in a layout with no clock; for `date` a layout naming no date
|
||||||
|
field, naming `time`; and for `time` a layout naming a date field, naming `date`. `{seq()}` spans `Fake`
|
||||||
|
calls and `repeat`, resets with a new generator, and is the natural primary key for
|
||||||
|
the SQL example above.
|
||||||
|
|
||||||
### Computation
|
### Computation
|
||||||
|
|
||||||
@@ -548,9 +663,9 @@ without naming `sv_SE`:
|
|||||||
|
|
||||||
Renders e.g. `Hej, Pat Smith!`. A reference path into a category is held like a
|
Renders e.g. `Hej, Pat Smith!`. A reference path into a category is held like a
|
||||||
[correlated](#correlated-fields) path, but for the whole render — one `Fake`, or one
|
[correlated](#correlated-fields) path, but for the whole render — one `Fake`, or one
|
||||||
record — rather than one format: `{.person.femalefirst} {.person.last}` name one
|
record — rather than one format: `{.person.first} {.person.last}` name one
|
||||||
person, as do the same two references in sibling fields or a nested template, and
|
person, as do the same two references in sibling fields or a nested template, and
|
||||||
`{lowercase(.person.femalefirst)}` reads that same draw. Each `repeat` iteration is
|
`{lowercase(.person.first)}` reads that same draw. Each `repeat` iteration is
|
||||||
a render of its own, in no group, so it draws anew, and a [draw group](#draw-group) holds a
|
a render of its own, in no group, so it draws anew, and a [draw group](#draw-group) holds a
|
||||||
draw apart. A bare reference names no field and makes its own picks each time —
|
draw apart. A bare reference names no field and makes its own picks each time —
|
||||||
`{/misc.uuid} {/misc.uuid}` is two draws — while the reference paths inside what it
|
`{/misc.uuid} {/misc.uuid}` is two draws — while the reference paths inside what it
|
||||||
@@ -569,8 +684,8 @@ its groups by name; the unnamed group spans them all.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{ "format": "{payer} pays {payee}; signed {signature}",
|
{ "format": "{payer} pays {payee}; signed {signature}",
|
||||||
"payer": { "format": "{/sv_SE.person.femalefirst} {/sv_SE.person.last}", "drawGroup": "payer" },
|
"payer": { "format": "{/sv_SE.person.first} {/sv_SE.person.last}", "drawGroup": "payer" },
|
||||||
"payee": "{/sv_SE.person.femalefirst} {/sv_SE.person.last}",
|
"payee": "{/sv_SE.person.first} {/sv_SE.person.last}",
|
||||||
"signature": { "format": "{/sv_SE.person.last}", "drawGroup": "payer" } }
|
"signature": { "format": "{/sv_SE.person.last}", "drawGroup": "payer" } }
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -647,7 +762,7 @@ a minor only adds, and a major is the only release that changes what exists.
|
|||||||
| Surface | Major | Minor |
|
| Surface | Major | Minor |
|
||||||
|---------|-------|-------|
|
|---------|-------|-------|
|
||||||
| Shipped data | remove or rename a path; change a category's format; remove a value, or change a weight or a repeat; add a reference from one shipped category into another; change a table's key, name, weight or parent column, or remove a row | a path outside a record's columns, a locale, a value in a list, a row |
|
| Shipped data | remove or rename a path; change a category's format; remove a value, or change a weight or a repeat; add a reference from one shipped category into another; change a table's key, name, weight or parent column, or remove a row | a path outside a record's columns, a locale, a value in a list, a row |
|
||||||
| Records | remove, rename, retype or add a column; let a column be null | a record, as a new category |
|
| Records (a table is one) | remove, rename, retype or add a column; let a column be null | a record, as a new category |
|
||||||
| Data format | a fence: a spelling `New` rejects that it accepted; a template option, since it reserves a field name | a builtin |
|
| Data format | a fence: a spelling `New` rejects that it accepted; a template option, since it reserves a field name | a builtin |
|
||||||
| CLI | remove or rename a flag, or change its default; change what an exit code means; change the framing a `--format` writes (header, quoting, statement shape), the `--list` layout, or what an error names | a flag, a format |
|
| CLI | remove or rename a flag, or change its default; change what an exit code means; change the framing a `--format` writes (header, quoting, statement shape), the `--list` layout, or what an error names | a flag, a format |
|
||||||
| Library | change or remove an exported name; raise the lowest supported Go | an exported name, a `With…` option |
|
| Library | change or remove an exported name; raise the lowest supported Go | an exported name, a `With…` option |
|
||||||
@@ -672,30 +787,71 @@ datatype and nullability, and each table's key, name, weight and parent columns;
|
|||||||
changes it or `data/` adds its `CHANGELOG.md` entry, which CI checks. A removed,
|
changes it or `data/` adds its `CHANGELOG.md` entry, which CI checks. A removed,
|
||||||
renamed or retyped line is a major.
|
renamed or retyped line is a major.
|
||||||
|
|
||||||
|
## Audience
|
||||||
|
|
||||||
|
App developers writing tests and fixtures, in Go and at a shell:
|
||||||
|
|
||||||
|
- a **bulk fixture author**, thousands of rows into CSV or SQL
|
||||||
|
- a **Go test author**, filling a struct with `FakeStruct`
|
||||||
|
- a **hand fixture author**, one value at a shell
|
||||||
|
- a **validator-facing author**, who needs a value a real checker accepts
|
||||||
|
|
||||||
|
and a **contributor**, who reads [`todo.md`](todo.md), [`AGENTS.md`](AGENTS.md) and
|
||||||
|
the Development section below, and who ships a register the four above then draw from.
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
||||||
1. **Valid by construction** — every value passes the check its real consumer
|
1. **The best fake-data tool available, and used because it is** — a developer
|
||||||
|
choosing a seed-data library or CLI, in any language, should find this the one
|
||||||
|
worth switching to, and every goal below it is what that costs. Merit is only
|
||||||
|
half the goal: once the grammar, the data and the CLI are complete and stable,
|
||||||
|
it ships where those developers install from and is announced where they read.
|
||||||
|
2. **Understanding the code is part of the product** — it is a compiler with static
|
||||||
|
fences behind a small API, it will grow, and the people who extend it will not be
|
||||||
|
the people who wrote it. So reading cost is judged alongside behaviour: reaching
|
||||||
|
the unit behind a symptom without asking a person, changing one piece without
|
||||||
|
holding the rest, names that tell the truth, and a file that stands with no second
|
||||||
|
document open beside it. A simulated reader panel scores those four, the score is a
|
||||||
|
ratchet no release lowers, and [`AGENTS.md`](AGENTS.md) says what each pull request
|
||||||
|
owes it.
|
||||||
|
3. **Valid by construction** — every value passes the check its real consumer
|
||||||
applies; facts that belong together come from one draw, within a value and
|
applies; facts that belong together come from one draw, within a value and
|
||||||
across categories.
|
across categories.
|
||||||
2. **Text means what it says** — a format renders as written; only `{…}` varies,
|
4. **Text means what it says** — a format renders as written; only `{…}` varies,
|
||||||
random characters included (`{digits(3)}`). One spelling per result; the wrong
|
random characters included (`{digits(3)}`). One spelling per result; the wrong
|
||||||
one is a load error naming the right one.
|
one is a load error naming the right one.
|
||||||
3. **Every mistake is a load error** — `New` rejects the data and `NewTemplate`
|
5. **Every mistake is a load error** — `New` rejects the data and `NewTemplate`
|
||||||
the inline template; on a loaded generator `Fake` fails only for an unknown
|
the inline template; on a loaded generator `Fake` fails only for an unknown
|
||||||
path, `FakeStruct` only for a non-struct argument or a type its tags do not
|
path, `FakeStruct` only for a non-struct argument or a type its tags do not
|
||||||
describe, with the same error every call, and `Template.Fake` cannot fail at all.
|
describe, with the same error every call, and `Template.Fake` cannot fail at all.
|
||||||
4. **Zero to a value in one command** — `go install`, then `fejkdata sv_SE.person`:
|
6. **Zero to a value in one command** — `go install`, then `fejkdata sv_SE.person`:
|
||||||
no checkout, no flag. Flags are GNU-form (`--seed 42`, `-n 3`) in any position;
|
no checkout, no flag. Flags are GNU-form (`--seed 42`, `-n 3`) in any position;
|
||||||
the first custom template needs no escape and no option.
|
the first custom template needs no escape and no option.
|
||||||
5. **Data lives in JSON** — a builtin only for what data can't express.
|
7. **Data lives in JSON** — a builtin only for what data can't express.
|
||||||
6. **Reproducible** — seed in, same stream out; no builtin reads a clock.
|
8. **Reproducible** — seed in, same stream out; no builtin reads a clock.
|
||||||
7. **Zero dependencies** — standard library only.
|
9. **Zero dependencies** — standard library only.
|
||||||
8. **Docs index the grammar** — every syntax feature is a heading; every example
|
10. **Docs index the grammar** — every syntax feature is a heading; every example
|
||||||
runs under test and shows its output; a rule is stated once.
|
runs under test and shows its output; a rule is stated once.
|
||||||
9. **Fast enough to be free** — a value renders in about a microsecond and `New`
|
11. **Fast enough to be free** — a value renders in about a microsecond and `New`
|
||||||
parses and validates the whole set once upfront, so generating fixtures stays
|
parses and validates the whole set once upfront, so generating fixtures stays
|
||||||
noise against a test's own runtime.
|
noise against a test's own runtime.
|
||||||
|
12. **Data is sourced, or on its way there** — a shipped fact, a name, place,
|
||||||
|
code, id or classification, is read from a register or open dataset by a
|
||||||
|
[`data-import/`](data-import) script wherever one exists to read; where none
|
||||||
|
does yet a small hand-written set ships and [`todo.md`](todo.md) carries the
|
||||||
|
step that replaces it. Only non-factual copy stays authored. A sourced table
|
||||||
|
holds the rows its source holds: none is added by hand, and one is dropped
|
||||||
|
only by a rule the script states.
|
||||||
|
13. **Breadth follows what most systems store** — a category is added in proportion
|
||||||
|
to how many real schemas hold it: names, addresses, phones, ids, money and
|
||||||
|
timestamps before anything domain-specific, and a catalogue serving one niche
|
||||||
|
waits behind everything serving many.
|
||||||
|
14. **Realism is the default, inertness is selectable** — where a value could reach
|
||||||
|
something real, a domain anyone may register or an account a bank could issue,
|
||||||
|
the realistic breadth ships *and* so does the subset that provably reaches
|
||||||
|
nothing, each on its own path. A fixture that looks nothing like production
|
||||||
|
tests nothing; the caller who needs a value that can touch nothing asks for it
|
||||||
|
by name.
|
||||||
## Decisions
|
## Decisions
|
||||||
|
|
||||||
- **Options and fields share one namespace.** `format`, `weight`, `repeat`,
|
- **Options and fields share one namespace.** `format`, `weight`, `repeat`,
|
||||||
@@ -703,8 +859,7 @@ renamed or retyped line is a major.
|
|||||||
key, or prefixing options, would tax every template to guard against a
|
key, or prefixing options, would tax every template to guard against a
|
||||||
misspelt option.
|
misspelt option.
|
||||||
- **`{a|b}` stays beside nested choices.** `[[…], […]]` picks the same way, but
|
- **`{a|b}` stays beside nested choices.** `[[…], […]]` picks the same way, but
|
||||||
its arms are anonymous; `{femalefirst|malefirst}` keeps `person.femalefirst`
|
its arms are anonymous; `{female|male}` keeps `person.female` addressable.
|
||||||
addressable.
|
|
||||||
- **Flags follow getopt_long.** `--name value` and `--name=value` both work; a
|
- **Flags follow getopt_long.** `--name value` and `--name=value` both work; a
|
||||||
short flag's value attaches or follows (`-s42`, `-s 42`) and short flags bundle
|
short flag's value attaches or follows (`-s42`, `-s 42`) and short flags bundle
|
||||||
(`-hn 3`), as every shell user expects. A single-dash long flag is rejected
|
(`-hn 3`), as every shell user expects. A single-dash long flag is rejected
|
||||||
@@ -722,7 +877,9 @@ renamed or retyped line is a major.
|
|||||||
library's own advice reachable: the error for an object holding only a format
|
library's own advice reachable: the error for an object holding only a format
|
||||||
names `"…"`, and that spelling has to work where it is printed. An argument or struct
|
names `"…"`, and that spelling has to work where it is printed. An argument or struct
|
||||||
tag of one reference alone, `{/users}`, is refused naming the path `users`: both
|
tag of one reference alone, `{/users}`, is refused naming the path `users`: both
|
||||||
render the same text, and only the path names a record. `IsTemplate` exports the
|
render the same text, and only the path names a record. A folder-relative `{.name}`
|
||||||
|
or `{..name}` is refused naming `{/name}`, since an inline template sits in no
|
||||||
|
folder. `IsTemplate` exports the
|
||||||
rule, so the CLI, struct tags and any other caller read one.
|
rule, so the CLI, struct tags and any other caller read one.
|
||||||
- **An inline template skips the cycle fence.** `New` proves the loaded tree
|
- **An inline template skips the cycle fence.** `New` proves the loaded tree
|
||||||
acyclic, an inline node is a finite tree of its own, and nothing in the tree can
|
acyclic, an inline node is a finite tree of its own, and nothing in the tree can
|
||||||
@@ -947,8 +1104,7 @@ renamed or retyped line is a major.
|
|||||||
A table is a category with a TSV beside its file, so only a root choice has the
|
A table is a category with a TSV beside its file, so only a root choice has the
|
||||||
spelling the fence names; a nested choice of same-shaped templates and an inline
|
spelling the fence names; a nested choice of same-shaped templates and an inline
|
||||||
one keep loading. Fields must all be strings because a cell is a string node: a
|
one keep loading. Fields must all be strings because a cell is a string node: a
|
||||||
choice whose items carry a nested choice, as `misc.car` does, is not one table but
|
choice whose items carry a nested choice is not one table but two linked ones.
|
||||||
two linked ones, which a later conversion writes.
|
|
||||||
- **A table is a record of string columns.** Its columns are the CSV header and the
|
- **A table is a record of string columns.** Its columns are the CSV header and the
|
||||||
`INSERT` column list, fixed by the TSV header, so a table is a record by
|
`INSERT` column list, fixed by the TSV header, so a table is a record by
|
||||||
construction; every column is a string until a typed column option earns its place.
|
construction; every column is a string until a typed column option earns its place.
|
||||||
@@ -956,11 +1112,218 @@ renamed or retyped line is a major.
|
|||||||
against the parent's keys and a key's uniqueness is a data mistake, so both are
|
against the parent's keys and a key's uniqueness is a data mistake, so both are
|
||||||
load-time; the name index and the per-parent child lists serve only a draw or a
|
load-time; the name index and the per-parent child lists serve only a draw or a
|
||||||
selection, so they wait for the first one, keeping `New` linear in the bytes read.
|
selection, so they wait for the first one, keeping `New` linear in the bytes read.
|
||||||
|
- **Two categories may name one TSV.** Each is a view of the file with its own
|
||||||
|
format and options, at the cost of holding the rows twice, which is what a
|
||||||
|
category over a register with two natural formats asks for; a TSV nothing names
|
||||||
|
stays a load error, since that one is a file forgotten rather than shared.
|
||||||
|
- **The rows of a table are alternatives.** Only one row renders, so a cell in one
|
||||||
|
row and a cell in another never meet, and each may select its own row of another
|
||||||
|
table; the cells of one row, and whatever they reach, do meet, and so does the
|
||||||
|
format beside them. The rule the fence applies is that two reads meet unless
|
||||||
|
they sit in two rows of one table, or in a row outside a selected ancestor's. A
|
||||||
|
choice's items get no such treatment yet: two items selecting different rows
|
||||||
|
are still refused.
|
||||||
|
- **A table never reaches its own family, by any route.** A `repeat` iteration and a
|
||||||
|
`drawGroup` each draw apart on purpose, but a row that lists three localities from
|
||||||
|
other regions is the output the family exists to prevent, so the own-family fence
|
||||||
|
walks through both rather than stopping where the draw fences do.
|
||||||
|
- **Tables carrying token cells stay small.** The family fence compares the reads of
|
||||||
|
every pair of rows that can render together, so a table whose every row's cell
|
||||||
|
selects a row of another table loads in time quadratic in its rows: about a
|
||||||
|
second at four thousand rows. No shipped table carries such cells, and a register
|
||||||
|
is a column set rather than a set of references, so the fence is left as it is
|
||||||
|
until a real data set needs the indexed form.
|
||||||
|
- **A path is walked once without drawing before it is walked for real.** A path
|
||||||
|
that fails below its first level then moves no seeded stream, at the cost of one
|
||||||
|
draw-free walk per call, which allocates nothing.
|
||||||
|
- **A country's postal codes and streets are siblings under its locality.** No open
|
||||||
|
source pairs a Swedish street with its postnummer, and pairing the US through its
|
||||||
|
ZIPs would shape the two trees differently, so both draw inside the pinned
|
||||||
|
locality and an address agrees at that level. A street's own code is the exact
|
||||||
|
pairing to add when a source carries it.
|
||||||
|
- **A locale's `address` reads its country's `geo` tree, so the shipped set loads
|
||||||
|
whole.** `data/sv_SE` alone no longer loads: a test loads `data` and prefixes
|
||||||
|
the locale, and `--no-shipped-data -d` takes the whole `data` folder or a set of
|
||||||
|
one's own.
|
||||||
|
- **The default embed holds every Swedish postort the import can place and give a
|
||||||
|
street-delivery code and a street, and the US places of 25,000 or more.** Sweden
|
||||||
|
fits whole in 700 KB; every US place of 10,000 would pass a
|
||||||
|
megabyte and fetch 1,200 counties of TIGER files, so the threshold sits where the
|
||||||
|
two countries match in size, and `--min-population` and
|
||||||
|
`--streets-per-locality` on the import scripts build a fuller set. The two trees
|
||||||
|
add about 20 ms to `New`, which loads the shipped set in about 45 ms.
|
||||||
|
- **A locale's `address` restates its country record's format.** A record cannot
|
||||||
|
read another whole and keep its columns, so `sv_SE.address` names the same four
|
||||||
|
columns as `geo.SE.address`, each a reference into it, and the format appears
|
||||||
|
twice; a column is spelled the same in both, `street-number`, so the two never
|
||||||
|
disagree on a name.
|
||||||
|
- **A postort's kommun comes from its name, its tätort or its codes, never from
|
||||||
|
distance.** GeoNames leaves a fifth of Sweden's codes without a kommun and
|
||||||
|
carries stale spellings; the nearest code across a border named the wrong kommun
|
||||||
|
half the time it was tried, so a postort none of the three rules place is
|
||||||
|
dropped, as is one not cased like a place name.
|
||||||
|
- **A highway designation is not a street, and a US postal code belongs to the place
|
||||||
|
holding most of its land inside places.** `I- 55 Bus` and `US Hwy 1` carry the
|
||||||
|
most address ranges in many places and would head every address, so the import
|
||||||
|
drops names spelled as a route. A ZCTA goes to the place its largest in-place part
|
||||||
|
lies in, census-designated places left out since they never ship, and ships only
|
||||||
|
when that place does, so a few dozen places whose every code lies mostly in a
|
||||||
|
bigger neighbour ship no address; counting the land outside every place too would
|
||||||
|
drop a quarter of the places, whose codes straddle unincorporated land, for a
|
||||||
|
postal city the USPS mostly names the same way.
|
||||||
|
- **`--list` stays a plain list of paths.** It is what a script reads, so every line
|
||||||
|
has to be a path that `Fake` takes; a marker for the tables a `[selector]` follows,
|
||||||
|
or a legend above them, would make the output something to parse before use.
|
||||||
|
`--help` names the selector spelling instead, and the Table section teaches it.
|
||||||
|
- **A layout is always quoted.** A layout may carry the comma that separates
|
||||||
|
arguments, `'January 2, 2006'`, and one spelling for every layout beats a rule
|
||||||
|
about which ones need the quotes, so the bare spelling is refused naming the
|
||||||
|
quoted one. The layout is Go's reference time because the library renders with
|
||||||
|
it and a Go caller already knows it; its names are English, and a locale's own
|
||||||
|
month and weekday names are data.
|
||||||
|
- **A title is a table under `sex`.** A prefix drawn apart would put `Mr` on a record
|
||||||
|
whose `sex` column says `female`, which is the disagreement the record exists to
|
||||||
|
prevent; the tables this set already has are what a title needs, so `en_US.title`
|
||||||
|
links to `sex` as `first-name` does. Swedish has no everyday sexed honorific, so
|
||||||
|
`sv_SE.title` is a table as well but carries no `parent`. Its weight column is
|
||||||
|
`share`, not the `count` a name table carries, because the values are a curated
|
||||||
|
proportion rather than bearers anyone counted.
|
||||||
|
- **A table owns the spelling of a selector on it.** A reference reaches a table by a
|
||||||
|
path that carries no selector — `sv_SE.person.first` reads `first-name` through
|
||||||
|
`sex` — so the walk that resolved a name cannot say where a reader would type one.
|
||||||
|
The table's own location can, which is why it keeps its path, and why an ambiguity
|
||||||
|
error names `sv_SE.sex[f].first-name[Kim]` rather than the table's own name.
|
||||||
|
- **No builtin reads the clock, so a date is bounded by days, never by an age.**
|
||||||
|
An `age(min,max)` would make a seeded fixture change with the day it runs on,
|
||||||
|
which is what a seed exists to prevent; a birthdate for someone 20 to 60 is
|
||||||
|
`date(1966-01-01,2006-12-31,…)`, re-pinned as any fixture is.
|
||||||
|
- **A name column without a key resolves inside its parent.** A given name both
|
||||||
|
sexes carry is a row under each, so `name` cannot be the key; the parent's row
|
||||||
|
tells the two apart, `sex[f].first-name[Kim]`, the ambiguity error spells each
|
||||||
|
row inside its parent, and a name repeating inside one parent row is refused at
|
||||||
|
load, since nothing could then select it.
|
||||||
|
- **`misc` is what every locale shares.** A category whose facts differ by country
|
||||||
|
belongs in that country's locale, read from the register that country's own
|
||||||
|
records use; `misc` takes only sources that are international. NHTSA vPIC and
|
||||||
|
Mobility Sweden's registrations are national, so they build `en_US.car` and
|
||||||
|
`sv_SE.car`; `misc.car` waits for an international source rather than take one
|
||||||
|
of theirs.
|
||||||
|
- **A register's canonical spelling loses to the one its domain writes.** Where a
|
||||||
|
source offers several spellings of one fact, the shipped one is what records in
|
||||||
|
that domain carry. `misc.timezone` reads `zone.tab` and not the `zone1970.tab`
|
||||||
|
that supersedes it, because the latter keeps one zone per set of countries that
|
||||||
|
have agreed since 1970: it spells Sweden `Europe/Berlin`, and no Swedish system
|
||||||
|
writes that. For the same reason `misc.language` takes the ISO 639-2 register's
|
||||||
|
first synonym over CLDR, which says "Chinese, Mandarin" for `zh`.
|
||||||
|
- **`misc.territory` is the spine, and a `misc` table naming a territory links to
|
||||||
|
it.** Where every territory row has a child the column is a `parent`, and the
|
||||||
|
import drops the child rows whose territory the set does not ship — 17 of
|
||||||
|
`misc.timezone`'s, Antarctica's ten among them. Agreement across a record is
|
||||||
|
worth more than the last rows of a table. Where no such link can hold the fact
|
||||||
|
stays a column. Layer your own `misc.territory` over the shipped one and you
|
||||||
|
must layer `misc.timezone` too, or the link fails at load naming the row.
|
||||||
|
- **A table whose register publishes no frequency draws evenly.** `misc.httpmethod`,
|
||||||
|
`misc.port`, `misc.httpstatus`, `misc.mimetype` and `misc.tld` weigh every row alike,
|
||||||
|
so GET is a ninth of the methods drawn. Goal 10 keeps an authored fact out of a
|
||||||
|
sourced table, and no register publishes how often a method, a port or a TLD is used,
|
||||||
|
so a weight here would be invented. Where one exists it is read, as `misc.timezone`
|
||||||
|
reads GeoNames populations and `sv_SE.first-name` SCB bearers.
|
||||||
|
- **`misc.port` selects by number, and carries no `name`.** 29 of its services sit on
|
||||||
|
more than one port, `http-alt` on three, so `misc.port[http-alt]` could name no one
|
||||||
|
row. The number is what a port field holds anyway, and `misc.port[443].service`
|
||||||
|
reads the other way.
|
||||||
|
- **`misc.car` is one flat table, not a make linked to its models.** A row is a make
|
||||||
|
and a model drawn together, so no render pairs a Volvo with a RAV4. Two linked
|
||||||
|
tables would reach the same pairs and add a selector nothing asks for; a make alone
|
||||||
|
is `misc.car.make`.
|
||||||
|
- **`misc.territory` names its sovereign in a column, and there is no `misc.country`
|
||||||
|
table.** ISO 3166-1 codes territories, so `territory` is the honest name, and
|
||||||
|
`is_independent` in the register gives each one's state. A second table of the 195
|
||||||
|
sovereigns would hold a `DK` row beside the territory `DK` row, both carrying
|
||||||
|
Denmark's capital, currency, flag and TLD — two owners for one fact, drifting at
|
||||||
|
the next import. Splitting the columns to avoid that is worse: put `capital` on
|
||||||
|
the territory alone and a country row can no longer name Copenhagen. The column
|
||||||
|
cannot be a `parent`, since a table never reaches its own family; a test proves
|
||||||
|
every value names a row instead. A territory the register records no state for
|
||||||
|
stands alone, which is `EH` alone, and naming one for it would be a claim
|
||||||
|
fejkdata has no business making.
|
||||||
|
- **`misc.loglevel` is a table keyed by the code, rendering POSIX's keyword.** A flat
|
||||||
|
list of names carries neither the code a PRI encodes nor a selector reaching it, and
|
||||||
|
goal 3 draws the two as one fact. The canonical spelling losing to the one its domain
|
||||||
|
writes, above, settles the rest: a configuration writes `info`, so RFC 5424's
|
||||||
|
`Informational` stays the `severity` column, and the code and the keyword hold the
|
||||||
|
two selector slots.
|
||||||
|
- **`misc.tld` keys carry the leading dot, where other tables key on a bare code.**
|
||||||
|
The register spells a TLD `.se` and `misc.territory.tld` already ships it so, which a
|
||||||
|
bare key would make two spellings of one fact; `{/misc.tld}` also composes onto a
|
||||||
|
host with no separator. `misc.tld[se]` misses for it, which `todo.md` carries.
|
||||||
|
- **`misc.tld` is a table of its own, and `misc.territory.tld` stays a column.** A
|
||||||
|
`parent` demands a child for every parent row, so linking them would drop every root
|
||||||
|
zone row naming no territory, which is most of them, and goal 12 holds a sourced
|
||||||
|
table whole. The loader refuses the link outright anyway: `tld` is a column of
|
||||||
|
`misc.territory`, and a table may not be named like a column of its ancestor.
|
||||||
|
- **`misc.territory` carries a currency code, it does not link to `misc.currency`.**
|
||||||
|
A `parent` demands a child for every parent row, and ISO 4217 registers codes no
|
||||||
|
country's row can name: the funds codes (Mvdol, WIR Euro, US Dollar (Next day)),
|
||||||
|
and VED beside VES, both Venezuela's, of which a country row names one. Linking
|
||||||
|
would trade the register for the link, and `misc.territory.currency` already pairs a
|
||||||
|
country with its currency in one draw.
|
||||||
|
- **An extension may name two media types.** `.xml`, `.rtf`, `.sub`, `.mpp` and `.ac`
|
||||||
|
each name two rows of `misc.mimetype`. Separating them would mean dropping a
|
||||||
|
registered type, or naming one by an extension that is not its own — `.mpt` is
|
||||||
|
Project's template, not its document. Selecting such a name is an error listing
|
||||||
|
both keys; select by type instead.
|
||||||
|
- **The Swedish ids draw Skatteverket's test series.** A Luhn-valid personnummer
|
||||||
|
over a random birth number may be a living person's; 238 and 239 after any date
|
||||||
|
are blocked from assignment, so the shipped `personnummer` and
|
||||||
|
`samordningsnummer` use those. They sit in a `birth-number` table under `sex`
|
||||||
|
rather than as a column of it: the render's shared draw of the family is what
|
||||||
|
makes the number and the name agree on sex, and `sex` stays one shape across
|
||||||
|
locales instead of collecting every sex-keyed id fact. A samordningsnummer's
|
||||||
|
day, the birthday plus 60, is drawn from 61 to 88, valid in every month, rather
|
||||||
|
than computed from the date drawn.
|
||||||
|
- **The US given names come from a mirror of the SSA file.** ssa.gov refuses a
|
||||||
|
client outside the US, so `names-us.py` reads a GitHub copy that ends at 2020,
|
||||||
|
which a count over the births since 1930 barely feels; `--names` takes the
|
||||||
|
official zip. The SSA's placeholder rows are top-1000 entries that name nobody, so
|
||||||
|
the import drops them by name rather than by a rank a regeneration would move.
|
||||||
- **`List` advertises direct descents only.** `region.municipality.locality` is
|
- **`List` advertises direct descents only.** `region.municipality.locality` is
|
||||||
listed, and `region.locality` resolves too but is not: the set of every descent
|
listed, and `region.locality` resolves too but is not: the set of every descent
|
||||||
through a chain of five tables is every subsequence of it, and the direct chain is
|
through a chain of five tables is every subsequence of it, and the direct chain is
|
||||||
the one a reader can predict from the tables' parents.
|
the one a reader can predict from the tables' parents.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
fejkdata.go Generator, New, options, the embedded data set, List
|
||||||
|
node.go the node model and JSON -> node compilation
|
||||||
|
table.go tables: the rows TSV, its options and links, row selection and draws
|
||||||
|
path.go the dotted-path walk with its selectors, and proving a path resolves
|
||||||
|
render.go Fake and the recursive renderer (choices, format strings, expansions)
|
||||||
|
record.go records: Record, the JSON/CSV/SQL serializers, and their entry points
|
||||||
|
struct.go structs: FakeStruct, fake tags, and a field's Go type as its column's datatype
|
||||||
|
inline.go inline templates: Template, NewTemplate, FakeTemplate, IsTemplate, and their compile and link
|
||||||
|
template.go the {token} grammar: scanning, tokens, operands, validation, compiling a format
|
||||||
|
hold.go the hold: one draw per expansion for paths and operands, and its fences
|
||||||
|
draw.go one reference draw per render and group: draw sets, the group option, and its fence
|
||||||
|
family.go a family of linked tables: the rows a render pins, and the fence over paths into one family
|
||||||
|
reference.go reference sigils, and binding references across the tree
|
||||||
|
graph.go the render graph: edges, cycles, the repeat bound, tree walks
|
||||||
|
builtins.go the {name()} function registry and its implementations
|
||||||
|
layout.go date and time layouts: the instants one is proved against, and the two samples
|
||||||
|
checksum.go the check characters a derivation appends, and the IBAN they sit inside
|
||||||
|
transform.go the builtins that rewrite an operand's value, and the ASCII folding
|
||||||
|
calc.go the {calc()} arithmetic evaluator: parser, eval, validation
|
||||||
|
datatype.go column datatypes: DataType, where datatype and null may sit, a column's datatype
|
||||||
|
value.go the value proof: what a typed column or calc operand holds, checked at load
|
||||||
|
data.go data loading: fs.FS folders/files -> namespace tree, multi-source merge
|
||||||
|
cmd/fejkdata/ the fejkdata CLI
|
||||||
|
data/ shipped data (JSON, and a TSV per table), embedded at build: locale folders, geo, misc
|
||||||
|
data-import/ the scripts that rebuild each sourced table (see DATA-LICENSES.md)
|
||||||
|
release-tooling/ the release CI publishes from the changelog heading
|
||||||
|
testdata/ the pinned shipped shape (see Versioning)
|
||||||
|
```
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Everything runs in Docker — **no local tooling beyond Docker is needed**.
|
Everything runs in Docker — **no local tooling beyond Docker is needed**.
|
||||||
@@ -983,6 +1346,15 @@ docker compose run --rm --user "$(id -u):$(id -g)" fmt # gofmt -w .
|
|||||||
docker compose run --rm --user "$(id -u):$(id -g)" tidy # go mod tidy
|
docker compose run --rm --user "$(id -u):$(id -g)" tidy # go mod tidy
|
||||||
```
|
```
|
||||||
|
|
||||||
|
A `--user` command answering `permission denied` on `/cache` has met root-owned
|
||||||
|
files in the `gocache` volume: Docker creates the volume root-owned, and every
|
||||||
|
command here that omits `--user` writes into it as root. Hand it back, and again
|
||||||
|
whenever it recurs:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose run --rm --user root --entrypoint chown test -R "$(id -u):$(id -g)" /cache
|
||||||
|
```
|
||||||
|
|
||||||
Every pull request runs `docker build .` against both the latest and the lowest
|
Every pull request runs `docker build .` against both the latest and the lowest
|
||||||
supported Go, and must pass before it can be merged — unless it changes none of
|
supported Go, and must pass before it can be merged — unless it changes none of
|
||||||
the files the build and its tests read, nor the workflow itself, in which case
|
the files the build and its tests read, nor the workflow itself, in which case
|
||||||
@@ -1005,11 +1377,33 @@ REPIN=1 docker compose run --rm --user "$(id -u):$(id -g)" test
|
|||||||
|
|
||||||
A shipped table built from a source is rebuilt by its script under
|
A shipped table built from a source is rebuilt by its script under
|
||||||
[`data-import/`](data-import), one command per dataset, fetching the source named in
|
[`data-import/`](data-import), one command per dataset, fetching the source named in
|
||||||
[`DATA-LICENSES.md`](DATA-LICENSES.md):
|
[`DATA-LICENSES.md`](DATA-LICENSES.md). Downloads are cached under
|
||||||
|
`data-import/cache/`, which is ignored by version control and grows past a
|
||||||
|
gigabyte, so pass `--cache DIR` to reuse a copy you already have and delete it to
|
||||||
|
fetch afresh; `geo-us.py` fetches two
|
||||||
|
TIGER/Line files per county it ships, a few hundred megabytes, `geo-se.py` needs
|
||||||
|
a Trafikverket API key, free at [data.trafikverket.se](https://data.trafikverket.se/),
|
||||||
|
in `TRAFIKVERKET_API_KEY` or a `--key-file`, and the Census host behind `geo-us.py`
|
||||||
|
and `names-us.py` rejects a client for a while after a burst, so `--surnames` takes
|
||||||
|
a copy of the surname file:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/country.py
|
|
||||||
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/currency.py
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/currency.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" -e TRAFIKVERKET_API_KEY data-import data-import/geo-se.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/geo-us.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/httpmethod.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/httpstatus.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/language.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/loglevel.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/mimetype.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/names-se.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/names-us.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/port.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/protocol.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/territory.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/timezone.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/tld.py
|
||||||
|
docker compose run --rm --user "$(id -u):$(id -g)" data-import data-import/useragent.py
|
||||||
```
|
```
|
||||||
|
|
||||||
To release, head `CHANGELOG.md` with the version's section in place of `Unreleased`
|
To release, head `CHANGELOG.md` with the version's section in place of `Unreleased`
|
||||||
@@ -1017,35 +1411,6 @@ and merge: once `main` passes the gate, CI tags that commit `vX.Y.Z` and publish
|
|||||||
the Gitea release with the section as its body. A top heading of `[Unreleased]`
|
the Gitea release with the section as its body. A top heading of `[Unreleased]`
|
||||||
publishes nothing.
|
publishes nothing.
|
||||||
|
|
||||||
## Layout
|
|
||||||
|
|
||||||
```
|
|
||||||
fejkdata.go Generator, New, options, the embedded data set, List
|
|
||||||
node.go the node model and JSON -> node compilation
|
|
||||||
table.go tables: the rows TSV, its options and links, row selection and draws
|
|
||||||
path.go the dotted-path walk with its selectors, and proving a path resolves
|
|
||||||
render.go Fake and the recursive renderer (choices, format strings, expansions)
|
|
||||||
record.go records: Record, the JSON/CSV/SQL serializers, and their entry points
|
|
||||||
struct.go structs: FakeStruct, fake tags, and a field's Go type as its column's datatype
|
|
||||||
inline.go inline templates: Template, NewTemplate, FakeTemplate, IsTemplate, and their compile and link
|
|
||||||
template.go the {token} grammar: scanning, tokens, operands, validation, compiling a format
|
|
||||||
hold.go the hold: one draw per expansion for paths and operands, and its fences
|
|
||||||
draw.go one reference draw per render and group: draw sets, the group option, and its fence
|
|
||||||
family.go a family of linked tables: the rows a render pins, and the fence over paths into one family
|
|
||||||
reference.go reference sigils, and binding references across the tree
|
|
||||||
graph.go the render graph: edges, cycles, the repeat bound, tree walks
|
|
||||||
builtins.go the {name()} function registry and its implementations
|
|
||||||
calc.go the {calc()} arithmetic evaluator: parser, eval, validation
|
|
||||||
datatype.go column datatypes: DataType, where datatype and null may sit, a column's datatype
|
|
||||||
value.go the value proof: what a typed column or calc operand holds, checked at load
|
|
||||||
data.go data loading: fs.FS folders/files -> namespace tree, multi-source merge
|
|
||||||
cmd/fejkdata/ the fejkdata CLI
|
|
||||||
data/ shipped data (JSON, and a TSV per table), embedded at build: locale folders + a misc folder
|
|
||||||
data-import/ the scripts that rebuild each sourced table (see DATA-LICENSES.md)
|
|
||||||
release-tooling/ the release CI publishes from the changelog heading
|
|
||||||
testdata/ the pinned shipped shape (see Versioning)
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT — see [LICENSE](LICENSE). Forked from [github.com/Timewave-AB/fakes](https://github.com/Timewave-AB/fakes).
|
MIT — see [LICENSE](LICENSE). Forked from [github.com/Timewave-AB/fakes](https://github.com/Timewave-AB/fakes).
|
||||||
|
|||||||
+6
-6
@@ -26,12 +26,12 @@ func benchPath(b *testing.B, dir, path string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPerson(b *testing.B) { benchPath(b, "data/sv_SE", "person") }
|
func BenchmarkPerson(b *testing.B) { benchPath(b, "data", "sv_SE.person") }
|
||||||
func BenchmarkAddress(b *testing.B) { benchPath(b, "data/sv_SE", "address") }
|
func BenchmarkAddress(b *testing.B) { benchPath(b, "data", "sv_SE.address") }
|
||||||
func BenchmarkWord(b *testing.B) { benchPath(b, "data/sv_SE", "word") }
|
func BenchmarkWord(b *testing.B) { benchPath(b, "data", "sv_SE.word") }
|
||||||
func BenchmarkCreditcard(b *testing.B) { benchPath(b, "data/misc", "creditcard") }
|
func BenchmarkCreditcard(b *testing.B) { benchPath(b, "data", "misc.creditcard") }
|
||||||
func BenchmarkSSN(b *testing.B) { benchPath(b, "data/sv_SE", "ssn") }
|
func BenchmarkPersonnummer(b *testing.B) { benchPath(b, "data", "sv_SE.personnummer") }
|
||||||
func BenchmarkUUIDv7(b *testing.B) { benchPath(b, "data/misc", "uuid") }
|
func BenchmarkUUIDv7(b *testing.B) { benchPath(b, "data", "misc.uuid") }
|
||||||
|
|
||||||
func tmpData(b *testing.B, name, body string) string {
|
func tmpData(b *testing.B, name, body string) string {
|
||||||
b.Helper()
|
b.Helper()
|
||||||
|
|||||||
+3
-193
@@ -7,7 +7,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// maxLen caps sample output lengths (hex, nanoid, base64, digits, upper, lower)
|
// maxLen caps sample output lengths (hex, nanoid, base64, digits, upper, lower)
|
||||||
@@ -60,6 +59,8 @@ var builtins = map[string]builtin{
|
|||||||
cc := a[0]
|
cc := a[0]
|
||||||
return func(s *session, _ string, _ []string) string { return iban(s, cc) }
|
return func(s *session, _ string, _ []string) string { return iban(s, cc) }
|
||||||
}},
|
}},
|
||||||
|
"date": {arity: -1, check: dateArgs, prep: datePrep},
|
||||||
|
"time": {arity: -1, check: timeArg, prep: timePrep},
|
||||||
"calc": {arity: -1, check: checkCalc, prep: calcPrep, operands: calcOperands},
|
"calc": {arity: -1, check: checkCalc, prep: calcPrep, operands: calcOperands},
|
||||||
"lowercase": {arity: 1, check: transformArg, prep: transformPrep(strings.ToLower), operands: transformOperand},
|
"lowercase": {arity: 1, check: transformArg, prep: transformPrep(strings.ToLower), operands: transformOperand},
|
||||||
"uppercase": {arity: 1, check: transformArg, prep: transformPrep(strings.ToUpper), operands: transformOperand},
|
"uppercase": {arity: 1, check: transformArg, prep: transformPrep(strings.ToUpper), operands: transformOperand},
|
||||||
@@ -88,13 +89,11 @@ func derive(f func(emitted string) string) func([]string) callFn {
|
|||||||
return func(_ *session, emitted string, _ []string) string { return f(emitted) }
|
return func(_ *session, emitted string, _ []string) string { return f(emitted) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sample(f func(rng) string) func([]string) callFn {
|
func sample(f func(rng) string) func([]string) callFn {
|
||||||
return func([]string) callFn {
|
return func([]string) callFn {
|
||||||
return func(s *session, _ string, _ []string) string { return f(s) }
|
return func(s *session, _ string, _ []string) string { return f(s) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func chars(alphabet string) func([]string) callFn {
|
func chars(alphabet string) func([]string) callFn {
|
||||||
return func(a []string) callFn {
|
return func(a []string) callFn {
|
||||||
n := atoi(a[0])
|
n := atoi(a[0])
|
||||||
@@ -113,96 +112,6 @@ func formatFloat(v float64, dp int) string {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// transforms are the builtins that rewrite one operand's value; they nest, so
|
|
||||||
// {lowercase(ascii(x))} folds then lowers.
|
|
||||||
var transforms = map[string]func(string) string{
|
|
||||||
"ascii": asciiFold,
|
|
||||||
"lowercase": strings.ToLower,
|
|
||||||
"uppercase": strings.ToUpper,
|
|
||||||
}
|
|
||||||
|
|
||||||
// unwrapTransform peels nested transform calls off an operand arg, returning the
|
|
||||||
// field it finally names and the transforms to apply, innermost last.
|
|
||||||
func unwrapTransform(arg string) (leaf string, chain []func(string) string, err error) {
|
|
||||||
for {
|
|
||||||
name, args, isCall := funcCall(arg)
|
|
||||||
if !isCall {
|
|
||||||
return arg, chain, nil
|
|
||||||
}
|
|
||||||
fn, isTransform := transforms[name]
|
|
||||||
if !isTransform {
|
|
||||||
return "", nil, fmt.Errorf("%s(%s) is not a transform, so it cannot be an operand", name, strings.Join(args, ","))
|
|
||||||
}
|
|
||||||
if len(args) != 1 {
|
|
||||||
return "", nil, fmt.Errorf("%s takes 1 arg, got %d", name, len(args))
|
|
||||||
}
|
|
||||||
chain = append(chain, fn)
|
|
||||||
arg = args[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func transformArg(fields map[string]node, a []string) error {
|
|
||||||
leaf, _, err := unwrapTransform(a[0])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if isRef(leaf) {
|
|
||||||
_, _, err := refShape(leaf)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return checkArm(leaf, fields, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func transformOperand(a []string) []string {
|
|
||||||
leaf, _, err := unwrapTransform(a[0])
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return []string{leaf}
|
|
||||||
}
|
|
||||||
|
|
||||||
func transformPrep(outer func(string) string) func([]string) callFn {
|
|
||||||
return func(a []string) callFn {
|
|
||||||
_, chain, err := unwrapTransform(a[0])
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("fejkdata: transform arg %q reached prep unvalidated: %v", a[0], err))
|
|
||||||
}
|
|
||||||
return func(_ *session, _ string, operands []string) string {
|
|
||||||
v := operands[0]
|
|
||||||
for i := len(chain) - 1; i >= 0; i-- {
|
|
||||||
v = chain[i](v)
|
|
||||||
}
|
|
||||||
return outer(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// asciiFolds maps the Latin letters with diacritics or ligatures to ASCII.
|
|
||||||
var asciiFolds = map[rune]string{
|
|
||||||
'À': "A", 'Á': "A", 'Â': "A", 'Ã': "A", 'Ä': "A", 'Å': "A", 'Æ': "AE", 'Ç': "C",
|
|
||||||
'È': "E", 'É': "E", 'Ê': "E", 'Ë': "E", 'Ì': "I", 'Í': "I", 'Î': "I", 'Ï': "I",
|
|
||||||
'Ð': "D", 'Ñ': "N", 'Ò': "O", 'Ó': "O", 'Ô': "O", 'Õ': "O", 'Ö': "O", 'Ø': "O",
|
|
||||||
'Ù': "U", 'Ú': "U", 'Û': "U", 'Ü': "U", 'Ý': "Y", 'Þ': "Th", 'ß': "ss", 'Œ': "OE",
|
|
||||||
'à': "a", 'á': "a", 'â': "a", 'ã': "a", 'ä': "a", 'å': "a", 'æ': "ae", 'ç': "c",
|
|
||||||
'è': "e", 'é': "e", 'ê': "e", 'ë': "e", 'ì': "i", 'í': "i", 'î': "i", 'ï': "i",
|
|
||||||
'ð': "d", 'ñ': "n", 'ò': "o", 'ó': "o", 'ô': "o", 'õ': "o", 'ö': "o", 'ø': "o",
|
|
||||||
'ù': "u", 'ú': "u", 'û': "u", 'ü': "u", 'ý': "y", 'þ': "th", 'ÿ': "y", 'œ': "oe",
|
|
||||||
}
|
|
||||||
|
|
||||||
// asciiFold rewrites s to ASCII: folded Latin letters stay, any other non-ASCII
|
|
||||||
// rune is dropped.
|
|
||||||
func asciiFold(s string) string {
|
|
||||||
var b strings.Builder
|
|
||||||
for _, r := range s {
|
|
||||||
if r <= unicode.MaxASCII {
|
|
||||||
b.WriteRune(r)
|
|
||||||
} else {
|
|
||||||
b.WriteString(asciiFolds[r])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// atoi parses an arg a builtin's check already validated. It panics rather than
|
// atoi parses an arg a builtin's check already validated. It panics rather than
|
||||||
// returning zero, so a check that stops covering its own args is a stack trace and
|
// returning zero, so a check that stops covering its own args is a stack trace and
|
||||||
// not a silently wrong length, range or decimal count.
|
// not a silently wrong length, range or decimal count.
|
||||||
@@ -222,7 +131,6 @@ func atof(s string) float64 {
|
|||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func randBytes(r rng, n int) []byte {
|
func randBytes(r rng, n int) []byte {
|
||||||
b := make([]byte, n)
|
b := make([]byte, n)
|
||||||
for i := range b {
|
for i := range b {
|
||||||
@@ -230,7 +138,6 @@ func randBytes(r rng, n int) []byte {
|
|||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func randChars(r rng, n int, alphabet string) string {
|
func randChars(r rng, n int, alphabet string) string {
|
||||||
b := make([]byte, n)
|
b := make([]byte, n)
|
||||||
for i := range b {
|
for i := range b {
|
||||||
@@ -253,7 +160,6 @@ func plainInt(s string) (int, error) {
|
|||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func posIntArg(_ map[string]node, a []string) error {
|
func posIntArg(_ map[string]node, a []string) error {
|
||||||
n, err := plainInt(a[0])
|
n, err := plainInt(a[0])
|
||||||
if errors.Is(err, strconv.ErrRange) {
|
if errors.Is(err, strconv.ErrRange) {
|
||||||
@@ -270,7 +176,6 @@ func posIntArg(_ map[string]node, a []string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func intRangeArgs(_ map[string]node, a []string) error {
|
func intRangeArgs(_ map[string]node, a []string) error {
|
||||||
lo, err := plainInt(a[0])
|
lo, err := plainInt(a[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -291,7 +196,6 @@ func intRangeArgs(_ map[string]node, a []string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func floatArgs(_ map[string]node, a []string) error {
|
func floatArgs(_ map[string]node, a []string) error {
|
||||||
lo, e1 := strconv.ParseFloat(a[0], 64)
|
lo, e1 := strconv.ParseFloat(a[0], 64)
|
||||||
hi, e2 := strconv.ParseFloat(a[1], 64)
|
hi, e2 := strconv.ParseFloat(a[1], 64)
|
||||||
@@ -319,10 +223,9 @@ func floatArgs(_ map[string]node, a []string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func seqArg(_ map[string]node, a []string) error {
|
func seqArg(_ map[string]node, a []string) error {
|
||||||
if len(a) > 1 {
|
if len(a) > 1 {
|
||||||
return fmt.Errorf("seq takes at most one name, got %d args", len(a))
|
return fmt.Errorf("seq takes at most one name, got %d", len(a))
|
||||||
}
|
}
|
||||||
if len(a) == 1 && a[0] == "" {
|
if len(a) == 1 && a[0] == "" {
|
||||||
return fmt.Errorf("seq name must not be empty")
|
return fmt.Errorf("seq name must not be empty")
|
||||||
@@ -373,96 +276,3 @@ func ulid(r rng) string {
|
|||||||
}
|
}
|
||||||
return string(out)
|
return string(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// luhnCheck returns the Luhn check digit (0-9) over the digits of s; non-digit
|
|
||||||
// runes are skipped. Doubling runs from the rightmost digit, so the result is
|
|
||||||
// correct whatever the payload length.
|
|
||||||
func luhnCheck(s string) int {
|
|
||||||
sum, double := 0, true
|
|
||||||
for i := len(s) - 1; i >= 0; i-- {
|
|
||||||
c := s[i]
|
|
||||||
if c < '0' || c > '9' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
d := int(c - '0')
|
|
||||||
if double {
|
|
||||||
if d *= 2; d > 9 {
|
|
||||||
d -= 9
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double = !double
|
|
||||||
sum += d
|
|
||||||
}
|
|
||||||
return (10 - sum%10) % 10
|
|
||||||
}
|
|
||||||
|
|
||||||
// mod11Check returns the weighted mod-11 check character over the digits of s
|
|
||||||
// (weights 2..7 cycling from the right). A would-be value of 10 emits 'X', as in
|
|
||||||
// ISBN-10 / ISO 7064; non-digits are skipped.
|
|
||||||
func mod11Check(s string) string {
|
|
||||||
sum, w := 0, 2
|
|
||||||
for i := len(s) - 1; i >= 0; i-- {
|
|
||||||
c := s[i]
|
|
||||||
if c < '0' || c > '9' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
sum += int(c-'0') * w
|
|
||||||
if w++; w > 7 {
|
|
||||||
w = 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if chk := (11 - sum%11) % 11; chk != 10 {
|
|
||||||
return string(rune('0' + chk))
|
|
||||||
}
|
|
||||||
return "X"
|
|
||||||
}
|
|
||||||
|
|
||||||
// eanCheck returns the EAN-13 / UPC-A / ISBN-13 / GTIN check digit over the
|
|
||||||
// digits of s: weights 3 and 1 alternating from the rightmost digit, mod 10.
|
|
||||||
func eanCheck(s string) string {
|
|
||||||
sum, w := 0, 3
|
|
||||||
for i := len(s) - 1; i >= 0; i-- {
|
|
||||||
c := s[i]
|
|
||||||
if c < '0' || c > '9' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
sum += int(c-'0') * w
|
|
||||||
w = 4 - w // 3 <-> 1
|
|
||||||
}
|
|
||||||
return string(rune('0' + (10-sum%10)%10))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ibanLen maps a supported country code to the full IBAN length. The check digits
|
|
||||||
// sit between the country code and the BBAN, so — unlike luhn/ean — iban can't be
|
|
||||||
// a left-to-right derivation; it generates the whole value instead.
|
|
||||||
var ibanLen = map[string]int{"BE": 16, "DE": 22, "DK": 18, "ES": 24, "FI": 18, "NO": 15, "SE": 24}
|
|
||||||
|
|
||||||
func ibanArg(_ map[string]node, a []string) error {
|
|
||||||
if _, ok := ibanLen[a[0]]; !ok {
|
|
||||||
return fmt.Errorf("iban(%q): unsupported country code", a[0])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// iban generates a structurally valid IBAN for cc: a numeric BBAN of the right
|
|
||||||
// length, then mod-97 check digits. Real bank/branch structure isn't modelled —
|
|
||||||
// the result passes length and checksum validation, which is what fake data needs.
|
|
||||||
func iban(r rng, cc string) string {
|
|
||||||
bban := make([]byte, ibanLen[cc]-4)
|
|
||||||
for i := range bban {
|
|
||||||
bban[i] = byte('0' + r.IntN(10))
|
|
||||||
}
|
|
||||||
rem := 0
|
|
||||||
feed := func(d int) { rem = (rem*10 + d) % 97 }
|
|
||||||
for _, c := range bban {
|
|
||||||
feed(int(c - '0'))
|
|
||||||
}
|
|
||||||
for i := 0; i < len(cc); i++ { // letters A-Z -> 10..35, fed as two digits
|
|
||||||
v := int(cc[i]-'A') + 10
|
|
||||||
feed(v / 10)
|
|
||||||
feed(v % 10)
|
|
||||||
}
|
|
||||||
feed(0)
|
|
||||||
feed(0)
|
|
||||||
return fmt.Sprintf("%s%02d%s", cc, 98-rem, bban)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBuiltinIDGenerators(t *testing.T) {
|
func TestBuiltinIDGenerators(t *testing.T) {
|
||||||
@@ -41,6 +43,7 @@ func TestBuiltinSamplesReproducible(t *testing.T) {
|
|||||||
`"{uuid()}"`, `"{ulid()}"`,
|
`"{uuid()}"`, `"{ulid()}"`,
|
||||||
`"{nanoid(12)}"`, `"{int(1,1000000)}"`,
|
`"{nanoid(12)}"`, `"{int(1,1000000)}"`,
|
||||||
`"{float(0,1,6)}"`, `"{base64(12)}"`, `"{iban(SE)}"`,
|
`"{float(0,1,6)}"`, `"{base64(12)}"`, `"{iban(SE)}"`,
|
||||||
|
`"{date(2000-01-01,2020-12-31,'2006-01-02 15:04:05')}"`, `"{time('15:04:05')}"`,
|
||||||
} {
|
} {
|
||||||
if a, b := mustRender(t, engine(7), tmpl), mustRender(t, engine(7), tmpl); a != b {
|
if a, b := mustRender(t, engine(7), tmpl), mustRender(t, engine(7), tmpl); a != b {
|
||||||
t.Fatalf("%s not reproducible: %q != %q", tmpl, a, b)
|
t.Fatalf("%s not reproducible: %q != %q", tmpl, a, b)
|
||||||
@@ -233,3 +236,135 @@ func TestClassBuiltinArgs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestBuiltinDateAndTime pins the two clock-free samples: date draws a second in
|
||||||
|
// [from 00:00:00, to 23:59:59], both days reachable, and renders it in the quoted Go
|
||||||
|
// layout, commas and English names included; time draws a second within one day.
|
||||||
|
func TestBuiltinDateAndTime(t *testing.T) {
|
||||||
|
f := engine(1)
|
||||||
|
seen := map[string]bool{}
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
got := mustRender(t, f, `"{date(1990-01-01,1990-12-31,'2006-01-02')}"`)
|
||||||
|
if d, err := time.Parse("2006-01-02", got); err != nil || d.Year() != 1990 {
|
||||||
|
t.Fatalf("date = %q, want a 1990 calendar date (err %v)", got, err)
|
||||||
|
}
|
||||||
|
seen[got] = true
|
||||||
|
}
|
||||||
|
if len(seen) < 200 {
|
||||||
|
t.Fatalf("date drew %d distinct days of 365 in 500, want a uniform spread", len(seen))
|
||||||
|
}
|
||||||
|
lo, hi := false, false
|
||||||
|
for i := 0; i < 200; i++ {
|
||||||
|
got := mustRender(t, f, `"{date(2020-02-28,2020-02-29,'2006-01-02')}"`)
|
||||||
|
if got != "2020-02-28" && got != "2020-02-29" {
|
||||||
|
t.Fatalf("date(2020-02-28,2020-02-29) = %q, out of range", got)
|
||||||
|
}
|
||||||
|
lo, hi = lo || got == "2020-02-28", hi || got == "2020-02-29"
|
||||||
|
}
|
||||||
|
if !lo || !hi {
|
||||||
|
t.Fatalf("date never hit a bound: lo=%v hi=%v (bounds must be inclusive)", lo, hi)
|
||||||
|
}
|
||||||
|
if got := mustRender(t, f, `"{date(2020-07-04,2020-07-05,'January 2, 2006')}"`); got != "July 4, 2020" && got != "July 5, 2020" {
|
||||||
|
t.Fatalf("date with a comma in its layout = %q", got)
|
||||||
|
}
|
||||||
|
rfc := regexp.MustCompile(`^2021-\d\d-\d\dT\d\d:\d\d:\d\dZ$`)
|
||||||
|
clock := regexp.MustCompile(`^([01]\d|2[0-3]):[0-5]\d$`)
|
||||||
|
ampm := regexp.MustCompile(`^(1[0-2]|[1-9]):[0-5]\d (AM|PM)$`)
|
||||||
|
seconds := map[string]bool{}
|
||||||
|
for i := 0; i < 300; i++ {
|
||||||
|
got := mustRender(t, f, `"{date(2021-01-01,2021-12-31,'2006-01-02T15:04:05Z07:00')}"`)
|
||||||
|
if !rfc.MatchString(got) {
|
||||||
|
t.Fatalf("date in an RFC 3339 layout = %q, want %s", got, rfc)
|
||||||
|
}
|
||||||
|
seconds[got[17:19]] = true
|
||||||
|
if got := mustRender(t, f, `"{time('15:04')}"`); !clock.MatchString(got) {
|
||||||
|
t.Fatalf("time('15:04') = %q, want %s", got, clock)
|
||||||
|
}
|
||||||
|
if got := mustRender(t, f, `"{time('3:04 PM')}"`); !ampm.MatchString(got) {
|
||||||
|
t.Fatalf("time('3:04 PM') = %q, want %s", got, ampm)
|
||||||
|
}
|
||||||
|
got = mustRender(t, f, `"{date(1950-01-01,2000-12-31,'060102')}-238{luhn()}"`)
|
||||||
|
if d := digitsOnly(got); len(d) != 10 || !luhnValid(d) {
|
||||||
|
t.Fatalf("a personnummer over date() = %q, want ten Luhn-valid digits", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(seconds) < 30 {
|
||||||
|
t.Fatalf("date drew %d distinct seconds in 300, want the whole day, not midnight", len(seconds))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestBuiltinDateArgs pins the New-time checks: bounds are calendar dates in order,
|
||||||
|
// the layout is quoted, names a field, and for time names no date field.
|
||||||
|
func TestBuiltinDateArgs(t *testing.T) {
|
||||||
|
for tmpl, want := range map[string]string{
|
||||||
|
`"{date(1990-13-01,1990-12-31,'2006-01-02')}"`: "1990-13-01",
|
||||||
|
`"{date(1990-12-31,1990-01-01,'2006-01-02')}"`: "is after",
|
||||||
|
`"{date(1990-01-01,1990-01-01,'2006-01-02')}"`: "write it as text",
|
||||||
|
`"{date(1990-01-01,1990-12-31,2006-01-02)}"`: "'2006-01-02'",
|
||||||
|
`"{date(1990-01-01,1990-12-31,'January 2, 2006)}"`: "'",
|
||||||
|
`"{date(1990-01-01,1990-12-31,\"January 2, 2006\")}"`: "quoted: 'January 2, 2006'",
|
||||||
|
`"{date(1990-01-01,1990-12-31,'x')}"`: "text",
|
||||||
|
`"{date(1990-01-01,1990-12-31,'')}"`: "text",
|
||||||
|
`"{date(1990-01-01,1990-12-31)}"`: "3 arguments",
|
||||||
|
`"{date(1990-01-01,1990-12-31,January 2, 2006)}"`: "'January 2, 2006'",
|
||||||
|
`"{time(3:04 PM, Mon)}"`: "'3:04 PM, Mon'",
|
||||||
|
`"{time(15:04)}"`: "'15:04'",
|
||||||
|
`"{time('2006-01-02 15:04')}"`: "date(",
|
||||||
|
`"{time('x')}"`: "text",
|
||||||
|
`"{date(1990-01-01,1990-12-31,'15:04')}"`: "time('15:04')",
|
||||||
|
} {
|
||||||
|
_, err := compile(parse(t, tmpl))
|
||||||
|
if err == nil || !strings.Contains(err.Error(), want) {
|
||||||
|
t.Errorf("compile(%s) = %v, want an error mentioning %q", tmpl, err, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestBuiltinLayoutErrorsNameARunnableSpelling pins the two layout errors a user
|
||||||
|
// can follow: a double-quoted layout is named single-quoted, without its own
|
||||||
|
// quotes carried into the suggestion, whether it split on a comma or not.
|
||||||
|
func TestBuiltinLayoutErrorsNameARunnableSpelling(t *testing.T) {
|
||||||
|
_, err := compile(parse(t, `"{date(1990-01-01,1990-12-31,\"2006-01-02\")}"`))
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "write '2006-01-02'") {
|
||||||
|
t.Fatalf("a double-quoted layout = %v, want it named single-quoted", err)
|
||||||
|
}
|
||||||
|
if strings.Contains(err.Error(), `'"`) {
|
||||||
|
t.Errorf("%v names a layout that renders its own quotes", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "is double-quoted") {
|
||||||
|
t.Errorf("%v does not say which quotes were wrong", err)
|
||||||
|
}
|
||||||
|
_, err = compile(parse(t, `"{time(15:04)}"`))
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "write '15:04'") {
|
||||||
|
t.Fatalf("a bare layout = %v, want it named quoted", err)
|
||||||
|
}
|
||||||
|
// The comma hint belongs to a layout that split, not to a call given extra args.
|
||||||
|
_, err = compile(parse(t, `"{time(0,12,'15:04')}"`))
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "takes 1 argument, got 3") {
|
||||||
|
t.Fatalf("time with three args = %v, want the count named in the singular", err)
|
||||||
|
}
|
||||||
|
if strings.Contains(err.Error(), "holding a comma") {
|
||||||
|
t.Errorf("%v offers the comma hint though the layout is already quoted", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestBuiltinDateSpansOneDay pins that from == to is a day: with a clock layout it
|
||||||
|
// draws every second of it, and without one it could only emit one value.
|
||||||
|
func TestBuiltinDateSpansOneDay(t *testing.T) {
|
||||||
|
f := engine(1)
|
||||||
|
seen := map[string]bool{}
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
got := mustRender(t, f, `"{date(2026-01-01,2026-01-01,'2006-01-02 15:04:05')}"`)
|
||||||
|
if !strings.HasPrefix(got, "2026-01-01 ") {
|
||||||
|
t.Fatalf("date over one day = %q, out of range", got)
|
||||||
|
}
|
||||||
|
seen[got] = true
|
||||||
|
}
|
||||||
|
if len(seen) < 400 {
|
||||||
|
t.Fatalf("date over one day drew %d distinct seconds in 500, want the whole day", len(seen))
|
||||||
|
}
|
||||||
|
_, err := compile(parse(t, `"{date(2026-01-01,2026-01-01,'2006-01-02')}"`))
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "write it as text") {
|
||||||
|
t.Fatalf("one day in a date-only layout = %v, want it named a constant", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
package fejkdata
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// luhnCheck returns the Luhn check digit (0-9) over the digits of s; non-digit
|
||||||
|
// runes are skipped. Doubling runs from the rightmost digit, so the result is
|
||||||
|
// correct whatever the payload length.
|
||||||
|
func luhnCheck(s string) int {
|
||||||
|
sum, double := 0, true
|
||||||
|
for i := len(s) - 1; i >= 0; i-- {
|
||||||
|
c := s[i]
|
||||||
|
if c < '0' || c > '9' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
d := int(c - '0')
|
||||||
|
if double {
|
||||||
|
if d *= 2; d > 9 {
|
||||||
|
d -= 9
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double = !double
|
||||||
|
sum += d
|
||||||
|
}
|
||||||
|
return (10 - sum%10) % 10
|
||||||
|
}
|
||||||
|
|
||||||
|
// mod11Check returns the weighted mod-11 check character over the digits of s
|
||||||
|
// (weights 2..7 cycling from the right). A would-be value of 10 emits 'X', as in
|
||||||
|
// ISBN-10 / ISO 7064; non-digits are skipped.
|
||||||
|
func mod11Check(s string) string {
|
||||||
|
sum, w := 0, 2
|
||||||
|
for i := len(s) - 1; i >= 0; i-- {
|
||||||
|
c := s[i]
|
||||||
|
if c < '0' || c > '9' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sum += int(c-'0') * w
|
||||||
|
if w++; w > 7 {
|
||||||
|
w = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if chk := (11 - sum%11) % 11; chk != 10 {
|
||||||
|
return string(rune('0' + chk))
|
||||||
|
}
|
||||||
|
return "X"
|
||||||
|
}
|
||||||
|
|
||||||
|
// eanCheck returns the EAN-13 / UPC-A / ISBN-13 / GTIN check digit over the
|
||||||
|
// digits of s: weights 3 and 1 alternating from the rightmost digit, mod 10.
|
||||||
|
func eanCheck(s string) string {
|
||||||
|
sum, w := 0, 3
|
||||||
|
for i := len(s) - 1; i >= 0; i-- {
|
||||||
|
c := s[i]
|
||||||
|
if c < '0' || c > '9' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sum += int(c-'0') * w
|
||||||
|
w = 4 - w // 3 <-> 1
|
||||||
|
}
|
||||||
|
return string(rune('0' + (10-sum%10)%10))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ibanLen maps a supported country code to the full IBAN length. The check digits
|
||||||
|
// sit between the country code and the BBAN, so — unlike luhn/ean — iban can't be
|
||||||
|
// a left-to-right derivation; it generates the whole value instead.
|
||||||
|
var ibanLen = map[string]int{"BE": 16, "DE": 22, "DK": 18, "ES": 24, "FI": 18, "NO": 15, "SE": 24}
|
||||||
|
|
||||||
|
func ibanArg(_ map[string]node, a []string) error {
|
||||||
|
if _, ok := ibanLen[a[0]]; !ok {
|
||||||
|
return fmt.Errorf("iban(%q): unsupported country code", a[0])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// iban generates a structurally valid IBAN for cc: a numeric BBAN of the right
|
||||||
|
// length, then mod-97 check digits. Real bank/branch structure isn't modelled —
|
||||||
|
// the result passes length and checksum validation, which is what fake data needs.
|
||||||
|
func iban(r rng, cc string) string {
|
||||||
|
bban := make([]byte, ibanLen[cc]-4)
|
||||||
|
for i := range bban {
|
||||||
|
bban[i] = byte('0' + r.IntN(10))
|
||||||
|
}
|
||||||
|
rem := 0
|
||||||
|
feed := func(d int) { rem = (rem*10 + d) % 97 }
|
||||||
|
for _, c := range bban {
|
||||||
|
feed(int(c - '0'))
|
||||||
|
}
|
||||||
|
for i := 0; i < len(cc); i++ { // letters A-Z -> 10..35, fed as two digits
|
||||||
|
v := int(cc[i]-'A') + 10
|
||||||
|
feed(v / 10)
|
||||||
|
feed(v % 10)
|
||||||
|
}
|
||||||
|
feed(0)
|
||||||
|
feed(0)
|
||||||
|
return fmt.Sprintf("%s%02d%s", cc, 98-rem, bban)
|
||||||
|
}
|
||||||
+19
-2
@@ -24,10 +24,13 @@ import (
|
|||||||
const usage = `Usage: fejkdata [flags] <path|template>
|
const usage = `Usage: fejkdata [flags] <path|template>
|
||||||
|
|
||||||
<path> a category, or a dotted path into one (person, person.last);
|
<path> a category, or a dotted path into one (person, person.last);
|
||||||
a table's row by key or name: 'misc.country[SE]', 'misc.country[Sweden].tld'
|
a table's row by key or name: 'misc.territory[SE]', 'misc.territory[Sweden].tld'
|
||||||
<template> a format string or JSON value to render inline, e.g.
|
<template> a format string or JSON value to render inline, e.g.
|
||||||
'name: {/sv_SE.person.last}' or '{"format":"{x}","x":["bosse","lina"]}'
|
'name: {/sv_SE.person.last}' or '{"format":"{x}","x":["bosse","lina"]}'
|
||||||
|
|
||||||
|
A layout inside a template is single-quoted, so quote the whole argument with " to
|
||||||
|
keep it: "{date(1990-01-01,2010-12-31,'2006-01-02')}".
|
||||||
|
|
||||||
An argument containing a { token, or a JSON object, array or string, is a
|
An argument containing a { token, or a JSON object, array or string, is a
|
||||||
template; any other argument is a path (a path never contains a brace or a quote,
|
template; any other argument is a path (a path never contains a brace or a quote,
|
||||||
and a bracket only as a [selector] after a table's name). Templates reach the
|
and a bracket only as a [selector] after a table's name). Templates reach the
|
||||||
@@ -279,7 +282,7 @@ func (in invocation) check() (argKind, error) {
|
|||||||
return argPath, nil
|
return argPath, nil
|
||||||
}
|
}
|
||||||
if len(in.paths) != 1 {
|
if len(in.paths) != 1 {
|
||||||
return argPath, fmt.Errorf("expected one path or template, got %d", len(in.paths))
|
return argPath, fmt.Errorf("expected one path or template, got %d%s", len(in.paths), templateSplit(in.paths))
|
||||||
}
|
}
|
||||||
return classify(in.paths[0])
|
return classify(in.paths[0])
|
||||||
}
|
}
|
||||||
@@ -475,11 +478,25 @@ func run(args []string, stdout, stderr io.Writer) int {
|
|||||||
return misuse(stderr, te.error)
|
return misuse(stderr, te.error)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(stderr, err)
|
fmt.Fprintln(stderr, err)
|
||||||
|
if errors.Is(err, fejkdata.ErrNoColumns) {
|
||||||
|
fmt.Fprintln(stderr, "wrap that JSON in single quotes, which keep a shell from expanding its braces")
|
||||||
|
}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// templateSplit names the cure for a template a shell split on its spaces, which is
|
||||||
|
// what several arguments carrying a token mean.
|
||||||
|
func templateSplit(paths []string) string {
|
||||||
|
for _, p := range paths {
|
||||||
|
if strings.Contains(p, "{") {
|
||||||
|
return `; a template's spaces split the argument, so wrap the whole argument in "…", or in '…' where it carries double quotes`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func misuse(stderr io.Writer, err error) int {
|
func misuse(stderr io.Writer, err error) int {
|
||||||
// A library error already names the program, so the prefix is not doubled.
|
// A library error already names the program, so the prefix is not doubled.
|
||||||
fmt.Fprintf(stderr, "fejkdata: %s\ntry 'fejkdata --help'\n", strings.TrimPrefix(err.Error(), "fejkdata: "))
|
fmt.Fprintf(stderr, "fejkdata: %s\ntry 'fejkdata --help'\n", strings.TrimPrefix(err.Error(), "fejkdata: "))
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
svSE = "../../data/sv_SE"
|
svSE = "../../data/sv_SE"
|
||||||
enUS = "../../data/en_US"
|
enUS = "../../data/en_US"
|
||||||
|
misc = "../../data/misc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runOut(args ...string) (int, string, string) {
|
func runOut(args ...string) (int, string, string) {
|
||||||
@@ -222,6 +223,14 @@ func TestRunMisuse(t *testing.T) {
|
|||||||
t.Errorf("run(%v) stdout = %q, want nothing", args, out)
|
t.Errorf("run(%v) stdout = %q, want nothing", args, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// A template a shell split names both quotings, since which one cures it turns
|
||||||
|
// on whether the argument carries a double-quoted JSON.
|
||||||
|
_, _, errb := runOut("{date(1990-01-01,2010-12-31,", "January", "2,", "2006)}")
|
||||||
|
for _, want := range []string{`wrap the whole argument in "…"`, `or in '…'`} {
|
||||||
|
if !strings.Contains(errb, want) {
|
||||||
|
t.Errorf("a split template stderr = %q, want it to name %s", errb, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunMultipleDataPaths(t *testing.T) {
|
func TestRunMultipleDataPaths(t *testing.T) {
|
||||||
@@ -343,8 +352,8 @@ func TestRunSelectsATableRow(t *testing.T) {
|
|||||||
if code, _, errb := runOut("--no-shipped-data", "-d", dir, "[Skåne län]"); code != 2 || !strings.Contains(errb, "JSON") {
|
if code, _, errb := runOut("--no-shipped-data", "-d", dir, "[Skåne län]"); code != 2 || !strings.Contains(errb, "JSON") {
|
||||||
t.Fatalf("[Skåne län] = %d, stderr=%q, want misuse: a leading bracket that is no JSON names nothing", code, errb)
|
t.Fatalf("[Skåne län] = %d, stderr=%q, want misuse: a leading bracket that is no JSON names nothing", code, errb)
|
||||||
}
|
}
|
||||||
if code, out, _ := runOut("--seed", "1", "--format", "csv", "misc.country[SE]"); code != 0 || !strings.HasPrefix(out, "alpha2,") || !strings.Contains(out, "\nSE,SWE,") {
|
if code, out, _ := runOut("--seed", "1", "--format", "csv", "misc.territory[SE]"); code != 0 || !strings.HasPrefix(out, "alpha2,") || !strings.Contains(out, "\nSE,SWE,") {
|
||||||
t.Fatalf("--format csv misc.country[SE] = %d, %q", code, out)
|
t.Fatalf("--format csv misc.territory[SE] = %d, %q", code, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,14 +414,14 @@ func TestRunTemplateMisuse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRunNoShippedData(t *testing.T) {
|
func TestRunNoShippedData(t *testing.T) {
|
||||||
code, list, errb := runOut("--no-shipped-data", "-d", svSE, "--list")
|
code, list, errb := runOut("--no-shipped-data", "-d", misc, "--list")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
t.Fatalf("run = %d, stderr=%q", code, errb)
|
t.Fatalf("run = %d, stderr=%q", code, errb)
|
||||||
}
|
}
|
||||||
if strings.Contains(list, "en_US") || !strings.Contains(list, "person\n") {
|
if strings.Contains(list, "sv_SE") || !strings.Contains(list, "uuid\n") {
|
||||||
t.Errorf("--no-shipped-data --list = %q, want only the given dir", list)
|
t.Errorf("--no-shipped-data --list = %q, want only the given dir", list)
|
||||||
}
|
}
|
||||||
code, out, _ := runOut("--no-shipped-data", "-d", svSE, "-s", "3", "person")
|
code, out, _ := runOut("--no-shipped-data", "-d", misc, "-s", "3", "uuid")
|
||||||
if code != 0 || strings.TrimSpace(out) == "" {
|
if code != 0 || strings.TrimSpace(out) == "" {
|
||||||
t.Errorf("run = %d, out=%q", code, out)
|
t.Errorf("run = %d, out=%q", code, out)
|
||||||
}
|
}
|
||||||
@@ -612,3 +621,21 @@ func TestRunNumbersFollowTheShell(t *testing.T) {
|
|||||||
t.Errorf("run(--seed 007 --repeat +3) = %d, %q, stderr %q; want the same as --seed 7 --repeat 3 %q", code, got, errb, want)
|
t.Errorf("run(--seed 007 --repeat +3) = %d, %q, stderr %q; want the same as --seed 7 --repeat 3 %q", code, got, errb, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestRunRecordOfAFieldlessPath pins the way out of asking a category of one value
|
||||||
|
// for columns: the record to write, and the quoting a shell needs to take it. The
|
||||||
|
// argument is well-formed and only the data cannot serve it, so the code is 1.
|
||||||
|
func TestRunRecordOfAFieldlessPath(t *testing.T) {
|
||||||
|
code, out, errb := runOut("--format", "csv", "sv_SE.personnummer")
|
||||||
|
if code != 1 {
|
||||||
|
t.Fatalf("run(--format csv sv_SE.personnummer) = %d, want 1", code)
|
||||||
|
}
|
||||||
|
for _, want := range []string{`{"format":"","personnummer":"{/sv_SE.personnummer}"}`, "single quotes"} {
|
||||||
|
if !strings.Contains(errb, want) {
|
||||||
|
t.Errorf("stderr = %q, want it to name %s", errb, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if out != "" {
|
||||||
|
t.Errorf("stdout = %q, want nothing", out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+9
-23
@@ -1,35 +1,29 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Rebuild data/misc/currency.tsv from datasets/currency-codes (PDDL) and CLDR's symbols (Unicode).
|
"""Rebuild data/misc/currency.tsv from datasets/currency-codes (PDDL) and CLDR's symbols (Unicode).
|
||||||
|
|
||||||
data-import/currency.py [--source URL_OR_FILE] [--symbols URL_OR_FILE ...] [--out FILE]
|
data-import/currency.py [--source URL_OR_FILE] [--symbols URL_OR_FILE ...] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
The symbols come from the first locale file that has one, narrow symbols before wide.
|
The symbols come from the first locale file that has one, narrow symbols before wide.
|
||||||
"""
|
"""
|
||||||
import argparse
|
import argparse
|
||||||
import csv
|
import csv
|
||||||
import io
|
import io
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import urllib.request
|
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
SOURCE = "https://raw.githubusercontent.com/datasets/currency-codes/main/data/codes-all.csv"
|
SOURCE = "https://raw.githubusercontent.com/datasets/currency-codes/main/data/codes-all.csv"
|
||||||
SYMBOLS = [
|
SYMBOLS = [
|
||||||
"https://raw.githubusercontent.com/unicode-org/cldr/main/common/main/en.xml",
|
"https://raw.githubusercontent.com/unicode-org/cldr/main/common/main/en.xml",
|
||||||
"https://raw.githubusercontent.com/unicode-org/cldr/main/common/main/root.xml",
|
"https://raw.githubusercontent.com/unicode-org/cldr/main/common/main/root.xml",
|
||||||
]
|
]
|
||||||
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "currency.tsv"
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "currency.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
COLUMNS = ["code", "decimals", "name", "numeric", "symbol"]
|
COLUMNS = ["code", "decimals", "name", "numeric", "symbol"]
|
||||||
|
|
||||||
|
|
||||||
def read(source):
|
|
||||||
if re.match(r"^https?://", source):
|
|
||||||
with urllib.request.urlopen(source, timeout=60) as r:
|
|
||||||
return r.read().decode("utf-8")
|
|
||||||
return Path(source).read_text(encoding="utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def symbols(xml_texts):
|
def symbols(xml_texts):
|
||||||
"""CLDR's symbol per code: the first locale's narrow symbol, else the first locale's wide one."""
|
"""CLDR's symbol per code: the first locale's narrow symbol, else the first locale's wide one."""
|
||||||
narrow, wide = {}, {}
|
narrow, wide = {}, {}
|
||||||
@@ -58,24 +52,16 @@ def rows(text, symbol):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def write(out, table):
|
|
||||||
lines = ["\t".join(COLUMNS)]
|
|
||||||
for row in sorted(table, key=lambda r: r["code"]):
|
|
||||||
cells = [row[c] for c in COLUMNS]
|
|
||||||
assert all(cells) and not any("\t" in c or "\n" in c for c in cells), row
|
|
||||||
lines.append("\t".join(cells))
|
|
||||||
Path(out).write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
||||||
return len(lines) - 1
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
p.add_argument("--source", default=SOURCE)
|
p.add_argument("--source", default=SOURCE)
|
||||||
p.add_argument("--symbols", nargs="+", default=SYMBOLS)
|
p.add_argument("--symbols", nargs="+", default=SYMBOLS)
|
||||||
p.add_argument("--out", default=str(OUT))
|
p.add_argument("--out", default=str(OUT))
|
||||||
a = p.parse_args()
|
a = p.parse_args()
|
||||||
n = write(a.out, rows(read(a.source), symbols(read(s) for s in a.symbols)))
|
symbol = symbols(source.fetch(s, a.cache, Path(s).name).decode("utf-8") for s in a.symbols)
|
||||||
print(f"{a.out}: {n} rows", file=sys.stderr)
|
table = rows(source.fetch(a.source, a.cache, "codes-all.csv").decode("utf-8"), symbol)
|
||||||
|
tsv.write(a.out, COLUMNS, sorted(table, key=lambda r: r["code"]))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -0,0 +1,234 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/geo/SE/*.tsv from SCB (CC0), GeoNames (CC BY 4.0) and Trafikverket NVDB (CC0).
|
||||||
|
|
||||||
|
TRAFIKVERKET_API_KEY=… data-import/geo-se.py [--key-file FILE] [--cache DIR] [--streets-per-locality N] [--out DIR]
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import collections
|
||||||
|
import csv
|
||||||
|
import io
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
import zipfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
import xlsx
|
||||||
|
|
||||||
|
CODES = "https://www.scb.se/contentassets/7a89e48960f741e08918e489ea36354a/kommunlankod-2026.xlsx"
|
||||||
|
POPULATION = "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/BE/BE0101/BE0101A/BefolkningNy"
|
||||||
|
POPULATION_QUERY = {
|
||||||
|
"query": [
|
||||||
|
{"code": "Region", "selection": {"filter": "all", "values": ["*"]}},
|
||||||
|
{"code": "ContentsCode", "selection": {"filter": "item", "values": ["BE0101N1"]}},
|
||||||
|
{"code": "Tid", "selection": {"filter": "top", "values": ["1"]}},
|
||||||
|
],
|
||||||
|
"response": {"format": "json"},
|
||||||
|
}
|
||||||
|
TATORTER = "https://geodata.scb.se/geoserver/stat/wfs?service=WFS&version=2.0.0&request=GetFeature&typeNames=stat:Tatorter_2023&outputFormat=csv&propertyName=tatort,kommun,bef"
|
||||||
|
POSTAL_CODES = "https://download.geonames.org/export/zip/SE.zip"
|
||||||
|
NVDB = "https://api.trafikinfo.trafikverket.se/v2/data.json"
|
||||||
|
NVDB_PAGE = 50000
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "geo" / "SE"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
TIMEZONE = "Europe/Stockholm"
|
||||||
|
ONE_POSITION = {"Stockholm", "Göteborg", "Malmö"}
|
||||||
|
UNMATCHED_POPULATION = 200
|
||||||
|
|
||||||
|
|
||||||
|
def scb_codes(cache):
|
||||||
|
regions, municipalities = {}, {}
|
||||||
|
for cells in xlsx.rows(source.fetch(CODES, cache, "kommunlankod.xlsx", magic=b"PK")):
|
||||||
|
if len(cells) < 2 or not re.fullmatch(r"\d{2}|\d{4}", cells[0]):
|
||||||
|
continue
|
||||||
|
(regions if len(cells[0]) == 2 else municipalities)[cells[0]] = cells[1].strip()
|
||||||
|
return regions, municipalities
|
||||||
|
|
||||||
|
|
||||||
|
def scb_population(cache):
|
||||||
|
body = json.dumps(POPULATION_QUERY).encode()
|
||||||
|
data = source.fetch(POPULATION, cache, "befolkning.json", data=body, headers={"Content-Type": "application/json"})
|
||||||
|
return {row["key"][0]: row["values"][0] for row in json.loads(data.decode("utf-8-sig"))["data"]}
|
||||||
|
|
||||||
|
|
||||||
|
def scb_tatorter(cache):
|
||||||
|
text = source.fetch(TATORTER, cache, "tatorter.csv").decode("utf-8")
|
||||||
|
by_name = collections.defaultdict(list)
|
||||||
|
for r in csv.DictReader(io.StringIO(text)):
|
||||||
|
by_name[r["tatort"]].append((r["kommun"], int(r["bef"])))
|
||||||
|
return by_name
|
||||||
|
|
||||||
|
|
||||||
|
def geonames(cache):
|
||||||
|
z = zipfile.ZipFile(io.BytesIO(source.fetch(POSTAL_CODES, cache, "SE.zip", magic=b"PK")))
|
||||||
|
rows = []
|
||||||
|
for line in z.read("SE.txt").decode("utf-8").splitlines():
|
||||||
|
f = line.split("\t")
|
||||||
|
lat, lon = (float(f[9]), float(f[10])) if f[9] and f[10] else (None, None)
|
||||||
|
rows.append({"code": f[1], "locality": f[2], "municipality": f[6], "lat": lat, "lon": lon})
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def nvdb_segments(cache, key):
|
||||||
|
path = cache / "nvdb-gatunamn.tsv"
|
||||||
|
if not path.exists():
|
||||||
|
with open(path.with_suffix(".part"), "w", encoding="utf-8") as out:
|
||||||
|
change = "0"
|
||||||
|
while True:
|
||||||
|
query = (
|
||||||
|
f'<REQUEST><LOGIN authenticationkey="{key}"/>'
|
||||||
|
f'<QUERY objecttype="Gatunamn" namespace="vägdata.nvdb_dk_o" schemaversion="1.0" limit="{NVDB_PAGE}" changeid="{change}">'
|
||||||
|
"<FILTER><EQ name=\"Deleted\" value=\"false\"/></FILTER>"
|
||||||
|
"<INCLUDE>Namn</INCLUDE><INCLUDE>Geometry.WKT-WGS84-3D</INCLUDE></QUERY></REQUEST>"
|
||||||
|
)
|
||||||
|
req = urllib.request.Request(NVDB, data=query.encode(), headers={"Content-Type": "text/xml"})
|
||||||
|
with urllib.request.urlopen(req, timeout=600) as r:
|
||||||
|
result = json.load(r)["RESPONSE"]["RESULT"][0]
|
||||||
|
rows = result.get("Gatunamn", [])
|
||||||
|
for row in rows:
|
||||||
|
m = re.match(r"LINESTRING Z \(([-\d.]+) ([-\d.]+) ", row.get("Geometry", {}).get("WKT-WGS84-3D", ""))
|
||||||
|
name = " ".join(row.get("Namn", "").split())
|
||||||
|
if m and name:
|
||||||
|
out.write(f"{name}\t{m.group(1)}\t{m.group(2)}\n")
|
||||||
|
change = result["INFO"]["LASTCHANGEID"]
|
||||||
|
if len(rows) < NVDB_PAGE:
|
||||||
|
break
|
||||||
|
path.with_suffix(".part").rename(path)
|
||||||
|
for line in path.read_text(encoding="utf-8").splitlines():
|
||||||
|
name, lon, lat = line.split("\t")
|
||||||
|
yield name, float(lat), float(lon)
|
||||||
|
|
||||||
|
|
||||||
|
class Nearest:
|
||||||
|
"""Nearest point by an equirectangular distance, over a degree grid."""
|
||||||
|
|
||||||
|
def __init__(self, points, cell=0.05):
|
||||||
|
self.cell = cell
|
||||||
|
self.grid = collections.defaultdict(list)
|
||||||
|
for lat, lon, value in points:
|
||||||
|
self.grid[(int(lat // cell), int(lon // cell))].append((lat, lon, value))
|
||||||
|
|
||||||
|
def find(self, lat, lon):
|
||||||
|
ci, cj = int(lat // self.cell), int(lon // self.cell)
|
||||||
|
best, best_d = None, math.inf
|
||||||
|
ring = 0
|
||||||
|
while ring < 400:
|
||||||
|
for i in range(ci - ring, ci + ring + 1):
|
||||||
|
for j in range(cj - ring, cj + ring + 1):
|
||||||
|
if max(abs(i - ci), abs(j - cj)) != ring:
|
||||||
|
continue
|
||||||
|
for plat, plon, value in self.grid.get((i, j), ()):
|
||||||
|
d = (plat - lat) ** 2 + ((plon - lon) * math.cos(math.radians(lat))) ** 2
|
||||||
|
if d < best_d:
|
||||||
|
best, best_d = value, d
|
||||||
|
if best is not None and math.sqrt(best_d) < ring * self.cell * math.cos(math.radians(lat)):
|
||||||
|
return best
|
||||||
|
ring += 1
|
||||||
|
return best
|
||||||
|
|
||||||
|
|
||||||
|
def street_delivery(name, codes):
|
||||||
|
"""The codes delivered to a street: the digit after the postort's own prefix says box, company or reply."""
|
||||||
|
if name in ONE_POSITION:
|
||||||
|
return [c for c in codes if c[1] != "0"]
|
||||||
|
largest = collections.Counter(c[:3] for c in codes).most_common(1)[0][1]
|
||||||
|
length = 3 if largest * 2 >= len(codes) else 2
|
||||||
|
return [c for c in codes if c[length] not in "018"]
|
||||||
|
|
||||||
|
|
||||||
|
def municipality_of(name, rows, tatorter, municipalities):
|
||||||
|
named = [code for code, n in municipalities.items() if n == name]
|
||||||
|
if named:
|
||||||
|
return named[0], "kommun"
|
||||||
|
voted = collections.Counter(r["municipality"] for r in rows if r["municipality"] in municipalities)
|
||||||
|
matches = tatorter.get(name, [])
|
||||||
|
if matches:
|
||||||
|
in_vote = [m for m in matches if voted and m[0] == voted.most_common(1)[0][0]]
|
||||||
|
return max(in_vote or matches, key=lambda m: m[1])[0], "tatort"
|
||||||
|
if voted:
|
||||||
|
return voted.most_common(1)[0][0], "codes"
|
||||||
|
return None, "unplaced"
|
||||||
|
|
||||||
|
|
||||||
|
def population_of(name, municipality, tatorter, municipalities, population):
|
||||||
|
matches = [m for m in tatorter.get(name, []) if m[0] == municipality]
|
||||||
|
if matches:
|
||||||
|
return str(max(m[1] for m in matches))
|
||||||
|
return population[municipality] if municipalities[municipality] == name else str(UNMATCHED_POPULATION)
|
||||||
|
|
||||||
|
|
||||||
|
def well_cased(name):
|
||||||
|
return all(part[:1].isupper() and (len(part) == 1 or not part.isupper()) for part in re.split(r"[ -]", name))
|
||||||
|
|
||||||
|
|
||||||
|
def localities(codes, tatorter, municipalities, population):
|
||||||
|
"""Each postort with its municipality, weight, centroid and street-delivery codes."""
|
||||||
|
by_locality = collections.defaultdict(list)
|
||||||
|
for r in codes:
|
||||||
|
by_locality[r["locality"]].append(r)
|
||||||
|
out, how = {}, collections.Counter()
|
||||||
|
for name, rows in by_locality.items():
|
||||||
|
municipality, method = municipality_of(name, rows, tatorter, municipalities)
|
||||||
|
how[method] += 1
|
||||||
|
kept = street_delivery(name, [r["code"].replace(" ", "") for r in rows])
|
||||||
|
with_point = [r for r in rows if r["lat"] is not None]
|
||||||
|
if municipality is None or not kept or not with_point or not well_cased(name):
|
||||||
|
continue
|
||||||
|
lat = sum(r["lat"] for r in with_point) / len(with_point)
|
||||||
|
lon = sum(r["lon"] for r in with_point) / len(with_point)
|
||||||
|
out[name] = {"name": name, "municipality": municipality, "population": population_of(name, municipality, tatorter, municipalities, population), "lat": f"{lat:.4f}", "lon": f"{lon:.4f}", "codes": kept}
|
||||||
|
print(f"municipality by {dict(how)}; {len(by_locality) - len(out)} postorter dropped", file=sys.stderr)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def streets(segments, codes, localities, per_locality):
|
||||||
|
"""The names with most segments per locality, each segment at its nearest code centroid."""
|
||||||
|
nearest = Nearest((r["lat"], r["lon"], r["locality"]) for r in codes if r["lat"] is not None and r["locality"] in localities)
|
||||||
|
count = collections.Counter()
|
||||||
|
for name, lat, lon in segments:
|
||||||
|
if name[0].isalpha():
|
||||||
|
count[(nearest.find(lat, lon), name)] += 1
|
||||||
|
of = collections.defaultdict(list)
|
||||||
|
for (locality, name), n in count.items():
|
||||||
|
of[locality].append((n, name))
|
||||||
|
return {locality: [{"name": name, "locality": locality, "segments": n} for n, name in sorted(named, key=lambda s: (-s[0], s[1]))[:per_locality]] for locality, named in of.items()}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--key-file", help="file holding the Trafikverket API key; TRAFIKVERKET_API_KEY otherwise")
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
p.add_argument("--streets-per-locality", type=int, default=10)
|
||||||
|
a = p.parse_args()
|
||||||
|
key = Path(a.key_file).read_text().strip() if a.key_file else os.environ.get("TRAFIKVERKET_API_KEY")
|
||||||
|
if not key:
|
||||||
|
sys.exit("set TRAFIKVERKET_API_KEY or pass --key-file")
|
||||||
|
cache, out = Path(a.cache), Path(a.out)
|
||||||
|
cache.mkdir(parents=True, exist_ok=True)
|
||||||
|
out.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
regions, municipalities = scb_codes(cache)
|
||||||
|
population = scb_population(cache)
|
||||||
|
codes = geonames(cache)
|
||||||
|
places = localities(codes, scb_tatorter(cache), municipalities, population)
|
||||||
|
named = streets(nvdb_segments(cache, key), codes, places, a.streets_per_locality)
|
||||||
|
places = {name: l for name, l in places.items() if name in named}
|
||||||
|
empty = sorted(m for m in municipalities if not any(l["municipality"] == m for l in places.values()))
|
||||||
|
if empty:
|
||||||
|
sys.exit(f"municipalities without a locality: {empty}")
|
||||||
|
|
||||||
|
tsv.write(out / "region.tsv", ["code", "name", "population", "timezone"], [{"code": c, "name": n, "population": population[c], "timezone": TIMEZONE} for c, n in sorted(regions.items())])
|
||||||
|
tsv.write(out / "municipality.tsv", ["code", "name", "region", "population"], [{"code": c, "name": n, "region": c[:2], "population": population[c]} for c, n in sorted(municipalities.items())])
|
||||||
|
tsv.write(out / "locality.tsv", ["name", "municipality", "population", "lat", "lon"], [l for _, l in sorted(places.items())])
|
||||||
|
tsv.write(out / "postal-code.tsv", ["code", "locality"], sorted(({"code": f"{c[:3]} {c[3:]}", "locality": l["name"]} for l in places.values() for c in l["codes"]), key=lambda r: r["code"]))
|
||||||
|
tsv.write(out / "street.tsv", ["name", "locality", "segments"], [s for locality in sorted(named) for s in named[locality]])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/geo/US/*.tsv from the Census Bureau's Gazetteer, population estimates, ZCTA relationships and TIGER/Line files (public domain).
|
||||||
|
|
||||||
|
data-import/geo-us.py [--cache DIR] [--min-population N] [--streets-per-locality N] [--out DIR]
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import collections
|
||||||
|
import concurrent.futures
|
||||||
|
import csv
|
||||||
|
import io
|
||||||
|
import re
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import zipfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
GAZETTEER = "https://www2.census.gov/geo/docs/maps-data/data/gazetteer/2026_Gazetteer/2026_Gaz_{}_national.zip"
|
||||||
|
POPULATION = "https://www2.census.gov/programs-surveys/popest/datasets/2020-2025/{}"
|
||||||
|
STATES = POPULATION.format("state/totals/NST-EST2025-ALLDATA.csv")
|
||||||
|
COUNTIES = POPULATION.format("counties/totals/co-est2025-alldata.csv")
|
||||||
|
PLACES = POPULATION.format("cities/totals/sub-est2025.csv")
|
||||||
|
ZCTA_PLACE = "https://www2.census.gov/geo/docs/maps-data/data/rel2020/zcta520/tab20_zcta520_place20_natl.txt"
|
||||||
|
TIGER = "https://www2.census.gov/geo/tiger/TIGER2025/{0}/tl_2025_{1}_{2}.zip"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "geo" / "US"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
ESTIMATE = "POPESTIMATE2025"
|
||||||
|
CDP = "57"
|
||||||
|
HIGHWAY = re.compile(r"\b(I- |Hwy |Highway |Loop |Rte |Route |Rd )\d")
|
||||||
|
SUFFIX = re.compile(r" (city and borough|city|town|village|borough|municipality|comunidad|zona urbana|metropolitan government|metro government|consolidated government|unified government|urban county|corporation|plantation)( \(balance\))?$")
|
||||||
|
# Places whose Census name is a merged government's; the postal city is what an address carries.
|
||||||
|
NAMES = {"1303440": "Athens", "1304204": "Augusta", "1349008": "Macon", "2148006": "Louisville", "3011397": "Butte", "4732742": "Hartsville", "4752006": "Nashville"}
|
||||||
|
TIMEZONES = {
|
||||||
|
"AK": "America/Anchorage", "AL": "America/Chicago", "AR": "America/Chicago", "AZ": "America/Phoenix",
|
||||||
|
"CA": "America/Los_Angeles", "CO": "America/Denver", "CT": "America/New_York", "DC": "America/New_York",
|
||||||
|
"DE": "America/New_York", "FL": "America/New_York", "GA": "America/New_York", "HI": "Pacific/Honolulu",
|
||||||
|
"IA": "America/Chicago", "ID": "America/Boise", "IL": "America/Chicago", "IN": "America/Indiana/Indianapolis",
|
||||||
|
"KS": "America/Chicago", "KY": "America/New_York", "LA": "America/Chicago", "MA": "America/New_York",
|
||||||
|
"MD": "America/New_York", "ME": "America/New_York", "MI": "America/Detroit", "MN": "America/Chicago",
|
||||||
|
"MO": "America/Chicago", "MS": "America/Chicago", "MT": "America/Denver", "NC": "America/New_York",
|
||||||
|
"ND": "America/Chicago", "NE": "America/Chicago", "NH": "America/New_York", "NJ": "America/New_York",
|
||||||
|
"NM": "America/Denver", "NV": "America/Los_Angeles", "NY": "America/New_York", "OH": "America/New_York",
|
||||||
|
"OK": "America/Chicago", "OR": "America/Los_Angeles", "PA": "America/New_York", "PR": "America/Puerto_Rico",
|
||||||
|
"RI": "America/New_York", "SC": "America/New_York", "SD": "America/Chicago", "TN": "America/Chicago",
|
||||||
|
"TX": "America/Chicago", "UT": "America/Denver", "VA": "America/New_York", "VT": "America/New_York",
|
||||||
|
"WA": "America/Los_Angeles", "WI": "America/Chicago", "WV": "America/New_York", "WY": "America/Denver",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def text(data):
|
||||||
|
try:
|
||||||
|
return data.decode("utf-8-sig")
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return data.decode("latin-1")
|
||||||
|
|
||||||
|
|
||||||
|
def gazetteer(cache, kind):
|
||||||
|
z = zipfile.ZipFile(io.BytesIO(source.fetch(GAZETTEER.format(kind), cache, f"gaz_{kind}.zip", magic=b"PK")))
|
||||||
|
rows = text(z.read(z.namelist()[0])).splitlines()
|
||||||
|
header = [h.strip() for h in rows[0].split("|")]
|
||||||
|
return [dict(zip(header, (c.strip() for c in row.split("|")))) for row in rows[1:]]
|
||||||
|
|
||||||
|
|
||||||
|
def csv_rows(cache, url, name):
|
||||||
|
return list(csv.DictReader(io.StringIO(text(source.fetch(url, cache, name)))))
|
||||||
|
|
||||||
|
|
||||||
|
def dbf_rows(data, wanted):
|
||||||
|
"""The records of a dBASE file, the wanted fields only."""
|
||||||
|
count, header_len, record_len = struct.unpack("<xxxxIHH", data[:12])
|
||||||
|
fields, pos = [], 32
|
||||||
|
while data[pos] != 0x0D:
|
||||||
|
name = data[pos:pos + 11].split(b"\0")[0].decode()
|
||||||
|
fields.append((name, data[pos + 16]))
|
||||||
|
pos += 32
|
||||||
|
pos = header_len
|
||||||
|
for _ in range(count):
|
||||||
|
record = data[pos:pos + record_len]
|
||||||
|
pos += record_len
|
||||||
|
if record[:1] == b"*":
|
||||||
|
continue
|
||||||
|
row, at = {}, 1
|
||||||
|
for name, length in fields:
|
||||||
|
if name in wanted:
|
||||||
|
row[name] = record[at:at + length].decode("utf-8", "replace").strip()
|
||||||
|
at += length
|
||||||
|
yield row
|
||||||
|
|
||||||
|
|
||||||
|
def tiger_zip(cache, kind, county):
|
||||||
|
return source.fetch(TIGER.format(kind.upper(), county, kind), cache, f"tl_{county}_{kind}.zip", magic=b"PK")
|
||||||
|
|
||||||
|
|
||||||
|
def tiger(cache, kind, county, wanted):
|
||||||
|
z = zipfile.ZipFile(io.BytesIO(tiger_zip(cache, kind, county)))
|
||||||
|
return dbf_rows(z.read(f"tl_2025_{county}_{kind}.dbf"), wanted)
|
||||||
|
|
||||||
|
|
||||||
|
def place_name(geoid, name):
|
||||||
|
if geoid in NAMES:
|
||||||
|
return NAMES[geoid]
|
||||||
|
stripped = SUFFIX.sub("", name)
|
||||||
|
if stripped == name:
|
||||||
|
print(f"{geoid}: no suffix stripped from {name!r}", file=sys.stderr)
|
||||||
|
return stripped
|
||||||
|
|
||||||
|
|
||||||
|
def localities(cache, min_population, counties):
|
||||||
|
"""Each shipped place with its county, population and centroid."""
|
||||||
|
place_population, county_part = {}, collections.defaultdict(list)
|
||||||
|
for r in csv_rows(cache, PLACES, "sub-est2025.csv"):
|
||||||
|
if r["SUMLEV"] == "162":
|
||||||
|
place_population[r["STATE"] + r["PLACE"]] = int(r[ESTIMATE])
|
||||||
|
elif r["SUMLEV"] == "157":
|
||||||
|
county_part[r["STATE"] + r["PLACE"]].append((int(r[ESTIMATE]), r["STATE"] + r["COUNTY"]))
|
||||||
|
out = {}
|
||||||
|
for r in gazetteer(cache, "place"):
|
||||||
|
geoid, population = r["GEOID"], place_population.get(r["GEOID"], 0)
|
||||||
|
if r["FUNCSTAT"] not in ("A", "F", "N") or r["LSAD"] == CDP or population < min_population or not county_part.get(geoid):
|
||||||
|
continue
|
||||||
|
county = max(county_part[geoid])[1]
|
||||||
|
if county not in counties:
|
||||||
|
print(f"{geoid} {r['NAME']}: county {county} unknown, dropped", file=sys.stderr)
|
||||||
|
continue
|
||||||
|
out[geoid] = {"code": geoid, "name": place_name(geoid, r["NAME"]), "municipality": county, "population": population, "lat": r["INTPTLAT"], "lon": r["INTPTLONG"]}
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def postal_codes(cache, localities):
|
||||||
|
"""Each ZCTA whose largest part inside an incorporated place lies in a shipped place."""
|
||||||
|
parts = {}
|
||||||
|
for r in csv.DictReader(io.StringIO(text(source.fetch(ZCTA_PLACE, cache, "zcta-place.txt"))), delimiter="|"):
|
||||||
|
if r["GEOID_ZCTA5_20"] and r["GEOID_PLACE_20"] and not r["NAMELSAD_PLACE_20"].endswith(" CDP"):
|
||||||
|
parts.setdefault(r["GEOID_ZCTA5_20"], []).append((int(r["AREALAND_PART"]), r["GEOID_PLACE_20"]))
|
||||||
|
largest = {zcta: max(p)[1] for zcta, p in parts.items()}
|
||||||
|
return {zcta: place for zcta, place in largest.items() if place in localities}
|
||||||
|
|
||||||
|
|
||||||
|
def streets(cache, counties, locality_of_zcta, per_locality):
|
||||||
|
"""The names with most TIGER address ranges per place, and the address ranges per ZCTA."""
|
||||||
|
with concurrent.futures.ThreadPoolExecutor(3) as pool:
|
||||||
|
list(pool.map(lambda c: (tiger_zip(cache, "addr", c), tiger_zip(cache, "featnames", c)), counties))
|
||||||
|
addresses, count = collections.Counter(), collections.Counter()
|
||||||
|
for county in counties:
|
||||||
|
zips = collections.defaultdict(set)
|
||||||
|
for r in tiger(cache, "addr", county, {"TLID", "ZIP"}):
|
||||||
|
if r["ZIP"] in locality_of_zcta:
|
||||||
|
zips[r["TLID"]].add(r["ZIP"])
|
||||||
|
addresses[r["ZIP"]] += 1
|
||||||
|
for r in tiger(cache, "featnames", county, {"TLID", "FULLNAME", "PAFLAG"}):
|
||||||
|
if r["PAFLAG"] == "P" and r["FULLNAME"] and not HIGHWAY.search(r["FULLNAME"]):
|
||||||
|
for z in zips.get(r["TLID"], ()):
|
||||||
|
count[(locality_of_zcta[z], r["FULLNAME"])] += 1
|
||||||
|
of = collections.defaultdict(list)
|
||||||
|
for (locality, name), n in count.items():
|
||||||
|
of[locality].append((n, name))
|
||||||
|
named = {locality: [{"name": name, "locality": locality, "addresses": n} for n, name in sorted(ranked, key=lambda s: (-s[0], s[1]))[:per_locality]] for locality, ranked in of.items()}
|
||||||
|
return named, addresses
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--min-population", type=int, default=25000)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
p.add_argument("--streets-per-locality", type=int, default=10)
|
||||||
|
a = p.parse_args()
|
||||||
|
cache, out = Path(a.cache), Path(a.out)
|
||||||
|
cache.mkdir(parents=True, exist_ok=True)
|
||||||
|
out.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
state_population = {r["STATE"]: r[ESTIMATE] for r in csv_rows(cache, STATES, "nst-est2025.csv") if r["SUMLEV"] == "040"}
|
||||||
|
regions = {r["USPS"]: {"abbr": r["USPS"], "code": r["GEOID"], "name": r["NAME"], "population": state_population[r["GEOID"]], "timezone": TIMEZONES[r["USPS"]]} for r in gazetteer(cache, "state")}
|
||||||
|
county_population = {r["STATE"] + r["COUNTY"]: r[ESTIMATE] for r in csv_rows(cache, COUNTIES, "co-est2025.csv") if r["SUMLEV"] == "050"}
|
||||||
|
counties, unestimated = {}, collections.Counter()
|
||||||
|
for r in gazetteer(cache, "counties"):
|
||||||
|
if r["GEOID"] not in county_population:
|
||||||
|
unestimated[r["USPS"]] += 1
|
||||||
|
continue
|
||||||
|
counties[r["GEOID"]] = {"code": r["GEOID"], "name": r["NAME"], "region": r["USPS"], "population": county_population[r["GEOID"]]}
|
||||||
|
print(f"counties without a population estimate, dropped: {dict(unestimated)}", file=sys.stderr)
|
||||||
|
|
||||||
|
places = localities(cache, a.min_population, counties)
|
||||||
|
locality_of_zcta = postal_codes(cache, places)
|
||||||
|
named, addresses = streets(cache, sorted({l["municipality"] for l in places.values()}), locality_of_zcta, a.streets_per_locality)
|
||||||
|
for geoid in [l for l in places if l not in named]:
|
||||||
|
print(f"{geoid} {places[geoid]['name']}: no streets, dropped", file=sys.stderr)
|
||||||
|
del places[geoid]
|
||||||
|
kept_counties = {l["municipality"] for l in places.values()}
|
||||||
|
kept_regions = {counties[c]["region"] for c in kept_counties}
|
||||||
|
|
||||||
|
tsv.write(out / "region.tsv", ["abbr", "code", "name", "population", "timezone"], [r for _, r in sorted(regions.items()) if r["abbr"] in kept_regions])
|
||||||
|
tsv.write(out / "municipality.tsv", ["code", "name", "region", "population"], [c for _, c in sorted(counties.items()) if c["code"] in kept_counties])
|
||||||
|
tsv.write(out / "locality.tsv", ["code", "name", "municipality", "population", "lat", "lon"], [l for _, l in sorted(places.items())])
|
||||||
|
tsv.write(out / "postal-code.tsv", ["code", "locality", "addresses"], [{"code": z, "locality": l, "addresses": addresses[z]} for z, l in sorted(locality_of_zcta.items()) if addresses[z] and l in places])
|
||||||
|
tsv.write(out / "street.tsv", ["name", "locality", "addresses"], [s for locality in sorted(named) for s in named[locality]])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/httpmethod.tsv from the IANA HTTP Method Registry.
|
||||||
|
|
||||||
|
data-import/httpmethod.py [--source URL_OR_FILE] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
|
A method ships when the register cites RFC 9110 section 9.3 or RFC 5789 for it, which
|
||||||
|
is the eight HTTP defines and PATCH; the register's other entries do not. The
|
||||||
|
register's `yes` and `no` ship as `true` and `false`, which a consumer's boolean reads.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import io
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://www.iana.org/assignments/http-methods/methods.csv"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "httpmethod.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["idempotent", "method", "safe"]
|
||||||
|
CORE = re.compile(r"\[RFC9110, Section 9\.3\.|\[RFC5789, Section 2\]")
|
||||||
|
BOOLEAN = {"yes": "true", "no": "false"}
|
||||||
|
SELECTOR = '[]{}"|' # mirrors inSelector in table.go
|
||||||
|
EXPECTED = 9
|
||||||
|
|
||||||
|
|
||||||
|
def rows(text):
|
||||||
|
for r in csv.DictReader(io.StringIO(text)):
|
||||||
|
method = (r["Method Name"] or "").strip()
|
||||||
|
if not CORE.search(r["Reference"] or ""):
|
||||||
|
continue
|
||||||
|
if set(method) & set(SELECTOR):
|
||||||
|
sys.exit(f"{method}: a method holding one of {SELECTOR} is one a selector cannot spell")
|
||||||
|
answers = {}
|
||||||
|
for column in ("Safe", "Idempotent"):
|
||||||
|
answer = (r[column] or "").strip()
|
||||||
|
if answer not in BOOLEAN:
|
||||||
|
sys.exit(f"{method}: {column} {answer!r} is neither yes nor no")
|
||||||
|
answers[column] = BOOLEAN[answer]
|
||||||
|
yield {"idempotent": answers["Idempotent"], "method": method, "safe": answers["Safe"]}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
a = p.parse_args()
|
||||||
|
table = sorted(rows(source.fetch(a.source, a.cache, "http-methods.csv").decode("utf-8")), key=lambda r: r["method"])
|
||||||
|
if len(table) != EXPECTED:
|
||||||
|
sys.exit(f"{len(table)} methods cite RFC 9110 section 9.3 or RFC 5789, not {EXPECTED}; the register's Reference column has moved")
|
||||||
|
tsv.write(a.out, COLUMNS, table)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/httpstatus.tsv from the IANA HTTP Status Code Registry.
|
||||||
|
|
||||||
|
data-import/httpstatus.py [--source URL_OR_FILE] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
|
What ships is the codes in use: a range, an unassigned code and a qualified reason are all skipped.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import io
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "httpstatus.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["code", "reason"]
|
||||||
|
|
||||||
|
|
||||||
|
def rows(text):
|
||||||
|
for r in csv.DictReader(io.StringIO(text)):
|
||||||
|
code, reason = r["Value"].strip(), r["Description"].strip()
|
||||||
|
if code.isdigit() and reason and "(" not in reason and reason != "Unassigned":
|
||||||
|
yield {"code": code, "reason": reason}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
a = p.parse_args()
|
||||||
|
table = rows(source.fetch(a.source, a.cache, "http-status-codes-1.csv").decode("utf-8"))
|
||||||
|
tsv.write(a.out, COLUMNS, sorted(table, key=lambda r: int(r["code"])))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/language.tsv from datasets/language-codes (PDDL), the LoC ISO 639-2 register.
|
||||||
|
|
||||||
|
data-import/language.py [--source URL_OR_FILE] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
|
Only the 639-2 entries carrying a 639-1 code ship, since the alpha-2 code is the key.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import io
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://raw.githubusercontent.com/datasets/language-codes/main/data/language-codes-full.csv"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "language.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["code", "code3", "name"]
|
||||||
|
|
||||||
|
|
||||||
|
def name(english):
|
||||||
|
"""The register lists every synonym; the first, without its qualifier, is the one a selector spells."""
|
||||||
|
return re.sub(r"\s*\([^)]*\)", "", english.split(";")[0]).strip()
|
||||||
|
|
||||||
|
|
||||||
|
def rows(text):
|
||||||
|
for r in csv.DictReader(io.StringIO(text)):
|
||||||
|
if r["alpha2"]:
|
||||||
|
yield {"code": r["alpha2"], "code3": r["alpha3-t"] or r["alpha3-b"], "name": name(r["English"])}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
a = p.parse_args()
|
||||||
|
table = rows(source.fetch(a.source, a.cache, "language-codes-full.csv").decode("utf-8"))
|
||||||
|
tsv.write(a.out, COLUMNS, sorted(table, key=lambda r: r["code"]))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/loglevel.tsv from RFC 5424 and POSIX <syslog.h>.
|
||||||
|
|
||||||
|
data-import/loglevel.py [--source URL_OR_FILE] [--posix URL_OR_FILE] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
|
Every severity in Table 2 ships, paired to POSIX's keywords by the order each source
|
||||||
|
lists them, which holds only because a keyword prefixes the severity RFC 5424 numbers
|
||||||
|
alike.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import html
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://www.rfc-editor.org/rfc/rfc5424.txt"
|
||||||
|
POSIX = "https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/syslog.h.html"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "loglevel.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["code", "keyword", "severity"]
|
||||||
|
TABLE = re.compile(r"Table 1\.\s+Syslog Message Facilities(.*?)Table 2\.\s+Syslog Message Severities", re.S)
|
||||||
|
ROW = re.compile(r"^ +(\d) +([A-Z][a-z]+): ", re.M)
|
||||||
|
SECTION = re.compile(r"severity level portion of the.*?macros:(.*?)The following shall be declared as functions", re.S)
|
||||||
|
MACRO = re.compile(r"\bLOG_([A-Z]+)\b")
|
||||||
|
EXPECTED = 8
|
||||||
|
|
||||||
|
|
||||||
|
def severities(text):
|
||||||
|
table = TABLE.search(text)
|
||||||
|
if not table:
|
||||||
|
sys.exit("the RFC holds no text between the facility and the severity caption; its tables have moved")
|
||||||
|
return ROW.findall(table.group(1))
|
||||||
|
|
||||||
|
|
||||||
|
def keywords(page):
|
||||||
|
section = SECTION.search(html.unescape(re.sub(r"<[^>]+>", "", page)))
|
||||||
|
if not section:
|
||||||
|
sys.exit("POSIX spells no severity list between its own caption and the function declarations; the page has moved")
|
||||||
|
return [m.lower() for m in MACRO.findall(section.group(1))]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--posix", default=POSIX)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
a = p.parse_args()
|
||||||
|
table = sorted(severities(source.fetch(a.source, a.cache, "rfc5424.txt").decode("utf-8")))
|
||||||
|
codes = [code for code, _ in table]
|
||||||
|
if codes != [str(i) for i in range(EXPECTED)]:
|
||||||
|
sys.exit(f"the severity table numbers {codes}, not 0 through {EXPECTED - 1}")
|
||||||
|
words = keywords(source.fetch(a.posix, a.cache, "posix-syslog.h.html").decode("utf-8"))
|
||||||
|
if len(words) != EXPECTED:
|
||||||
|
sys.exit(f"POSIX lists {len(words)} severity macros, not {EXPECTED}: {words}")
|
||||||
|
rows = []
|
||||||
|
for (code, severity), keyword in zip(table, words):
|
||||||
|
if not severity.lower().startswith(keyword):
|
||||||
|
sys.exit(f"severity {code} is {severity} in the RFC and {keyword} in POSIX, which is no prefix of it")
|
||||||
|
rows.append({"code": code, "keyword": keyword, "severity": severity})
|
||||||
|
tsv.write(a.out, COLUMNS, rows)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/mimetype.tsv from mime-db (MIT), the IANA media type registry with extensions.
|
||||||
|
|
||||||
|
data-import/mimetype.py [--source URL_OR_FILE] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
|
Only types mime-db records as IANA-registered, with a filename extension, ship.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://raw.githubusercontent.com/jshttp/mime-db/master/db.json"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "mimetype.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["ext", "type"]
|
||||||
|
FIXUPS = {"application/mp4": "mp4s", "audio/mpeg": "mp3", "audio/ogg": "ogg", "video/quicktime": "mov"}
|
||||||
|
|
||||||
|
|
||||||
|
def rows(db):
|
||||||
|
for mimetype, entry in db.items():
|
||||||
|
if entry.get("source") == "iana" and entry.get("extensions"):
|
||||||
|
yield {"ext": "." + FIXUPS.get(mimetype, entry["extensions"][0]), "type": mimetype}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
a = p.parse_args()
|
||||||
|
table = rows(json.loads(source.fetch(a.source, a.cache, "mime-db.json").decode("utf-8")))
|
||||||
|
tsv.write(a.out, COLUMNS, sorted(table, key=lambda r: r["type"]))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/sv_SE/first-name.tsv and last-name.tsv from SCB's whole-population name counts (CC0, "Källa: SCB").
|
||||||
|
|
||||||
|
data-import/names-se.py [--source URL_OR_FILE] [--first N] [--last N] [--cache DIR] [--out DIR]
|
||||||
|
|
||||||
|
A tilltalsnamn goes under each sex that carries it, so a name both sexes carry has two rows.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
import xlsx
|
||||||
|
|
||||||
|
SOURCE = "https://www.scb.se/contentassets/9fe7dbb460994c72b835163dbc491ef9/namn-med-minst-tva-barare-31-december-2022.xlsx"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "sv_SE"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
SHEETS = {"f": "Tilltalsnamn kvinnor", "m": "Tilltalsnamn män"}
|
||||||
|
SURNAMES = "Efternamn"
|
||||||
|
NAME = re.compile(r"^[^\W\d_]{2,}([ '-][^\W\d_]{2,})*$")
|
||||||
|
PARTICLES = {"af", "av", "da", "de", "del", "den", "der", "di", "dos", "du", "la", "le", "van", "von"}
|
||||||
|
|
||||||
|
|
||||||
|
def cased(name):
|
||||||
|
"""SCB's uppercase name as it is written: each part capitalised, a particle before another part lowercased."""
|
||||||
|
parts = name.lower().split(" ")
|
||||||
|
return " ".join(w if w in PARTICLES and len(parts) > 1 else w.title() for w in parts)
|
||||||
|
|
||||||
|
|
||||||
|
def counted(rows, top):
|
||||||
|
"""The top names of a sheet by bearers, initials and single letters dropped."""
|
||||||
|
names = [(cells[0], int(cells[1])) for cells in rows if len(cells) >= 2 and cells[1].isdigit() and NAME.match(cells[0])]
|
||||||
|
return sorted(names, key=lambda n: (-n[1], n[0]))[:top]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--first", type=int, default=2000, help="names per sex")
|
||||||
|
p.add_argument("--last", type=int, default=5000)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
a = p.parse_args()
|
||||||
|
data = source.fetch(a.source, a.cache, "scb-namn-2022.xlsx", magic=b"PK")
|
||||||
|
first = [{"name": cased(n), "sex": sex, "count": c} for sex, sheet in SHEETS.items() for n, c in counted(xlsx.rows(data, sheet), a.first)]
|
||||||
|
last = [{"name": cased(n), "count": c} for n, c in counted(xlsx.rows(data, SURNAMES), a.last)]
|
||||||
|
out = Path(a.out)
|
||||||
|
tsv.write(out / "first-name.tsv", ["name", "sex", "count"], sorted(first, key=lambda r: (r["name"], r["sex"])))
|
||||||
|
tsv.write(out / "last-name.tsv", ["name", "count"], sorted(last, key=lambda r: r["name"]))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/en_US/first-name.tsv and last-name.tsv from SSA baby names and the Census 2010 surnames (public domain).
|
||||||
|
|
||||||
|
data-import/names-us.py [--names URL_OR_FILE] [--surnames URL_OR_FILE] [--from-year YEAR] [--first N] [--last N] [--cache DIR] [--out DIR]
|
||||||
|
|
||||||
|
A given name is counted over the births of --from-year and later, under each sex it was given to, so a
|
||||||
|
name both sexes carry has two rows. --names takes SSA's names.zip or a merged name,sex,count,year file;
|
||||||
|
--surnames takes the Census names.zip or its Names_2010Census.csv.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import collections
|
||||||
|
import csv
|
||||||
|
import io
|
||||||
|
import re
|
||||||
|
import zipfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
NAMES = "https://raw.githubusercontent.com/hackerb9/ssa-baby-names/master/alldata.txt"
|
||||||
|
SURNAMES = "https://www2.census.gov/topics/genealogy/2010surnames/names.zip"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "en_US"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
MC = re.compile(r"^Mc([a-z])")
|
||||||
|
PLACEHOLDERS = {"Baby", "Female", "Infant", "Male", "Notnamed", "Unknown", "Unnamed"}
|
||||||
|
|
||||||
|
|
||||||
|
def csv_or_zip_rows(data, member):
|
||||||
|
"""The rows of a CSV, or of every member of a zip named like member, name,sex,count[,year]."""
|
||||||
|
if data.startswith(b"PK"):
|
||||||
|
z = zipfile.ZipFile(io.BytesIO(data))
|
||||||
|
for n in sorted(z.namelist()):
|
||||||
|
if re.fullmatch(member, n):
|
||||||
|
year = re.sub(r"\D", "", n)
|
||||||
|
for r in csv.reader(io.StringIO(z.read(n).decode("utf-8-sig"))):
|
||||||
|
yield r + [year] if year else r
|
||||||
|
return
|
||||||
|
yield from csv.reader(io.StringIO(data.decode("utf-8-sig")))
|
||||||
|
|
||||||
|
|
||||||
|
def given(data, from_year):
|
||||||
|
counts = collections.Counter()
|
||||||
|
for r in csv_or_zip_rows(data, r"yob\d{4}\.txt"):
|
||||||
|
if len(r) >= 4 and r[3].isdigit() and int(r[3]) >= from_year and r[0] not in PLACEHOLDERS:
|
||||||
|
counts[(r[0], r[1].lower())] += int(r[2])
|
||||||
|
return counts
|
||||||
|
|
||||||
|
|
||||||
|
def surname(name):
|
||||||
|
"""A Census uppercase surname as it is written: capitalised, and Mc before a capital."""
|
||||||
|
return MC.sub(lambda m: "Mc" + m.group(1).upper(), name.title())
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--first", type=int, default=2000, help="names per sex")
|
||||||
|
p.add_argument("--from-year", type=int, default=1930)
|
||||||
|
p.add_argument("--last", type=int, default=5000)
|
||||||
|
p.add_argument("--names", default=NAMES)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
p.add_argument("--surnames", default=SURNAMES)
|
||||||
|
a = p.parse_args()
|
||||||
|
counts = given(source.fetch(a.names, a.cache, "ssa-names.txt"), a.from_year)
|
||||||
|
first = []
|
||||||
|
for sex in ("f", "m"):
|
||||||
|
top = sorted(((n, c) for (n, s), c in counts.items() if s == sex), key=lambda n: (-n[1], n[0]))[:a.first]
|
||||||
|
first += [{"name": n, "sex": sex, "count": c} for n, c in top]
|
||||||
|
rows = csv_or_zip_rows(source.fetch(a.surnames, a.cache, "census-surnames-2010.zip"), r"Names_2010Census\.csv")
|
||||||
|
last = [{"name": surname(r[0]), "count": int(r[2])} for r in rows if len(r) >= 3 and r[2].isdigit() and r[0].isalpha()]
|
||||||
|
last = sorted(last, key=lambda r: (-r["count"], r["name"]))[:a.last]
|
||||||
|
out = Path(a.out)
|
||||||
|
tsv.write(out / "first-name.tsv", ["name", "sex", "count"], sorted(first, key=lambda r: (r["name"], r["sex"])))
|
||||||
|
tsv.write(out / "last-name.tsv", ["name", "count"], sorted(last, key=lambda r: r["name"]))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/port.tsv from the IANA Service Name and Transport Protocol Port Number Registry.
|
||||||
|
|
||||||
|
data-import/port.py [--source URL_OR_FILE] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
|
A row needs a service name and a numeric TCP port. A port the registry lists more than
|
||||||
|
once keeps the first service it describes, or the first of them where it describes none,
|
||||||
|
so a number selects one row.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import io
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.csv"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "port.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["number", "service"]
|
||||||
|
FLOOR = 4000
|
||||||
|
|
||||||
|
|
||||||
|
def rows(text):
|
||||||
|
best, described = {}, set()
|
||||||
|
for r in csv.DictReader(io.StringIO(text)):
|
||||||
|
service, number = (r["Service Name"] or "").strip(), (r["Port Number"] or "").strip()
|
||||||
|
transport, description = (r["Transport Protocol"] or "").strip(), (r["Description"] or "").strip()
|
||||||
|
if transport != "tcp" or not service or not number.isdigit():
|
||||||
|
continue
|
||||||
|
if not 1 <= int(number) <= 65535:
|
||||||
|
sys.exit(f"{service}: port {number} is outside 1-65535")
|
||||||
|
if number not in best or (description and number not in described):
|
||||||
|
best[number] = {"number": number, "service": service}
|
||||||
|
if description:
|
||||||
|
described.add(number)
|
||||||
|
return sorted(best.values(), key=lambda r: int(r["number"]))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
a = p.parse_args()
|
||||||
|
table = rows(source.fetch(a.source, a.cache, "service-names-port-numbers.csv").decode("utf-8"))
|
||||||
|
if len(table) < FLOOR:
|
||||||
|
sys.exit(f"only {len(table)} ports named a TCP service; the registry's columns have moved")
|
||||||
|
tsv.write(a.out, COLUMNS, table)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/protocol.tsv from the IANA Protocol Numbers registry.
|
||||||
|
|
||||||
|
data-import/protocol.py [--source URL_OR_FILE] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
|
A row needs a number and a keyword, which drops the seven numbers assigned to a class of
|
||||||
|
protocols rather than to one; a keyword the registry reserves or marks deprecated goes
|
||||||
|
too. Where the registry names no protocol beside the keyword, the keyword is the name.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import io
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://www.iana.org/assignments/protocol-numbers/protocol-numbers-1.csv"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "protocol.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["keyword", "name", "number"]
|
||||||
|
SKIP = ("Reserved", "deprecated")
|
||||||
|
SELECTOR = '[]{}"|' # mirrors inSelector in table.go
|
||||||
|
|
||||||
|
|
||||||
|
def rows(text):
|
||||||
|
for r in csv.DictReader(io.StringIO(text)):
|
||||||
|
number, keyword = (r["Decimal"] or "").strip(), (r["Keyword"] or "").strip()
|
||||||
|
if not number.isdigit() or not keyword or any(s in keyword for s in SKIP):
|
||||||
|
continue
|
||||||
|
if not 0 <= int(number) <= 255:
|
||||||
|
sys.exit(f"{keyword}: protocol number {number} is outside 0-255")
|
||||||
|
yield {"keyword": keyword, "name": " ".join((r["Protocol"] or "").split()) or keyword, "number": number}
|
||||||
|
|
||||||
|
|
||||||
|
def refuse_an_unselectable_row(table):
|
||||||
|
"""What the loader refuses at New, and a name that names two rows rather than one."""
|
||||||
|
keywords, names = {}, {}
|
||||||
|
for r in table:
|
||||||
|
for column in ("keyword", "name"):
|
||||||
|
if set(r[column]) & set(SELECTOR):
|
||||||
|
sys.exit(f"{r['keyword']}: {column} {r[column]!r} holds one of {SELECTOR}, which a selector cannot spell")
|
||||||
|
if r["keyword"] in keywords:
|
||||||
|
sys.exit(f"{r['keyword']}: repeats the keyword of protocol {keywords[r['keyword']]}")
|
||||||
|
keywords[r["keyword"]] = r["number"]
|
||||||
|
for r in table:
|
||||||
|
if r["name"] != r["keyword"] and r["name"] in keywords:
|
||||||
|
sys.exit(f"{r['keyword']}: name {r['name']!r} is another protocol's keyword")
|
||||||
|
if r["name"] in names:
|
||||||
|
sys.exit(f"{r['keyword']}: name {r['name']!r} repeats {names[r['name']]}'s, so it selects neither")
|
||||||
|
names[r["name"]] = r["keyword"]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
a = p.parse_args()
|
||||||
|
table = sorted(rows(source.fetch(a.source, a.cache, "protocol-numbers-1.csv").decode("utf-8")), key=lambda r: int(r["number"]))
|
||||||
|
refuse_an_unselectable_row(table)
|
||||||
|
tsv.write(a.out, COLUMNS, table)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
"""A source fetched once into the cache."""
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import urllib.request
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def fetch(source, cache, name, magic=b"", data=None, headers=None):
|
||||||
|
"""The bytes of a URL, downloaded into cache/name once, or of a local file."""
|
||||||
|
if not re.match(r"^https?://", source):
|
||||||
|
return Path(source).read_bytes()
|
||||||
|
path = Path(cache) / name
|
||||||
|
if path.exists():
|
||||||
|
return path.read_bytes()
|
||||||
|
for attempt in range(1, 6):
|
||||||
|
req = urllib.request.Request(source, data=data, headers={"User-Agent": "fejkdata data-import", **(headers or {})})
|
||||||
|
try:
|
||||||
|
with urllib.request.urlopen(req, timeout=600) as r:
|
||||||
|
body = r.read()
|
||||||
|
except OSError:
|
||||||
|
body = b""
|
||||||
|
if body and body.startswith(magic) and b"Request Rejected" not in body[:512]:
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
path.write_bytes(body)
|
||||||
|
return body
|
||||||
|
if attempt < 5:
|
||||||
|
time.sleep(10 * attempt)
|
||||||
|
sys.exit(f"{source}: no valid download in 5 attempts")
|
||||||
@@ -1,30 +1,28 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Rebuild data/misc/country.tsv from datasets/country-codes (PDDL).
|
"""Rebuild data/misc/territory.tsv from datasets/country-codes (PDDL).
|
||||||
|
|
||||||
data-import/country.py [--source URL_OR_FILE] [--out FILE]
|
data-import/territory.py [--source URL_OR_FILE] [--cache DIR] [--out FILE]
|
||||||
"""
|
"""
|
||||||
import argparse
|
import argparse
|
||||||
import csv
|
import csv
|
||||||
import io
|
import io
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import urllib.request
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
SOURCE = "https://raw.githubusercontent.com/datasets/country-codes/main/data/country-codes.csv"
|
SOURCE = "https://raw.githubusercontent.com/datasets/country-codes/main/data/country-codes.csv"
|
||||||
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "country.tsv"
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "territory.tsv"
|
||||||
COLUMNS = ["alpha2", "alpha3", "calling-code", "capital", "currency", "flag", "languages", "name", "numeric", "tld"]
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["alpha2", "alpha3", "calling-code", "capital", "country", "currency", "flag", "languages", "name", "numeric", "tld"]
|
||||||
|
SOVEREIGN = re.compile(r"^(?:Part of|Territor(?:y|ies) of|Crown dependency of|Commonwealth of|Associated with) ([A-Z]{2})$")
|
||||||
|
STANDALONE = {"In contention", "International"}
|
||||||
# Gaps in the source, keyed by alpha2.
|
# Gaps in the source, keyed by alpha2.
|
||||||
FIXUPS = {"TR": {"currency": "TRY"}}
|
FIXUPS = {"TR": {"currency": "TRY"}}
|
||||||
|
|
||||||
|
|
||||||
def read(source):
|
|
||||||
if re.match(r"^https?://", source):
|
|
||||||
with urllib.request.urlopen(source, timeout=60) as r:
|
|
||||||
return r.read().decode("utf-8")
|
|
||||||
return Path(source).read_text(encoding="utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def flag(alpha2):
|
def flag(alpha2):
|
||||||
return "".join(chr(0x1F1E6 + ord(c) - ord("A")) for c in alpha2)
|
return "".join(chr(0x1F1E6 + ord(c) - ord("A")) for c in alpha2)
|
||||||
|
|
||||||
@@ -38,6 +36,16 @@ def languages(field):
|
|||||||
return ",".join(p for p in field.split(",") if p)
|
return ",".join(p for p in field.split(",") if p)
|
||||||
|
|
||||||
|
|
||||||
|
def country(alpha2, independent):
|
||||||
|
"""The sovereign state the register records; a territory it records none for stands alone."""
|
||||||
|
m = SOVEREIGN.match(independent)
|
||||||
|
if m:
|
||||||
|
return m.group(1)
|
||||||
|
if independent == "Yes" or independent in STANDALONE:
|
||||||
|
return alpha2
|
||||||
|
sys.exit(f"{alpha2}: is_independent {independent!r} names no sovereign this script can read")
|
||||||
|
|
||||||
|
|
||||||
def rows(text):
|
def rows(text):
|
||||||
for r in csv.DictReader(io.StringIO(text)):
|
for r in csv.DictReader(io.StringIO(text)):
|
||||||
alpha2 = r["ISO3166-1-Alpha-2"]
|
alpha2 = r["ISO3166-1-Alpha-2"]
|
||||||
@@ -46,6 +54,7 @@ def rows(text):
|
|||||||
"alpha3": r["ISO3166-1-Alpha-3"],
|
"alpha3": r["ISO3166-1-Alpha-3"],
|
||||||
"calling-code": calling_code(r["Dial"]),
|
"calling-code": calling_code(r["Dial"]),
|
||||||
"capital": r["Capital"],
|
"capital": r["Capital"],
|
||||||
|
"country": country(alpha2, r["is_independent"]),
|
||||||
"currency": r["ISO4217-currency_alphabetic_code"].split(",")[0],
|
"currency": r["ISO4217-currency_alphabetic_code"].split(",")[0],
|
||||||
"flag": flag(alpha2),
|
"flag": flag(alpha2),
|
||||||
"languages": languages(r["Languages"]),
|
"languages": languages(r["Languages"]),
|
||||||
@@ -58,23 +67,18 @@ def rows(text):
|
|||||||
yield row
|
yield row
|
||||||
|
|
||||||
|
|
||||||
def write(out, table):
|
|
||||||
lines = ["\t".join(COLUMNS)]
|
|
||||||
for row in sorted(table, key=lambda r: r["alpha2"]):
|
|
||||||
cells = [row[c] for c in COLUMNS]
|
|
||||||
assert not any("\t" in c or "\n" in c for c in cells), row
|
|
||||||
lines.append("\t".join(cells))
|
|
||||||
Path(out).write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
||||||
return len(lines) - 1
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
p.add_argument("--source", default=SOURCE)
|
p.add_argument("--source", default=SOURCE)
|
||||||
p.add_argument("--out", default=str(OUT))
|
p.add_argument("--out", default=str(OUT))
|
||||||
a = p.parse_args()
|
a = p.parse_args()
|
||||||
n = write(a.out, rows(read(a.source)))
|
table = sorted(rows(source.fetch(a.source, a.cache, "country-codes.csv").decode("utf-8")), key=lambda r: r["alpha2"])
|
||||||
print(f"{a.out}: {n} rows", file=sys.stderr)
|
shipped = {r["alpha2"] for r in table}
|
||||||
|
for r in table:
|
||||||
|
if r["country"] not in shipped:
|
||||||
|
sys.exit(f"{r['alpha2']}: country {r['country']} is no shipped territory; a sovereign the set drops leaves its territories unreadable")
|
||||||
|
tsv.write(a.out, COLUMNS, table)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/timezone.tsv from the IANA tzdb tarball (public domain) and GeoNames (CC BY 4.0).
|
||||||
|
|
||||||
|
data-import/timezone.py [--source URL_OR_FILE] [--cities URL_OR_FILE] [--cache DIR] [--out FILE] [--territories FILE]
|
||||||
|
|
||||||
|
The offset is the zone's standard offset, the first field of its Zone rule's last
|
||||||
|
continuation line, with a Link resolved to its target. The weight is the population
|
||||||
|
GeoNames records in the zone's cities of 15,000 or more, never below that threshold,
|
||||||
|
so a drawn zone is one people live in.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import io
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import tarfile
|
||||||
|
import zipfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://data.iana.org/time-zones/tzdata-latest.tar.gz"
|
||||||
|
CITIES = "https://download.geonames.org/export/dump/cities15000.zip"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "timezone.tsv"
|
||||||
|
TERRITORIES = Path(__file__).resolve().parent.parent / "data" / "misc" / "territory.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["offset", "territory", "weight", "zone"]
|
||||||
|
REGIONS = ["africa", "antarctica", "asia", "australasia", "backward", "etcetera", "europe", "northamerica", "southamerica"]
|
||||||
|
# GeoNames' own cutoff, so a zone it records no city in weighs less than one would.
|
||||||
|
FLOOR = 15000
|
||||||
|
|
||||||
|
|
||||||
|
def member(tar, name):
|
||||||
|
try:
|
||||||
|
f = tar.extractfile(name)
|
||||||
|
except KeyError:
|
||||||
|
f = None
|
||||||
|
if f is None:
|
||||||
|
sys.exit(f"{name}: the tarball no longer holds it as a file; the tzdb layout has moved")
|
||||||
|
return f.read().decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def offsets(tar):
|
||||||
|
"""Every zone's standard offset, and every link's target."""
|
||||||
|
std, links = {}, {}
|
||||||
|
for name in REGIONS:
|
||||||
|
zone = None
|
||||||
|
for raw in member(tar, name).splitlines():
|
||||||
|
line = raw.split("#")[0].rstrip()
|
||||||
|
if not line.strip():
|
||||||
|
continue
|
||||||
|
if line.startswith("Zone"):
|
||||||
|
f = line.split()
|
||||||
|
zone, std[f[1]] = f[1], f[2]
|
||||||
|
elif line.startswith("Link"):
|
||||||
|
f = line.split()
|
||||||
|
links[f[2]], zone = f[1], None
|
||||||
|
elif line[0] in " \t" and zone:
|
||||||
|
std[zone] = line.split()[0]
|
||||||
|
else:
|
||||||
|
zone = None
|
||||||
|
return std, links
|
||||||
|
|
||||||
|
|
||||||
|
def resolve(zone, std, links):
|
||||||
|
for _ in range(10):
|
||||||
|
if zone in std:
|
||||||
|
return std[zone]
|
||||||
|
if zone not in links:
|
||||||
|
return None
|
||||||
|
zone = links[zone]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def utc_offset(raw):
|
||||||
|
"""±HH:MM from a tzdb STDOFF field, which writes the minutes and seconds only when it has them."""
|
||||||
|
m = re.match(r"^(-)?(\d{1,2})(?::(\d{2})(?::(\d{2}))?)?$", raw)
|
||||||
|
if not m or (m.group(4) or "00") != "00":
|
||||||
|
return None
|
||||||
|
return f"{'-' if m.group(1) else '+'}{int(m.group(2)):02d}:{m.group(3) or '00'}"
|
||||||
|
|
||||||
|
|
||||||
|
def population(body):
|
||||||
|
"""The population GeoNames records per timezone, summed over its cities."""
|
||||||
|
with zipfile.ZipFile(io.BytesIO(body)) as z:
|
||||||
|
text = z.read("cities15000.txt").decode("utf-8")
|
||||||
|
per = {}
|
||||||
|
for city in csv.reader(io.StringIO(text), delimiter="\t", quoting=csv.QUOTE_NONE):
|
||||||
|
if len(city) > 17 and city[17] and city[14].isdigit():
|
||||||
|
per[city[17]] = per.get(city[17], 0) + int(city[14])
|
||||||
|
return per
|
||||||
|
|
||||||
|
|
||||||
|
def rows(tar, territories, pop):
|
||||||
|
std, links = offsets(tar)
|
||||||
|
for line in member(tar, "zone.tab").splitlines():
|
||||||
|
if line.startswith("#") or not line.strip():
|
||||||
|
continue
|
||||||
|
fields = line.split("\t")
|
||||||
|
if len(fields) < 3:
|
||||||
|
sys.exit(f"zone.tab: {line!r} has {len(fields)} fields; a row names a territory, a location and a zone")
|
||||||
|
territory, zone = fields[0], fields[2]
|
||||||
|
if territory not in territories:
|
||||||
|
continue
|
||||||
|
raw = resolve(zone, std, links)
|
||||||
|
if raw is None:
|
||||||
|
sys.exit(f"{zone}: the tarball gives it no Zone rule and no Link to one")
|
||||||
|
offset = utc_offset(raw)
|
||||||
|
if offset is None:
|
||||||
|
sys.exit(f"{zone}: standard offset {raw!r} is not a ±HH:MM the table can spell")
|
||||||
|
yield {"offset": offset, "territory": territory, "weight": max(pop.get(zone, 0), FLOOR), "zone": zone}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
p.add_argument("--cities", default=CITIES)
|
||||||
|
p.add_argument("--territories", default=str(TERRITORIES))
|
||||||
|
a = p.parse_args()
|
||||||
|
shipped = {r["alpha2"] for r in csv.DictReader(io.StringIO(Path(a.territories).read_text(encoding="utf-8")), delimiter="\t")}
|
||||||
|
pop = population(source.fetch(a.cities, a.cache, "cities15000.zip", magic=b"PK"))
|
||||||
|
body = source.fetch(a.source, a.cache, "tzdata-latest.tar.gz", magic=b"\x1f\x8b")
|
||||||
|
with tarfile.open(fileobj=io.BytesIO(body)) as tar:
|
||||||
|
table = sorted(rows(tar, shipped, pop), key=lambda r: r["zone"])
|
||||||
|
print(f"tzdb {tar.extractfile('version').read().decode('utf-8').strip()}", file=sys.stderr)
|
||||||
|
linked = {r["territory"] for r in table}
|
||||||
|
if missing := shipped - linked:
|
||||||
|
sys.exit(f"no zone for {sorted(missing)}; a parent row without a child is a load error")
|
||||||
|
if (floored := sum(1 for r in table if r["weight"] == FLOOR)) > len(table) // 2:
|
||||||
|
sys.exit(f"{floored} of {len(table)} zones fell to the floor; GeoNames' population or timezone column has moved")
|
||||||
|
tsv.write(a.out, COLUMNS, table)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/tld.tsv from the IANA Root Zone Database.
|
||||||
|
|
||||||
|
data-import/tld.py [--source URL_OR_FILE] [--zone URL_OR_FILE] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
|
A TLD ships when the database names a manager for it; one it marks "Not assigned" is a
|
||||||
|
delegation the root zone no longer holds, and the zone file is fetched to prove the two
|
||||||
|
agree. The key is the A-label the root zone holds; `unicode` is the form the database
|
||||||
|
displays, less the bidi marks it wraps a right-to-left label in, and proved to punycode
|
||||||
|
back to the key.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import html
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://www.iana.org/domains/root/db"
|
||||||
|
ZONE = "https://data.iana.org/TLD/tlds-alpha-by-domain.txt"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "tld.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["tld", "type", "unicode"]
|
||||||
|
TYPES = ("country-code", "generic", "generic-restricted", "infrastructure", "sponsored")
|
||||||
|
BIDI = {0x200E: None, 0x200F: None}
|
||||||
|
ROW = re.compile(r'<a href="/domains/root/db/([^"]+)\.html">([^<]+)</a>.*?</td>\s*<td>([^<]*)</td>\s*<td>(.*?)</td>', re.S)
|
||||||
|
|
||||||
|
|
||||||
|
def rows(page):
|
||||||
|
for a_label, shown, kind, manager in ROW.findall(page):
|
||||||
|
if "Not assigned" in manager:
|
||||||
|
continue
|
||||||
|
kind = kind.strip()
|
||||||
|
if kind not in TYPES:
|
||||||
|
sys.exit(f"{a_label}: the database types it {kind!r}, which is none of {TYPES}")
|
||||||
|
yield {"tld": "." + a_label, "type": kind, "unicode": html.unescape(shown).strip().translate(BIDI)}
|
||||||
|
|
||||||
|
|
||||||
|
def prove_each_unicode_form_is_its_key(table):
|
||||||
|
"""The displayed form is the key's own spelling, which punycode encodes back to."""
|
||||||
|
for r in table:
|
||||||
|
label = r["unicode"][1:]
|
||||||
|
encoded = label if label.isascii() else "xn--" + label.encode("punycode").decode("ascii")
|
||||||
|
if "." + encoded != r["tld"]:
|
||||||
|
sys.exit(f"{r['tld']}: the database displays {r['unicode']!r}, which is no spelling of it")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--zone", default=ZONE)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
a = p.parse_args()
|
||||||
|
table = sorted(rows(source.fetch(a.source, a.cache, "root-db.html").decode("utf-8")), key=lambda r: r["tld"])
|
||||||
|
prove_each_unicode_form_is_its_key(table)
|
||||||
|
listing = source.fetch(a.zone, a.cache, "tlds-alpha-by-domain.txt").decode("utf-8")
|
||||||
|
delegated = {"." + line.strip().lower() for line in listing.splitlines() if line.strip() and not line.startswith("#")}
|
||||||
|
shipped = {r["tld"] for r in table}
|
||||||
|
if len(table) != len(delegated) or shipped != delegated:
|
||||||
|
sys.exit(f"the database assigns {len(table)} rows where the root zone holds {len(delegated)} TLDs: {sorted(shipped ^ delegated)[:10]}")
|
||||||
|
tsv.write(a.out, COLUMNS, table)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
"""A table written as the loader admits it."""
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def write(path, columns, rows):
|
||||||
|
"""Write the rows as a TSV; the table needs two rows, and every cell must be non-empty and free of tabs, newlines and braces."""
|
||||||
|
lines = ["\t".join(columns)]
|
||||||
|
for row in rows:
|
||||||
|
cells = [str(row[c]) for c in columns]
|
||||||
|
if not all(cells) or any(re.search(r"[\t\n{}]", c) for c in cells):
|
||||||
|
raise ValueError(f"{path}: a cell is empty or holds a tab, newline or brace: {row}")
|
||||||
|
lines.append("\t".join(cells))
|
||||||
|
if len(lines) < 3:
|
||||||
|
raise ValueError(f"{path}: has {len(lines) - 1} rows below its header; a table is at least two rows")
|
||||||
|
Path(path).write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||||
|
print(f"{path}: {len(lines) - 1} rows", file=sys.stderr)
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rebuild data/misc/useragent.tsv from microlinkhq/top-user-agents (MIT).
|
||||||
|
|
||||||
|
data-import/useragent.py [--source URL] [--cache DIR] [--out FILE]
|
||||||
|
|
||||||
|
The desktop and mobile lists partition the whole, so `device` is read rather than
|
||||||
|
parsed. A row ships when the string names a browser and an operating system both.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import source
|
||||||
|
import tsv
|
||||||
|
|
||||||
|
SOURCE = "https://raw.githubusercontent.com/microlinkhq/top-user-agents/master/src"
|
||||||
|
OUT = Path(__file__).resolve().parent.parent / "data" / "misc" / "useragent.tsv"
|
||||||
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
|
COLUMNS = ["browser", "device", "os", "ua"]
|
||||||
|
# First match wins: a Chromium fork this list does not name ships as Chrome.
|
||||||
|
BROWSERS = [("Edge", r"Edg(A|iOS)?/"), ("Opera", r"OPR/"), ("Samsung Internet", r"SamsungBrowser/"),
|
||||||
|
("Chrome", r"(Chrome|CriOS)/"), ("Firefox", r"(Firefox|FxiOS)/"), ("Safari", r"Version/[\d.]+ .*Safari")]
|
||||||
|
SYSTEMS = [("iOS", r"iPhone|iPad|CPU OS "), ("Android", r"Android"), ("ChromeOS", r"CrOS"),
|
||||||
|
("Windows", r"Windows NT"), ("macOS", r"Macintosh|Mac OS X"), ("Linux", r"X11.*Linux|Ubuntu")]
|
||||||
|
|
||||||
|
|
||||||
|
def named(table, ua):
|
||||||
|
for name, pattern in table:
|
||||||
|
if re.search(pattern, ua):
|
||||||
|
return name
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def rows(desktop, mobile):
|
||||||
|
seen, kept = set(), []
|
||||||
|
for device, uas in (("desktop", desktop), ("mobile", mobile)):
|
||||||
|
for ua in uas:
|
||||||
|
browser, os = named(BROWSERS, ua), named(SYSTEMS, ua)
|
||||||
|
if not browser or not os:
|
||||||
|
print(f"dropped, naming no {'browser' if not browser else 'operating system'}: {ua}", file=sys.stderr)
|
||||||
|
continue
|
||||||
|
if ua in seen:
|
||||||
|
sys.exit(f"{ua}: listed twice, which would draw it twice as often")
|
||||||
|
seen.add(ua)
|
||||||
|
kept.append({"browser": browser, "device": device, "os": os, "ua": ua})
|
||||||
|
if len(kept) < 0.8 * (len(desktop) + len(mobile)):
|
||||||
|
sys.exit(f"only {len(kept)} of {len(desktop) + len(mobile)} strings named both; the tokens have moved")
|
||||||
|
return kept
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||||
|
p.add_argument("--cache", default=str(CACHE))
|
||||||
|
p.add_argument("--source", default=SOURCE)
|
||||||
|
p.add_argument("--out", default=str(OUT))
|
||||||
|
a = p.parse_args()
|
||||||
|
lists = [json.loads(source.fetch(f"{a.source}/{n}.json", a.cache, f"top-user-agents-{n}.json")) for n in ("desktop", "mobile")]
|
||||||
|
tsv.write(a.out, COLUMNS, sorted(rows(*lists), key=lambda r: (r["browser"], r["os"], r["ua"])))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
"""The rows of an xlsx sheet."""
|
||||||
|
import io
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import zipfile
|
||||||
|
|
||||||
|
NS = {"m": "http://schemas.openxmlformats.org/spreadsheetml/2006/main", "r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships"}
|
||||||
|
|
||||||
|
|
||||||
|
def rows(data, sheet=None):
|
||||||
|
"""The rows of an xlsx sheet named sheet, the first sheet by default, each a list of cell texts."""
|
||||||
|
z = zipfile.ZipFile(io.BytesIO(data))
|
||||||
|
strings = ["".join(t.text or "" for t in si.iter("{%s}t" % NS["m"])) for si in ET.fromstring(z.read("xl/sharedStrings.xml")).findall("m:si", NS)]
|
||||||
|
rels = {r.get("Id"): r.get("Target") for r in ET.fromstring(z.read("xl/_rels/workbook.xml.rels"))}
|
||||||
|
sheets = {s.get("name"): rels[s.get("{%s}id" % NS["r"])] for s in ET.fromstring(z.read("xl/workbook.xml")).iter("{%s}sheet" % NS["m"])}
|
||||||
|
target = sheets[sheet] if sheet else next(iter(sheets.values()))
|
||||||
|
for row in ET.fromstring(z.read("xl/" + target)).findall(".//m:row", NS):
|
||||||
|
cells = []
|
||||||
|
for c in row.findall("m:c", NS):
|
||||||
|
v = c.find("m:v", NS)
|
||||||
|
cells.append("" if v is None else strings[int(v.text)] if c.get("t") == "s" else v.text)
|
||||||
|
yield cells
|
||||||
@@ -43,7 +43,7 @@ func loadData(sources []dataSource) (map[string]node, error) {
|
|||||||
}
|
}
|
||||||
info, err := os.Stat(src.path)
|
info, err := os.Stat(src.path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("data path %s: %w", src.path, err)
|
||||||
}
|
}
|
||||||
if !info.IsDir() {
|
if !info.IsDir() {
|
||||||
return nil, fmt.Errorf("%s is not a directory", src.path)
|
return nil, fmt.Errorf("%s is not a directory", src.path)
|
||||||
@@ -62,6 +62,7 @@ func loadData(sources []dataSource) (map[string]node, error) {
|
|||||||
if len(root) == 0 {
|
if len(root) == 0 {
|
||||||
return nil, fmt.Errorf("no .json data found")
|
return nil, fmt.Errorf("no .json data found")
|
||||||
}
|
}
|
||||||
|
setTablePaths(root)
|
||||||
if err := linkTables(root); err != nil {
|
if err := linkTables(root); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-14
@@ -1,17 +1,8 @@
|
|||||||
{
|
{
|
||||||
"format": "{street-number} {street}\n{locality}, {region} {postal-code}",
|
"format": "{street-number} {street}\n{locality}, {region} {postal-code}",
|
||||||
"street": {
|
"street": "{/geo.US.address.street}",
|
||||||
"format": "{name} {suffix}",
|
"street-number": "{/geo.US.address.street-number}",
|
||||||
"name": ["Adams", "Ashby", "Aspen", "Bay", "Birch", "Bridge", "Cedar", "Chestnut", "Church", "Clark", "Cypress", "Dogwood", "Elm", "Forest", "Franklin", "Garden", "Grove", "Hawthorn", "Hickory", "Highland", "Jackson", "Jefferson", "Juniper", "Lake", "Laurel", "Liberty", "Lincoln", "Madison", "Magnolia", "Maple", "Market", "Meadow", "Mill", "Oak", "Park", "Pine", "Poplar", "Prospect", "Ridge", "River", "Spruce", "Sunset", "Sycamore", "Union", "Walnut", "Washington", "Willow", "Wilson"],
|
"locality": "{/geo.US.address.locality}",
|
||||||
"suffix": ["Avenue", "Boulevard", "Circle", "Court", "Drive", "Lane", "Place", "Road", "Street", "Terrace", "Trail", "Way"]
|
"region": "{/geo.US.address.region}",
|
||||||
},
|
"postal-code": "{/geo.US.address.postal-code}"
|
||||||
"street-number": [
|
|
||||||
"{int(10,99)}",
|
|
||||||
{ "format": "{int(100,999)}", "weight": 2 },
|
|
||||||
{ "format": "{int(1000,9999)}", "weight": 0.5 },
|
|
||||||
{ "format": "{int(10,99)}{int(100,999)}", "weight": 0.3 }
|
|
||||||
],
|
|
||||||
"locality": ["Albany", "Atlanta", "Austin", "Baltimore", "Boston", "Charlotte", "Chicago", "Cincinnati", "Cleveland", "Columbus", "Dallas", "Denver", "Detroit", "El Paso", "Fort Worth", "Fresno", "Houston", "Indianapolis", "Jacksonville", "Kansas City", "Las Vegas", "Long Beach", "Los Angeles", "Memphis", "Mesa", "Miami", "Milwaukee", "Minneapolis", "Nashville", "New Orleans", "Oakland", "Oklahoma City", "Omaha", "Orlando", "Philadelphia", "Phoenix", "Pittsburgh", "Portland", "Raleigh", "Sacramento", "San Antonio", "San Diego", "San Jose", "Seattle", "St. Louis", "Tampa", "Tucson", "Tulsa"],
|
|
||||||
"region": ["AL", "AZ", "CA", "CO", "CT", "FL", "GA", "IL", "IN", "KY", "LA", "MA", "MD", "MI", "MN", "MO", "NC", "NJ", "NV", "NY", "OH", "OK", "OR", "PA", "TN", "TX", "VA", "WA", "WI"],
|
|
||||||
"postal-code": ["{int(10000,99999)}", { "format": "{int(10000,99999)}-{digits(4)}", "weight": 0.3 }]
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-13
@@ -1,13 +1 @@
|
|||||||
{
|
"{date(1970-01-01,2029-12-31,'01/02/2006')}"
|
||||||
"format": "{month}/{day}/{year}",
|
|
||||||
"month": ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"],
|
|
||||||
"day": ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28"],
|
|
||||||
"year": [
|
|
||||||
"197{digits(1)}",
|
|
||||||
"198{digits(1)}",
|
|
||||||
{ "format": "199{digits(1)}", "weight": 2 },
|
|
||||||
{ "format": "200{digits(1)}", "weight": 3 },
|
|
||||||
{ "format": "201{digits(1)}", "weight": 3 },
|
|
||||||
{ "format": "202{digits(1)}", "weight": 2 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "first-name.tsv", "name": "name", "parent": "sex", "weight": "count" }
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"format": "{area}-{group}-{serial}",
|
||||||
|
"area": "9{digits(2)}",
|
||||||
|
"group": [
|
||||||
|
{ "format": "{int(50,65)}", "weight": 16 },
|
||||||
|
{ "format": "{int(70,88)}", "weight": 19 },
|
||||||
|
{ "format": "{int(90,92)}", "weight": 3 },
|
||||||
|
{ "format": "{int(94,99)}", "weight": 6 }
|
||||||
|
],
|
||||||
|
"serial": [
|
||||||
|
{ "format": "000{int(1,9)}", "weight": 9 },
|
||||||
|
{ "format": "00{int(10,99)}", "weight": 90 },
|
||||||
|
{ "format": "0{int(100,999)}", "weight": 900 },
|
||||||
|
{ "format": "{int(1000,9999)}", "weight": 9000 }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "last-name.tsv", "key": "name", "weight": "count" }
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"format": "{prefix}{femalefirst|malefirst} {last}",
|
"format": "{prefix}{first} {last}",
|
||||||
"femalefirst": ["Abigail", "Addison", "Amelia", "Aria", "Aubrey", "Audrey", "Aurora", "Ava", "Bella", "Brooklyn", "Camila", "Caroline", "Charlotte", "Chloe", "Claire", "Eleanor", "Elizabeth", "Ella", "Ellie", "Emily", "Emma", "Evelyn", "Gianna", "Grace", "Hannah", "Harper", "Hazel", "Isabella", "Layla", "Leah", "Lillian", "Lily", "Lucy", "Luna", "Madison", "Maya", "Mia", "Mila", "Naomi", "Natalie", "Nora", "Olivia", "Paisley", "Penelope", "Riley", "Savannah", "Scarlett", "Sofia", "Sophia", "Stella", "Victoria", "Violet", "Zoe"],
|
"first": "{.first-name.name}",
|
||||||
"malefirst": ["Aiden", "Alexander", "Andrew", "Anthony", "Asher", "Benjamin", "Caleb", "Carter", "Charles", "Christopher", "Daniel", "David", "Dylan", "Elijah", "Ethan", "Ezra", "Gabriel", "Grayson", "Henry", "Isaac", "Jack", "Jackson", "Jacob", "James", "Jayden", "John", "Joseph", "Joshua", "Julian", "Levi", "Liam", "Lincoln", "Logan", "Lucas", "Luke", "Mason", "Mateo", "Matthew", "Michael", "Nathan", "Noah", "Oliver", "Owen", "Samuel", "Sebastian", "Theodore", "Thomas", "William", "Wyatt"],
|
"last": "{.last-name.name}",
|
||||||
"last": ["Adams", "Allen", "Anderson", "Bailey", "Baker", "Bell", "Bennett", "Brooks", "Brown", "Campbell", "Carter", "Clark", "Collins", "Cook", "Cooper", "Cox", "Davis", "Edwards", "Evans", "Flores", "Foster", "Garcia", "Gonzalez", "Gray", "Green", "Hall", "Harris", "Hayes", "Hernandez", "Hill", "Howard", "Hughes", "Jackson", "James", "Jenkins", "Johnson", "Jones", "Kelly", "King", "Lee", "Lewis", "Long", "Lopez", "Martin", "Martinez", "Miller", "Mitchell", "Moore", "Morgan", "Morris", "Murphy", "Nelson", "Parker", "Perez", "Perry", "Peterson", "Phillips", "Powell", "Price", "Ramirez", "Reed", "Richardson", "Rivera", "Roberts", "Robinson", "Rodriguez", "Rogers", "Ross", "Russell", "Sanchez", "Sanders", "Scott", "Smith", "Stewart", "Sullivan", "Taylor", "Thomas", "Thompson", "Torres", "Turner", "Walker", "Ward", "Watson", "White", "Williams", "Wilson", "Wood", "Wright", "Young"],
|
"prefix": [null, { "format": "{.title.name} ", "weight": 0.1 }],
|
||||||
"prefix": ["", { "format": "{title} ", "title": ["Dr", "Miss", "Mr", "Mrs", "Ms", "Mx", "Prof"], "weight": 0.1 }]
|
"sex": "{.sex.name}"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "sex.tsv", "key": "code", "name": "name" }
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
code name
|
||||||
|
f female
|
||||||
|
m male
|
||||||
|
+19
-1
@@ -1 +1,19 @@
|
|||||||
"{int(100,999)}-{digits(2)}-{digits(4)}"
|
{
|
||||||
|
"format": "{area}-{group}-{serial}",
|
||||||
|
"area": [
|
||||||
|
{ "format": "00{int(1,9)}", "weight": 9 },
|
||||||
|
{ "format": "0{int(10,99)}", "weight": 90 },
|
||||||
|
{ "format": "{int(100,665)}", "weight": 566 },
|
||||||
|
{ "format": "{int(667,899)}", "weight": 233 }
|
||||||
|
],
|
||||||
|
"group": [
|
||||||
|
{ "format": "0{int(1,9)}", "weight": 9 },
|
||||||
|
{ "format": "{int(10,99)}", "weight": 90 }
|
||||||
|
],
|
||||||
|
"serial": [
|
||||||
|
{ "format": "000{int(1,9)}", "weight": 9 },
|
||||||
|
{ "format": "00{int(10,99)}", "weight": 90 },
|
||||||
|
{ "format": "0{int(100,999)}", "weight": 900 },
|
||||||
|
{ "format": "{int(1000,9999)}", "weight": 9000 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1 @@
|
|||||||
{
|
"{time('3:04 PM')}"
|
||||||
"format": "{hour}:{minute} {ampm}",
|
|
||||||
"hour": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
|
|
||||||
"minute": { "format": "{t}{digits(1)}", "t": ["0", "1", "2", "3", "4", "5"] },
|
|
||||||
"ampm": ["AM", "PM"]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "title.tsv", "name": "name", "parent": "sex", "weight": "share" }
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
name sex share
|
||||||
|
Dr f 6
|
||||||
|
Dr m 6
|
||||||
|
Miss f 4
|
||||||
|
Mr m 60
|
||||||
|
Mrs f 22
|
||||||
|
Ms f 30
|
||||||
|
Mx f 1
|
||||||
|
Mx m 1
|
||||||
|
Prof f 3
|
||||||
|
Prof m 3
|
||||||
|
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"format": "{street} {street-number}\n{postal-code} {locality}",
|
||||||
|
"street": "{.street.name}",
|
||||||
|
"street-number": [
|
||||||
|
"{int(1,9)}",
|
||||||
|
"{int(10,99)}",
|
||||||
|
{ "format": "{int(100,999)}", "weight": 0.2 },
|
||||||
|
{ "format": "{int(1,9)}{upper(1)}", "weight": 0.2 },
|
||||||
|
{ "format": "{int(10,99)}{upper(1)}", "weight": 0.1 },
|
||||||
|
{ "format": "{int(100,999)}{upper(1)}", "weight": 0.05 }
|
||||||
|
],
|
||||||
|
"postal-code": "{.postal-code.code}",
|
||||||
|
"locality": "{.locality.name}"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "locality.tsv", "key": "name", "parent": "municipality", "weight": "population" }
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "municipality.tsv", "key": "code", "name": "name", "parent": "region", "weight": "population" }
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
code name region population
|
||||||
|
0114 Upplands Väsby 01 50323
|
||||||
|
0115 Vallentuna 01 35119
|
||||||
|
0117 Österåker 01 49787
|
||||||
|
0120 Värmdö 01 46635
|
||||||
|
0123 Järfälla 01 88950
|
||||||
|
0125 Ekerö 01 28910
|
||||||
|
0126 Huddinge 01 114304
|
||||||
|
0127 Botkyrka 01 95905
|
||||||
|
0128 Salem 01 17507
|
||||||
|
0136 Haninge 01 100895
|
||||||
|
0138 Tyresö 01 49179
|
||||||
|
0139 Upplands-Bro 01 32868
|
||||||
|
0140 Nykvarn 01 12342
|
||||||
|
0160 Täby 01 77744
|
||||||
|
0162 Danderyd 01 32425
|
||||||
|
0163 Sollentuna 01 77624
|
||||||
|
0180 Stockholm 01 995574
|
||||||
|
0181 Södertälje 01 102911
|
||||||
|
0182 Nacka 01 112112
|
||||||
|
0183 Sundbyberg 01 56274
|
||||||
|
0184 Solna 01 85789
|
||||||
|
0186 Lidingö 01 48377
|
||||||
|
0187 Vaxholm 01 11822
|
||||||
|
0188 Norrtälje 01 66585
|
||||||
|
0191 Sigtuna 01 52767
|
||||||
|
0192 Nynäshamn 01 30579
|
||||||
|
0305 Håbo 03 22973
|
||||||
|
0319 Älvkarleby 03 9552
|
||||||
|
0330 Knivsta 03 21193
|
||||||
|
0331 Heby 03 14345
|
||||||
|
0360 Tierp 03 21104
|
||||||
|
0380 Uppsala 03 248016
|
||||||
|
0381 Enköping 03 48591
|
||||||
|
0382 Östhammar 03 22138
|
||||||
|
0428 Vingåker 04 8750
|
||||||
|
0461 Gnesta 04 11458
|
||||||
|
0480 Nyköping 04 58344
|
||||||
|
0481 Oxelösund 04 12031
|
||||||
|
0482 Flen 04 15362
|
||||||
|
0483 Katrineholm 04 34154
|
||||||
|
0484 Eskilstuna 04 107203
|
||||||
|
0486 Strängnäs 04 39313
|
||||||
|
0488 Trosa 04 14927
|
||||||
|
0509 Ödeshög 05 5237
|
||||||
|
0512 Ydre 05 3626
|
||||||
|
0513 Kinda 05 9957
|
||||||
|
0560 Boxholm 05 5517
|
||||||
|
0561 Åtvidaberg 05 11467
|
||||||
|
0562 Finspång 05 21623
|
||||||
|
0563 Valdemarsvik 05 7525
|
||||||
|
0580 Linköping 05 168035
|
||||||
|
0581 Norrköping 05 144980
|
||||||
|
0582 Söderköping 05 14789
|
||||||
|
0583 Motala 05 43505
|
||||||
|
0584 Vadstena 05 7490
|
||||||
|
0586 Mjölby 05 28695
|
||||||
|
0604 Aneby 06 6797
|
||||||
|
0617 Gnosjö 06 9131
|
||||||
|
0642 Mullsjö 06 7594
|
||||||
|
0643 Habo 06 13456
|
||||||
|
0662 Gislaved 06 28936
|
||||||
|
0665 Vaggeryd 06 14825
|
||||||
|
0680 Jönköping 06 147654
|
||||||
|
0682 Nässjö 06 31587
|
||||||
|
0683 Värnamo 06 34542
|
||||||
|
0684 Sävsjö 06 11563
|
||||||
|
0685 Vetlanda 06 27528
|
||||||
|
0686 Eksjö 06 17792
|
||||||
|
0687 Tranås 06 18604
|
||||||
|
0760 Uppvidinge 07 9061
|
||||||
|
0761 Lessebo 07 8289
|
||||||
|
0763 Tingsryd 07 11966
|
||||||
|
0764 Alvesta 07 19830
|
||||||
|
0765 Älmhult 07 17653
|
||||||
|
0767 Markaryd 07 9938
|
||||||
|
0780 Växjö 07 98334
|
||||||
|
0781 Ljungby 07 28280
|
||||||
|
0821 Högsby 08 5321
|
||||||
|
0834 Torsås 08 6984
|
||||||
|
0840 Mörbylånga 08 16224
|
||||||
|
0860 Hultsfred 08 13673
|
||||||
|
0861 Mönsterås 08 13069
|
||||||
|
0862 Emmaboda 08 9006
|
||||||
|
0880 Kalmar 08 72704
|
||||||
|
0881 Nybro 08 19951
|
||||||
|
0882 Oskarshamn 08 26923
|
||||||
|
0883 Västervik 08 36447
|
||||||
|
0884 Vimmerby 08 15384
|
||||||
|
0885 Borgholm 08 10666
|
||||||
|
0980 Gotland 09 60971
|
||||||
|
1060 Olofström 10 13000
|
||||||
|
1080 Karlskrona 10 66301
|
||||||
|
1081 Ronneby 10 28741
|
||||||
|
1082 Karlshamn 10 31751
|
||||||
|
1083 Sölvesborg 10 17430
|
||||||
|
1214 Svalöv 12 14543
|
||||||
|
1230 Staffanstorp 12 27303
|
||||||
|
1231 Burlöv 12 20101
|
||||||
|
1233 Vellinge 12 37816
|
||||||
|
1256 Östra Göinge 12 13978
|
||||||
|
1257 Örkelljunga 12 10277
|
||||||
|
1260 Bjuv 12 15985
|
||||||
|
1261 Kävlinge 12 32477
|
||||||
|
1262 Lomma 12 24715
|
||||||
|
1263 Svedala 12 23581
|
||||||
|
1264 Skurup 12 17099
|
||||||
|
1265 Sjöbo 12 19337
|
||||||
|
1266 Hörby 12 15562
|
||||||
|
1267 Höör 12 17518
|
||||||
|
1270 Tomelilla 12 13639
|
||||||
|
1272 Bromölla 12 12470
|
||||||
|
1273 Osby 12 12947
|
||||||
|
1275 Perstorp 12 7235
|
||||||
|
1276 Klippan 12 17714
|
||||||
|
1277 Åstorp 12 16449
|
||||||
|
1278 Båstad 12 16026
|
||||||
|
1280 Malmö 12 365644
|
||||||
|
1281 Lund 12 131590
|
||||||
|
1282 Landskrona 12 47309
|
||||||
|
1283 Helsingborg 12 152091
|
||||||
|
1284 Höganäs 12 28430
|
||||||
|
1285 Eslöv 12 34922
|
||||||
|
1286 Ystad 12 32106
|
||||||
|
1287 Trelleborg 12 47269
|
||||||
|
1290 Kristianstad 12 86379
|
||||||
|
1291 Simrishamn 12 18890
|
||||||
|
1292 Ängelholm 12 45110
|
||||||
|
1293 Hässleholm 12 52114
|
||||||
|
1315 Hylte 13 10196
|
||||||
|
1380 Halmstad 13 106084
|
||||||
|
1381 Laholm 13 26595
|
||||||
|
1382 Falkenberg 13 47337
|
||||||
|
1383 Varberg 13 69070
|
||||||
|
1384 Kungsbacka 13 85792
|
||||||
|
1401 Härryda 14 40003
|
||||||
|
1402 Partille 14 41060
|
||||||
|
1407 Öckerö 14 12771
|
||||||
|
1415 Stenungsund 14 27851
|
||||||
|
1419 Tjörn 14 16092
|
||||||
|
1421 Orust 14 15352
|
||||||
|
1427 Sotenäs 14 9104
|
||||||
|
1430 Munkedal 14 10354
|
||||||
|
1435 Tanum 14 12773
|
||||||
|
1438 Dals-Ed 14 4606
|
||||||
|
1439 Färgelanda 14 6376
|
||||||
|
1440 Ale 14 32576
|
||||||
|
1441 Lerum 14 43570
|
||||||
|
1442 Vårgårda 14 12474
|
||||||
|
1443 Bollebygd 14 9802
|
||||||
|
1444 Grästorp 14 5555
|
||||||
|
1445 Essunga 14 5560
|
||||||
|
1446 Karlsborg 14 7023
|
||||||
|
1447 Gullspång 14 5031
|
||||||
|
1452 Tranemo 14 11839
|
||||||
|
1460 Bengtsfors 14 9076
|
||||||
|
1461 Mellerud 14 9052
|
||||||
|
1462 Lilla Edet 14 14442
|
||||||
|
1463 Mark 14 35155
|
||||||
|
1465 Svenljunga 14 10747
|
||||||
|
1466 Herrljunga 14 9497
|
||||||
|
1470 Vara 14 16088
|
||||||
|
1471 Götene 14 13286
|
||||||
|
1472 Tibro 14 11338
|
||||||
|
1473 Töreboda 14 9043
|
||||||
|
1480 Göteborg 14 608993
|
||||||
|
1481 Mölndal 14 71420
|
||||||
|
1482 Kungälv 14 50313
|
||||||
|
1484 Lysekil 14 13907
|
||||||
|
1485 Uddevalla 14 57010
|
||||||
|
1486 Strömstad 14 13482
|
||||||
|
1487 Vänersborg 14 40041
|
||||||
|
1488 Trollhättan 14 59003
|
||||||
|
1489 Alingsås 14 42722
|
||||||
|
1490 Borås 14 114872
|
||||||
|
1491 Ulricehamn 14 24985
|
||||||
|
1492 Åmål 14 11906
|
||||||
|
1493 Mariestad 14 24583
|
||||||
|
1494 Lidköping 14 40425
|
||||||
|
1495 Skara 14 18707
|
||||||
|
1496 Skövde 14 57995
|
||||||
|
1497 Hjo 14 9350
|
||||||
|
1498 Tidaholm 14 12805
|
||||||
|
1499 Falköping 14 32806
|
||||||
|
1715 Kil 17 12061
|
||||||
|
1730 Eda 17 8412
|
||||||
|
1737 Torsby 17 11321
|
||||||
|
1760 Storfors 17 3788
|
||||||
|
1761 Hammarö 17 16992
|
||||||
|
1762 Munkfors 17 3625
|
||||||
|
1763 Forshaga 17 11520
|
||||||
|
1764 Grums 17 9004
|
||||||
|
1765 Årjäng 17 9825
|
||||||
|
1766 Sunne 17 13356
|
||||||
|
1780 Karlstad 17 98084
|
||||||
|
1781 Kristinehamn 17 23756
|
||||||
|
1782 Filipstad 17 9776
|
||||||
|
1783 Hagfors 17 11418
|
||||||
|
1784 Arvika 17 25547
|
||||||
|
1785 Säffle 17 14899
|
||||||
|
1814 Lekeberg 18 8606
|
||||||
|
1860 Laxå 18 5423
|
||||||
|
1861 Hallsberg 18 16120
|
||||||
|
1862 Degerfors 18 9278
|
||||||
|
1863 Hällefors 18 6321
|
||||||
|
1864 Ljusnarsberg 18 4369
|
||||||
|
1880 Örebro 18 160140
|
||||||
|
1881 Kumla 18 22681
|
||||||
|
1882 Askersund 18 11477
|
||||||
|
1883 Karlskoga 18 30180
|
||||||
|
1884 Nora 18 10639
|
||||||
|
1885 Lindesberg 18 23141
|
||||||
|
1904 Skinnskatteberg 19 4256
|
||||||
|
1907 Surahammar 19 9845
|
||||||
|
1960 Kungsör 19 8694
|
||||||
|
1961 Hallstahammar 19 16653
|
||||||
|
1962 Norberg 19 5452
|
||||||
|
1980 Västerås 19 160634
|
||||||
|
1981 Sala 19 22843
|
||||||
|
1982 Fagersta 19 13072
|
||||||
|
1983 Köping 19 25729
|
||||||
|
1984 Arboga 19 13980
|
||||||
|
2021 Vansbro 20 6752
|
||||||
|
2023 Malung-Sälen 20 10254
|
||||||
|
2026 Gagnef 20 10384
|
||||||
|
2029 Leksand 20 16137
|
||||||
|
2031 Rättvik 20 10998
|
||||||
|
2034 Orsa 20 6851
|
||||||
|
2039 Älvdalen 20 6882
|
||||||
|
2061 Smedjebacken 20 10823
|
||||||
|
2062 Mora 20 20540
|
||||||
|
2080 Falun 20 59945
|
||||||
|
2081 Borlänge 20 51425
|
||||||
|
2082 Säter 20 11223
|
||||||
|
2083 Hedemora 20 15281
|
||||||
|
2084 Avesta 20 22417
|
||||||
|
2085 Ludvika 20 26634
|
||||||
|
2101 Ockelbo 21 5715
|
||||||
|
2104 Hofors 21 9281
|
||||||
|
2121 Ovanåker 21 11341
|
||||||
|
2132 Nordanstig 21 9262
|
||||||
|
2161 Ljusdal 21 18445
|
||||||
|
2180 Gävle 21 103838
|
||||||
|
2181 Sandviken 21 38360
|
||||||
|
2182 Söderhamn 21 24545
|
||||||
|
2183 Bollnäs 21 26243
|
||||||
|
2184 Hudiksvall 21 37528
|
||||||
|
2260 Ånge 22 9044
|
||||||
|
2262 Timrå 22 17521
|
||||||
|
2280 Härnösand 22 24515
|
||||||
|
2281 Sundsvall 22 99048
|
||||||
|
2282 Kramfors 22 17491
|
||||||
|
2283 Sollefteå 22 18396
|
||||||
|
2284 Örnsköldsvik 22 55443
|
||||||
|
2303 Ragunda 23 5146
|
||||||
|
2305 Bräcke 23 6035
|
||||||
|
2309 Krokom 23 15680
|
||||||
|
2313 Strömsund 23 11023
|
||||||
|
2321 Åre 23 12693
|
||||||
|
2326 Berg 23 7108
|
||||||
|
2361 Härjedalen 23 10175
|
||||||
|
2380 Östersund 23 64979
|
||||||
|
2401 Nordmaling 24 6942
|
||||||
|
2403 Bjurholm 24 2359
|
||||||
|
2404 Vindeln 24 5417
|
||||||
|
2409 Robertsfors 24 6690
|
||||||
|
2417 Norsjö 24 3968
|
||||||
|
2418 Malå 24 2962
|
||||||
|
2421 Storuman 24 5577
|
||||||
|
2422 Sorsele 24 2357
|
||||||
|
2425 Dorotea 24 2294
|
||||||
|
2460 Vännäs 24 9132
|
||||||
|
2462 Vilhelmina 24 6229
|
||||||
|
2463 Åsele 24 2694
|
||||||
|
2480 Umeå 24 134249
|
||||||
|
2481 Lycksele 24 12118
|
||||||
|
2482 Skellefteå 24 78150
|
||||||
|
2505 Arvidsjaur 25 6089
|
||||||
|
2506 Arjeplog 25 2599
|
||||||
|
2510 Jokkmokk 25 4701
|
||||||
|
2513 Överkalix 25 3201
|
||||||
|
2514 Kalix 25 15391
|
||||||
|
2518 Övertorneå 25 4057
|
||||||
|
2521 Pajala 25 5857
|
||||||
|
2523 Gällivare 25 17233
|
||||||
|
2560 Älvsbyn 25 7774
|
||||||
|
2580 Luleå 25 79645
|
||||||
|
2581 Piteå 25 42447
|
||||||
|
2582 Boden 25 28049
|
||||||
|
2583 Haparanda 25 9151
|
||||||
|
2584 Kiruna 25 22426
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{code}", "rows": "postal-code.tsv", "key": "code", "parent": "locality" }
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "region.tsv", "key": "code", "name": "name", "weight": "population" }
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
code name population timezone
|
||||||
|
01 Stockholms län 2473307 Europe/Stockholm
|
||||||
|
03 Uppsala län 407912 Europe/Stockholm
|
||||||
|
04 Södermanlands län 301542 Europe/Stockholm
|
||||||
|
05 Östergötlands län 472446 Europe/Stockholm
|
||||||
|
06 Jönköpings län 370009 Europe/Stockholm
|
||||||
|
07 Kronobergs län 203351 Europe/Stockholm
|
||||||
|
08 Kalmar län 246352 Europe/Stockholm
|
||||||
|
09 Gotlands län 60971 Europe/Stockholm
|
||||||
|
10 Blekinge län 157223 Europe/Stockholm
|
||||||
|
12 Skåne län 1428626 Europe/Stockholm
|
||||||
|
13 Hallands län 345074 Europe/Stockholm
|
||||||
|
14 Västra Götalands län 1772821 Europe/Stockholm
|
||||||
|
17 Värmlands län 283384 Europe/Stockholm
|
||||||
|
18 Örebro län 308375 Europe/Stockholm
|
||||||
|
19 Västmanlands län 281158 Europe/Stockholm
|
||||||
|
20 Dalarnas län 286546 Europe/Stockholm
|
||||||
|
21 Gävleborgs län 284558 Europe/Stockholm
|
||||||
|
22 Västernorrlands län 241458 Europe/Stockholm
|
||||||
|
23 Jämtlands län 132839 Europe/Stockholm
|
||||||
|
24 Västerbottens län 281138 Europe/Stockholm
|
||||||
|
25 Norrbottens län 248620 Europe/Stockholm
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "street.tsv", "parent": "locality", "weight": "segments" }
|
||||||
+14765
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"format": "{street-number} {street}\n{locality}, {region} {postal-code}",
|
||||||
|
"street": "{.street.name}",
|
||||||
|
"street-number": [
|
||||||
|
"{int(10,99)}",
|
||||||
|
{ "format": "{int(100,999)}", "weight": 2 },
|
||||||
|
{ "format": "{int(1000,9999)}", "weight": 0.5 },
|
||||||
|
{ "format": "{int(10,99)}{int(100,999)}", "weight": 0.3 }
|
||||||
|
],
|
||||||
|
"locality": "{.locality.name}",
|
||||||
|
"region": "{.region.abbr}",
|
||||||
|
"postal-code": "{.postal-code.code}"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "locality.tsv", "key": "code", "name": "name", "parent": "municipality", "weight": "population" }
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "municipality.tsv", "key": "code", "name": "name", "parent": "region", "weight": "population" }
|
||||||
@@ -0,0 +1,666 @@
|
|||||||
|
code name region population
|
||||||
|
01001 Autauga County AL 61920
|
||||||
|
01003 Baldwin County AL 267761
|
||||||
|
01031 Coffee County AL 56953
|
||||||
|
01055 Etowah County AL 103886
|
||||||
|
01069 Houston County AL 110318
|
||||||
|
01073 Jefferson County AL 665742
|
||||||
|
01077 Lauderdale County AL 97135
|
||||||
|
01081 Lee County AL 189881
|
||||||
|
01083 Limestone County AL 122928
|
||||||
|
01089 Madison County AL 433516
|
||||||
|
01097 Mobile County AL 411658
|
||||||
|
01101 Montgomery County AL 225891
|
||||||
|
01103 Morgan County AL 126483
|
||||||
|
01113 Russell County AL 58898
|
||||||
|
01117 Shelby County AL 238552
|
||||||
|
01125 Tuscaloosa County AL 241368
|
||||||
|
02020 Anchorage Municipality AK 287155
|
||||||
|
02090 Fairbanks North Star Borough AK 93972
|
||||||
|
02110 Juneau City and Borough AK 31609
|
||||||
|
04003 Cochise County AZ 126332
|
||||||
|
04005 Coconino County AZ 144368
|
||||||
|
04013 Maricopa County AZ 4689558
|
||||||
|
04015 Mohave County AZ 228102
|
||||||
|
04019 Pima County AZ 1074685
|
||||||
|
04021 Pinal County AZ 539380
|
||||||
|
04025 Yavapai County AZ 252552
|
||||||
|
04027 Yuma County AZ 224449
|
||||||
|
05007 Benton County AR 332554
|
||||||
|
05031 Craighead County AR 116957
|
||||||
|
05045 Faulkner County AR 133979
|
||||||
|
05051 Garland County AR 99695
|
||||||
|
05055 Greene County AR 47411
|
||||||
|
05069 Jefferson County AR 62987
|
||||||
|
05085 Lonoke County AR 76664
|
||||||
|
05091 Miller County AR 42357
|
||||||
|
05115 Pope County AR 64976
|
||||||
|
05119 Pulaski County AR 404611
|
||||||
|
05125 Saline County AR 133288
|
||||||
|
05131 Sebastian County AR 130641
|
||||||
|
05143 Washington County AR 271213
|
||||||
|
06001 Alameda County CA 1636630
|
||||||
|
06007 Butte County CA 209211
|
||||||
|
06013 Contra Costa County CA 1170070
|
||||||
|
06019 Fresno County CA 1035456
|
||||||
|
06023 Humboldt County CA 131647
|
||||||
|
06025 Imperial County CA 181411
|
||||||
|
06029 Kern County CA 927068
|
||||||
|
06031 Kings County CA 154327
|
||||||
|
06037 Los Angeles County CA 9694934
|
||||||
|
06039 Madera County CA 167927
|
||||||
|
06041 Marin County CA 253694
|
||||||
|
06047 Merced County CA 297260
|
||||||
|
06053 Monterey County CA 433729
|
||||||
|
06055 Napa County CA 132949
|
||||||
|
06059 Orange County CA 3149507
|
||||||
|
06061 Placer County CA 442081
|
||||||
|
06065 Riverside County CA 2544916
|
||||||
|
06067 Sacramento County CA 1618460
|
||||||
|
06069 San Benito County CA 70082
|
||||||
|
06071 San Bernardino County CA 2224091
|
||||||
|
06073 San Diego County CA 3282248
|
||||||
|
06075 San Francisco County CA 826079
|
||||||
|
06077 San Joaquin County CA 823815
|
||||||
|
06079 San Luis Obispo County CA 282367
|
||||||
|
06081 San Mateo County CA 743568
|
||||||
|
06083 Santa Barbara County CA 442065
|
||||||
|
06085 Santa Clara County CA 1914391
|
||||||
|
06087 Santa Cruz County CA 258852
|
||||||
|
06089 Shasta County CA 181648
|
||||||
|
06095 Solano County CA 455376
|
||||||
|
06097 Sonoma County CA 486444
|
||||||
|
06099 Stanislaus County CA 557719
|
||||||
|
06101 Sutter County CA 98787
|
||||||
|
06107 Tulare County CA 485146
|
||||||
|
06111 Ventura County CA 830851
|
||||||
|
06113 Yolo County CA 224410
|
||||||
|
08001 Adams County CO 554668
|
||||||
|
08005 Arapahoe County CO 673820
|
||||||
|
08013 Boulder County CO 328560
|
||||||
|
08014 Broomfield County CO 79174
|
||||||
|
08031 Denver County CO 740613
|
||||||
|
08035 Douglas County CO 399396
|
||||||
|
08041 El Paso County CO 757040
|
||||||
|
08059 Jefferson County CO 580451
|
||||||
|
08069 Larimer County CO 377292
|
||||||
|
08077 Mesa County CO 162845
|
||||||
|
08101 Pueblo County CO 169277
|
||||||
|
08123 Weld County CO 378426
|
||||||
|
09110 Capitol Planning Region CT 994115
|
||||||
|
09120 Greater Bridgeport Planning Region CT 337697
|
||||||
|
09130 Lower Connecticut River Valley Planning Region CT 177311
|
||||||
|
09140 Naugatuck Valley Planning Region CT 463349
|
||||||
|
09160 Northwest Hills Planning Region CT 114690
|
||||||
|
09170 South Central Connecticut Planning Region CT 578741
|
||||||
|
09180 Southeastern Connecticut Planning Region CT 284015
|
||||||
|
09190 Western Connecticut Planning Region CT 640482
|
||||||
|
10001 Kent County DE 194786
|
||||||
|
10003 New Castle County DE 588026
|
||||||
|
11001 District of Columbia DC 693645
|
||||||
|
12001 Alachua County FL 290028
|
||||||
|
12005 Bay County FL 204479
|
||||||
|
12009 Brevard County FL 663982
|
||||||
|
12011 Broward County FL 2013317
|
||||||
|
12031 Duval County FL 1062963
|
||||||
|
12033 Escambia County FL 333834
|
||||||
|
12035 Flagler County FL 140360
|
||||||
|
12057 Hillsborough County FL 1574115
|
||||||
|
12061 Indian River County FL 172799
|
||||||
|
12069 Lake County FL 456068
|
||||||
|
12071 Lee County FL 875607
|
||||||
|
12073 Leon County FL 299048
|
||||||
|
12081 Manatee County FL 468200
|
||||||
|
12083 Marion County FL 442660
|
||||||
|
12086 Miami-Dade County FL 2802029
|
||||||
|
12091 Okaloosa County FL 221810
|
||||||
|
12095 Orange County FL 1528002
|
||||||
|
12097 Osceola County FL 481718
|
||||||
|
12099 Palm Beach County FL 1575726
|
||||||
|
12103 Pinellas County FL 948563
|
||||||
|
12105 Polk County FL 874790
|
||||||
|
12111 St. Lucie County FL 402449
|
||||||
|
12115 Sarasota County FL 479958
|
||||||
|
12117 Seminole County FL 491884
|
||||||
|
12127 Volusia County FL 606573
|
||||||
|
13015 Bartow County GA 120800
|
||||||
|
13021 Bibb County GA 157556
|
||||||
|
13031 Bulloch County GA 86949
|
||||||
|
13045 Carroll County GA 131036
|
||||||
|
13051 Chatham County GA 311855
|
||||||
|
13057 Cherokee County GA 299273
|
||||||
|
13059 Clarke County GA 129921
|
||||||
|
13067 Cobb County GA 793345
|
||||||
|
13077 Coweta County GA 160240
|
||||||
|
13089 DeKalb County GA 774394
|
||||||
|
13095 Dougherty County GA 82616
|
||||||
|
13097 Douglas County GA 154293
|
||||||
|
13113 Fayette County GA 125156
|
||||||
|
13115 Floyd County GA 101378
|
||||||
|
13121 Fulton County GA 1098791
|
||||||
|
13135 Gwinnett County GA 1018099
|
||||||
|
13139 Hall County GA 226568
|
||||||
|
13151 Henry County GA 264922
|
||||||
|
13153 Houston County GA 178214
|
||||||
|
13179 Liberty County GA 70313
|
||||||
|
13185 Lowndes County GA 122867
|
||||||
|
13215 Muscogee County GA 202171
|
||||||
|
13245 Richmond County GA 206559
|
||||||
|
13285 Troup County GA 72844
|
||||||
|
13313 Whitfield County GA 106212
|
||||||
|
16001 Ada County ID 546141
|
||||||
|
16005 Bannock County ID 91591
|
||||||
|
16019 Bonneville County ID 135771
|
||||||
|
16027 Canyon County ID 275123
|
||||||
|
16055 Kootenai County ID 191864
|
||||||
|
16057 Latah County ID 41842
|
||||||
|
16065 Madison County ID 55172
|
||||||
|
16069 Nez Perce County ID 42905
|
||||||
|
16083 Twin Falls County ID 97539
|
||||||
|
17001 Adams County IL 64267
|
||||||
|
17007 Boone County IL 53568
|
||||||
|
17019 Champaign County IL 209972
|
||||||
|
17031 Cook County IL 5194625
|
||||||
|
17037 DeKalb County IL 101835
|
||||||
|
17043 DuPage County IL 934298
|
||||||
|
17089 Kane County IL 525757
|
||||||
|
17093 Kendall County IL 145470
|
||||||
|
17095 Knox County IL 47767
|
||||||
|
17097 Lake County IL 719339
|
||||||
|
17111 McHenry County IL 317751
|
||||||
|
17113 McLean County IL 171419
|
||||||
|
17115 Macon County IL 99300
|
||||||
|
17119 Madison County IL 263110
|
||||||
|
17143 Peoria County IL 178553
|
||||||
|
17161 Rock Island County IL 141869
|
||||||
|
17163 St. Clair County IL 250708
|
||||||
|
17167 Sangamon County IL 194170
|
||||||
|
17179 Tazewell County IL 130049
|
||||||
|
17183 Vermilion County IL 71259
|
||||||
|
17197 Will County IL 712253
|
||||||
|
17201 Winnebago County IL 283674
|
||||||
|
18003 Allen County IN 402329
|
||||||
|
18005 Bartholomew County IN 85729
|
||||||
|
18011 Boone County IN 80689
|
||||||
|
18019 Clark County IN 130451
|
||||||
|
18035 Delaware County IN 113106
|
||||||
|
18039 Elkhart County IN 208774
|
||||||
|
18043 Floyd County IN 82153
|
||||||
|
18053 Grant County IN 66524
|
||||||
|
18057 Hamilton County IN 387036
|
||||||
|
18059 Hancock County IN 90969
|
||||||
|
18063 Hendricks County IN 193510
|
||||||
|
18067 Howard County IN 83904
|
||||||
|
18081 Johnson County IN 174262
|
||||||
|
18089 Lake County IN 504612
|
||||||
|
18091 LaPorte County IN 111294
|
||||||
|
18095 Madison County IN 135088
|
||||||
|
18097 Marion County IN 992196
|
||||||
|
18105 Monroe County IN 143345
|
||||||
|
18127 Porter County IN 176049
|
||||||
|
18141 St. Joseph County IN 272861
|
||||||
|
18157 Tippecanoe County IN 190456
|
||||||
|
18163 Vanderburgh County IN 181995
|
||||||
|
18167 Vigo County IN 106512
|
||||||
|
18177 Wayne County IN 66169
|
||||||
|
19013 Black Hawk County IA 131532
|
||||||
|
19033 Cerro Gordo County IA 42372
|
||||||
|
19049 Dallas County IA 118457
|
||||||
|
19061 Dubuque County IA 99381
|
||||||
|
19103 Johnson County IA 160044
|
||||||
|
19113 Linn County IA 232028
|
||||||
|
19127 Marshall County IA 39890
|
||||||
|
19153 Polk County IA 516546
|
||||||
|
19155 Pottawattamie County IA 92996
|
||||||
|
19163 Scott County IA 175259
|
||||||
|
19169 Story County IA 101291
|
||||||
|
19179 Wapello County IA 35210
|
||||||
|
19193 Woodbury County IA 106649
|
||||||
|
20045 Douglas County KS 120920
|
||||||
|
20055 Finney County KS 37505
|
||||||
|
20057 Ford County KS 33993
|
||||||
|
20091 Johnson County KS 636906
|
||||||
|
20103 Leavenworth County KS 84590
|
||||||
|
20155 Reno County KS 61539
|
||||||
|
20161 Riley County KS 72598
|
||||||
|
20169 Saline County KS 53377
|
||||||
|
20173 Sedgwick County KS 538433
|
||||||
|
20177 Shawnee County KS 178607
|
||||||
|
20209 Wyandotte County KS 170597
|
||||||
|
21015 Boone County KY 145316
|
||||||
|
21047 Christian County KY 70115
|
||||||
|
21059 Daviess County KY 104898
|
||||||
|
21067 Fayette County KY 329751
|
||||||
|
21073 Franklin County KY 52649
|
||||||
|
21093 Hardin County KY 113482
|
||||||
|
21101 Henderson County KY 44255
|
||||||
|
21111 Jefferson County KY 795222
|
||||||
|
21113 Jessamine County KY 57147
|
||||||
|
21117 Kenton County KY 175779
|
||||||
|
21145 McCracken County KY 67553
|
||||||
|
21151 Madison County KY 101696
|
||||||
|
21209 Scott County KY 62262
|
||||||
|
21227 Warren County KY 149375
|
||||||
|
22015 Bossier Parish LA 131867
|
||||||
|
22017 Caddo Parish LA 224226
|
||||||
|
22019 Calcasieu Parish LA 208466
|
||||||
|
22033 East Baton Rouge Parish LA 456180
|
||||||
|
22045 Iberia Parish LA 66846
|
||||||
|
22051 Jefferson Parish LA 431398
|
||||||
|
22071 Orleans Parish LA 362154
|
||||||
|
22073 Ouachita Parish LA 158542
|
||||||
|
22079 Rapides Parish LA 125877
|
||||||
|
22103 St. Tammany Parish LA 279108
|
||||||
|
22109 Terrebonne Parish LA 104163
|
||||||
|
23001 Androscoggin County ME 116487
|
||||||
|
23005 Cumberland County ME 317222
|
||||||
|
23019 Penobscot County ME 157967
|
||||||
|
24003 Anne Arundel County MD 603380
|
||||||
|
24021 Frederick County MD 302883
|
||||||
|
24031 Montgomery County MD 1074582
|
||||||
|
24033 Prince George's County MD 970374
|
||||||
|
24043 Washington County MD 157731
|
||||||
|
24045 Wicomico County MD 106899
|
||||||
|
24510 Baltimore city MD 569997
|
||||||
|
25001 Barnstable County MA 233539
|
||||||
|
25003 Berkshire County MA 128224
|
||||||
|
25005 Bristol County MA 593640
|
||||||
|
25009 Essex County MA 826653
|
||||||
|
25013 Hampden County MA 464338
|
||||||
|
25015 Hampshire County MA 164065
|
||||||
|
25017 Middlesex County MA 1669979
|
||||||
|
25021 Norfolk County MA 739749
|
||||||
|
25023 Plymouth County MA 546829
|
||||||
|
25025 Suffolk County MA 791891
|
||||||
|
25027 Worcester County MA 888502
|
||||||
|
26017 Bay County MI 102123
|
||||||
|
26025 Calhoun County MI 133408
|
||||||
|
26049 Genesee County MI 401093
|
||||||
|
26065 Ingham County MI 289709
|
||||||
|
26075 Jackson County MI 159552
|
||||||
|
26077 Kalamazoo County MI 263795
|
||||||
|
26081 Kent County MI 675232
|
||||||
|
26099 Macomb County MI 886221
|
||||||
|
26111 Midland County MI 83754
|
||||||
|
26121 Muskegon County MI 177901
|
||||||
|
26125 Oakland County MI 1288337
|
||||||
|
26139 Ottawa County MI 308459
|
||||||
|
26145 Saginaw County MI 187688
|
||||||
|
26147 St. Clair County MI 160486
|
||||||
|
26161 Washtenaw County MI 370214
|
||||||
|
26163 Wayne County MI 1769038
|
||||||
|
27003 Anoka County MN 381605
|
||||||
|
27013 Blue Earth County MN 70634
|
||||||
|
27019 Carver County MN 114379
|
||||||
|
27027 Clay County MN 67734
|
||||||
|
27037 Dakota County MN 457710
|
||||||
|
27053 Hennepin County MN 1284784
|
||||||
|
27099 Mower County MN 40971
|
||||||
|
27109 Olmsted County MN 166731
|
||||||
|
27123 Ramsey County MN 541623
|
||||||
|
27131 Rice County MN 69939
|
||||||
|
27137 St. Louis County MN 200518
|
||||||
|
27139 Scott County MN 159017
|
||||||
|
27141 Sherburne County MN 104194
|
||||||
|
27145 Stearns County MN 164110
|
||||||
|
27147 Steele County MN 37464
|
||||||
|
27163 Washington County MN 286895
|
||||||
|
27169 Winona County MN 50523
|
||||||
|
28033 DeSoto County MS 197918
|
||||||
|
28035 Forrest County MS 79034
|
||||||
|
28047 Harrison County MS 217136
|
||||||
|
28049 Hinds County MS 211888
|
||||||
|
28071 Lafayette County MS 59597
|
||||||
|
28075 Lauderdale County MS 70317
|
||||||
|
28081 Lee County MS 83731
|
||||||
|
28089 Madison County MS 116298
|
||||||
|
28105 Oktibbeha County MS 51896
|
||||||
|
28121 Rankin County MS 162181
|
||||||
|
28151 Washington County MS 40446
|
||||||
|
29019 Boone County MO 191746
|
||||||
|
29021 Buchanan County MO 83540
|
||||||
|
29031 Cape Girardeau County MO 83999
|
||||||
|
29037 Cass County MO 115859
|
||||||
|
29043 Christian County MO 96725
|
||||||
|
29047 Clay County MO 265032
|
||||||
|
29051 Cole County MO 77908
|
||||||
|
29077 Greene County MO 309286
|
||||||
|
29095 Jackson County MO 732994
|
||||||
|
29097 Jasper County MO 127428
|
||||||
|
29183 St. Charles County MO 426499
|
||||||
|
29189 St. Louis County MO 990911
|
||||||
|
29510 St. Louis city MO 278144
|
||||||
|
30013 Cascade County MT 85029
|
||||||
|
30029 Flathead County MT 115429
|
||||||
|
30031 Gallatin County MT 128740
|
||||||
|
30049 Lewis and Clark County MT 75331
|
||||||
|
30063 Missoula County MT 123513
|
||||||
|
30093 Silver Bow County MT 36118
|
||||||
|
30111 Yellowstone County MT 172692
|
||||||
|
31001 Adams County NE 31071
|
||||||
|
31019 Buffalo County NE 51172
|
||||||
|
31053 Dodge County NE 38057
|
||||||
|
31055 Douglas County NE 606460
|
||||||
|
31079 Hall County NE 63633
|
||||||
|
31109 Lancaster County NE 334049
|
||||||
|
31119 Madison County NE 36106
|
||||||
|
31141 Platte County NE 35649
|
||||||
|
31153 Sarpy County NE 208303
|
||||||
|
32003 Clark County NV 2407226
|
||||||
|
32019 Lyon County NV 65088
|
||||||
|
32031 Washoe County NV 509386
|
||||||
|
32510 Carson City NV 58571
|
||||||
|
33011 Hillsborough County NH 433415
|
||||||
|
33013 Merrimack County NH 158078
|
||||||
|
33017 Strafford County NH 135043
|
||||||
|
34001 Atlantic County NJ 278657
|
||||||
|
34003 Bergen County NJ 977026
|
||||||
|
34007 Camden County NJ 535799
|
||||||
|
34011 Cumberland County NJ 157148
|
||||||
|
34013 Essex County NJ 896379
|
||||||
|
34017 Hudson County NJ 735033
|
||||||
|
34021 Mercer County NJ 399289
|
||||||
|
34023 Middlesex County NJ 883335
|
||||||
|
34025 Monmouth County NJ 651035
|
||||||
|
34031 Passaic County NJ 531624
|
||||||
|
34039 Union County NJ 601863
|
||||||
|
35001 Bernalillo County NM 667601
|
||||||
|
35005 Chaves County NM 63364
|
||||||
|
35009 Curry County NM 46655
|
||||||
|
35013 Doña Ana County NM 229091
|
||||||
|
35015 Eddy County NM 62509
|
||||||
|
35025 Lea County NM 74749
|
||||||
|
35035 Otero County NM 70368
|
||||||
|
35043 Sandoval County NM 159565
|
||||||
|
35045 San Juan County NM 120340
|
||||||
|
35049 Santa Fe County NM 156907
|
||||||
|
36001 Albany County NY 321225
|
||||||
|
36007 Broome County NY 195736
|
||||||
|
36011 Cayuga County NY 74365
|
||||||
|
36013 Chautauqua County NY 124126
|
||||||
|
36015 Chemung County NY 80415
|
||||||
|
36027 Dutchess County NY 300708
|
||||||
|
36029 Erie County NY 946741
|
||||||
|
36047 Kings County NY 2653963
|
||||||
|
36055 Monroe County NY 750506
|
||||||
|
36059 Nassau County NY 1398939
|
||||||
|
36063 Niagara County NY 208912
|
||||||
|
36065 Oneida County NY 226392
|
||||||
|
36067 Onondaga County NY 466584
|
||||||
|
36071 Orange County NY 417669
|
||||||
|
36083 Rensselaer County NY 160510
|
||||||
|
36091 Saratoga County NY 241343
|
||||||
|
36093 Schenectady County NY 162581
|
||||||
|
36103 Suffolk County NY 1546090
|
||||||
|
36109 Tompkins County NY 104047
|
||||||
|
36119 Westchester County NY 1015743
|
||||||
|
37001 Alamance County NC 186177
|
||||||
|
37019 Brunswick County NC 174702
|
||||||
|
37021 Buncombe County NC 277417
|
||||||
|
37025 Cabarrus County NC 249725
|
||||||
|
37035 Catawba County NC 170172
|
||||||
|
37049 Craven County NC 105025
|
||||||
|
37051 Cumberland County NC 338473
|
||||||
|
37057 Davidson County NC 180182
|
||||||
|
37063 Durham County NC 347240
|
||||||
|
37067 Forsyth County NC 401718
|
||||||
|
37071 Gaston County NC 246558
|
||||||
|
37081 Guilford County NC 562234
|
||||||
|
37097 Iredell County NC 211798
|
||||||
|
37101 Johnston County NC 256448
|
||||||
|
37105 Lee County NC 70258
|
||||||
|
37119 Mecklenburg County NC 1233383
|
||||||
|
37127 Nash County NC 99365
|
||||||
|
37129 New Hanover County NC 245959
|
||||||
|
37133 Onslow County NC 217175
|
||||||
|
37135 Orange County NC 152498
|
||||||
|
37147 Pitt County NC 182936
|
||||||
|
37151 Randolph County NC 149516
|
||||||
|
37159 Rowan County NC 155096
|
||||||
|
37179 Union County NC 267674
|
||||||
|
37183 Wake County NC 1257235
|
||||||
|
37191 Wayne County NC 122278
|
||||||
|
37195 Wilson County NC 81150
|
||||||
|
38015 Burleigh County ND 103251
|
||||||
|
38017 Cass County ND 201794
|
||||||
|
38035 Grand Forks County ND 74501
|
||||||
|
38059 Morton County ND 34601
|
||||||
|
38089 Stark County ND 34013
|
||||||
|
38101 Ward County ND 68233
|
||||||
|
38105 Williams County ND 41767
|
||||||
|
39003 Allen County OH 100881
|
||||||
|
39009 Athens County OH 63197
|
||||||
|
39017 Butler County OH 400128
|
||||||
|
39023 Clark County OH 135340
|
||||||
|
39035 Cuyahoga County OH 1232925
|
||||||
|
39041 Delaware County OH 242032
|
||||||
|
39045 Fairfield County OH 169752
|
||||||
|
39049 Franklin County OH 1361536
|
||||||
|
39057 Greene County OH 174322
|
||||||
|
39061 Hamilton County OH 838418
|
||||||
|
39063 Hancock County OH 75034
|
||||||
|
39085 Lake County OH 232217
|
||||||
|
39089 Licking County OH 185564
|
||||||
|
39093 Lorain County OH 323219
|
||||||
|
39095 Lucas County OH 423347
|
||||||
|
39099 Mahoning County OH 224706
|
||||||
|
39101 Marion County OH 65115
|
||||||
|
39103 Medina County OH 185025
|
||||||
|
39109 Miami County OH 112634
|
||||||
|
39113 Montgomery County OH 539598
|
||||||
|
39119 Muskingum County OH 87014
|
||||||
|
39133 Portage County OH 163404
|
||||||
|
39139 Richland County OH 124893
|
||||||
|
39151 Stark County OH 373771
|
||||||
|
39153 Summit County OH 538376
|
||||||
|
39155 Trumbull County OH 198972
|
||||||
|
39159 Union County OH 73446
|
||||||
|
39165 Warren County OH 257181
|
||||||
|
39169 Wayne County OH 116758
|
||||||
|
39173 Wood County OH 134176
|
||||||
|
40027 Cleveland County OK 303973
|
||||||
|
40031 Comanche County OK 122158
|
||||||
|
40047 Garfield County OK 61779
|
||||||
|
40101 Muskogee County OK 66708
|
||||||
|
40109 Oklahoma County OK 822125
|
||||||
|
40119 Payne County OK 83889
|
||||||
|
40125 Pottawatomie County OK 75102
|
||||||
|
40143 Tulsa County OK 698782
|
||||||
|
40147 Washington County OK 54037
|
||||||
|
41003 Benton County OR 97728
|
||||||
|
41005 Clackamas County OR 426280
|
||||||
|
41017 Deschutes County OR 213072
|
||||||
|
41029 Jackson County OR 221795
|
||||||
|
41033 Josephine County OR 87867
|
||||||
|
41039 Lane County OR 381584
|
||||||
|
41043 Linn County OR 132843
|
||||||
|
41047 Marion County OR 355777
|
||||||
|
41051 Multnomah County OR 795391
|
||||||
|
41067 Washington County OR 611708
|
||||||
|
41071 Yamhill County OR 110024
|
||||||
|
42003 Allegheny County PA 1225035
|
||||||
|
42011 Berks County PA 440072
|
||||||
|
42013 Blair County PA 119541
|
||||||
|
42027 Centre County PA 157393
|
||||||
|
42043 Dauphin County PA 293351
|
||||||
|
42045 Delaware County PA 580937
|
||||||
|
42049 Erie County PA 265832
|
||||||
|
42069 Lackawanna County PA 216502
|
||||||
|
42071 Lancaster County PA 563159
|
||||||
|
42075 Lebanon County PA 146380
|
||||||
|
42077 Lehigh County PA 384383
|
||||||
|
42079 Luzerne County PA 332126
|
||||||
|
42081 Lycoming County PA 112587
|
||||||
|
42091 Montgomery County PA 877643
|
||||||
|
42095 Northampton County PA 324411
|
||||||
|
42101 Philadelphia County PA 1574281
|
||||||
|
42133 York County PA 473197
|
||||||
|
44003 Kent County RI 173495
|
||||||
|
44007 Providence County RI 678179
|
||||||
|
45003 Aiken County SC 181515
|
||||||
|
45007 Anderson County SC 219930
|
||||||
|
45013 Beaufort County SC 204433
|
||||||
|
45015 Berkeley County SC 274666
|
||||||
|
45019 Charleston County SC 436200
|
||||||
|
45035 Dorchester County SC 178397
|
||||||
|
45041 Florence County SC 138504
|
||||||
|
45045 Greenville County SC 583125
|
||||||
|
45051 Horry County SC 427551
|
||||||
|
45063 Lexington County SC 317588
|
||||||
|
45077 Pickens County SC 139198
|
||||||
|
45079 Richland County SC 434956
|
||||||
|
45083 Spartanburg County SC 380857
|
||||||
|
45085 Sumter County SC 105067
|
||||||
|
45091 York County SC 306887
|
||||||
|
46011 Brookings County SD 37635
|
||||||
|
46013 Brown County SD 37561
|
||||||
|
46099 Minnehaha County SD 212691
|
||||||
|
46103 Pennington County SD 116792
|
||||||
|
47001 Anderson County TN 82066
|
||||||
|
47003 Bedford County TN 55273
|
||||||
|
47009 Blount County TN 143820
|
||||||
|
47011 Bradley County TN 115465
|
||||||
|
47037 Davidson County TN 745904
|
||||||
|
47063 Hamblen County TN 68843
|
||||||
|
47065 Hamilton County TN 390833
|
||||||
|
47093 Knox County TN 511453
|
||||||
|
47113 Madison County TN 100790
|
||||||
|
47119 Maury County TN 118131
|
||||||
|
47125 Montgomery County TN 249935
|
||||||
|
47141 Putnam County TN 86612
|
||||||
|
47149 Rutherford County TN 386352
|
||||||
|
47157 Shelby County TN 910226
|
||||||
|
47163 Sullivan County TN 163759
|
||||||
|
47165 Sumner County TN 215538
|
||||||
|
47179 Washington County TN 141199
|
||||||
|
47187 Williamson County TN 272061
|
||||||
|
47189 Wilson County TN 175033
|
||||||
|
48005 Angelina County TX 88154
|
||||||
|
48027 Bell County TX 402248
|
||||||
|
48029 Bexar County TX 2160088
|
||||||
|
48037 Bowie County TX 92696
|
||||||
|
48039 Brazoria County TX 419080
|
||||||
|
48041 Brazos County TX 249088
|
||||||
|
48061 Cameron County TX 433946
|
||||||
|
48085 Collin County TX 1297179
|
||||||
|
48091 Comal County TX 209166
|
||||||
|
48099 Coryell County TX 85592
|
||||||
|
48113 Dallas County TX 2661397
|
||||||
|
48121 Denton County TX 1069346
|
||||||
|
48135 Ector County TX 173801
|
||||||
|
48139 Ellis County TX 240867
|
||||||
|
48141 El Paso County TX 877858
|
||||||
|
48157 Fort Bend County TX 975191
|
||||||
|
48167 Galveston County TX 372207
|
||||||
|
48181 Grayson County TX 153613
|
||||||
|
48183 Gregg County TX 126095
|
||||||
|
48187 Guadalupe County TX 201111
|
||||||
|
48201 Harris County TX 5045026
|
||||||
|
48209 Hays County TX 304390
|
||||||
|
48215 Hidalgo County TX 921549
|
||||||
|
48231 Hunt County TX 123336
|
||||||
|
48245 Jefferson County TX 254321
|
||||||
|
48251 Johnson County TX 218048
|
||||||
|
48257 Kaufman County TX 209235
|
||||||
|
48265 Kerr County TX 54037
|
||||||
|
48277 Lamar County TX 51503
|
||||||
|
48303 Lubbock County TX 328906
|
||||||
|
48309 McLennan County TX 272020
|
||||||
|
48323 Maverick County TX 58823
|
||||||
|
48329 Midland County TX 187855
|
||||||
|
48339 Montgomery County TX 781194
|
||||||
|
48347 Nacogdoches County TX 66035
|
||||||
|
48349 Navarro County TX 57181
|
||||||
|
48355 Nueces County TX 352992
|
||||||
|
48367 Parker County TX 184767
|
||||||
|
48381 Randall County TX 152351
|
||||||
|
48397 Rockwall County TX 140738
|
||||||
|
48423 Smith County TX 252549
|
||||||
|
48439 Tarrant County TX 2248466
|
||||||
|
48441 Taylor County TX 150077
|
||||||
|
48451 Tom Green County TX 120602
|
||||||
|
48453 Travis County TX 1389670
|
||||||
|
48465 Val Verde County TX 47835
|
||||||
|
48469 Victoria County TX 92656
|
||||||
|
48471 Walker County TX 83842
|
||||||
|
48479 Webb County TX 281224
|
||||||
|
48485 Wichita County TX 129555
|
||||||
|
48491 Williamson County TX 752827
|
||||||
|
49005 Cache County UT 145000
|
||||||
|
49011 Davis County UT 381227
|
||||||
|
49021 Iron County UT 67141
|
||||||
|
49035 Salt Lake County UT 1220916
|
||||||
|
49045 Tooele County UT 87461
|
||||||
|
49049 Utah County UT 759859
|
||||||
|
49053 Washington County UT 213670
|
||||||
|
49057 Weber County UT 278174
|
||||||
|
50007 Chittenden County VT 169115
|
||||||
|
51059 Fairfax County VA 1167873
|
||||||
|
51107 Loudoun County VA 449749
|
||||||
|
51121 Montgomery County VA 98434
|
||||||
|
51510 Alexandria city VA 160662
|
||||||
|
51540 Charlottesville city VA 44388
|
||||||
|
51550 Chesapeake city VA 255332
|
||||||
|
51590 Danville city VA 41647
|
||||||
|
51600 Fairfax city VA 26772
|
||||||
|
51630 Fredericksburg city VA 30393
|
||||||
|
51650 Hampton city VA 137315
|
||||||
|
51660 Harrisonburg city VA 50839
|
||||||
|
51680 Lynchburg city VA 81347
|
||||||
|
51683 Manassas city VA 44332
|
||||||
|
51700 Newport News city VA 183230
|
||||||
|
51710 Norfolk city VA 231013
|
||||||
|
51730 Petersburg city VA 33734
|
||||||
|
51740 Portsmouth city VA 96777
|
||||||
|
51760 Richmond city VA 237257
|
||||||
|
51770 Roanoke city VA 99111
|
||||||
|
51775 Salem city VA 25816
|
||||||
|
51790 Staunton city VA 26801
|
||||||
|
51800 Suffolk city VA 104699
|
||||||
|
51810 Virginia Beach city VA 453737
|
||||||
|
51840 Winchester city VA 28272
|
||||||
|
53005 Benton County WA 221722
|
||||||
|
53007 Chelan County WA 81941
|
||||||
|
53011 Clark County WA 532119
|
||||||
|
53015 Cowlitz County WA 114885
|
||||||
|
53021 Franklin County WA 102612
|
||||||
|
53025 Grant County WA 105727
|
||||||
|
53033 King County WA 2344939
|
||||||
|
53035 Kitsap County WA 283374
|
||||||
|
53053 Pierce County WA 946288
|
||||||
|
53057 Skagit County WA 132975
|
||||||
|
53061 Snohomish County WA 870656
|
||||||
|
53063 Spokane County WA 558344
|
||||||
|
53067 Thurston County WA 304261
|
||||||
|
53071 Walla Walla County WA 62361
|
||||||
|
53073 Whatcom County WA 236392
|
||||||
|
53075 Whitman County WA 48512
|
||||||
|
53077 Yakima County WA 259185
|
||||||
|
54011 Cabell County WV 91183
|
||||||
|
54039 Kanawha County WV 172381
|
||||||
|
54061 Monongalia County WV 107991
|
||||||
|
54069 Ohio County WV 40496
|
||||||
|
54107 Wood County WV 82385
|
||||||
|
55009 Brown County WI 275803
|
||||||
|
55025 Dane County WI 590375
|
||||||
|
55031 Douglas County WI 43990
|
||||||
|
55035 Eau Claire County WI 109033
|
||||||
|
55039 Fond du Lac County WI 104669
|
||||||
|
55059 Kenosha County WI 168448
|
||||||
|
55063 La Crosse County WI 121339
|
||||||
|
55071 Manitowoc County WI 81710
|
||||||
|
55073 Marathon County WI 139432
|
||||||
|
55079 Milwaukee County WI 924216
|
||||||
|
55087 Outagamie County WI 195894
|
||||||
|
55089 Ozaukee County WI 94346
|
||||||
|
55097 Portage County WI 71943
|
||||||
|
55101 Racine County WI 198919
|
||||||
|
55105 Rock County WI 166472
|
||||||
|
55117 Sheboygan County WI 118047
|
||||||
|
55131 Washington County WI 139238
|
||||||
|
55133 Waukesha County WI 417210
|
||||||
|
55139 Winnebago County WI 174218
|
||||||
|
56001 Albany County WY 38558
|
||||||
|
56005 Campbell County WY 48145
|
||||||
|
56021 Laramie County WY 102938
|
||||||
|
56025 Natrona County WY 80526
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{code}", "rows": "postal-code.tsv", "key": "code", "parent": "locality", "weight": "addresses" }
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "region.tsv", "key": "abbr", "name": "name", "weight": "population" }
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
abbr code name population timezone
|
||||||
|
AK 02 Alaska 737270 America/Anchorage
|
||||||
|
AL 01 Alabama 5193088 America/Chicago
|
||||||
|
AR 05 Arkansas 3114791 America/Chicago
|
||||||
|
AZ 04 Arizona 7623818 America/Phoenix
|
||||||
|
CA 06 California 39355309 America/Los_Angeles
|
||||||
|
CO 08 Colorado 6012561 America/Denver
|
||||||
|
CT 09 Connecticut 3688496 America/New_York
|
||||||
|
DC 11 District of Columbia 693645 America/New_York
|
||||||
|
DE 10 Delaware 1059952 America/New_York
|
||||||
|
FL 12 Florida 23462518 America/New_York
|
||||||
|
GA 13 Georgia 11302748 America/New_York
|
||||||
|
IA 19 Iowa 3238387 America/Chicago
|
||||||
|
ID 16 Idaho 2029733 America/Boise
|
||||||
|
IL 17 Illinois 12719141 America/Chicago
|
||||||
|
IN 18 Indiana 6973333 America/Indiana/Indianapolis
|
||||||
|
KS 20 Kansas 2977220 America/Chicago
|
||||||
|
KY 21 Kentucky 4606864 America/New_York
|
||||||
|
LA 22 Louisiana 4618189 America/Chicago
|
||||||
|
MA 25 Massachusetts 7154084 America/New_York
|
||||||
|
MD 24 Maryland 6265347 America/New_York
|
||||||
|
ME 23 Maine 1414874 America/New_York
|
||||||
|
MI 26 Michigan 10127884 America/Detroit
|
||||||
|
MN 27 Minnesota 5830405 America/Chicago
|
||||||
|
MO 29 Missouri 6270541 America/Chicago
|
||||||
|
MS 28 Mississippi 2954160 America/Chicago
|
||||||
|
MT 30 Montana 1144694 America/Denver
|
||||||
|
NC 37 North Carolina 11197968 America/New_York
|
||||||
|
ND 38 North Dakota 799358 America/Chicago
|
||||||
|
NE 31 Nebraska 2018006 America/Chicago
|
||||||
|
NH 33 New Hampshire 1415342 America/New_York
|
||||||
|
NJ 34 New Jersey 9548215 America/New_York
|
||||||
|
NM 35 New Mexico 2125498 America/Denver
|
||||||
|
NV 32 Nevada 3282188 America/Los_Angeles
|
||||||
|
NY 36 New York 20002427 America/New_York
|
||||||
|
OH 39 Ohio 11900510 America/New_York
|
||||||
|
OK 40 Oklahoma 4123288 America/Chicago
|
||||||
|
OR 41 Oregon 4273586 America/Los_Angeles
|
||||||
|
PA 42 Pennsylvania 13059432 America/New_York
|
||||||
|
RI 44 Rhode Island 1114521 America/New_York
|
||||||
|
SC 45 South Carolina 5570274 America/New_York
|
||||||
|
SD 46 South Dakota 935094 America/Chicago
|
||||||
|
TN 47 Tennessee 7315076 America/Chicago
|
||||||
|
TX 48 Texas 31709821 America/Chicago
|
||||||
|
UT 49 Utah 3538904 America/Denver
|
||||||
|
VA 51 Virginia 8880107 America/New_York
|
||||||
|
VT 50 Vermont 644663 America/New_York
|
||||||
|
WA 53 Washington 8001020 America/Los_Angeles
|
||||||
|
WI 55 Wisconsin 5972787 America/Chicago
|
||||||
|
WV 54 West Virginia 1766147 America/New_York
|
||||||
|
WY 56 Wyoming 588753 America/Denver
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "street.tsv", "parent": "locality", "weight": "addresses" }
|
||||||
+15841
File diff suppressed because it is too large
Load Diff
+1
-10
@@ -1,10 +1 @@
|
|||||||
[
|
{ "format": "{make} {model}", "rows": "car.tsv" }
|
||||||
{ "format": "{maker} {model}", "maker": "BMW", "model": ["3 Series", "5 Series", "X3", "X5"] },
|
|
||||||
{ "format": "{maker} {model}", "maker": "Ford", "model": ["Fiesta", "Focus", "Mustang", "Explorer"] },
|
|
||||||
{ "format": "{maker} {model}", "maker": "Honda", "model": ["Civic", "Accord", "CR-V", "Jazz"] },
|
|
||||||
{ "format": "{maker} {model}", "maker": "Mercedes-Benz", "model": ["A-Class", "C-Class", "E-Class", "GLC"] },
|
|
||||||
{ "format": "{maker} {model}", "maker": "Tesla", "model": ["Model 3", "Model S", "Model X", "Model Y"] },
|
|
||||||
{ "format": "{maker} {model}", "maker": "Toyota", "model": ["Corolla", "Camry", "RAV4", "Yaris"] },
|
|
||||||
{ "format": "{maker} {model}", "maker": "Volkswagen", "model": ["Golf", "Passat", "Polo", "Tiguan"] },
|
|
||||||
{ "format": "{maker} {model}", "maker": "Volvo", "model": ["XC40", "XC60", "XC90", "V60"] }
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
make model
|
||||||
|
BMW 3 Series
|
||||||
|
BMW 5 Series
|
||||||
|
BMW X3
|
||||||
|
BMW X5
|
||||||
|
Ford Explorer
|
||||||
|
Ford Fiesta
|
||||||
|
Ford Focus
|
||||||
|
Ford Mustang
|
||||||
|
Honda Accord
|
||||||
|
Honda CR-V
|
||||||
|
Honda Civic
|
||||||
|
Honda Jazz
|
||||||
|
Mercedes-Benz A-Class
|
||||||
|
Mercedes-Benz C-Class
|
||||||
|
Mercedes-Benz E-Class
|
||||||
|
Mercedes-Benz GLC
|
||||||
|
Tesla Model 3
|
||||||
|
Tesla Model S
|
||||||
|
Tesla Model X
|
||||||
|
Tesla Model Y
|
||||||
|
Toyota Camry
|
||||||
|
Toyota Corolla
|
||||||
|
Toyota RAV4
|
||||||
|
Toyota Yaris
|
||||||
|
Volkswagen Golf
|
||||||
|
Volkswagen Passat
|
||||||
|
Volkswagen Polo
|
||||||
|
Volkswagen Tiguan
|
||||||
|
Volvo V60
|
||||||
|
Volvo XC40
|
||||||
|
Volvo XC60
|
||||||
|
Volvo XC90
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
{ "format": "{name}", "rows": "country.tsv", "key": "alpha2", "name": "name" }
|
|
||||||
@@ -1,242 +0,0 @@
|
|||||||
alpha2 alpha3 calling-code capital currency flag languages name numeric tld
|
|
||||||
AD AND 376 Andorra la Vella EUR 🇦🇩 ca Andorra 020 .ad
|
|
||||||
AE ARE 971 Abu Dhabi AED 🇦🇪 ar-AE,fa,en,hi,ur United Arab Emirates 784 .ae
|
|
||||||
AF AFG 93 Kabul AFN 🇦🇫 fa-AF,ps,uz-AF,tk Afghanistan 004 .af
|
|
||||||
AG ATG 1-268 St. John's XCD 🇦🇬 en-AG Antigua & Barbuda 028 .ag
|
|
||||||
AI AIA 1-264 The Valley XCD 🇦🇮 en-AI Anguilla 660 .ai
|
|
||||||
AL ALB 355 Tirana ALL 🇦🇱 sq,el Albania 008 .al
|
|
||||||
AM ARM 374 Yerevan AMD 🇦🇲 hy Armenia 051 .am
|
|
||||||
AO AGO 244 Luanda AOA 🇦🇴 pt-AO Angola 024 .ao
|
|
||||||
AR ARG 54 Buenos Aires ARS 🇦🇷 es-AR,en,it,de,fr,gn Argentina 032 .ar
|
|
||||||
AS ASM 1-684 Pago Pago USD 🇦🇸 en-AS,sm,to American Samoa 016 .as
|
|
||||||
AT AUT 43 Vienna EUR 🇦🇹 de-AT,hr,hu,sl Austria 040 .at
|
|
||||||
AU AUS 61 Canberra AUD 🇦🇺 en-AU Australia 036 .au
|
|
||||||
AW ABW 297 Oranjestad AWG 🇦🇼 nl-AW,pap,es,en Aruba 533 .aw
|
|
||||||
AX ALA 358 Mariehamn EUR 🇦🇽 sv-AX Åland Islands 248 .ax
|
|
||||||
AZ AZE 994 Baku AZN 🇦🇿 az,ru,hy Azerbaijan 031 .az
|
|
||||||
BA BIH 387 Sarajevo BAM 🇧🇦 bs,hr-BA,sr-BA Bosnia 070 .ba
|
|
||||||
BB BRB 1-246 Bridgetown BBD 🇧🇧 en-BB Barbados 052 .bb
|
|
||||||
BD BGD 880 Dhaka BDT 🇧🇩 bn-BD,en Bangladesh 050 .bd
|
|
||||||
BE BEL 32 Brussels EUR 🇧🇪 nl-BE,fr-BE,de-BE Belgium 056 .be
|
|
||||||
BF BFA 226 Ouagadougou XOF 🇧🇫 fr-BF,mos Burkina Faso 854 .bf
|
|
||||||
BG BGR 359 Sofia EUR 🇧🇬 bg,tr-BG,rom Bulgaria 100 .bg
|
|
||||||
BH BHR 973 Manama BHD 🇧🇭 ar-BH,en,fa,ur Bahrain 048 .bh
|
|
||||||
BI BDI 257 Gitega BIF 🇧🇮 fr-BI,rn Burundi 108 .bi
|
|
||||||
BJ BEN 229 Porto-Novo XOF 🇧🇯 fr-BJ Benin 204 .bj
|
|
||||||
BL BLM 590 Gustavia EUR 🇧🇱 fr St. Barthélemy 652 .gp
|
|
||||||
BM BMU 1-441 Hamilton BMD 🇧🇲 en-BM,pt Bermuda 060 .bm
|
|
||||||
BN BRN 673 Bandar Seri Begawan BND 🇧🇳 ms-BN,en-BN Brunei 096 .bn
|
|
||||||
BO BOL 591 Sucre BOB 🇧🇴 es-BO,qu,ay Bolivia 068 .bo
|
|
||||||
BR BRA 55 Brasilia BRL 🇧🇷 pt-BR,es,en,fr Brazil 076 .br
|
|
||||||
BS BHS 1-242 Nassau BSD 🇧🇸 en-BS Bahamas 044 .bs
|
|
||||||
BT BTN 975 Thimphu INR 🇧🇹 dz Bhutan 064 .bt
|
|
||||||
BW BWA 267 Gaborone BWP 🇧🇼 en-BW,tn-BW Botswana 072 .bw
|
|
||||||
BY BLR 375 Minsk BYN 🇧🇾 be,ru Belarus 112 .by
|
|
||||||
BZ BLZ 501 Belmopan BZD 🇧🇿 en-BZ,es Belize 084 .bz
|
|
||||||
CA CAN 1 Ottawa CAD 🇨🇦 en-CA,fr-CA,iu Canada 124 .ca
|
|
||||||
CC CCK 61 West Island AUD 🇨🇨 ms-CC,en Cocos Islands 166 .cc
|
|
||||||
CD COD 243 Kinshasa CDF 🇨🇩 fr-CD,ln,ktu,kg,sw,lua Congo - Kinshasa 180 .cd
|
|
||||||
CF CAF 236 Bangui XAF 🇨🇫 fr-CF,sg,ln,kg Central African Republic 140 .cf
|
|
||||||
CG COG 242 Brazzaville XAF 🇨🇬 fr-CG,kg,ln-CG Congo - Brazzaville 178 .cg
|
|
||||||
CH CHE 41 Bern CHF 🇨🇭 de-CH,fr-CH,it-CH,rm Switzerland 756 .ch
|
|
||||||
CI CIV 225 Yamoussoukro XOF 🇨🇮 fr-CI Côte d’Ivoire 384 .ci
|
|
||||||
CK COK 682 Avarua NZD 🇨🇰 en-CK,mi Cook Islands 184 .ck
|
|
||||||
CL CHL 56 Santiago CLP 🇨🇱 es-CL Chile 152 .cl
|
|
||||||
CM CMR 237 Yaounde XAF 🇨🇲 en-CM,fr-CM Cameroon 120 .cm
|
|
||||||
CN CHN 86 Beijing CNY 🇨🇳 zh-CN,yue,wuu,dta,ug,za China 156 .cn
|
|
||||||
CO COL 57 Bogota COP 🇨🇴 es-CO Colombia 170 .co
|
|
||||||
CR CRI 506 San Jose CRC 🇨🇷 es-CR,en Costa Rica 188 .cr
|
|
||||||
CU CUB 53 Havana CUP 🇨🇺 es-CU,pap Cuba 192 .cu
|
|
||||||
CV CPV 238 Praia CVE 🇨🇻 pt-CV Cape Verde 132 .cv
|
|
||||||
CW CUW 599 Willemstad XCG 🇨🇼 nl,pap Curaçao 531 .cw
|
|
||||||
CX CXR 61 Flying Fish Cove AUD 🇨🇽 en,zh,ms-CX Christmas Island 162 .cx
|
|
||||||
CY CYP 357 Nicosia EUR 🇨🇾 el-CY,tr-CY,en Cyprus 196 .cy
|
|
||||||
CZ CZE 420 Prague CZK 🇨🇿 cs,sk Czechia 203 .cz
|
|
||||||
DE DEU 49 Berlin EUR 🇩🇪 de Germany 276 .de
|
|
||||||
DJ DJI 253 Djibouti DJF 🇩🇯 fr-DJ,ar,so-DJ,aa Djibouti 262 .dj
|
|
||||||
DK DNK 45 Copenhagen DKK 🇩🇰 da-DK,en,fo,de-DK Denmark 208 .dk
|
|
||||||
DM DMA 1-767 Roseau XCD 🇩🇲 en-DM Dominica 212 .dm
|
|
||||||
DO DOM 1-809 Santo Domingo DOP 🇩🇴 es-DO Dominican Republic 214 .do
|
|
||||||
DZ DZA 213 Algiers DZD 🇩🇿 ar-DZ Algeria 012 .dz
|
|
||||||
EC ECU 593 Quito USD 🇪🇨 es-EC Ecuador 218 .ec
|
|
||||||
EE EST 372 Tallinn EUR 🇪🇪 et,ru Estonia 233 .ee
|
|
||||||
EG EGY 20 Cairo EGP 🇪🇬 ar-EG,en,fr Egypt 818 .eg
|
|
||||||
EH ESH 212 El-Aaiun MAD 🇪🇭 ar,mey Western Sahara 732 .eh
|
|
||||||
ER ERI 291 Asmara ERN 🇪🇷 aa-ER,ar,tig,kun,ti-ER Eritrea 232 .er
|
|
||||||
ES ESP 34 Madrid EUR 🇪🇸 es-ES,ca,gl,eu,oc Spain 724 .es
|
|
||||||
ET ETH 251 Addis Ababa ETB 🇪🇹 am,en-ET,om-ET,ti-ET,so-ET,sid Ethiopia 231 .et
|
|
||||||
FI FIN 358 Helsinki EUR 🇫🇮 fi-FI,sv-FI,smn Finland 246 .fi
|
|
||||||
FJ FJI 679 Suva FJD 🇫🇯 en-FJ,fj Fiji 242 .fj
|
|
||||||
FK FLK 500 Stanley FKP 🇫🇰 en-FK Falkland Islands 238 .fk
|
|
||||||
FM FSM 691 Palikir USD 🇫🇲 en-FM,chk,pon,yap,kos,uli,woe,nkr,kpg Micronesia 583 .fm
|
|
||||||
FO FRO 298 Torshavn DKK 🇫🇴 fo,da-FO Faroe Islands 234 .fo
|
|
||||||
FR FRA 33 Paris EUR 🇫🇷 fr-FR,frp,br,co,ca,eu,oc France 250 .fr
|
|
||||||
GA GAB 241 Libreville XAF 🇬🇦 fr-GA Gabon 266 .ga
|
|
||||||
GB GBR 44 London GBP 🇬🇧 en-GB,cy-GB,gd UK 826 .uk
|
|
||||||
GD GRD 1-473 St. George's XCD 🇬🇩 en-GD Grenada 308 .gd
|
|
||||||
GE GEO 995 Tbilisi GEL 🇬🇪 ka,ru,hy,az Georgia 268 .ge
|
|
||||||
GF GUF 594 Cayenne EUR 🇬🇫 fr-GF French Guiana 254 .gf
|
|
||||||
GG GGY 44 St Peter Port GBP 🇬🇬 en,nrf Guernsey 831 .gg
|
|
||||||
GH GHA 233 Accra GHS 🇬🇭 en-GH,ak,ee,tw Ghana 288 .gh
|
|
||||||
GI GIB 350 Gibraltar GIP 🇬🇮 en-GI,es,it,pt Gibraltar 292 .gi
|
|
||||||
GL GRL 299 Nuuk DKK 🇬🇱 kl,da-GL,en Greenland 304 .gl
|
|
||||||
GM GMB 220 Banjul GMD 🇬🇲 en-GM,mnk,wof,wo,ff Gambia 270 .gm
|
|
||||||
GN GIN 224 Conakry GNF 🇬🇳 fr-GN Guinea 324 .gn
|
|
||||||
GP GLP 590 Basse-Terre EUR 🇬🇵 fr-GP Guadeloupe 312 .gp
|
|
||||||
GQ GNQ 240 Ciudad de la Paz XAF 🇬🇶 es-GQ,fr,pt Equatorial Guinea 226 .gq
|
|
||||||
GR GRC 30 Athens EUR 🇬🇷 el-GR,en,fr Greece 300 .gr
|
|
||||||
GT GTM 502 Guatemala City GTQ 🇬🇹 es-GT Guatemala 320 .gt
|
|
||||||
GU GUM 1-671 Hagatna USD 🇬🇺 en-GU,ch-GU Guam 316 .gu
|
|
||||||
GW GNB 245 Bissau XOF 🇬🇼 pt-GW,pov Guinea-Bissau 624 .gw
|
|
||||||
GY GUY 592 Georgetown GYD 🇬🇾 en-GY Guyana 328 .gy
|
|
||||||
HK HKG 852 Hong Kong HKD 🇭🇰 zh-HK,yue,zh,en Hong Kong 344 .hk
|
|
||||||
HN HND 504 Tegucigalpa HNL 🇭🇳 es-HN,cab,miq Honduras 340 .hn
|
|
||||||
HR HRV 385 Zagreb EUR 🇭🇷 hr-HR,sr Croatia 191 .hr
|
|
||||||
HT HTI 509 Port-au-Prince HTG 🇭🇹 ht,fr-HT Haiti 332 .ht
|
|
||||||
HU HUN 36 Budapest HUF 🇭🇺 hu-HU Hungary 348 .hu
|
|
||||||
ID IDN 62 Jakarta IDR 🇮🇩 id,en,nl,jv Indonesia 360 .id
|
|
||||||
IE IRL 353 Dublin EUR 🇮🇪 en-IE,ga-IE Ireland 372 .ie
|
|
||||||
IL ISR 972 Jerusalem ILS 🇮🇱 he,ar-IL,en-IL Israel 376 .il
|
|
||||||
IM IMN 44 Douglas GBP 🇮🇲 en,gv Isle of Man 833 .im
|
|
||||||
IN IND 91 New Delhi INR 🇮🇳 en-IN,hi,bn,te,mr,ta,ur,gu,kn,ml,or,pa,as,bh,sat,ks,ne,sd,kok,doi,mni,sit,sa,fr,lus,inc India 356 .in
|
|
||||||
IO IOT 246 Diego Garcia USD 🇮🇴 en-IO British Indian Ocean Territory 086 .io
|
|
||||||
IQ IRQ 964 Baghdad IQD 🇮🇶 ar-IQ,ku,hy Iraq 368 .iq
|
|
||||||
IR IRN 98 Tehran IRR 🇮🇷 fa-IR,ku Iran 364 .ir
|
|
||||||
IS ISL 354 Reykjavik ISK 🇮🇸 is,en,de,da,sv,no Iceland 352 .is
|
|
||||||
IT ITA 39 Rome EUR 🇮🇹 it-IT,de-IT,fr-IT,sc,ca,co,sl Italy 380 .it
|
|
||||||
JE JEY 44 Saint Helier GBP 🇯🇪 en,fr,nrf Jersey 832 .je
|
|
||||||
JM JAM 1-876 Kingston JMD 🇯🇲 en-JM Jamaica 388 .jm
|
|
||||||
JO JOR 962 Amman JOD 🇯🇴 ar-JO,en Jordan 400 .jo
|
|
||||||
JP JPN 81 Tokyo JPY 🇯🇵 ja Japan 392 .jp
|
|
||||||
KE KEN 254 Nairobi KES 🇰🇪 en-KE,sw-KE Kenya 404 .ke
|
|
||||||
KG KGZ 996 Bishkek KGS 🇰🇬 ky,uz,ru Kyrgyzstan 417 .kg
|
|
||||||
KH KHM 855 Phnom Penh KHR 🇰🇭 km,fr,en Cambodia 116 .kh
|
|
||||||
KI KIR 686 Tarawa AUD 🇰🇮 en-KI,gil Kiribati 296 .ki
|
|
||||||
KM COM 269 Moroni KMF 🇰🇲 ar,fr-KM Comoros 174 .km
|
|
||||||
KN KNA 1-869 Basseterre XCD 🇰🇳 en-KN St. Kitts & Nevis 659 .kn
|
|
||||||
KP PRK 850 Pyongyang KPW 🇰🇵 ko-KP North Korea 408 .kp
|
|
||||||
KR KOR 82 Seoul KRW 🇰🇷 ko-KR,en South Korea 410 .kr
|
|
||||||
KW KWT 965 Kuwait City KWD 🇰🇼 ar-KW,en Kuwait 414 .kw
|
|
||||||
KY CYM 1-345 George Town KYD 🇰🇾 en-KY Cayman Islands 136 .ky
|
|
||||||
KZ KAZ 7 Nur-Sultan KZT 🇰🇿 kk,ru Kazakhstan 398 .kz
|
|
||||||
LA LAO 856 Vientiane LAK 🇱🇦 lo,fr,en Laos 418 .la
|
|
||||||
LB LBN 961 Beirut LBP 🇱🇧 ar-LB,fr-LB,en,hy Lebanon 422 .lb
|
|
||||||
LC LCA 1-758 Castries XCD 🇱🇨 en-LC St. Lucia 662 .lc
|
|
||||||
LI LIE 423 Vaduz CHF 🇱🇮 de-LI Liechtenstein 438 .li
|
|
||||||
LK LKA 94 Colombo LKR 🇱🇰 si,ta,en Sri Lanka 144 .lk
|
|
||||||
LR LBR 231 Monrovia LRD 🇱🇷 en-LR Liberia 430 .lr
|
|
||||||
LS LSO 266 Maseru LSL 🇱🇸 en-LS,st,zu,xh Lesotho 426 .ls
|
|
||||||
LT LTU 370 Vilnius EUR 🇱🇹 lt,ru,pl Lithuania 440 .lt
|
|
||||||
LU LUX 352 Luxembourg EUR 🇱🇺 lb,de-LU,fr-LU Luxembourg 442 .lu
|
|
||||||
LV LVA 371 Riga EUR 🇱🇻 lv,ru,lt Latvia 428 .lv
|
|
||||||
LY LBY 218 Tripoli LYD 🇱🇾 ar-LY,it,en Libya 434 .ly
|
|
||||||
MA MAR 212 Rabat MAD 🇲🇦 ar-MA,ber,fr Morocco 504 .ma
|
|
||||||
MC MCO 377 Monaco EUR 🇲🇨 fr-MC,en,it Monaco 492 .mc
|
|
||||||
MD MDA 373 Chisinau MDL 🇲🇩 ro,ru,gag,tr Moldova 498 .md
|
|
||||||
ME MNE 382 Podgorica EUR 🇲🇪 sr,hu,bs,sq,hr,rom Montenegro 499 .me
|
|
||||||
MF MAF 590 Marigot EUR 🇲🇫 fr St. Martin 663 .gp
|
|
||||||
MG MDG 261 Antananarivo MGA 🇲🇬 fr-MG,mg Madagascar 450 .mg
|
|
||||||
MH MHL 692 Majuro USD 🇲🇭 mh,en-MH Marshall Islands 584 .mh
|
|
||||||
MK MKD 389 Skopje MKD 🇲🇰 mk,sq,tr,rmm,sr North Macedonia 807 .mk
|
|
||||||
ML MLI 223 Bamako XOF 🇲🇱 fr-ML,bm Mali 466 .ml
|
|
||||||
MM MMR 95 Nay Pyi Taw MMK 🇲🇲 my Myanmar 104 .mm
|
|
||||||
MN MNG 976 Ulaanbaatar MNT 🇲🇳 mn,ru Mongolia 496 .mn
|
|
||||||
MO MAC 853 Macao MOP 🇲🇴 zh,zh-MO,pt Macao 446 .mo
|
|
||||||
MP MNP 1-670 Saipan USD 🇲🇵 fil,tl,zh,ch-MP,en-MP Northern Mariana Islands 580 .mp
|
|
||||||
MQ MTQ 596 Fort-de-France EUR 🇲🇶 fr-MQ Martinique 474 .mq
|
|
||||||
MR MRT 222 Nouakchott MRU 🇲🇷 ar-MR,fuc,snk,fr,mey,wo Mauritania 478 .mr
|
|
||||||
MS MSR 1-664 Plymouth XCD 🇲🇸 en-MS Montserrat 500 .ms
|
|
||||||
MT MLT 356 Valletta EUR 🇲🇹 mt,en-MT Malta 470 .mt
|
|
||||||
MU MUS 230 Port Louis MUR 🇲🇺 en-MU,bho,fr Mauritius 480 .mu
|
|
||||||
MV MDV 960 Male MVR 🇲🇻 dv,en Maldives 462 .mv
|
|
||||||
MW MWI 265 Lilongwe MWK 🇲🇼 ny,yao,tum,swk Malawi 454 .mw
|
|
||||||
MX MEX 52 Mexico City MXN 🇲🇽 es-MX Mexico 484 .mx
|
|
||||||
MY MYS 60 Kuala Lumpur MYR 🇲🇾 ms-MY,en,zh,ta,te,ml,pa,th Malaysia 458 .my
|
|
||||||
MZ MOZ 258 Maputo MZN 🇲🇿 pt-MZ,vmw Mozambique 508 .mz
|
|
||||||
NA NAM 264 Windhoek NAD 🇳🇦 en-NA,af,de,hz,naq Namibia 516 .na
|
|
||||||
NC NCL 687 Noumea XPF 🇳🇨 fr-NC New Caledonia 540 .nc
|
|
||||||
NE NER 227 Niamey XOF 🇳🇪 fr-NE,ha,kr,dje Niger 562 .ne
|
|
||||||
NF NFK 672 Kingston AUD 🇳🇫 en-NF Norfolk Island 574 .nf
|
|
||||||
NG NGA 234 Abuja NGN 🇳🇬 en-NG,ha,yo,ig,ff Nigeria 566 .ng
|
|
||||||
NI NIC 505 Managua NIO 🇳🇮 es-NI,en Nicaragua 558 .ni
|
|
||||||
NL NLD 31 Amsterdam EUR 🇳🇱 nl-NL,fy-NL Netherlands 528 .nl
|
|
||||||
NO NOR 47 Oslo NOK 🇳🇴 no,nb,nn,se,fi Norway 578 .no
|
|
||||||
NP NPL 977 Kathmandu NPR 🇳🇵 ne,en Nepal 524 .np
|
|
||||||
NR NRU 674 Yaren AUD 🇳🇷 na,en-NR Nauru 520 .nr
|
|
||||||
NU NIU 683 Alofi NZD 🇳🇺 niu,en-NU Niue 570 .nu
|
|
||||||
NZ NZL 64 Wellington NZD 🇳🇿 en-NZ,mi New Zealand 554 .nz
|
|
||||||
OM OMN 968 Muscat OMR 🇴🇲 ar-OM,en,bal,ur Oman 512 .om
|
|
||||||
PA PAN 507 Panama City PAB 🇵🇦 es-PA,en Panama 591 .pa
|
|
||||||
PE PER 51 Lima PEN 🇵🇪 es-PE,qu,ay Peru 604 .pe
|
|
||||||
PF PYF 689 Papeete XPF 🇵🇫 fr-PF,ty French Polynesia 258 .pf
|
|
||||||
PG PNG 675 Port Moresby PGK 🇵🇬 en-PG,ho,meu,tpi Papua New Guinea 598 .pg
|
|
||||||
PH PHL 63 Manila PHP 🇵🇭 tl,en-PH,fil,ceb,ilo,hil,war,pam,bik,bcl,pag,mrw,tsg,mdh,cbk,krj,sgd,msb,akl,ibg,yka,mta,abx Philippines 608 .ph
|
|
||||||
PK PAK 92 Islamabad PKR 🇵🇰 ur-PK,en-PK,pa,sd,ps,brh Pakistan 586 .pk
|
|
||||||
PL POL 48 Warsaw PLN 🇵🇱 pl Poland 616 .pl
|
|
||||||
PM SPM 508 Saint-Pierre EUR 🇵🇲 fr-PM St. Pierre & Miquelon 666 .pm
|
|
||||||
PN PCN 870 Adamstown NZD 🇵🇳 en-PN Pitcairn 612 .pn
|
|
||||||
PR PRI 1 San Juan USD 🇵🇷 en-PR,es-PR Puerto Rico 630 .pr
|
|
||||||
PT PRT 351 Lisbon EUR 🇵🇹 pt-PT,mwl Portugal 620 .pt
|
|
||||||
PW PLW 680 Melekeok USD 🇵🇼 pau,sov,en-PW,tox,ja,fil,zh Palau 585 .pw
|
|
||||||
PY PRY 595 Asuncion PYG 🇵🇾 es-PY,gn Paraguay 600 .py
|
|
||||||
QA QAT 974 Doha QAR 🇶🇦 ar-QA,es Qatar 634 .qa
|
|
||||||
RE REU 262 Saint-Denis EUR 🇷🇪 fr-RE Réunion 638 .re
|
|
||||||
RO ROU 40 Bucharest RON 🇷🇴 ro,hu,rom Romania 642 .ro
|
|
||||||
RS SRB 381 Belgrade RSD 🇷🇸 sr,hu,bs,rom Serbia 688 .rs
|
|
||||||
RU RUS 7 Moscow RUB 🇷🇺 ru,tt,xal,cau,ady,kv,ce,tyv,cv,udm,tut,mns,bua,myv,mdf,chm,ba,inh,kbd,krc,av,sah,nog Russia 643 .ru
|
|
||||||
RW RWA 250 Kigali RWF 🇷🇼 rw,en-RW,fr-RW,sw Rwanda 646 .rw
|
|
||||||
SA SAU 966 Riyadh SAR 🇸🇦 ar-SA Saudi Arabia 682 .sa
|
|
||||||
SB SLB 677 Honiara SBD 🇸🇧 en-SB,tpi Solomon Islands 090 .sb
|
|
||||||
SC SYC 248 Victoria SCR 🇸🇨 en-SC,fr-SC Seychelles 690 .sc
|
|
||||||
SD SDN 249 Khartoum SDG 🇸🇩 ar-SD,en,fia Sudan 729 .sd
|
|
||||||
SE SWE 46 Stockholm SEK 🇸🇪 sv-SE,se,sma,fi-SE Sweden 752 .se
|
|
||||||
SG SGP 65 Singapore SGD 🇸🇬 cmn,en-SG,ms-SG,ta-SG,zh-SG Singapore 702 .sg
|
|
||||||
SH SHN 290 Jamestown SHP 🇸🇭 en-SH St. Helena 654 .sh
|
|
||||||
SI SVN 386 Ljubljana EUR 🇸🇮 sl,sh Slovenia 705 .si
|
|
||||||
SJ SJM 47 Longyearbyen NOK 🇸🇯 no,ru Svalbard & Jan Mayen 744 .sj
|
|
||||||
SK SVK 421 Bratislava EUR 🇸🇰 sk,hu Slovakia 703 .sk
|
|
||||||
SL SLE 232 Freetown SLE 🇸🇱 en-SL,men,tem Sierra Leone 694 .sl
|
|
||||||
SM SMR 378 San Marino EUR 🇸🇲 it-SM San Marino 674 .sm
|
|
||||||
SN SEN 221 Dakar XOF 🇸🇳 fr-SN,wo,fuc,mnk Senegal 686 .sn
|
|
||||||
SO SOM 252 Mogadishu SOS 🇸🇴 so-SO,ar-SO,it,en-SO Somalia 706 .so
|
|
||||||
SR SUR 597 Paramaribo SRD 🇸🇷 nl-SR,en,srn,hns,jv Suriname 740 .sr
|
|
||||||
SS SSD 211 Juba SSP 🇸🇸 en South Sudan 728 .ss
|
|
||||||
ST STP 239 Sao Tome STN 🇸🇹 pt-ST São Tomé & Príncipe 678 .st
|
|
||||||
SV SLV 503 San Salvador SVC 🇸🇻 es-SV El Salvador 222 .sv
|
|
||||||
SX SXM 1-721 Philipsburg XCG 🇸🇽 nl,en Sint Maarten 534 .sx
|
|
||||||
SY SYR 963 Damascus SYP 🇸🇾 ar-SY,ku,hy,arc,fr,en Syria 760 .sy
|
|
||||||
SZ SWZ 268 Mbabane SZL 🇸🇿 en-SZ,ss-SZ Eswatini 748 .sz
|
|
||||||
TC TCA 1-649 Cockburn Town USD 🇹🇨 en-TC Turks & Caicos Islands 796 .tc
|
|
||||||
TD TCD 235 N'Djamena XAF 🇹🇩 fr-TD,ar-TD,sre Chad 148 .td
|
|
||||||
TF ATF 262 Port-aux-Francais EUR 🇹🇫 fr French Southern Territories 260 .tf
|
|
||||||
TG TGO 228 Lome XOF 🇹🇬 fr-TG,ee,hna,kbp,dag,ha Togo 768 .tg
|
|
||||||
TH THA 66 Bangkok THB 🇹🇭 th,en Thailand 764 .th
|
|
||||||
TJ TJK 992 Dushanbe TJS 🇹🇯 tg,ru Tajikistan 762 .tj
|
|
||||||
TL TLS 670 Dili USD 🇹🇱 tet,pt-TL,id,en Timor-Leste 626 .tl
|
|
||||||
TM TKM 993 Ashgabat TMT 🇹🇲 tk,ru,uz Turkmenistan 795 .tm
|
|
||||||
TN TUN 216 Tunis TND 🇹🇳 ar-TN,fr Tunisia 788 .tn
|
|
||||||
TO TON 676 Nuku'alofa TOP 🇹🇴 to,en-TO Tonga 776 .to
|
|
||||||
TR TUR 90 Ankara TRY 🇹🇷 tr-TR,ku,diq,az,av Türkiye 792 .tr
|
|
||||||
TT TTO 1-868 Port of Spain TTD 🇹🇹 en-TT,hns,fr,es,zh Trinidad & Tobago 780 .tt
|
|
||||||
TV TUV 688 Funafuti AUD 🇹🇻 tvl,en,sm,gil Tuvalu 798 .tv
|
|
||||||
TW TWN 886 Taipei TWD 🇹🇼 zh-TW,zh,nan,hak Taiwan 158 .tw
|
|
||||||
TZ TZA 255 Dodoma TZS 🇹🇿 sw-TZ,en,ar Tanzania 834 .tz
|
|
||||||
UA UKR 380 Kyiv UAH 🇺🇦 uk,ru-UA,rom,pl,hu Ukraine 804 .ua
|
|
||||||
UG UGA 256 Kampala UGX 🇺🇬 en-UG,lg,sw,ar Uganda 800 .ug
|
|
||||||
US USA 1 Washington USD 🇺🇸 en-US,es-US,haw,fr US 840 .us
|
|
||||||
UY URY 598 Montevideo UYU 🇺🇾 es-UY Uruguay 858 .uy
|
|
||||||
UZ UZB 998 Tashkent UZS 🇺🇿 uz,ru,tg Uzbekistan 860 .uz
|
|
||||||
VA VAT 39 Vatican City EUR 🇻🇦 la,it,fr Vatican City 336 .va
|
|
||||||
VC VCT 1-784 Kingstown XCD 🇻🇨 en-VC,fr St. Vincent & Grenadines 670 .vc
|
|
||||||
VE VEN 58 Caracas VES 🇻🇪 es-VE Venezuela 862 .ve
|
|
||||||
VG VGB 1-284 Road Town USD 🇻🇬 en-VG British Virgin Islands 092 .vg
|
|
||||||
VI VIR 1-340 Charlotte Amalie USD 🇻🇮 en-VI U.S. Virgin Islands 850 .vi
|
|
||||||
VN VNM 84 Hanoi VND 🇻🇳 vi,en,fr,zh,km Vietnam 704 .vn
|
|
||||||
VU VUT 678 Port Vila VUV 🇻🇺 bi,en-VU,fr-VU Vanuatu 548 .vu
|
|
||||||
WF WLF 681 Mata Utu XPF 🇼🇫 wls,fud,fr-WF Wallis & Futuna 876 .wf
|
|
||||||
WS WSM 685 Apia WST 🇼🇸 sm,en-WS Samoa 882 .ws
|
|
||||||
YE YEM 967 Sanaa YER 🇾🇪 ar-YE Yemen 887 .ye
|
|
||||||
YT MYT 262 Mamoudzou EUR 🇾🇹 fr-YT Mayotte 175 .yt
|
|
||||||
ZA ZAF 27 Pretoria ZAR 🇿🇦 zu,xh,af,nso,en-ZA,tn,st,ts,ss,ve,nr South Africa 710 .za
|
|
||||||
ZM ZMB 260 Lusaka ZMW 🇿🇲 en-ZM,bem,loz,lun,lue,ny,toi Zambia 894 .zm
|
|
||||||
ZW ZWE 263 Harare ZWG 🇿🇼 en-ZW,sn,nr,nd Zimbabwe 716 .zw
|
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
"{date(2000-01-01,2029-12-31,'2006-01-02T15:04:05Z')}"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{method}", "rows": "httpmethod.tsv", "key": "method" }
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
idempotent method safe
|
||||||
|
false CONNECT false
|
||||||
|
true DELETE false
|
||||||
|
true GET true
|
||||||
|
true HEAD true
|
||||||
|
true OPTIONS true
|
||||||
|
false PATCH false
|
||||||
|
false POST false
|
||||||
|
true PUT false
|
||||||
|
true TRACE true
|
||||||
|
@@ -1,17 +1,61 @@
|
|||||||
code reason
|
code reason
|
||||||
|
100 Continue
|
||||||
|
101 Switching Protocols
|
||||||
|
102 Processing
|
||||||
|
103 Early Hints
|
||||||
200 OK
|
200 OK
|
||||||
201 Created
|
201 Created
|
||||||
|
202 Accepted
|
||||||
|
203 Non-Authoritative Information
|
||||||
204 No Content
|
204 No Content
|
||||||
|
205 Reset Content
|
||||||
|
206 Partial Content
|
||||||
|
207 Multi-Status
|
||||||
|
208 Already Reported
|
||||||
|
226 IM Used
|
||||||
|
300 Multiple Choices
|
||||||
301 Moved Permanently
|
301 Moved Permanently
|
||||||
302 Found
|
302 Found
|
||||||
|
303 See Other
|
||||||
304 Not Modified
|
304 Not Modified
|
||||||
|
305 Use Proxy
|
||||||
|
307 Temporary Redirect
|
||||||
|
308 Permanent Redirect
|
||||||
400 Bad Request
|
400 Bad Request
|
||||||
401 Unauthorized
|
401 Unauthorized
|
||||||
|
402 Payment Required
|
||||||
403 Forbidden
|
403 Forbidden
|
||||||
404 Not Found
|
404 Not Found
|
||||||
|
405 Method Not Allowed
|
||||||
|
406 Not Acceptable
|
||||||
|
407 Proxy Authentication Required
|
||||||
|
408 Request Timeout
|
||||||
409 Conflict
|
409 Conflict
|
||||||
422 Unprocessable Entity
|
410 Gone
|
||||||
|
411 Length Required
|
||||||
|
412 Precondition Failed
|
||||||
|
413 Content Too Large
|
||||||
|
414 URI Too Long
|
||||||
|
415 Unsupported Media Type
|
||||||
|
416 Range Not Satisfiable
|
||||||
|
417 Expectation Failed
|
||||||
|
421 Misdirected Request
|
||||||
|
422 Unprocessable Content
|
||||||
|
423 Locked
|
||||||
|
424 Failed Dependency
|
||||||
|
425 Too Early
|
||||||
|
426 Upgrade Required
|
||||||
|
428 Precondition Required
|
||||||
429 Too Many Requests
|
429 Too Many Requests
|
||||||
|
431 Request Header Fields Too Large
|
||||||
|
451 Unavailable For Legal Reasons
|
||||||
500 Internal Server Error
|
500 Internal Server Error
|
||||||
|
501 Not Implemented
|
||||||
502 Bad Gateway
|
502 Bad Gateway
|
||||||
503 Service Unavailable
|
503 Service Unavailable
|
||||||
|
504 Gateway Timeout
|
||||||
|
505 HTTP Version Not Supported
|
||||||
|
506 Variant Also Negotiates
|
||||||
|
507 Insufficient Storage
|
||||||
|
508 Loop Detected
|
||||||
|
511 Network Authentication Required
|
||||||
|
|||||||
|
+184
-17
@@ -1,17 +1,184 @@
|
|||||||
code name
|
code code3 name
|
||||||
ar Arabic
|
aa aar Afar
|
||||||
zh Chinese
|
ab abk Abkhazian
|
||||||
da Danish
|
ae ave Avestan
|
||||||
nl Dutch
|
af afr Afrikaans
|
||||||
en English
|
ak aka Akan
|
||||||
fi Finnish
|
am amh Amharic
|
||||||
fr French
|
an arg Aragonese
|
||||||
de German
|
ar ara Arabic
|
||||||
it Italian
|
as asm Assamese
|
||||||
ja Japanese
|
av ava Avaric
|
||||||
no Norwegian
|
ay aym Aymara
|
||||||
pl Polish
|
az aze Azerbaijani
|
||||||
pt Portuguese
|
ba bak Bashkir
|
||||||
ru Russian
|
be bel Belarusian
|
||||||
es Spanish
|
bg bul Bulgarian
|
||||||
sv Swedish
|
bi bis Bislama
|
||||||
|
bm bam Bambara
|
||||||
|
bn ben Bengali
|
||||||
|
bo bod Tibetan
|
||||||
|
br bre Breton
|
||||||
|
bs bos Bosnian
|
||||||
|
ca cat Catalan
|
||||||
|
ce che Chechen
|
||||||
|
ch cha Chamorro
|
||||||
|
co cos Corsican
|
||||||
|
cr cre Cree
|
||||||
|
cs ces Czech
|
||||||
|
cu chu Church Slavic
|
||||||
|
cv chv Chuvash
|
||||||
|
cy cym Welsh
|
||||||
|
da dan Danish
|
||||||
|
de deu German
|
||||||
|
dv div Divehi
|
||||||
|
dz dzo Dzongkha
|
||||||
|
ee ewe Ewe
|
||||||
|
el ell Modern Greek
|
||||||
|
en eng English
|
||||||
|
eo epo Esperanto
|
||||||
|
es spa Spanish
|
||||||
|
et est Estonian
|
||||||
|
eu eus Basque
|
||||||
|
fa fas Persian
|
||||||
|
ff ful Fulah
|
||||||
|
fi fin Finnish
|
||||||
|
fj fij Fijian
|
||||||
|
fo fao Faroese
|
||||||
|
fr fra French
|
||||||
|
fy fry Western Frisian
|
||||||
|
ga gle Irish
|
||||||
|
gd gla Gaelic
|
||||||
|
gl glg Galician
|
||||||
|
gn grn Guarani
|
||||||
|
gu guj Gujarati
|
||||||
|
gv glv Manx
|
||||||
|
ha hau Hausa
|
||||||
|
he heb Hebrew
|
||||||
|
hi hin Hindi
|
||||||
|
ho hmo Hiri Motu
|
||||||
|
hr hrv Croatian
|
||||||
|
ht hat Haitian
|
||||||
|
hu hun Hungarian
|
||||||
|
hy hye Armenian
|
||||||
|
hz her Herero
|
||||||
|
ia ina Interlingua
|
||||||
|
id ind Indonesian
|
||||||
|
ie ile Interlingue
|
||||||
|
ig ibo Igbo
|
||||||
|
ii iii Sichuan Yi
|
||||||
|
ik ipk Inupiaq
|
||||||
|
io ido Ido
|
||||||
|
is isl Icelandic
|
||||||
|
it ita Italian
|
||||||
|
iu iku Inuktitut
|
||||||
|
ja jpn Japanese
|
||||||
|
jv jav Javanese
|
||||||
|
ka kat Georgian
|
||||||
|
kg kon Kongo
|
||||||
|
ki kik Kikuyu
|
||||||
|
kj kua Kuanyama
|
||||||
|
kk kaz Kazakh
|
||||||
|
kl kal Kalaallisut
|
||||||
|
km khm Central Khmer
|
||||||
|
kn kan Kannada
|
||||||
|
ko kor Korean
|
||||||
|
kr kau Kanuri
|
||||||
|
ks kas Kashmiri
|
||||||
|
ku kur Kurdish
|
||||||
|
kv kom Komi
|
||||||
|
kw cor Cornish
|
||||||
|
ky kir Kirghiz
|
||||||
|
la lat Latin
|
||||||
|
lb ltz Luxembourgish
|
||||||
|
lg lug Ganda
|
||||||
|
li lim Limburgan
|
||||||
|
ln lin Lingala
|
||||||
|
lo lao Lao
|
||||||
|
lt lit Lithuanian
|
||||||
|
lu lub Luba-Katanga
|
||||||
|
lv lav Latvian
|
||||||
|
mg mlg Malagasy
|
||||||
|
mh mah Marshallese
|
||||||
|
mi mri Maori
|
||||||
|
mk mkd Macedonian
|
||||||
|
ml mal Malayalam
|
||||||
|
mn mon Mongolian
|
||||||
|
mr mar Marathi
|
||||||
|
ms msa Malay
|
||||||
|
mt mlt Maltese
|
||||||
|
my mya Burmese
|
||||||
|
na nau Nauru
|
||||||
|
nb nob Norwegian Bokmål
|
||||||
|
nd nde North Ndebele
|
||||||
|
ne nep Nepali
|
||||||
|
ng ndo Ndonga
|
||||||
|
nl nld Dutch
|
||||||
|
nn nno Norwegian Nynorsk
|
||||||
|
no nor Norwegian
|
||||||
|
nr nbl South Ndebele
|
||||||
|
nv nav Navajo
|
||||||
|
ny nya Chichewa
|
||||||
|
oc oci Occitan
|
||||||
|
oj oji Ojibwa
|
||||||
|
om orm Oromo
|
||||||
|
or ori Oriya
|
||||||
|
os oss Ossetian
|
||||||
|
pa pan Panjabi
|
||||||
|
pi pli Pali
|
||||||
|
pl pol Polish
|
||||||
|
ps pus Pushto
|
||||||
|
pt por Portuguese
|
||||||
|
qu que Quechua
|
||||||
|
rm roh Romansh
|
||||||
|
rn run Rundi
|
||||||
|
ro ron Romanian
|
||||||
|
ru rus Russian
|
||||||
|
rw kin Kinyarwanda
|
||||||
|
sa san Sanskrit
|
||||||
|
sc srd Sardinian
|
||||||
|
sd snd Sindhi
|
||||||
|
se sme Northern Sami
|
||||||
|
sg sag Sango
|
||||||
|
si sin Sinhala
|
||||||
|
sk slk Slovak
|
||||||
|
sl slv Slovenian
|
||||||
|
sm smo Samoan
|
||||||
|
sn sna Shona
|
||||||
|
so som Somali
|
||||||
|
sq sqi Albanian
|
||||||
|
sr srp Serbian
|
||||||
|
ss ssw Swati
|
||||||
|
st sot Sotho, Southern
|
||||||
|
su sun Sundanese
|
||||||
|
sv swe Swedish
|
||||||
|
sw swa Swahili
|
||||||
|
ta tam Tamil
|
||||||
|
te tel Telugu
|
||||||
|
tg tgk Tajik
|
||||||
|
th tha Thai
|
||||||
|
ti tir Tigrinya
|
||||||
|
tk tuk Turkmen
|
||||||
|
tl tgl Tagalog
|
||||||
|
tn tsn Tswana
|
||||||
|
to ton Tonga
|
||||||
|
tr tur Turkish
|
||||||
|
ts tso Tsonga
|
||||||
|
tt tat Tatar
|
||||||
|
tw twi Twi
|
||||||
|
ty tah Tahitian
|
||||||
|
ug uig Uighur
|
||||||
|
uk ukr Ukrainian
|
||||||
|
ur urd Urdu
|
||||||
|
uz uzb Uzbek
|
||||||
|
ve ven Venda
|
||||||
|
vi vie Vietnamese
|
||||||
|
vo vol Volapük
|
||||||
|
wa wln Walloon
|
||||||
|
wo wol Wolof
|
||||||
|
xh xho Xhosa
|
||||||
|
yi yid Yiddish
|
||||||
|
yo yor Yoruba
|
||||||
|
za zha Zhuang
|
||||||
|
zh zho Chinese
|
||||||
|
zu zul Zulu
|
||||||
|
|||||||
|
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{keyword}", "rows": "loglevel.tsv", "key": "code", "name": "keyword" }
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
code keyword severity
|
||||||
|
0 emerg Emergency
|
||||||
|
1 alert Alert
|
||||||
|
2 crit Critical
|
||||||
|
3 err Error
|
||||||
|
4 warning Warning
|
||||||
|
5 notice Notice
|
||||||
|
6 info Informational
|
||||||
|
7 debug Debug
|
||||||
|
@@ -1,16 +1,702 @@
|
|||||||
ext type
|
ext type
|
||||||
|
.ez application/andrew-inset
|
||||||
|
.atom application/atom+xml
|
||||||
|
.atomcat application/atomcat+xml
|
||||||
|
.atomdeleted application/atomdeleted+xml
|
||||||
|
.atomsvc application/atomsvc+xml
|
||||||
|
.dwd application/atsc-dwd+xml
|
||||||
|
.held application/atsc-held+xml
|
||||||
|
.rsat application/atsc-rsat+xml
|
||||||
|
.aml application/automationml-aml+xml
|
||||||
|
.amlx application/automationml-amlx+zip
|
||||||
|
.xcs application/calendar+xml
|
||||||
|
.ccxml application/ccxml+xml
|
||||||
|
.cdfx application/cdfx+xml
|
||||||
|
.cdmia application/cdmi-capability
|
||||||
|
.cdmic application/cdmi-container
|
||||||
|
.cdmid application/cdmi-domain
|
||||||
|
.cdmio application/cdmi-object
|
||||||
|
.cdmiq application/cdmi-queue
|
||||||
|
.cpl application/cpl+xml
|
||||||
|
.cwl application/cwl
|
||||||
|
.mpd application/dash+xml
|
||||||
|
.mpp application/dash-patch+xml
|
||||||
|
.davmount application/davmount+xml
|
||||||
|
.dcm application/dicom
|
||||||
|
.dssc application/dssc+der
|
||||||
|
.xdssc application/dssc+xml
|
||||||
|
.emma application/emma+xml
|
||||||
|
.emotionml application/emotionml+xml
|
||||||
|
.epub application/epub+zip
|
||||||
|
.exi application/exi
|
||||||
|
.exp application/express
|
||||||
|
.fdf application/fdf
|
||||||
|
.fdt application/fdt+xml
|
||||||
|
.pfr application/font-tdpfr
|
||||||
|
.geojson application/geo+json
|
||||||
|
.gml application/gml+xml
|
||||||
.gz application/gzip
|
.gz application/gzip
|
||||||
|
.stk application/hyperstudio
|
||||||
|
.ink application/inkml+xml
|
||||||
|
.ipfix application/ipfix
|
||||||
|
.its application/its+xml
|
||||||
|
.jar application/java-archive
|
||||||
.json application/json
|
.json application/json
|
||||||
|
.kbl application/kbl+xml
|
||||||
|
.jsonld application/ld+json
|
||||||
|
.lgr application/lgr+xml
|
||||||
|
.lostxml application/lost+xml
|
||||||
|
.hqx application/mac-binhex40
|
||||||
|
.mads application/mads+xml
|
||||||
|
.webmanifest application/manifest+json
|
||||||
|
.mrc application/marc
|
||||||
|
.mrcx application/marcxml+xml
|
||||||
|
.ma application/mathematica
|
||||||
|
.mathml application/mathml+xml
|
||||||
|
.mbox application/mbox
|
||||||
|
.mpf application/media-policy-dataset+xml
|
||||||
|
.mscml application/mediaservercontrol+xml
|
||||||
|
.meta4 application/metalink4+xml
|
||||||
|
.mets application/mets+xml
|
||||||
|
.maei application/mmt-aei+xml
|
||||||
|
.musd application/mmt-usd+xml
|
||||||
|
.mods application/mods+xml
|
||||||
|
.m21 application/mp21
|
||||||
|
.mp4s application/mp4
|
||||||
|
.doc application/msword
|
||||||
|
.mxf application/mxf
|
||||||
|
.nq application/n-quads
|
||||||
|
.nt application/n-triples
|
||||||
|
.cjs application/node
|
||||||
|
.bin application/octet-stream
|
||||||
|
.oda application/oda
|
||||||
|
.opf application/oebps-package+xml
|
||||||
|
.ogx application/ogg
|
||||||
|
.oxps application/oxps
|
||||||
|
.relo application/p2p-overlay+xml
|
||||||
|
.xer application/patch-ops-error+xml
|
||||||
.pdf application/pdf
|
.pdf application/pdf
|
||||||
|
.pgp application/pgp-encrypted
|
||||||
|
.asc application/pgp-keys
|
||||||
|
.sig application/pgp-signature
|
||||||
|
.p10 application/pkcs10
|
||||||
|
.p7m application/pkcs7-mime
|
||||||
|
.p7s application/pkcs7-signature
|
||||||
|
.p8 application/pkcs8
|
||||||
|
.ac application/pkix-attr-cert
|
||||||
|
.cer application/pkix-cert
|
||||||
|
.crl application/pkix-crl
|
||||||
|
.pkipath application/pkix-pkipath
|
||||||
|
.pki application/pkixcmp
|
||||||
|
.pls application/pls+xml
|
||||||
|
.ai application/postscript
|
||||||
|
.provx application/provenance+xml
|
||||||
|
.cww application/prs.cww
|
||||||
|
.xsf application/prs.xsf+xml
|
||||||
|
.pskcxml application/pskc+xml
|
||||||
|
.rdf application/rdf+xml
|
||||||
|
.rif application/reginfo+xml
|
||||||
|
.rnc application/relax-ng-compact-syntax
|
||||||
|
.rl application/resource-lists+xml
|
||||||
|
.rld application/resource-lists-diff+xml
|
||||||
|
.rs application/rls-services+xml
|
||||||
|
.rapd application/route-apd+xml
|
||||||
|
.sls application/route-s-tsid+xml
|
||||||
|
.rusd application/route-usd+xml
|
||||||
|
.gbr application/rpki-ghostbusters
|
||||||
|
.mft application/rpki-manifest
|
||||||
|
.roa application/rpki-roa
|
||||||
|
.rtf application/rtf
|
||||||
|
.sbml application/sbml+xml
|
||||||
|
.scq application/scvp-cv-request
|
||||||
|
.scs application/scvp-cv-response
|
||||||
|
.spq application/scvp-vp-request
|
||||||
|
.spp application/scvp-vp-response
|
||||||
|
.sdp application/sdp
|
||||||
|
.senmlx application/senml+xml
|
||||||
|
.sensmlx application/sensml+xml
|
||||||
|
.setpay application/set-payment-initiation
|
||||||
|
.setreg application/set-registration-initiation
|
||||||
|
.shf application/shf+xml
|
||||||
|
.siv application/sieve
|
||||||
|
.smi application/smil+xml
|
||||||
|
.rq application/sparql-query
|
||||||
|
.srx application/sparql-results+xml
|
||||||
|
.sql application/sql
|
||||||
|
.gram application/srgs
|
||||||
|
.grxml application/srgs+xml
|
||||||
|
.sru application/sru+xml
|
||||||
|
.ssml application/ssml+xml
|
||||||
|
.swidtag application/swid+xml
|
||||||
|
.tei application/tei+xml
|
||||||
|
.tfi application/thraud+xml
|
||||||
|
.tsd application/timestamped-data
|
||||||
|
.toml application/toml
|
||||||
|
.trig application/trig
|
||||||
|
.ttml application/ttml+xml
|
||||||
|
.rsheet application/urc-ressheet+xml
|
||||||
|
.td application/urc-targetdesc+xml
|
||||||
|
.vec application/vec+xml
|
||||||
|
.1km application/vnd.1000minds.decision-model+xml
|
||||||
|
.plb application/vnd.3gpp.pic-bw-large
|
||||||
|
.psb application/vnd.3gpp.pic-bw-small
|
||||||
|
.pvb application/vnd.3gpp.pic-bw-var
|
||||||
|
.tcap application/vnd.3gpp2.tcap
|
||||||
|
.pwn application/vnd.3m.post-it-notes
|
||||||
|
.aso application/vnd.accpac.simply.aso
|
||||||
|
.imp application/vnd.accpac.simply.imp
|
||||||
|
.acu application/vnd.acucobol
|
||||||
|
.atc application/vnd.acucorp
|
||||||
|
.fcdt application/vnd.adobe.formscentral.fcdt
|
||||||
|
.fxp application/vnd.adobe.fxp
|
||||||
|
.xdp application/vnd.adobe.xdp+xml
|
||||||
|
.age application/vnd.age
|
||||||
|
.ahead application/vnd.ahead.space
|
||||||
|
.azf application/vnd.airzip.filesecure.azf
|
||||||
|
.azs application/vnd.airzip.filesecure.azs
|
||||||
|
.acc application/vnd.americandynamics.acc
|
||||||
|
.ami application/vnd.amiga.ami
|
||||||
|
.cii application/vnd.anser-web-certificate-issue-initiation
|
||||||
|
.atx application/vnd.antix.game-component
|
||||||
|
.parquet application/vnd.apache.parquet
|
||||||
|
.mpkg application/vnd.apple.installer+xml
|
||||||
|
.key application/vnd.apple.keynote
|
||||||
|
.m3u8 application/vnd.apple.mpegurl
|
||||||
|
.numbers application/vnd.apple.numbers
|
||||||
|
.pages application/vnd.apple.pages
|
||||||
|
.swi application/vnd.aristanetworks.swi
|
||||||
|
.iota application/vnd.astraea-software.iota
|
||||||
|
.aep application/vnd.audiograph
|
||||||
|
.bmml application/vnd.balsamiq.bmml+xml
|
||||||
|
.mpm application/vnd.blueice.multipass
|
||||||
|
.bmi application/vnd.bmi
|
||||||
|
.rep application/vnd.businessobjects
|
||||||
|
.cdxml application/vnd.chemdraw+xml
|
||||||
|
.mmd application/vnd.chipnuts.karaoke-mmd
|
||||||
|
.cdy application/vnd.cinderella
|
||||||
|
.csl application/vnd.citationstyles.style+xml
|
||||||
|
.cla application/vnd.claymore
|
||||||
|
.rp9 application/vnd.cloanto.rp9
|
||||||
|
.c4g application/vnd.clonk.c4group
|
||||||
|
.c11amc application/vnd.cluetrust.cartomobile-config
|
||||||
|
.c11amz application/vnd.cluetrust.cartomobile-config-pkg
|
||||||
|
.csp application/vnd.commonspace
|
||||||
|
.cdbcmsg application/vnd.contact.cmsg
|
||||||
|
.cmc application/vnd.cosmocaller
|
||||||
|
.clkx application/vnd.crick.clicker
|
||||||
|
.clkk application/vnd.crick.clicker.keyboard
|
||||||
|
.clkp application/vnd.crick.clicker.palette
|
||||||
|
.clkt application/vnd.crick.clicker.template
|
||||||
|
.clkw application/vnd.crick.clicker.wordbank
|
||||||
|
.wbs application/vnd.criticaltools.wbs+xml
|
||||||
|
.pml application/vnd.ctc-posml
|
||||||
|
.ppd application/vnd.cups-ppd
|
||||||
|
.dart application/vnd.dart
|
||||||
|
.rdz application/vnd.data-vision.rdz
|
||||||
|
.dbf application/vnd.dbf
|
||||||
|
.dcmp application/vnd.dcmp+xml
|
||||||
|
.uvf application/vnd.dece.data
|
||||||
|
.uvt application/vnd.dece.ttml+xml
|
||||||
|
.uvx application/vnd.dece.unspecified
|
||||||
|
.uvz application/vnd.dece.zip
|
||||||
|
.fe_launch application/vnd.denovo.fcselayout-link
|
||||||
|
.dna application/vnd.dna
|
||||||
|
.dpg application/vnd.dpgraph
|
||||||
|
.dfac application/vnd.dreamfactory
|
||||||
|
.ait application/vnd.dvb.ait
|
||||||
|
.svc application/vnd.dvb.service
|
||||||
|
.geo application/vnd.dynageo
|
||||||
|
.mag application/vnd.ecowin.chart
|
||||||
|
.nml application/vnd.enliven
|
||||||
|
.esf application/vnd.epson.esf
|
||||||
|
.msf application/vnd.epson.msf
|
||||||
|
.qam application/vnd.epson.quickanime
|
||||||
|
.slt application/vnd.epson.salt
|
||||||
|
.ssf application/vnd.epson.ssf
|
||||||
|
.es3 application/vnd.eszigno3+xml
|
||||||
|
.ez2 application/vnd.ezpix-album
|
||||||
|
.ez3 application/vnd.ezpix-package
|
||||||
|
.mseed application/vnd.fdsn.mseed
|
||||||
|
.seed application/vnd.fdsn.seed
|
||||||
|
.gph application/vnd.flographit
|
||||||
|
.ftc application/vnd.fluxtime.clip
|
||||||
|
.fm application/vnd.framemaker
|
||||||
|
.fsc application/vnd.fsc.weblaunch
|
||||||
|
.oas application/vnd.fujitsu.oasys
|
||||||
|
.oa2 application/vnd.fujitsu.oasys2
|
||||||
|
.oa3 application/vnd.fujitsu.oasys3
|
||||||
|
.fg5 application/vnd.fujitsu.oasysgp
|
||||||
|
.bh2 application/vnd.fujitsu.oasysprs
|
||||||
|
.ddd application/vnd.fujixerox.ddd
|
||||||
|
.xdw application/vnd.fujixerox.docuworks
|
||||||
|
.xbd application/vnd.fujixerox.docuworks.binder
|
||||||
|
.fzs application/vnd.fuzzysheet
|
||||||
|
.txd application/vnd.genomatix.tuxedo
|
||||||
|
.ggb application/vnd.geogebra.file
|
||||||
|
.ggs application/vnd.geogebra.slides
|
||||||
|
.ggt application/vnd.geogebra.tool
|
||||||
|
.gex application/vnd.geometry-explorer
|
||||||
|
.gxt application/vnd.geonext
|
||||||
|
.g2w application/vnd.geoplan
|
||||||
|
.g3w application/vnd.geospace
|
||||||
|
.gmx application/vnd.gmx
|
||||||
|
.kml application/vnd.google-earth.kml+xml
|
||||||
|
.kmz application/vnd.google-earth.kmz
|
||||||
|
.xdcf application/vnd.gov.sk.xmldatacontainer+xml
|
||||||
|
.gqf application/vnd.grafeq
|
||||||
|
.gac application/vnd.groove-account
|
||||||
|
.ghf application/vnd.groove-help
|
||||||
|
.gim application/vnd.groove-identity-message
|
||||||
|
.grv application/vnd.groove-injector
|
||||||
|
.gtm application/vnd.groove-tool-message
|
||||||
|
.tpl application/vnd.groove-tool-template
|
||||||
|
.vcg application/vnd.groove-vcard
|
||||||
|
.hal application/vnd.hal+xml
|
||||||
|
.zmm application/vnd.handheld-entertainment+xml
|
||||||
|
.hbci application/vnd.hbci
|
||||||
|
.les application/vnd.hhe.lesson-player
|
||||||
|
.hpgl application/vnd.hp-hpgl
|
||||||
|
.hpid application/vnd.hp-hpid
|
||||||
|
.hps application/vnd.hp-hps
|
||||||
|
.jlt application/vnd.hp-jlyt
|
||||||
|
.pcl application/vnd.hp-pcl
|
||||||
|
.pclxl application/vnd.hp-pclxl
|
||||||
|
.sfd-hdstx application/vnd.hydrostatix.sof-data
|
||||||
|
.mpy application/vnd.ibm.minipay
|
||||||
|
.irm application/vnd.ibm.rights-management
|
||||||
|
.sc application/vnd.ibm.secure-container
|
||||||
|
.icc application/vnd.iccprofile
|
||||||
|
.igl application/vnd.igloader
|
||||||
|
.ivp application/vnd.immervision-ivp
|
||||||
|
.ivu application/vnd.immervision-ivu
|
||||||
|
.igm application/vnd.insors.igm
|
||||||
|
.xpw application/vnd.intercon.formnet
|
||||||
|
.i2g application/vnd.intergeo
|
||||||
|
.qbo application/vnd.intu.qbo
|
||||||
|
.qfx application/vnd.intu.qfx
|
||||||
|
.rcprofile application/vnd.ipunplugged.rcprofile
|
||||||
|
.irp application/vnd.irepository.package+xml
|
||||||
|
.xpr application/vnd.is-xpr
|
||||||
|
.fcs application/vnd.isac.fcs
|
||||||
|
.jam application/vnd.jam
|
||||||
|
.rms application/vnd.jcp.javame.midlet-rms
|
||||||
|
.jisp application/vnd.jisp
|
||||||
|
.joda application/vnd.joost.joda-archive
|
||||||
|
.ktz application/vnd.kahootz
|
||||||
|
.karbon application/vnd.kde.karbon
|
||||||
|
.chrt application/vnd.kde.kchart
|
||||||
|
.kfo application/vnd.kde.kformula
|
||||||
|
.flw application/vnd.kde.kivio
|
||||||
|
.kon application/vnd.kde.kontour
|
||||||
|
.kpr application/vnd.kde.kpresenter
|
||||||
|
.ksp application/vnd.kde.kspread
|
||||||
|
.kwd application/vnd.kde.kword
|
||||||
|
.htke application/vnd.kenameaapp
|
||||||
|
.kia application/vnd.kidspiration
|
||||||
|
.kne application/vnd.kinar
|
||||||
|
.skp application/vnd.koan
|
||||||
|
.sse application/vnd.kodak-descriptor
|
||||||
|
.lasxml application/vnd.las.las+xml
|
||||||
|
.lbd application/vnd.llamagraphics.life-balance.desktop
|
||||||
|
.lbe application/vnd.llamagraphics.life-balance.exchange+xml
|
||||||
|
.123 application/vnd.lotus-1-2-3
|
||||||
|
.apr application/vnd.lotus-approach
|
||||||
|
.pre application/vnd.lotus-freelance
|
||||||
|
.nsf application/vnd.lotus-notes
|
||||||
|
.org application/vnd.lotus-organizer
|
||||||
|
.scm application/vnd.lotus-screencam
|
||||||
|
.lwp application/vnd.lotus-wordpro
|
||||||
|
.portpkg application/vnd.macports.portpkg
|
||||||
|
.mvt application/vnd.mapbox-vector-tile
|
||||||
|
.mcd application/vnd.mcd
|
||||||
|
.mc1 application/vnd.medcalcdata
|
||||||
|
.cdkey application/vnd.mediastation.cdkey
|
||||||
|
.mwf application/vnd.mfer
|
||||||
|
.mfm application/vnd.mfmp
|
||||||
|
.flo application/vnd.micrografx.flo
|
||||||
|
.igx application/vnd.micrografx.igx
|
||||||
|
.mif application/vnd.mif
|
||||||
|
.daf application/vnd.mobius.daf
|
||||||
|
.dis application/vnd.mobius.dis
|
||||||
|
.mbk application/vnd.mobius.mbk
|
||||||
|
.mqy application/vnd.mobius.mqy
|
||||||
|
.msl application/vnd.mobius.msl
|
||||||
|
.plc application/vnd.mobius.plc
|
||||||
|
.txf application/vnd.mobius.txf
|
||||||
|
.mpn application/vnd.mophun.application
|
||||||
|
.mpc application/vnd.mophun.certificate
|
||||||
|
.xul application/vnd.mozilla.xul+xml
|
||||||
|
.cil application/vnd.ms-artgalry
|
||||||
|
.cab application/vnd.ms-cab-compressed
|
||||||
|
.xls application/vnd.ms-excel
|
||||||
|
.xlam application/vnd.ms-excel.addin.macroenabled.12
|
||||||
|
.xlsb application/vnd.ms-excel.sheet.binary.macroenabled.12
|
||||||
|
.xlsm application/vnd.ms-excel.sheet.macroenabled.12
|
||||||
|
.xltm application/vnd.ms-excel.template.macroenabled.12
|
||||||
|
.eot application/vnd.ms-fontobject
|
||||||
|
.chm application/vnd.ms-htmlhelp
|
||||||
|
.ims application/vnd.ms-ims
|
||||||
|
.lrm application/vnd.ms-lrm
|
||||||
|
.thmx application/vnd.ms-officetheme
|
||||||
|
.ppt application/vnd.ms-powerpoint
|
||||||
|
.ppam application/vnd.ms-powerpoint.addin.macroenabled.12
|
||||||
|
.pptm application/vnd.ms-powerpoint.presentation.macroenabled.12
|
||||||
|
.sldm application/vnd.ms-powerpoint.slide.macroenabled.12
|
||||||
|
.ppsm application/vnd.ms-powerpoint.slideshow.macroenabled.12
|
||||||
|
.potm application/vnd.ms-powerpoint.template.macroenabled.12
|
||||||
|
.mpp application/vnd.ms-project
|
||||||
|
.docm application/vnd.ms-word.document.macroenabled.12
|
||||||
|
.dotm application/vnd.ms-word.template.macroenabled.12
|
||||||
|
.wps application/vnd.ms-works
|
||||||
|
.wpl application/vnd.ms-wpl
|
||||||
|
.xps application/vnd.ms-xpsdocument
|
||||||
|
.mseq application/vnd.mseq
|
||||||
|
.mus application/vnd.musician
|
||||||
|
.msty application/vnd.muvee.style
|
||||||
|
.taglet application/vnd.mynfc
|
||||||
|
.bdo application/vnd.nato.bindingdataobject+xml
|
||||||
|
.nlu application/vnd.neurolanguage.nlu
|
||||||
|
.ntf application/vnd.nitf
|
||||||
|
.nnd application/vnd.noblenet-directory
|
||||||
|
.nns application/vnd.noblenet-sealer
|
||||||
|
.nnw application/vnd.noblenet-web
|
||||||
|
.ac application/vnd.nokia.n-gage.ac+xml
|
||||||
|
.ngdat application/vnd.nokia.n-gage.data
|
||||||
|
.rpst application/vnd.nokia.radio-preset
|
||||||
|
.rpss application/vnd.nokia.radio-presets
|
||||||
|
.edm application/vnd.novadigm.edm
|
||||||
|
.edx application/vnd.novadigm.edx
|
||||||
|
.ext application/vnd.novadigm.ext
|
||||||
|
.odc application/vnd.oasis.opendocument.chart
|
||||||
|
.otc application/vnd.oasis.opendocument.chart-template
|
||||||
|
.odf application/vnd.oasis.opendocument.formula
|
||||||
|
.odft application/vnd.oasis.opendocument.formula-template
|
||||||
|
.odg application/vnd.oasis.opendocument.graphics
|
||||||
|
.otg application/vnd.oasis.opendocument.graphics-template
|
||||||
|
.odi application/vnd.oasis.opendocument.image
|
||||||
|
.oti application/vnd.oasis.opendocument.image-template
|
||||||
|
.odp application/vnd.oasis.opendocument.presentation
|
||||||
|
.otp application/vnd.oasis.opendocument.presentation-template
|
||||||
|
.ods application/vnd.oasis.opendocument.spreadsheet
|
||||||
|
.ots application/vnd.oasis.opendocument.spreadsheet-template
|
||||||
|
.odt application/vnd.oasis.opendocument.text
|
||||||
|
.odm application/vnd.oasis.opendocument.text-master
|
||||||
|
.ott application/vnd.oasis.opendocument.text-template
|
||||||
|
.oth application/vnd.oasis.opendocument.text-web
|
||||||
|
.xo application/vnd.olpc-sugar
|
||||||
|
.dd2 application/vnd.oma.dd2+xml
|
||||||
|
.obgx application/vnd.openblox.game+xml
|
||||||
|
.osm application/vnd.openstreetmap.data+xml
|
||||||
|
.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
|
||||||
|
.sldx application/vnd.openxmlformats-officedocument.presentationml.slide
|
||||||
|
.ppsx application/vnd.openxmlformats-officedocument.presentationml.slideshow
|
||||||
|
.potx application/vnd.openxmlformats-officedocument.presentationml.template
|
||||||
|
.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||||
|
.xltx application/vnd.openxmlformats-officedocument.spreadsheetml.template
|
||||||
|
.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
||||||
|
.dotx application/vnd.openxmlformats-officedocument.wordprocessingml.template
|
||||||
|
.mgp application/vnd.osgeo.mapguide.package
|
||||||
|
.dp application/vnd.osgi.dp
|
||||||
|
.esa application/vnd.osgi.subsystem
|
||||||
|
.pdb application/vnd.palm
|
||||||
|
.paw application/vnd.pawaafile
|
||||||
|
.str application/vnd.pg.format
|
||||||
|
.ei6 application/vnd.pg.osasli
|
||||||
|
.efif application/vnd.picsel
|
||||||
|
.wg application/vnd.pmi.widget
|
||||||
|
.plf application/vnd.pocketlearn
|
||||||
|
.pbd application/vnd.powerbuilder6
|
||||||
|
.systemverify application/vnd.pp.systemverify+xml
|
||||||
|
.box application/vnd.previewsystems.box
|
||||||
|
.mgz application/vnd.proteus.magazine
|
||||||
|
.qps application/vnd.publishare-delta-tree
|
||||||
|
.ptid application/vnd.pvi.ptid1
|
||||||
|
.xhtm application/vnd.pwg-xhtml-print+xml
|
||||||
|
.qxd application/vnd.quark.quarkxpress
|
||||||
|
.rar application/vnd.rar
|
||||||
|
.bed application/vnd.realvnc.bed
|
||||||
|
.mxl application/vnd.recordare.musicxml
|
||||||
|
.musicxml application/vnd.recordare.musicxml+xml
|
||||||
|
.cryptonote application/vnd.rig.cryptonote
|
||||||
|
.link66 application/vnd.route66.link66+xml
|
||||||
|
.st application/vnd.sailingtracker.track
|
||||||
|
.see application/vnd.seemail
|
||||||
|
.sema application/vnd.sema
|
||||||
|
.semd application/vnd.semd
|
||||||
|
.semf application/vnd.semf
|
||||||
|
.ifm application/vnd.shana.informed.formdata
|
||||||
|
.itp application/vnd.shana.informed.formtemplate
|
||||||
|
.iif application/vnd.shana.informed.interchange
|
||||||
|
.ipk application/vnd.shana.informed.package
|
||||||
|
.twd application/vnd.simtech-mindmapper
|
||||||
|
.mmf application/vnd.smaf
|
||||||
|
.teacher application/vnd.smart.teacher
|
||||||
|
.fo application/vnd.software602.filler.form+xml
|
||||||
|
.sdkm application/vnd.solent.sdkm+xml
|
||||||
|
.dxp application/vnd.spotfire.dxp
|
||||||
|
.sfs application/vnd.spotfire.sfs
|
||||||
|
.sqlite application/vnd.sqlite3
|
||||||
|
.smzip application/vnd.stepmania.package
|
||||||
|
.sm application/vnd.stepmania.stepchart
|
||||||
|
.wadl application/vnd.sun.wadl+xml
|
||||||
|
.sus application/vnd.sus-calendar
|
||||||
|
.svd application/vnd.svd
|
||||||
|
.xsm application/vnd.syncml+xml
|
||||||
|
.bdm application/vnd.syncml.dm+wbxml
|
||||||
|
.xdm application/vnd.syncml.dm+xml
|
||||||
|
.ddf application/vnd.syncml.dmddf+xml
|
||||||
|
.tao application/vnd.tao.intent-module-archive
|
||||||
|
.pcap application/vnd.tcpdump.pcap
|
||||||
|
.tmo application/vnd.tmobile-livetv
|
||||||
|
.tpt application/vnd.trid.tpt
|
||||||
|
.mxs application/vnd.triscape.mxs
|
||||||
|
.tra application/vnd.trueapp
|
||||||
|
.ufd application/vnd.ufdl
|
||||||
|
.utz application/vnd.uiq.theme
|
||||||
|
.umj application/vnd.umajin
|
||||||
|
.unityweb application/vnd.unity
|
||||||
|
.uoml application/vnd.uoml+xml
|
||||||
|
.vcx application/vnd.vcx
|
||||||
|
.vsd application/vnd.visio
|
||||||
|
.vis application/vnd.visionary
|
||||||
|
.vsf application/vnd.vsf
|
||||||
|
.wbxml application/vnd.wap.wbxml
|
||||||
|
.wmlc application/vnd.wap.wmlc
|
||||||
|
.wmlsc application/vnd.wap.wmlscriptc
|
||||||
|
.wtb application/vnd.webturbo
|
||||||
|
.nbp application/vnd.wolfram.player
|
||||||
|
.wpd application/vnd.wordperfect
|
||||||
|
.wqd application/vnd.wqd
|
||||||
|
.stf application/vnd.wt.stf
|
||||||
|
.xar application/vnd.xara
|
||||||
|
.xfdl application/vnd.xfdl
|
||||||
|
.hvd application/vnd.yamaha.hv-dic
|
||||||
|
.hvs application/vnd.yamaha.hv-script
|
||||||
|
.hvp application/vnd.yamaha.hv-voice
|
||||||
|
.osf application/vnd.yamaha.openscoreformat
|
||||||
|
.osfpvg application/vnd.yamaha.openscoreformat.osfpvg+xml
|
||||||
|
.saf application/vnd.yamaha.smaf-audio
|
||||||
|
.spf application/vnd.yamaha.smaf-phrase
|
||||||
|
.cmp application/vnd.yellowriver-custom-menu
|
||||||
|
.zir application/vnd.zul
|
||||||
|
.zaz application/vnd.zzazz.deck+xml
|
||||||
|
.vxml application/voicexml+xml
|
||||||
|
.wasm application/wasm
|
||||||
|
.wif application/watcherinfo+xml
|
||||||
|
.wgt application/widget
|
||||||
|
.wsdl application/wsdl+xml
|
||||||
|
.wspolicy application/wspolicy+xml
|
||||||
|
.der application/x-x509-ca-cert
|
||||||
|
.xav application/xcap-att+xml
|
||||||
|
.xca application/xcap-caps+xml
|
||||||
|
.xdf application/xcap-diff+xml
|
||||||
|
.xel application/xcap-el+xml
|
||||||
|
.xns application/xcap-ns+xml
|
||||||
|
.xenc application/xenc+xml
|
||||||
|
.xfdf application/xfdf
|
||||||
|
.xhtml application/xhtml+xml
|
||||||
|
.xlf application/xliff+xml
|
||||||
.xml application/xml
|
.xml application/xml
|
||||||
|
.dtd application/xml-dtd
|
||||||
|
.xop application/xop+xml
|
||||||
|
.xsl application/xslt+xml
|
||||||
|
.mxml application/xv+xml
|
||||||
|
.yang application/yang
|
||||||
|
.yin application/yin+xml
|
||||||
.zip application/zip
|
.zip application/zip
|
||||||
|
.3gpp audio/3gpp
|
||||||
|
.adts audio/aac
|
||||||
|
.amr audio/amr
|
||||||
|
.au audio/basic
|
||||||
|
.mka audio/matroska
|
||||||
|
.mxmf audio/mobile-xmf
|
||||||
|
.m4a audio/mp4
|
||||||
.mp3 audio/mpeg
|
.mp3 audio/mpeg
|
||||||
|
.ogg audio/ogg
|
||||||
|
.uva audio/vnd.dece.audio
|
||||||
|
.eol audio/vnd.digital-winds
|
||||||
|
.dra audio/vnd.dra
|
||||||
|
.dts audio/vnd.dts
|
||||||
|
.dtshd audio/vnd.dts.hd
|
||||||
|
.lvp audio/vnd.lucent.voice
|
||||||
|
.pya audio/vnd.ms-playready.media.pya
|
||||||
|
.ecelp4800 audio/vnd.nuera.ecelp4800
|
||||||
|
.ecelp7470 audio/vnd.nuera.ecelp7470
|
||||||
|
.ecelp9600 audio/vnd.nuera.ecelp9600
|
||||||
|
.rip audio/vnd.rip
|
||||||
|
.ttc font/collection
|
||||||
|
.otf font/otf
|
||||||
|
.ttf font/ttf
|
||||||
|
.woff font/woff
|
||||||
|
.woff2 font/woff2
|
||||||
|
.exr image/aces
|
||||||
|
.apng image/apng
|
||||||
|
.avci image/avci
|
||||||
|
.avcs image/avcs
|
||||||
|
.avif image/avif
|
||||||
|
.bmp image/bmp
|
||||||
|
.cgm image/cgm
|
||||||
|
.drle image/dicom-rle
|
||||||
|
.dpx image/dpx
|
||||||
|
.emf image/emf
|
||||||
|
.fits image/fits
|
||||||
|
.g3 image/g3fax
|
||||||
.gif image/gif
|
.gif image/gif
|
||||||
|
.heic image/heic
|
||||||
|
.heics image/heic-sequence
|
||||||
|
.heif image/heif
|
||||||
|
.heifs image/heif-sequence
|
||||||
|
.hej2 image/hej2k
|
||||||
|
.ief image/ief
|
||||||
|
.jaii image/jaii
|
||||||
|
.jais image/jais
|
||||||
|
.jls image/jls
|
||||||
|
.jp2 image/jp2
|
||||||
.jpg image/jpeg
|
.jpg image/jpeg
|
||||||
|
.jph image/jph
|
||||||
|
.jhc image/jphc
|
||||||
|
.jpm image/jpm
|
||||||
|
.jpx image/jpx
|
||||||
|
.jxl image/jxl
|
||||||
|
.jxr image/jxr
|
||||||
|
.jxra image/jxra
|
||||||
|
.jxrs image/jxrs
|
||||||
|
.jxs image/jxs
|
||||||
|
.jxsc image/jxsc
|
||||||
|
.jxsi image/jxsi
|
||||||
|
.jxss image/jxss
|
||||||
|
.ktx image/ktx
|
||||||
|
.ktx2 image/ktx2
|
||||||
.png image/png
|
.png image/png
|
||||||
|
.btif image/prs.btif
|
||||||
|
.pti image/prs.pti
|
||||||
.svg image/svg+xml
|
.svg image/svg+xml
|
||||||
|
.t38 image/t38
|
||||||
|
.tif image/tiff
|
||||||
|
.tfx image/tiff-fx
|
||||||
|
.psd image/vnd.adobe.photoshop
|
||||||
|
.azv image/vnd.airzip.accelerator.azv
|
||||||
|
.facti image/vnd.blockfact.facti
|
||||||
|
.uvi image/vnd.dece.graphic
|
||||||
|
.djvu image/vnd.djvu
|
||||||
|
.sub image/vnd.dvb.subtitle
|
||||||
|
.dwg image/vnd.dwg
|
||||||
|
.dxf image/vnd.dxf
|
||||||
|
.fbs image/vnd.fastbidsheet
|
||||||
|
.fpx image/vnd.fpx
|
||||||
|
.fst image/vnd.fst
|
||||||
|
.mmr image/vnd.fujixerox.edmics-mmr
|
||||||
|
.rlc image/vnd.fujixerox.edmics-rlc
|
||||||
|
.ico image/vnd.microsoft.icon
|
||||||
|
.mdi image/vnd.ms-modi
|
||||||
|
.npx image/vnd.net-fpx
|
||||||
|
.b16 image/vnd.pco.b16
|
||||||
|
.tap image/vnd.tencent.tap
|
||||||
|
.vtf image/vnd.valve.source.texture
|
||||||
|
.wbmp image/vnd.wap.wbmp
|
||||||
|
.xif image/vnd.xiff
|
||||||
|
.pcx image/vnd.zbrush.pcx
|
||||||
.webp image/webp
|
.webp image/webp
|
||||||
|
.wmf image/wmf
|
||||||
|
.disposition-notification message/disposition-notification
|
||||||
|
.u8msg message/global
|
||||||
|
.u8dsn message/global-delivery-status
|
||||||
|
.u8mdn message/global-disposition-notification
|
||||||
|
.u8hdr message/global-headers
|
||||||
|
.eml message/rfc822
|
||||||
|
.wsc message/vnd.wfa.wsc
|
||||||
|
.3mf model/3mf
|
||||||
|
.gltf model/gltf+json
|
||||||
|
.glb model/gltf-binary
|
||||||
|
.igs model/iges
|
||||||
|
.jt model/jt
|
||||||
|
.msh model/mesh
|
||||||
|
.mtl model/mtl
|
||||||
|
.obj model/obj
|
||||||
|
.prc model/prc
|
||||||
|
.step model/step
|
||||||
|
.stpx model/step+xml
|
||||||
|
.stpz model/step+zip
|
||||||
|
.stpxz model/step-xml+zip
|
||||||
|
.stl model/stl
|
||||||
|
.u3d model/u3d
|
||||||
|
.bary model/vnd.bary
|
||||||
|
.cld model/vnd.cld
|
||||||
|
.dae model/vnd.collada+xml
|
||||||
|
.dwf model/vnd.dwf
|
||||||
|
.gdl model/vnd.gdl
|
||||||
|
.gtw model/vnd.gtw
|
||||||
|
.mts model/vnd.mts
|
||||||
|
.ogex model/vnd.opengex
|
||||||
|
.x_b model/vnd.parasolid.transmit.binary
|
||||||
|
.x_t model/vnd.parasolid.transmit.text
|
||||||
|
.pyo model/vnd.pytha.pyox
|
||||||
|
.vds model/vnd.sap.vds
|
||||||
|
.usda model/vnd.usda
|
||||||
|
.usdz model/vnd.usdz+zip
|
||||||
|
.bsp model/vnd.valve.source.compiled-map
|
||||||
|
.vtu model/vnd.vtu
|
||||||
|
.wrl model/vrml
|
||||||
|
.x3db model/x3d+fastinfoset
|
||||||
|
.x3d model/x3d+xml
|
||||||
|
.x3dv model/x3d-vrml
|
||||||
|
.appcache text/cache-manifest
|
||||||
|
.ics text/calendar
|
||||||
|
.css text/css
|
||||||
.csv text/csv
|
.csv text/csv
|
||||||
.html text/html
|
.html text/html
|
||||||
|
.js text/javascript
|
||||||
|
.md text/markdown
|
||||||
|
.n3 text/n3
|
||||||
.txt text/plain
|
.txt text/plain
|
||||||
|
.dsc text/prs.lines.tag
|
||||||
|
.rtx text/richtext
|
||||||
|
.rtf text/rtf
|
||||||
|
.sgml text/sgml
|
||||||
|
.shex text/shex
|
||||||
|
.spdx text/spdx
|
||||||
|
.tsv text/tab-separated-values
|
||||||
|
.t text/troff
|
||||||
|
.ttl text/turtle
|
||||||
|
.uri text/uri-list
|
||||||
|
.vcard text/vcard
|
||||||
|
.curl text/vnd.curl
|
||||||
|
.sub text/vnd.dvb.subtitle
|
||||||
|
.ged text/vnd.familysearch.gedcom
|
||||||
|
.fly text/vnd.fly
|
||||||
|
.flx text/vnd.fmi.flexstor
|
||||||
|
.gv text/vnd.graphviz
|
||||||
|
.3dml text/vnd.in3d.3dml
|
||||||
|
.spot text/vnd.in3d.spot
|
||||||
|
.jad text/vnd.sun.j2me.app-descriptor
|
||||||
|
.wml text/vnd.wap.wml
|
||||||
|
.wmls text/vnd.wap.wmlscript
|
||||||
|
.vtt text/vtt
|
||||||
|
.wgsl text/wgsl
|
||||||
|
.xml text/xml
|
||||||
|
.3gp video/3gpp
|
||||||
|
.3g2 video/3gpp2
|
||||||
|
.h261 video/h261
|
||||||
|
.h263 video/h263
|
||||||
|
.h264 video/h264
|
||||||
|
.m4s video/iso.segment
|
||||||
|
.jpgv video/jpeg
|
||||||
|
.mkv video/matroska
|
||||||
|
.mk3d video/matroska-3d
|
||||||
|
.mj2 video/mj2
|
||||||
|
.ts video/mp2t
|
||||||
.mp4 video/mp4
|
.mp4 video/mp4
|
||||||
|
.mpeg video/mpeg
|
||||||
|
.ogv video/ogg
|
||||||
|
.mov video/quicktime
|
||||||
|
.uvh video/vnd.dece.hd
|
||||||
|
.uvm video/vnd.dece.mobile
|
||||||
|
.uvp video/vnd.dece.pd
|
||||||
|
.uvs video/vnd.dece.sd
|
||||||
|
.uvv video/vnd.dece.video
|
||||||
|
.dvb video/vnd.dvb.file
|
||||||
|
.fvt video/vnd.fvt
|
||||||
|
.mxu video/vnd.mpegurl
|
||||||
|
.pyv video/vnd.ms-playready.media.pyv
|
||||||
|
.uvu video/vnd.uvvu.mp4
|
||||||
|
.viv video/vnd.vivo
|
||||||
|
|||||||
|
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{number}", "rows": "port.tsv", "key": "number" }
|
||||||
+5890
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{keyword}", "rows": "protocol.tsv", "key": "keyword", "name": "name" }
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
keyword name number
|
||||||
|
HOPOPT IPv6 Hop-by-Hop Option 0
|
||||||
|
ICMP Internet Control Message 1
|
||||||
|
IGMP Internet Group Management 2
|
||||||
|
GGP Gateway-to-Gateway 3
|
||||||
|
IPv4 IPv4 encapsulation 4
|
||||||
|
ST Stream 5
|
||||||
|
TCP Transmission Control 6
|
||||||
|
CBT CBT 7
|
||||||
|
EGP Exterior Gateway Protocol 8
|
||||||
|
IGP any private interior gateway (used by Cisco for their IGRP) 9
|
||||||
|
BBN-RCC-MON BBN RCC Monitoring 10
|
||||||
|
NVP-II Network Voice Protocol 11
|
||||||
|
PUP PUP 12
|
||||||
|
EMCON EMCON 14
|
||||||
|
XNET Cross Net Debugger 15
|
||||||
|
CHAOS Chaos 16
|
||||||
|
UDP User Datagram 17
|
||||||
|
MUX Multiplexing 18
|
||||||
|
DCN-MEAS DCN Measurement Subsystems 19
|
||||||
|
HMP Host Monitoring 20
|
||||||
|
PRM Packet Radio Measurement 21
|
||||||
|
XNS-IDP XEROX NS IDP 22
|
||||||
|
TRUNK-1 Trunk-1 23
|
||||||
|
TRUNK-2 Trunk-2 24
|
||||||
|
LEAF-1 Leaf-1 25
|
||||||
|
LEAF-2 Leaf-2 26
|
||||||
|
RDP Reliable Data Protocol 27
|
||||||
|
IRTP Internet Reliable Transaction 28
|
||||||
|
ISO-TP4 ISO Transport Protocol Class 4 29
|
||||||
|
NETBLT Bulk Data Transfer Protocol 30
|
||||||
|
MFE-NSP MFE Network Services Protocol 31
|
||||||
|
MERIT-INP MERIT Internodal Protocol 32
|
||||||
|
DCCP Datagram Congestion Control Protocol 33
|
||||||
|
3PC Third Party Connect Protocol 34
|
||||||
|
IDPR Inter-Domain Policy Routing Protocol 35
|
||||||
|
XTP XTP 36
|
||||||
|
DDP Datagram Delivery Protocol 37
|
||||||
|
IDPR-CMTP IDPR Control Message Transport Proto 38
|
||||||
|
TP++ TP++ Transport Protocol 39
|
||||||
|
IL IL Transport Protocol 40
|
||||||
|
IPv6 IPv6 encapsulation 41
|
||||||
|
SDRP Source Demand Routing Protocol 42
|
||||||
|
IPv6-Route Routing Header for IPv6 43
|
||||||
|
IPv6-Frag Fragment Header for IPv6 44
|
||||||
|
IDRP Inter-Domain Routing Protocol 45
|
||||||
|
RSVP Reservation Protocol 46
|
||||||
|
GRE Generic Routing Encapsulation 47
|
||||||
|
DSR Dynamic Source Routing Protocol 48
|
||||||
|
BNA BNA 49
|
||||||
|
ESP Encap Security Payload 50
|
||||||
|
AH Authentication Header 51
|
||||||
|
I-NLSP Integrated Net Layer Security TUBA 52
|
||||||
|
NARP NBMA Address Resolution Protocol 54
|
||||||
|
Min-IPv4 Minimal IPv4 Encapsulation 55
|
||||||
|
TLSP Transport Layer Security Protocol using Kryptonet key management 56
|
||||||
|
SKIP SKIP 57
|
||||||
|
IPv6-ICMP ICMP for IPv6 58
|
||||||
|
IPv6-NoNxt No Next Header for IPv6 59
|
||||||
|
IPv6-Opts Destination Options for IPv6 60
|
||||||
|
CFTP CFTP 62
|
||||||
|
SAT-EXPAK SATNET and Backroom EXPAK 64
|
||||||
|
KRYPTOLAN Kryptolan 65
|
||||||
|
RVD MIT Remote Virtual Disk Protocol 66
|
||||||
|
IPPC Internet Pluribus Packet Core 67
|
||||||
|
SAT-MON SATNET Monitoring 69
|
||||||
|
VISA VISA Protocol 70
|
||||||
|
IPCV Internet Packet Core Utility 71
|
||||||
|
CPNX Computer Protocol Network Executive 72
|
||||||
|
CPHB Computer Protocol Heart Beat 73
|
||||||
|
WSN Wang Span Network 74
|
||||||
|
PVP Packet Video Protocol 75
|
||||||
|
BR-SAT-MON Backroom SATNET Monitoring 76
|
||||||
|
SUN-ND SUN ND PROTOCOL-Temporary 77
|
||||||
|
WB-MON WIDEBAND Monitoring 78
|
||||||
|
WB-EXPAK WIDEBAND EXPAK 79
|
||||||
|
ISO-IP ISO Internet Protocol 80
|
||||||
|
VMTP VMTP 81
|
||||||
|
SECURE-VMTP SECURE-VMTP 82
|
||||||
|
VINES VINES 83
|
||||||
|
IPTM Internet Protocol Traffic Manager 84
|
||||||
|
NSFNET-IGP NSFNET-IGP 85
|
||||||
|
DGP Dissimilar Gateway Protocol 86
|
||||||
|
TCF TCF 87
|
||||||
|
EIGRP EIGRP 88
|
||||||
|
OSPFIGP OSPFIGP 89
|
||||||
|
Sprite-RPC Sprite RPC Protocol 90
|
||||||
|
LARP Locus Address Resolution Protocol 91
|
||||||
|
MTP Multicast Transport Protocol 92
|
||||||
|
AX.25 AX.25 Frames 93
|
||||||
|
IPIP IP-within-IP Encapsulation Protocol 94
|
||||||
|
SCC-SP Semaphore Communications Sec. Pro. 96
|
||||||
|
ETHERIP Ethernet-within-IP Encapsulation 97
|
||||||
|
ENCAP Encapsulation Header 98
|
||||||
|
GMTP GMTP 100
|
||||||
|
IFMP Ipsilon Flow Management Protocol 101
|
||||||
|
PNNI PNNI over IP 102
|
||||||
|
PIM Protocol Independent Multicast 103
|
||||||
|
ARIS ARIS 104
|
||||||
|
SCPS SCPS 105
|
||||||
|
QNX QNX 106
|
||||||
|
A/N Active Networks 107
|
||||||
|
IPComp IP Payload Compression Protocol 108
|
||||||
|
SNP Sitara Networks Protocol 109
|
||||||
|
Compaq-Peer Compaq Peer Protocol 110
|
||||||
|
IPX-in-IP IPX in IP 111
|
||||||
|
VRRP Virtual Router Redundancy Protocol 112
|
||||||
|
PGM PGM Reliable Transport Protocol 113
|
||||||
|
L2TP Layer Two Tunneling Protocol 115
|
||||||
|
DDX D-II Data Exchange (DDX) 116
|
||||||
|
IATP Interactive Agent Transfer Protocol 117
|
||||||
|
STP Schedule Transfer Protocol 118
|
||||||
|
SRP SpectraLink Radio Protocol 119
|
||||||
|
UTI UTI 120
|
||||||
|
SMP Simple Message Protocol 121
|
||||||
|
PTP Performance Transparency Protocol 123
|
||||||
|
ISIS over IPv4 ISIS over IPv4 124
|
||||||
|
FIRE FIRE 125
|
||||||
|
CRTP Combat Radio Transport Protocol 126
|
||||||
|
CRUDP Combat Radio User Datagram 127
|
||||||
|
SSCOPMCE SSCOPMCE 128
|
||||||
|
IPLT IPLT 129
|
||||||
|
SPS Secure Packet Shield 130
|
||||||
|
PIPE Private IP Encapsulation within IP 131
|
||||||
|
SCTP Stream Control Transmission Protocol 132
|
||||||
|
FC Fibre Channel 133
|
||||||
|
RSVP-E2E-IGNORE RSVP-E2E-IGNORE 134
|
||||||
|
Mobility Header Mobility Header 135
|
||||||
|
UDPLite UDPLite 136
|
||||||
|
MPLS-in-IP MPLS-in-IP 137
|
||||||
|
manet MANET Protocols 138
|
||||||
|
HIP Host Identity Protocol 139
|
||||||
|
Shim6 Shim6 Protocol 140
|
||||||
|
WESP Wrapped Encapsulating Security Payload 141
|
||||||
|
ROHC Robust Header Compression 142
|
||||||
|
Ethernet Ethernet 143
|
||||||
|
AGGFRAG AGGFRAG encapsulation payload for ESP 144
|
||||||
|
NSH Network Service Header 145
|
||||||
|
Homa Homa 146
|
||||||
|
BIT-EMU Bit-stream Emulation 147
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "territory.tsv", "key": "alpha2", "name": "name" }
|
||||||
@@ -0,0 +1,242 @@
|
|||||||
|
alpha2 alpha3 calling-code capital country currency flag languages name numeric tld
|
||||||
|
AD AND 376 Andorra la Vella AD EUR 🇦🇩 ca Andorra 020 .ad
|
||||||
|
AE ARE 971 Abu Dhabi AE AED 🇦🇪 ar-AE,fa,en,hi,ur United Arab Emirates 784 .ae
|
||||||
|
AF AFG 93 Kabul AF AFN 🇦🇫 fa-AF,ps,uz-AF,tk Afghanistan 004 .af
|
||||||
|
AG ATG 1-268 St. John's AG XCD 🇦🇬 en-AG Antigua & Barbuda 028 .ag
|
||||||
|
AI AIA 1-264 The Valley GB XCD 🇦🇮 en-AI Anguilla 660 .ai
|
||||||
|
AL ALB 355 Tirana AL ALL 🇦🇱 sq,el Albania 008 .al
|
||||||
|
AM ARM 374 Yerevan AM AMD 🇦🇲 hy Armenia 051 .am
|
||||||
|
AO AGO 244 Luanda AO AOA 🇦🇴 pt-AO Angola 024 .ao
|
||||||
|
AR ARG 54 Buenos Aires AR ARS 🇦🇷 es-AR,en,it,de,fr,gn Argentina 032 .ar
|
||||||
|
AS ASM 1-684 Pago Pago US USD 🇦🇸 en-AS,sm,to American Samoa 016 .as
|
||||||
|
AT AUT 43 Vienna AT EUR 🇦🇹 de-AT,hr,hu,sl Austria 040 .at
|
||||||
|
AU AUS 61 Canberra AU AUD 🇦🇺 en-AU Australia 036 .au
|
||||||
|
AW ABW 297 Oranjestad NL AWG 🇦🇼 nl-AW,pap,es,en Aruba 533 .aw
|
||||||
|
AX ALA 358 Mariehamn FI EUR 🇦🇽 sv-AX Åland Islands 248 .ax
|
||||||
|
AZ AZE 994 Baku AZ AZN 🇦🇿 az,ru,hy Azerbaijan 031 .az
|
||||||
|
BA BIH 387 Sarajevo BA BAM 🇧🇦 bs,hr-BA,sr-BA Bosnia 070 .ba
|
||||||
|
BB BRB 1-246 Bridgetown BB BBD 🇧🇧 en-BB Barbados 052 .bb
|
||||||
|
BD BGD 880 Dhaka BD BDT 🇧🇩 bn-BD,en Bangladesh 050 .bd
|
||||||
|
BE BEL 32 Brussels BE EUR 🇧🇪 nl-BE,fr-BE,de-BE Belgium 056 .be
|
||||||
|
BF BFA 226 Ouagadougou BF XOF 🇧🇫 fr-BF,mos Burkina Faso 854 .bf
|
||||||
|
BG BGR 359 Sofia BG EUR 🇧🇬 bg,tr-BG,rom Bulgaria 100 .bg
|
||||||
|
BH BHR 973 Manama BH BHD 🇧🇭 ar-BH,en,fa,ur Bahrain 048 .bh
|
||||||
|
BI BDI 257 Gitega BI BIF 🇧🇮 fr-BI,rn Burundi 108 .bi
|
||||||
|
BJ BEN 229 Porto-Novo BJ XOF 🇧🇯 fr-BJ Benin 204 .bj
|
||||||
|
BL BLM 590 Gustavia FR EUR 🇧🇱 fr St. Barthélemy 652 .gp
|
||||||
|
BM BMU 1-441 Hamilton GB BMD 🇧🇲 en-BM,pt Bermuda 060 .bm
|
||||||
|
BN BRN 673 Bandar Seri Begawan BN BND 🇧🇳 ms-BN,en-BN Brunei 096 .bn
|
||||||
|
BO BOL 591 Sucre BO BOB 🇧🇴 es-BO,qu,ay Bolivia 068 .bo
|
||||||
|
BR BRA 55 Brasilia BR BRL 🇧🇷 pt-BR,es,en,fr Brazil 076 .br
|
||||||
|
BS BHS 1-242 Nassau BS BSD 🇧🇸 en-BS Bahamas 044 .bs
|
||||||
|
BT BTN 975 Thimphu BT INR 🇧🇹 dz Bhutan 064 .bt
|
||||||
|
BW BWA 267 Gaborone BW BWP 🇧🇼 en-BW,tn-BW Botswana 072 .bw
|
||||||
|
BY BLR 375 Minsk BY BYN 🇧🇾 be,ru Belarus 112 .by
|
||||||
|
BZ BLZ 501 Belmopan BZ BZD 🇧🇿 en-BZ,es Belize 084 .bz
|
||||||
|
CA CAN 1 Ottawa CA CAD 🇨🇦 en-CA,fr-CA,iu Canada 124 .ca
|
||||||
|
CC CCK 61 West Island AU AUD 🇨🇨 ms-CC,en Cocos Islands 166 .cc
|
||||||
|
CD COD 243 Kinshasa CD CDF 🇨🇩 fr-CD,ln,ktu,kg,sw,lua Congo - Kinshasa 180 .cd
|
||||||
|
CF CAF 236 Bangui CF XAF 🇨🇫 fr-CF,sg,ln,kg Central African Republic 140 .cf
|
||||||
|
CG COG 242 Brazzaville CG XAF 🇨🇬 fr-CG,kg,ln-CG Congo - Brazzaville 178 .cg
|
||||||
|
CH CHE 41 Bern CH CHF 🇨🇭 de-CH,fr-CH,it-CH,rm Switzerland 756 .ch
|
||||||
|
CI CIV 225 Yamoussoukro CI XOF 🇨🇮 fr-CI Côte d’Ivoire 384 .ci
|
||||||
|
CK COK 682 Avarua NZ NZD 🇨🇰 en-CK,mi Cook Islands 184 .ck
|
||||||
|
CL CHL 56 Santiago CL CLP 🇨🇱 es-CL Chile 152 .cl
|
||||||
|
CM CMR 237 Yaounde CM XAF 🇨🇲 en-CM,fr-CM Cameroon 120 .cm
|
||||||
|
CN CHN 86 Beijing CN CNY 🇨🇳 zh-CN,yue,wuu,dta,ug,za China 156 .cn
|
||||||
|
CO COL 57 Bogota CO COP 🇨🇴 es-CO Colombia 170 .co
|
||||||
|
CR CRI 506 San Jose CR CRC 🇨🇷 es-CR,en Costa Rica 188 .cr
|
||||||
|
CU CUB 53 Havana CU CUP 🇨🇺 es-CU,pap Cuba 192 .cu
|
||||||
|
CV CPV 238 Praia CV CVE 🇨🇻 pt-CV Cape Verde 132 .cv
|
||||||
|
CW CUW 599 Willemstad NL XCG 🇨🇼 nl,pap Curaçao 531 .cw
|
||||||
|
CX CXR 61 Flying Fish Cove AU AUD 🇨🇽 en,zh,ms-CX Christmas Island 162 .cx
|
||||||
|
CY CYP 357 Nicosia CY EUR 🇨🇾 el-CY,tr-CY,en Cyprus 196 .cy
|
||||||
|
CZ CZE 420 Prague CZ CZK 🇨🇿 cs,sk Czechia 203 .cz
|
||||||
|
DE DEU 49 Berlin DE EUR 🇩🇪 de Germany 276 .de
|
||||||
|
DJ DJI 253 Djibouti DJ DJF 🇩🇯 fr-DJ,ar,so-DJ,aa Djibouti 262 .dj
|
||||||
|
DK DNK 45 Copenhagen DK DKK 🇩🇰 da-DK,en,fo,de-DK Denmark 208 .dk
|
||||||
|
DM DMA 1-767 Roseau DM XCD 🇩🇲 en-DM Dominica 212 .dm
|
||||||
|
DO DOM 1-809 Santo Domingo DO DOP 🇩🇴 es-DO Dominican Republic 214 .do
|
||||||
|
DZ DZA 213 Algiers DZ DZD 🇩🇿 ar-DZ Algeria 012 .dz
|
||||||
|
EC ECU 593 Quito EC USD 🇪🇨 es-EC Ecuador 218 .ec
|
||||||
|
EE EST 372 Tallinn EE EUR 🇪🇪 et,ru Estonia 233 .ee
|
||||||
|
EG EGY 20 Cairo EG EGP 🇪🇬 ar-EG,en,fr Egypt 818 .eg
|
||||||
|
EH ESH 212 El-Aaiun EH MAD 🇪🇭 ar,mey Western Sahara 732 .eh
|
||||||
|
ER ERI 291 Asmara ER ERN 🇪🇷 aa-ER,ar,tig,kun,ti-ER Eritrea 232 .er
|
||||||
|
ES ESP 34 Madrid ES EUR 🇪🇸 es-ES,ca,gl,eu,oc Spain 724 .es
|
||||||
|
ET ETH 251 Addis Ababa ET ETB 🇪🇹 am,en-ET,om-ET,ti-ET,so-ET,sid Ethiopia 231 .et
|
||||||
|
FI FIN 358 Helsinki FI EUR 🇫🇮 fi-FI,sv-FI,smn Finland 246 .fi
|
||||||
|
FJ FJI 679 Suva FJ FJD 🇫🇯 en-FJ,fj Fiji 242 .fj
|
||||||
|
FK FLK 500 Stanley GB FKP 🇫🇰 en-FK Falkland Islands 238 .fk
|
||||||
|
FM FSM 691 Palikir FM USD 🇫🇲 en-FM,chk,pon,yap,kos,uli,woe,nkr,kpg Micronesia 583 .fm
|
||||||
|
FO FRO 298 Torshavn DK DKK 🇫🇴 fo,da-FO Faroe Islands 234 .fo
|
||||||
|
FR FRA 33 Paris FR EUR 🇫🇷 fr-FR,frp,br,co,ca,eu,oc France 250 .fr
|
||||||
|
GA GAB 241 Libreville GA XAF 🇬🇦 fr-GA Gabon 266 .ga
|
||||||
|
GB GBR 44 London GB GBP 🇬🇧 en-GB,cy-GB,gd UK 826 .uk
|
||||||
|
GD GRD 1-473 St. George's GD XCD 🇬🇩 en-GD Grenada 308 .gd
|
||||||
|
GE GEO 995 Tbilisi GE GEL 🇬🇪 ka,ru,hy,az Georgia 268 .ge
|
||||||
|
GF GUF 594 Cayenne FR EUR 🇬🇫 fr-GF French Guiana 254 .gf
|
||||||
|
GG GGY 44 St Peter Port GB GBP 🇬🇬 en,nrf Guernsey 831 .gg
|
||||||
|
GH GHA 233 Accra GH GHS 🇬🇭 en-GH,ak,ee,tw Ghana 288 .gh
|
||||||
|
GI GIB 350 Gibraltar GB GIP 🇬🇮 en-GI,es,it,pt Gibraltar 292 .gi
|
||||||
|
GL GRL 299 Nuuk DK DKK 🇬🇱 kl,da-GL,en Greenland 304 .gl
|
||||||
|
GM GMB 220 Banjul GM GMD 🇬🇲 en-GM,mnk,wof,wo,ff Gambia 270 .gm
|
||||||
|
GN GIN 224 Conakry GN GNF 🇬🇳 fr-GN Guinea 324 .gn
|
||||||
|
GP GLP 590 Basse-Terre FR EUR 🇬🇵 fr-GP Guadeloupe 312 .gp
|
||||||
|
GQ GNQ 240 Ciudad de la Paz GQ XAF 🇬🇶 es-GQ,fr,pt Equatorial Guinea 226 .gq
|
||||||
|
GR GRC 30 Athens GR EUR 🇬🇷 el-GR,en,fr Greece 300 .gr
|
||||||
|
GT GTM 502 Guatemala City GT GTQ 🇬🇹 es-GT Guatemala 320 .gt
|
||||||
|
GU GUM 1-671 Hagatna US USD 🇬🇺 en-GU,ch-GU Guam 316 .gu
|
||||||
|
GW GNB 245 Bissau GW XOF 🇬🇼 pt-GW,pov Guinea-Bissau 624 .gw
|
||||||
|
GY GUY 592 Georgetown GY GYD 🇬🇾 en-GY Guyana 328 .gy
|
||||||
|
HK HKG 852 Hong Kong CN HKD 🇭🇰 zh-HK,yue,zh,en Hong Kong 344 .hk
|
||||||
|
HN HND 504 Tegucigalpa HN HNL 🇭🇳 es-HN,cab,miq Honduras 340 .hn
|
||||||
|
HR HRV 385 Zagreb HR EUR 🇭🇷 hr-HR,sr Croatia 191 .hr
|
||||||
|
HT HTI 509 Port-au-Prince HT HTG 🇭🇹 ht,fr-HT Haiti 332 .ht
|
||||||
|
HU HUN 36 Budapest HU HUF 🇭🇺 hu-HU Hungary 348 .hu
|
||||||
|
ID IDN 62 Jakarta ID IDR 🇮🇩 id,en,nl,jv Indonesia 360 .id
|
||||||
|
IE IRL 353 Dublin IE EUR 🇮🇪 en-IE,ga-IE Ireland 372 .ie
|
||||||
|
IL ISR 972 Jerusalem IL ILS 🇮🇱 he,ar-IL,en-IL Israel 376 .il
|
||||||
|
IM IMN 44 Douglas GB GBP 🇮🇲 en,gv Isle of Man 833 .im
|
||||||
|
IN IND 91 New Delhi IN INR 🇮🇳 en-IN,hi,bn,te,mr,ta,ur,gu,kn,ml,or,pa,as,bh,sat,ks,ne,sd,kok,doi,mni,sit,sa,fr,lus,inc India 356 .in
|
||||||
|
IO IOT 246 Diego Garcia GB USD 🇮🇴 en-IO British Indian Ocean Territory 086 .io
|
||||||
|
IQ IRQ 964 Baghdad IQ IQD 🇮🇶 ar-IQ,ku,hy Iraq 368 .iq
|
||||||
|
IR IRN 98 Tehran IR IRR 🇮🇷 fa-IR,ku Iran 364 .ir
|
||||||
|
IS ISL 354 Reykjavik IS ISK 🇮🇸 is,en,de,da,sv,no Iceland 352 .is
|
||||||
|
IT ITA 39 Rome IT EUR 🇮🇹 it-IT,de-IT,fr-IT,sc,ca,co,sl Italy 380 .it
|
||||||
|
JE JEY 44 Saint Helier GB GBP 🇯🇪 en,fr,nrf Jersey 832 .je
|
||||||
|
JM JAM 1-876 Kingston JM JMD 🇯🇲 en-JM Jamaica 388 .jm
|
||||||
|
JO JOR 962 Amman JO JOD 🇯🇴 ar-JO,en Jordan 400 .jo
|
||||||
|
JP JPN 81 Tokyo JP JPY 🇯🇵 ja Japan 392 .jp
|
||||||
|
KE KEN 254 Nairobi KE KES 🇰🇪 en-KE,sw-KE Kenya 404 .ke
|
||||||
|
KG KGZ 996 Bishkek KG KGS 🇰🇬 ky,uz,ru Kyrgyzstan 417 .kg
|
||||||
|
KH KHM 855 Phnom Penh KH KHR 🇰🇭 km,fr,en Cambodia 116 .kh
|
||||||
|
KI KIR 686 Tarawa KI AUD 🇰🇮 en-KI,gil Kiribati 296 .ki
|
||||||
|
KM COM 269 Moroni KM KMF 🇰🇲 ar,fr-KM Comoros 174 .km
|
||||||
|
KN KNA 1-869 Basseterre KN XCD 🇰🇳 en-KN St. Kitts & Nevis 659 .kn
|
||||||
|
KP PRK 850 Pyongyang KP KPW 🇰🇵 ko-KP North Korea 408 .kp
|
||||||
|
KR KOR 82 Seoul KR KRW 🇰🇷 ko-KR,en South Korea 410 .kr
|
||||||
|
KW KWT 965 Kuwait City KW KWD 🇰🇼 ar-KW,en Kuwait 414 .kw
|
||||||
|
KY CYM 1-345 George Town GB KYD 🇰🇾 en-KY Cayman Islands 136 .ky
|
||||||
|
KZ KAZ 7 Nur-Sultan KZ KZT 🇰🇿 kk,ru Kazakhstan 398 .kz
|
||||||
|
LA LAO 856 Vientiane LA LAK 🇱🇦 lo,fr,en Laos 418 .la
|
||||||
|
LB LBN 961 Beirut LB LBP 🇱🇧 ar-LB,fr-LB,en,hy Lebanon 422 .lb
|
||||||
|
LC LCA 1-758 Castries LC XCD 🇱🇨 en-LC St. Lucia 662 .lc
|
||||||
|
LI LIE 423 Vaduz LI CHF 🇱🇮 de-LI Liechtenstein 438 .li
|
||||||
|
LK LKA 94 Colombo LK LKR 🇱🇰 si,ta,en Sri Lanka 144 .lk
|
||||||
|
LR LBR 231 Monrovia LR LRD 🇱🇷 en-LR Liberia 430 .lr
|
||||||
|
LS LSO 266 Maseru LS LSL 🇱🇸 en-LS,st,zu,xh Lesotho 426 .ls
|
||||||
|
LT LTU 370 Vilnius LT EUR 🇱🇹 lt,ru,pl Lithuania 440 .lt
|
||||||
|
LU LUX 352 Luxembourg LU EUR 🇱🇺 lb,de-LU,fr-LU Luxembourg 442 .lu
|
||||||
|
LV LVA 371 Riga LV EUR 🇱🇻 lv,ru,lt Latvia 428 .lv
|
||||||
|
LY LBY 218 Tripoli LY LYD 🇱🇾 ar-LY,it,en Libya 434 .ly
|
||||||
|
MA MAR 212 Rabat MA MAD 🇲🇦 ar-MA,ber,fr Morocco 504 .ma
|
||||||
|
MC MCO 377 Monaco MC EUR 🇲🇨 fr-MC,en,it Monaco 492 .mc
|
||||||
|
MD MDA 373 Chisinau MD MDL 🇲🇩 ro,ru,gag,tr Moldova 498 .md
|
||||||
|
ME MNE 382 Podgorica ME EUR 🇲🇪 sr,hu,bs,sq,hr,rom Montenegro 499 .me
|
||||||
|
MF MAF 590 Marigot FR EUR 🇲🇫 fr St. Martin 663 .gp
|
||||||
|
MG MDG 261 Antananarivo MG MGA 🇲🇬 fr-MG,mg Madagascar 450 .mg
|
||||||
|
MH MHL 692 Majuro MH USD 🇲🇭 mh,en-MH Marshall Islands 584 .mh
|
||||||
|
MK MKD 389 Skopje MK MKD 🇲🇰 mk,sq,tr,rmm,sr North Macedonia 807 .mk
|
||||||
|
ML MLI 223 Bamako ML XOF 🇲🇱 fr-ML,bm Mali 466 .ml
|
||||||
|
MM MMR 95 Nay Pyi Taw MM MMK 🇲🇲 my Myanmar 104 .mm
|
||||||
|
MN MNG 976 Ulaanbaatar MN MNT 🇲🇳 mn,ru Mongolia 496 .mn
|
||||||
|
MO MAC 853 Macao CN MOP 🇲🇴 zh,zh-MO,pt Macao 446 .mo
|
||||||
|
MP MNP 1-670 Saipan US USD 🇲🇵 fil,tl,zh,ch-MP,en-MP Northern Mariana Islands 580 .mp
|
||||||
|
MQ MTQ 596 Fort-de-France FR EUR 🇲🇶 fr-MQ Martinique 474 .mq
|
||||||
|
MR MRT 222 Nouakchott MR MRU 🇲🇷 ar-MR,fuc,snk,fr,mey,wo Mauritania 478 .mr
|
||||||
|
MS MSR 1-664 Plymouth GB XCD 🇲🇸 en-MS Montserrat 500 .ms
|
||||||
|
MT MLT 356 Valletta MT EUR 🇲🇹 mt,en-MT Malta 470 .mt
|
||||||
|
MU MUS 230 Port Louis MU MUR 🇲🇺 en-MU,bho,fr Mauritius 480 .mu
|
||||||
|
MV MDV 960 Male MV MVR 🇲🇻 dv,en Maldives 462 .mv
|
||||||
|
MW MWI 265 Lilongwe MW MWK 🇲🇼 ny,yao,tum,swk Malawi 454 .mw
|
||||||
|
MX MEX 52 Mexico City MX MXN 🇲🇽 es-MX Mexico 484 .mx
|
||||||
|
MY MYS 60 Kuala Lumpur MY MYR 🇲🇾 ms-MY,en,zh,ta,te,ml,pa,th Malaysia 458 .my
|
||||||
|
MZ MOZ 258 Maputo MZ MZN 🇲🇿 pt-MZ,vmw Mozambique 508 .mz
|
||||||
|
NA NAM 264 Windhoek NA NAD 🇳🇦 en-NA,af,de,hz,naq Namibia 516 .na
|
||||||
|
NC NCL 687 Noumea FR XPF 🇳🇨 fr-NC New Caledonia 540 .nc
|
||||||
|
NE NER 227 Niamey NE XOF 🇳🇪 fr-NE,ha,kr,dje Niger 562 .ne
|
||||||
|
NF NFK 672 Kingston AU AUD 🇳🇫 en-NF Norfolk Island 574 .nf
|
||||||
|
NG NGA 234 Abuja NG NGN 🇳🇬 en-NG,ha,yo,ig,ff Nigeria 566 .ng
|
||||||
|
NI NIC 505 Managua NI NIO 🇳🇮 es-NI,en Nicaragua 558 .ni
|
||||||
|
NL NLD 31 Amsterdam NL EUR 🇳🇱 nl-NL,fy-NL Netherlands 528 .nl
|
||||||
|
NO NOR 47 Oslo NO NOK 🇳🇴 no,nb,nn,se,fi Norway 578 .no
|
||||||
|
NP NPL 977 Kathmandu NP NPR 🇳🇵 ne,en Nepal 524 .np
|
||||||
|
NR NRU 674 Yaren NR AUD 🇳🇷 na,en-NR Nauru 520 .nr
|
||||||
|
NU NIU 683 Alofi NZ NZD 🇳🇺 niu,en-NU Niue 570 .nu
|
||||||
|
NZ NZL 64 Wellington NZ NZD 🇳🇿 en-NZ,mi New Zealand 554 .nz
|
||||||
|
OM OMN 968 Muscat OM OMR 🇴🇲 ar-OM,en,bal,ur Oman 512 .om
|
||||||
|
PA PAN 507 Panama City PA PAB 🇵🇦 es-PA,en Panama 591 .pa
|
||||||
|
PE PER 51 Lima PE PEN 🇵🇪 es-PE,qu,ay Peru 604 .pe
|
||||||
|
PF PYF 689 Papeete FR XPF 🇵🇫 fr-PF,ty French Polynesia 258 .pf
|
||||||
|
PG PNG 675 Port Moresby PG PGK 🇵🇬 en-PG,ho,meu,tpi Papua New Guinea 598 .pg
|
||||||
|
PH PHL 63 Manila PH PHP 🇵🇭 tl,en-PH,fil,ceb,ilo,hil,war,pam,bik,bcl,pag,mrw,tsg,mdh,cbk,krj,sgd,msb,akl,ibg,yka,mta,abx Philippines 608 .ph
|
||||||
|
PK PAK 92 Islamabad PK PKR 🇵🇰 ur-PK,en-PK,pa,sd,ps,brh Pakistan 586 .pk
|
||||||
|
PL POL 48 Warsaw PL PLN 🇵🇱 pl Poland 616 .pl
|
||||||
|
PM SPM 508 Saint-Pierre FR EUR 🇵🇲 fr-PM St. Pierre & Miquelon 666 .pm
|
||||||
|
PN PCN 870 Adamstown GB NZD 🇵🇳 en-PN Pitcairn 612 .pn
|
||||||
|
PR PRI 1 San Juan US USD 🇵🇷 en-PR,es-PR Puerto Rico 630 .pr
|
||||||
|
PT PRT 351 Lisbon PT EUR 🇵🇹 pt-PT,mwl Portugal 620 .pt
|
||||||
|
PW PLW 680 Melekeok PW USD 🇵🇼 pau,sov,en-PW,tox,ja,fil,zh Palau 585 .pw
|
||||||
|
PY PRY 595 Asuncion PY PYG 🇵🇾 es-PY,gn Paraguay 600 .py
|
||||||
|
QA QAT 974 Doha QA QAR 🇶🇦 ar-QA,es Qatar 634 .qa
|
||||||
|
RE REU 262 Saint-Denis FR EUR 🇷🇪 fr-RE Réunion 638 .re
|
||||||
|
RO ROU 40 Bucharest RO RON 🇷🇴 ro,hu,rom Romania 642 .ro
|
||||||
|
RS SRB 381 Belgrade RS RSD 🇷🇸 sr,hu,bs,rom Serbia 688 .rs
|
||||||
|
RU RUS 7 Moscow RU RUB 🇷🇺 ru,tt,xal,cau,ady,kv,ce,tyv,cv,udm,tut,mns,bua,myv,mdf,chm,ba,inh,kbd,krc,av,sah,nog Russia 643 .ru
|
||||||
|
RW RWA 250 Kigali RW RWF 🇷🇼 rw,en-RW,fr-RW,sw Rwanda 646 .rw
|
||||||
|
SA SAU 966 Riyadh SA SAR 🇸🇦 ar-SA Saudi Arabia 682 .sa
|
||||||
|
SB SLB 677 Honiara SB SBD 🇸🇧 en-SB,tpi Solomon Islands 090 .sb
|
||||||
|
SC SYC 248 Victoria SC SCR 🇸🇨 en-SC,fr-SC Seychelles 690 .sc
|
||||||
|
SD SDN 249 Khartoum SD SDG 🇸🇩 ar-SD,en,fia Sudan 729 .sd
|
||||||
|
SE SWE 46 Stockholm SE SEK 🇸🇪 sv-SE,se,sma,fi-SE Sweden 752 .se
|
||||||
|
SG SGP 65 Singapore SG SGD 🇸🇬 cmn,en-SG,ms-SG,ta-SG,zh-SG Singapore 702 .sg
|
||||||
|
SH SHN 290 Jamestown GB SHP 🇸🇭 en-SH St. Helena 654 .sh
|
||||||
|
SI SVN 386 Ljubljana SI EUR 🇸🇮 sl,sh Slovenia 705 .si
|
||||||
|
SJ SJM 47 Longyearbyen NO NOK 🇸🇯 no,ru Svalbard & Jan Mayen 744 .sj
|
||||||
|
SK SVK 421 Bratislava SK EUR 🇸🇰 sk,hu Slovakia 703 .sk
|
||||||
|
SL SLE 232 Freetown SL SLE 🇸🇱 en-SL,men,tem Sierra Leone 694 .sl
|
||||||
|
SM SMR 378 San Marino SM EUR 🇸🇲 it-SM San Marino 674 .sm
|
||||||
|
SN SEN 221 Dakar SN XOF 🇸🇳 fr-SN,wo,fuc,mnk Senegal 686 .sn
|
||||||
|
SO SOM 252 Mogadishu SO SOS 🇸🇴 so-SO,ar-SO,it,en-SO Somalia 706 .so
|
||||||
|
SR SUR 597 Paramaribo SR SRD 🇸🇷 nl-SR,en,srn,hns,jv Suriname 740 .sr
|
||||||
|
SS SSD 211 Juba SS SSP 🇸🇸 en South Sudan 728 .ss
|
||||||
|
ST STP 239 Sao Tome ST STN 🇸🇹 pt-ST São Tomé & Príncipe 678 .st
|
||||||
|
SV SLV 503 San Salvador SV SVC 🇸🇻 es-SV El Salvador 222 .sv
|
||||||
|
SX SXM 1-721 Philipsburg NL XCG 🇸🇽 nl,en Sint Maarten 534 .sx
|
||||||
|
SY SYR 963 Damascus SY SYP 🇸🇾 ar-SY,ku,hy,arc,fr,en Syria 760 .sy
|
||||||
|
SZ SWZ 268 Mbabane SZ SZL 🇸🇿 en-SZ,ss-SZ Eswatini 748 .sz
|
||||||
|
TC TCA 1-649 Cockburn Town GB USD 🇹🇨 en-TC Turks & Caicos Islands 796 .tc
|
||||||
|
TD TCD 235 N'Djamena TD XAF 🇹🇩 fr-TD,ar-TD,sre Chad 148 .td
|
||||||
|
TF ATF 262 Port-aux-Francais FR EUR 🇹🇫 fr French Southern Territories 260 .tf
|
||||||
|
TG TGO 228 Lome TG XOF 🇹🇬 fr-TG,ee,hna,kbp,dag,ha Togo 768 .tg
|
||||||
|
TH THA 66 Bangkok TH THB 🇹🇭 th,en Thailand 764 .th
|
||||||
|
TJ TJK 992 Dushanbe TJ TJS 🇹🇯 tg,ru Tajikistan 762 .tj
|
||||||
|
TL TLS 670 Dili TL USD 🇹🇱 tet,pt-TL,id,en Timor-Leste 626 .tl
|
||||||
|
TM TKM 993 Ashgabat TM TMT 🇹🇲 tk,ru,uz Turkmenistan 795 .tm
|
||||||
|
TN TUN 216 Tunis TN TND 🇹🇳 ar-TN,fr Tunisia 788 .tn
|
||||||
|
TO TON 676 Nuku'alofa TO TOP 🇹🇴 to,en-TO Tonga 776 .to
|
||||||
|
TR TUR 90 Ankara TR TRY 🇹🇷 tr-TR,ku,diq,az,av Türkiye 792 .tr
|
||||||
|
TT TTO 1-868 Port of Spain TT TTD 🇹🇹 en-TT,hns,fr,es,zh Trinidad & Tobago 780 .tt
|
||||||
|
TV TUV 688 Funafuti TV AUD 🇹🇻 tvl,en,sm,gil Tuvalu 798 .tv
|
||||||
|
TW TWN 886 Taipei TW TWD 🇹🇼 zh-TW,zh,nan,hak Taiwan 158 .tw
|
||||||
|
TZ TZA 255 Dodoma TZ TZS 🇹🇿 sw-TZ,en,ar Tanzania 834 .tz
|
||||||
|
UA UKR 380 Kyiv UA UAH 🇺🇦 uk,ru-UA,rom,pl,hu Ukraine 804 .ua
|
||||||
|
UG UGA 256 Kampala UG UGX 🇺🇬 en-UG,lg,sw,ar Uganda 800 .ug
|
||||||
|
US USA 1 Washington US USD 🇺🇸 en-US,es-US,haw,fr US 840 .us
|
||||||
|
UY URY 598 Montevideo UY UYU 🇺🇾 es-UY Uruguay 858 .uy
|
||||||
|
UZ UZB 998 Tashkent UZ UZS 🇺🇿 uz,ru,tg Uzbekistan 860 .uz
|
||||||
|
VA VAT 39 Vatican City VA EUR 🇻🇦 la,it,fr Vatican City 336 .va
|
||||||
|
VC VCT 1-784 Kingstown VC XCD 🇻🇨 en-VC,fr St. Vincent & Grenadines 670 .vc
|
||||||
|
VE VEN 58 Caracas VE VES 🇻🇪 es-VE Venezuela 862 .ve
|
||||||
|
VG VGB 1-284 Road Town GB USD 🇻🇬 en-VG British Virgin Islands 092 .vg
|
||||||
|
VI VIR 1-340 Charlotte Amalie US USD 🇻🇮 en-VI U.S. Virgin Islands 850 .vi
|
||||||
|
VN VNM 84 Hanoi VN VND 🇻🇳 vi,en,fr,zh,km Vietnam 704 .vn
|
||||||
|
VU VUT 678 Port Vila VU VUV 🇻🇺 bi,en-VU,fr-VU Vanuatu 548 .vu
|
||||||
|
WF WLF 681 Mata Utu FR XPF 🇼🇫 wls,fud,fr-WF Wallis & Futuna 876 .wf
|
||||||
|
WS WSM 685 Apia WS WST 🇼🇸 sm,en-WS Samoa 882 .ws
|
||||||
|
YE YEM 967 Sanaa YE YER 🇾🇪 ar-YE Yemen 887 .ye
|
||||||
|
YT MYT 262 Mamoudzou FR EUR 🇾🇹 fr-YT Mayotte 175 .yt
|
||||||
|
ZA ZAF 27 Pretoria ZA ZAR 🇿🇦 zu,xh,af,nso,en-ZA,tn,st,ts,ss,ve,nr South Africa 710 .za
|
||||||
|
ZM ZMB 260 Lusaka ZM ZMW 🇿🇲 en-ZM,bem,loz,lun,lue,ny,toi Zambia 894 .zm
|
||||||
|
ZW ZWE 263 Harare ZW ZWG 🇿🇼 en-ZW,sn,nr,nd Zimbabwe 716 .zw
|
||||||
|
@@ -1 +1 @@
|
|||||||
["UTC", "Africa/Cairo", "Africa/Johannesburg", "America/Chicago", "America/Denver", "America/Los_Angeles", "America/Mexico_City", "America/New_York", "America/Sao_Paulo", "America/Toronto", "Asia/Dubai", "Asia/Hong_Kong", "Asia/Kolkata", "Asia/Shanghai", "Asia/Singapore", "Asia/Tokyo", "Australia/Sydney", "Europe/Amsterdam", "Europe/Berlin", "Europe/London", "Europe/Madrid", "Europe/Moscow", "Europe/Oslo", "Europe/Paris", "Europe/Stockholm", "Europe/Warsaw", "Pacific/Auckland"]
|
{ "format": "{zone}", "rows": "timezone.tsv", "key": "zone", "parent": "territory", "weight": "weight" }
|
||||||
|
|||||||
@@ -0,0 +1,402 @@
|
|||||||
|
offset territory weight zone
|
||||||
|
+00:00 CI 17496811 Africa/Abidjan
|
||||||
|
+00:00 GH 11277813 Africa/Accra
|
||||||
|
+03:00 ET 18690487 Africa/Addis_Ababa
|
||||||
|
+01:00 DZ 20111539 Africa/Algiers
|
||||||
|
+03:00 ER 798575 Africa/Asmara
|
||||||
|
+00:00 ML 7673493 Africa/Bamako
|
||||||
|
+01:00 CF 2582076 Africa/Bangui
|
||||||
|
+00:00 GM 1305981 Africa/Banjul
|
||||||
|
+00:00 GW 904776 Africa/Bissau
|
||||||
|
+02:00 MW 3030905 Africa/Blantyre
|
||||||
|
+01:00 CG 3748808 Africa/Brazzaville
|
||||||
|
+02:00 BI 1251675 Africa/Bujumbura
|
||||||
|
+02:00 EG 47242427 Africa/Cairo
|
||||||
|
+00:00 MA 22808531 Africa/Casablanca
|
||||||
|
+01:00 ES 85985 Africa/Ceuta
|
||||||
|
+00:00 GN 6679241 Africa/Conakry
|
||||||
|
+00:00 SN 10055356 Africa/Dakar
|
||||||
|
+03:00 TZ 21350525 Africa/Dar_es_Salaam
|
||||||
|
+03:00 DJ 1316108 Africa/Djibouti
|
||||||
|
+01:00 CM 8330801 Africa/Douala
|
||||||
|
+00:00 EH 374107 Africa/El_Aaiun
|
||||||
|
+00:00 SL 1752243 Africa/Freetown
|
||||||
|
+02:00 BW 1262880 Africa/Gaborone
|
||||||
|
+02:00 ZW 4508424 Africa/Harare
|
||||||
|
+02:00 ZA 47939803 Africa/Johannesburg
|
||||||
|
+02:00 SS 1679674 Africa/Juba
|
||||||
|
+03:00 UG 9664318 Africa/Kampala
|
||||||
|
+02:00 SD 11781926 Africa/Khartoum
|
||||||
|
+02:00 RW 2910190 Africa/Kigali
|
||||||
|
+01:00 CD 20651243 Africa/Kinshasa
|
||||||
|
+01:00 NG 75725576 Africa/Lagos
|
||||||
|
+01:00 GA 1731692 Africa/Libreville
|
||||||
|
+00:00 TG 3089219 Africa/Lome
|
||||||
|
+01:00 AO 23567341 Africa/Luanda
|
||||||
|
+02:00 CD 16660579 Africa/Lubumbashi
|
||||||
|
+02:00 ZM 8422414 Africa/Lusaka
|
||||||
|
+01:00 GQ 355840 Africa/Malabo
|
||||||
|
+02:00 MZ 8598836 Africa/Maputo
|
||||||
|
+02:00 LS 739682 Africa/Maseru
|
||||||
|
+02:00 SZ 191312 Africa/Mbabane
|
||||||
|
+03:00 SO 6165052 Africa/Mogadishu
|
||||||
|
+00:00 LR 2127307 Africa/Monrovia
|
||||||
|
+03:00 KE 16920989 Africa/Nairobi
|
||||||
|
+01:00 TD 3363418 Africa/Ndjamena
|
||||||
|
+01:00 NE 3689982 Africa/Niamey
|
||||||
|
+00:00 MR 2157288 Africa/Nouakchott
|
||||||
|
+00:00 BF 6125427 Africa/Ouagadougou
|
||||||
|
+01:00 BJ 4001576 Africa/Porto-Novo
|
||||||
|
+00:00 ST 53300 Africa/Sao_Tome
|
||||||
|
+02:00 LY 6105792 Africa/Tripoli
|
||||||
|
+01:00 TN 7314557 Africa/Tunis
|
||||||
|
+02:00 NA 983097 Africa/Windhoek
|
||||||
|
-10:00 US 15000 America/Adak
|
||||||
|
-09:00 US 366200 America/Anchorage
|
||||||
|
-04:00 AI 15000 America/Anguilla
|
||||||
|
-04:00 AG 51737 America/Antigua
|
||||||
|
-03:00 BR 858988 America/Araguaina
|
||||||
|
-03:00 AR 11817784 America/Argentina/Buenos_Aires
|
||||||
|
-03:00 AR 580969 America/Argentina/Catamarca
|
||||||
|
-03:00 AR 8998034 America/Argentina/Cordoba
|
||||||
|
-03:00 AR 413866 America/Argentina/Jujuy
|
||||||
|
-03:00 AR 237745 America/Argentina/La_Rioja
|
||||||
|
-03:00 AR 695484 America/Argentina/Mendoza
|
||||||
|
-03:00 AR 241619 America/Argentina/Rio_Gallegos
|
||||||
|
-03:00 AR 2120781 America/Argentina/Salta
|
||||||
|
-03:00 AR 518624 America/Argentina/San_Juan
|
||||||
|
-03:00 AR 266728 America/Argentina/San_Luis
|
||||||
|
-03:00 AR 788916 America/Argentina/Tucuman
|
||||||
|
-03:00 AR 109506 America/Argentina/Ushuaia
|
||||||
|
-04:00 AW 90927 America/Aruba
|
||||||
|
-03:00 PY 3653883 America/Asuncion
|
||||||
|
-05:00 CA 15000 America/Atikokan
|
||||||
|
-03:00 BR 13131907 America/Bahia
|
||||||
|
-06:00 MX 36253 America/Bahia_Banderas
|
||||||
|
-04:00 BB 98511 America/Barbados
|
||||||
|
-03:00 BR 7977349 America/Belem
|
||||||
|
-06:00 BZ 132559 America/Belize
|
||||||
|
-04:00 CA 15000 America/Blanc-Sablon
|
||||||
|
-04:00 BR 550434 America/Boa_Vista
|
||||||
|
-05:00 CO 37243567 America/Bogota
|
||||||
|
-07:00 US 748802 America/Boise
|
||||||
|
-07:00 CA 15000 America/Cambridge_Bay
|
||||||
|
-04:00 BR 2429053 America/Campo_Grande
|
||||||
|
-05:00 MX 1328961 America/Cancun
|
||||||
|
-04:00 VE 28324666 America/Caracas
|
||||||
|
-03:00 GF 155245 America/Cayenne
|
||||||
|
-05:00 KY 44705 America/Cayman
|
||||||
|
-06:00 US 55510713 America/Chicago
|
||||||
|
-06:00 MX 1533843 America/Chihuahua
|
||||||
|
-07:00 MX 1512450 America/Ciudad_Juarez
|
||||||
|
-06:00 CR 1458629 America/Costa_Rica
|
||||||
|
-03:00 CL 62723 America/Coyhaique
|
||||||
|
-07:00 CA 15000 America/Creston
|
||||||
|
-04:00 BR 2960376 America/Cuiaba
|
||||||
|
-04:00 CW 145838 America/Curacao
|
||||||
|
+00:00 GL 15000 America/Danmarkshavn
|
||||||
|
-07:00 CA 15000 America/Dawson
|
||||||
|
-07:00 CA 21465 America/Dawson_Creek
|
||||||
|
-07:00 US 9069711 America/Denver
|
||||||
|
-05:00 US 4344725 America/Detroit
|
||||||
|
-04:00 DM 16571 America/Dominica
|
||||||
|
-06:00 CA 3518059 America/Edmonton
|
||||||
|
-05:00 BR 142900 America/Eirunepe
|
||||||
|
-06:00 SV 2571611 America/El_Salvador
|
||||||
|
-07:00 CA 15000 America/Fort_Nelson
|
||||||
|
-03:00 BR 21824546 America/Fortaleza
|
||||||
|
-04:00 CA 122883 America/Glace_Bay
|
||||||
|
-04:00 CA 15000 America/Goose_Bay
|
||||||
|
-05:00 TC 27489 America/Grand_Turk
|
||||||
|
-04:00 GD 15000 America/Grenada
|
||||||
|
-04:00 GP 250260 America/Guadeloupe
|
||||||
|
-06:00 GT 7302205 America/Guatemala
|
||||||
|
-05:00 EC 11564603 America/Guayaquil
|
||||||
|
-04:00 GY 314746 America/Guyana
|
||||||
|
-04:00 CA 843888 America/Halifax
|
||||||
|
-05:00 CU 11972822 America/Havana
|
||||||
|
-07:00 MX 2215048 America/Hermosillo
|
||||||
|
-05:00 US 2672398 America/Indiana/Indianapolis
|
||||||
|
-06:00 US 15000 America/Indiana/Knox
|
||||||
|
-05:00 US 15000 America/Indiana/Marengo
|
||||||
|
-05:00 US 15000 America/Indiana/Petersburg
|
||||||
|
-06:00 US 15000 America/Indiana/Tell_City
|
||||||
|
-05:00 US 15000 America/Indiana/Vevay
|
||||||
|
-05:00 US 15451 America/Indiana/Vincennes
|
||||||
|
-05:00 US 15000 America/Indiana/Winamac
|
||||||
|
-06:00 CA 15000 America/Inuvik
|
||||||
|
-05:00 CA 15000 America/Iqaluit
|
||||||
|
-05:00 JM 2069735 America/Jamaica
|
||||||
|
-09:00 US 31555 America/Juneau
|
||||||
|
-05:00 US 909379 America/Kentucky/Louisville
|
||||||
|
-05:00 US 15000 America/Kentucky/Monticello
|
||||||
|
-04:00 BO 6958595 America/La_Paz
|
||||||
|
-05:00 PE 21406340 America/Lima
|
||||||
|
-08:00 US 46301242 America/Los_Angeles
|
||||||
|
-04:00 SX 15000 America/Lower_Princes
|
||||||
|
-03:00 BR 4805317 America/Maceio
|
||||||
|
-06:00 NI 2621115 America/Managua
|
||||||
|
-04:00 BR 3918958 America/Manaus
|
||||||
|
-04:00 MF 15000 America/Marigot
|
||||||
|
-04:00 MQ 243860 America/Martinique
|
||||||
|
-06:00 MX 1899165 America/Matamoros
|
||||||
|
-07:00 MX 2951216 America/Mazatlan
|
||||||
|
-06:00 US 15000 America/Menominee
|
||||||
|
-06:00 MX 4154924 America/Merida
|
||||||
|
-09:00 US 15000 America/Metlakatla
|
||||||
|
-06:00 MX 61603325 America/Mexico_City
|
||||||
|
-03:00 PM 15000 America/Miquelon
|
||||||
|
-04:00 CA 381536 America/Moncton
|
||||||
|
-06:00 MX 9714766 America/Monterrey
|
||||||
|
-03:00 UY 2457462 America/Montevideo
|
||||||
|
-04:00 MS 15000 America/Montserrat
|
||||||
|
-05:00 BS 319054 America/Nassau
|
||||||
|
-05:00 US 88988896 America/New_York
|
||||||
|
-09:00 US 15000 America/Nome
|
||||||
|
-02:00 BR 15000 America/Noronha
|
||||||
|
-06:00 US 15000 America/North_Dakota/Beulah
|
||||||
|
-06:00 US 15000 America/North_Dakota/Center
|
||||||
|
-06:00 US 21382 America/North_Dakota/New_Salem
|
||||||
|
-02:00 GL 15000 America/Nuuk
|
||||||
|
-06:00 MX 50784 America/Ojinaga
|
||||||
|
-05:00 PA 1692726 America/Panama
|
||||||
|
-03:00 SR 454064 America/Paramaribo
|
||||||
|
-07:00 US 6541994 America/Phoenix
|
||||||
|
-05:00 HT 5328623 America/Port-au-Prince
|
||||||
|
-04:00 TT 456832 America/Port_of_Spain
|
||||||
|
-04:00 BR 1551818 America/Porto_Velho
|
||||||
|
-04:00 PR 1605968 America/Puerto_Rico
|
||||||
|
-03:00 CL 135935 America/Punta_Arenas
|
||||||
|
-06:00 CA 15000 America/Rankin_Inlet
|
||||||
|
-03:00 BR 8832691 America/Recife
|
||||||
|
-06:00 CA 982810 America/Regina
|
||||||
|
-06:00 CA 15000 America/Resolute
|
||||||
|
-05:00 BR 794527 America/Rio_Branco
|
||||||
|
-03:00 BR 1403419 America/Santarem
|
||||||
|
-04:00 CL 15912038 America/Santiago
|
||||||
|
-04:00 DO 7521391 America/Santo_Domingo
|
||||||
|
-03:00 BR 129186469 America/Sao_Paulo
|
||||||
|
-02:00 GL 15000 America/Scoresbysund
|
||||||
|
-09:00 US 15000 America/Sitka
|
||||||
|
-04:00 BL 15000 America/St_Barthelemy
|
||||||
|
-03:30 CA 202443 America/St_Johns
|
||||||
|
-04:00 KN 15000 America/St_Kitts
|
||||||
|
-04:00 LC 45210 America/St_Lucia
|
||||||
|
-04:00 VI 70601 America/St_Thomas
|
||||||
|
-04:00 VC 48723 America/St_Vincent
|
||||||
|
-06:00 CA 16604 America/Swift_Current
|
||||||
|
-06:00 HN 4808928 America/Tegucigalpa
|
||||||
|
-04:00 GL 15000 America/Thule
|
||||||
|
-08:00 MX 3797218 America/Tijuana
|
||||||
|
-05:00 CA 24763654 America/Toronto
|
||||||
|
-04:00 VG 15000 America/Tortola
|
||||||
|
-07:00 CA 6340886 America/Vancouver
|
||||||
|
-07:00 CA 28201 America/Whitehorse
|
||||||
|
-06:00 CA 922566 America/Winnipeg
|
||||||
|
-09:00 US 15000 America/Yakutat
|
||||||
|
+10:00 AU 15000 Antarctica/Macquarie
|
||||||
|
+01:00 SJ 15000 Arctic/Longyearbyen
|
||||||
|
+03:00 YE 6904010 Asia/Aden
|
||||||
|
+05:00 KZ 9055499 Asia/Almaty
|
||||||
|
+03:00 JO 4950859 Asia/Amman
|
||||||
|
+12:00 RU 15604 Asia/Anadyr
|
||||||
|
+05:00 KZ 282409 Asia/Aqtau
|
||||||
|
+05:00 KZ 598827 Asia/Aqtobe
|
||||||
|
+05:00 TM 2706037 Asia/Ashgabat
|
||||||
|
+05:00 KZ 388248 Asia/Atyrau
|
||||||
|
+03:00 IQ 29681856 Asia/Baghdad
|
||||||
|
+03:00 BH 815447 Asia/Bahrain
|
||||||
|
+04:00 AZ 5491302 Asia/Baku
|
||||||
|
+07:00 TH 49896297 Asia/Bangkok
|
||||||
|
+07:00 RU 1413356 Asia/Barnaul
|
||||||
|
+02:00 LB 4467748 Asia/Beirut
|
||||||
|
+06:00 KG 2233412 Asia/Bishkek
|
||||||
|
+08:00 BN 230416 Asia/Brunei
|
||||||
|
+09:00 RU 486311 Asia/Chita
|
||||||
|
+05:30 LK 4297175 Asia/Colombo
|
||||||
|
+03:00 SY 10939175 Asia/Damascus
|
||||||
|
+06:00 BD 35955225 Asia/Dhaka
|
||||||
|
+09:00 TL 311685 Asia/Dili
|
||||||
|
+04:00 AE 12931222 Asia/Dubai
|
||||||
|
+05:00 TJ 2578933 Asia/Dushanbe
|
||||||
|
+02:00 CY 109959 Asia/Famagusta
|
||||||
|
+07:00 VN 42129036 Asia/Ho_Chi_Minh
|
||||||
|
+08:00 HK 24678261 Asia/Hong_Kong
|
||||||
|
+07:00 MN 122174 Asia/Hovd
|
||||||
|
+08:00 RU 2231790 Asia/Irkutsk
|
||||||
|
+07:00 ID 68794489 Asia/Jakarta
|
||||||
|
+09:00 ID 2512221 Asia/Jayapura
|
||||||
|
+02:00 IL 7901151 Asia/Jerusalem
|
||||||
|
+04:30 AF 8764027 Asia/Kabul
|
||||||
|
+12:00 RU 247112 Asia/Kamchatka
|
||||||
|
+05:00 PK 88744953 Asia/Karachi
|
||||||
|
+05:45 NP 5913313 Asia/Kathmandu
|
||||||
|
+09:00 RU 15000 Asia/Khandyga
|
||||||
|
+05:30 IN 365373326 Asia/Kolkata
|
||||||
|
+07:00 RU 2615869 Asia/Krasnoyarsk
|
||||||
|
+08:00 MY 33322164 Asia/Kuala_Lumpur
|
||||||
|
+08:00 MY 4013140 Asia/Kuching
|
||||||
|
+03:00 KW 1662180 Asia/Kuwait
|
||||||
|
+08:00 MO 1236695 Asia/Macau
|
||||||
|
+11:00 RU 92782 Asia/Magadan
|
||||||
|
+08:00 ID 12458359 Asia/Makassar
|
||||||
|
+08:00 PH 64227523 Asia/Manila
|
||||||
|
+04:00 OM 3290021 Asia/Muscat
|
||||||
|
+02:00 CY 679420 Asia/Nicosia
|
||||||
|
+07:00 RU 2355475 Asia/Novokuznetsk
|
||||||
|
+07:00 RU 2119272 Asia/Novosibirsk
|
||||||
|
+06:00 RU 1243165 Asia/Omsk
|
||||||
|
+05:00 KZ 364799 Asia/Oral
|
||||||
|
+07:00 KH 4111780 Asia/Phnom_Penh
|
||||||
|
+07:00 ID 1819584 Asia/Pontianak
|
||||||
|
+09:00 KP 12876883 Asia/Pyongyang
|
||||||
|
+03:00 QA 1566088 Asia/Qatar
|
||||||
|
+05:00 KZ 529104 Asia/Qostanay
|
||||||
|
+05:00 KZ 511391 Asia/Qyzylorda
|
||||||
|
+03:00 SA 23913997 Asia/Riyadh
|
||||||
|
+11:00 RU 326982 Asia/Sakhalin
|
||||||
|
+05:00 UZ 3864475 Asia/Samarkand
|
||||||
|
+09:00 KR 47400555 Asia/Seoul
|
||||||
|
+08:00 CN 861293141 Asia/Shanghai
|
||||||
|
+08:00 SG 11621053 Asia/Singapore
|
||||||
|
+11:00 RU 15000 Asia/Srednekolymsk
|
||||||
|
+08:00 TW 26394699 Asia/Taipei
|
||||||
|
+05:00 UZ 7452125 Asia/Tashkent
|
||||||
|
+04:00 GE 1827911 Asia/Tbilisi
|
||||||
|
+03:30 IR 50648371 Asia/Tehran
|
||||||
|
+06:00 BT 170210 Asia/Thimphu
|
||||||
|
+09:00 JP 141330654 Asia/Tokyo
|
||||||
|
+07:00 RU 783576 Asia/Tomsk
|
||||||
|
+08:00 MN 1438738 Asia/Ulaanbaatar
|
||||||
|
+06:00 CN 12667986 Asia/Urumqi
|
||||||
|
+10:00 RU 15000 Asia/Ust-Nera
|
||||||
|
+07:00 LA 1561716 Asia/Vientiane
|
||||||
|
+10:00 RU 2534711 Asia/Vladivostok
|
||||||
|
+09:00 RU 902983 Asia/Yakutsk
|
||||||
|
+06:30 MM 18836338 Asia/Yangon
|
||||||
|
+05:00 RU 15407217 Asia/Yekaterinburg
|
||||||
|
+04:00 AM 2880620 Asia/Yerevan
|
||||||
|
-01:00 PT 20056 Atlantic/Azores
|
||||||
|
-04:00 BM 15000 Atlantic/Bermuda
|
||||||
|
+00:00 ES 2054431 Atlantic/Canary
|
||||||
|
-01:00 CV 252678 Atlantic/Cape_Verde
|
||||||
|
+00:00 FO 15000 Atlantic/Faroe
|
||||||
|
+00:00 PT 213794 Atlantic/Madeira
|
||||||
|
+00:00 IS 245356 Atlantic/Reykjavik
|
||||||
|
+00:00 SH 15000 Atlantic/St_Helena
|
||||||
|
-03:00 FK 15000 Atlantic/Stanley
|
||||||
|
+09:30 AU 1706678 Australia/Adelaide
|
||||||
|
+10:00 AU 5807246 Australia/Brisbane
|
||||||
|
+09:30 AU 17456 Australia/Broken_Hill
|
||||||
|
+09:30 AU 199509 Australia/Darwin
|
||||||
|
+08:45 AU 15000 Australia/Eucla
|
||||||
|
+10:00 AU 392450 Australia/Hobart
|
||||||
|
+10:00 AU 15000 Australia/Lindeman
|
||||||
|
+10:30 AU 15000 Australia/Lord_Howe
|
||||||
|
+10:00 AU 9304158 Australia/Melbourne
|
||||||
|
+08:00 AU 3086441 Australia/Perth
|
||||||
|
+10:00 AU 9352313 Australia/Sydney
|
||||||
|
+01:00 NL 13892513 Europe/Amsterdam
|
||||||
|
+01:00 AD 36283 Europe/Andorra
|
||||||
|
+04:00 RU 644812 Europe/Astrakhan
|
||||||
|
+02:00 GR 6286690 Europe/Athens
|
||||||
|
+01:00 RS 5756549 Europe/Belgrade
|
||||||
|
+01:00 DE 62740682 Europe/Berlin
|
||||||
|
+01:00 SK 2548401 Europe/Bratislava
|
||||||
|
+01:00 BE 9038306 Europe/Brussels
|
||||||
|
+02:00 RO 11070040 Europe/Bucharest
|
||||||
|
+01:00 HU 9366333 Europe/Budapest
|
||||||
|
+01:00 DE 15000 Europe/Busingen
|
||||||
|
+02:00 MD 1460347 Europe/Chisinau
|
||||||
|
+01:00 DK 3885672 Europe/Copenhagen
|
||||||
|
+01:00 IE 2720758 Europe/Dublin
|
||||||
|
+01:00 GI 26544 Europe/Gibraltar
|
||||||
|
+00:00 GG 16488 Europe/Guernsey
|
||||||
|
+02:00 FI 5265184 Europe/Helsinki
|
||||||
|
+00:00 IM 26218 Europe/Isle_of_Man
|
||||||
|
+03:00 TR 77554557 Europe/Istanbul
|
||||||
|
+00:00 JE 28000 Europe/Jersey
|
||||||
|
+02:00 RU 664545 Europe/Kaliningrad
|
||||||
|
+03:00 RU 782604 Europe/Kirov
|
||||||
|
+02:00 UA 35633582 Europe/Kyiv
|
||||||
|
+00:00 PT 6372176 Europe/Lisbon
|
||||||
|
+01:00 SI 552127 Europe/Ljubljana
|
||||||
|
+00:00 GB 57817786 Europe/London
|
||||||
|
+01:00 LU 131322 Europe/Luxembourg
|
||||||
|
+01:00 ES 42918247 Europe/Madrid
|
||||||
|
+01:00 MT 141714 Europe/Malta
|
||||||
|
+02:00 AX 15000 Europe/Mariehamn
|
||||||
|
+03:00 BY 6105410 Europe/Minsk
|
||||||
|
+01:00 MC 48977 Europe/Monaco
|
||||||
|
+03:00 RU 69342062 Europe/Moscow
|
||||||
|
+01:00 NO 3296711 Europe/Oslo
|
||||||
|
+01:00 FR 33093827 Europe/Paris
|
||||||
|
+01:00 ME 398494 Europe/Podgorica
|
||||||
|
+01:00 CZ 5924565 Europe/Prague
|
||||||
|
+02:00 LV 1206422 Europe/Riga
|
||||||
|
+01:00 IT 34033666 Europe/Rome
|
||||||
|
+04:00 RU 3546813 Europe/Samara
|
||||||
|
+01:00 SM 15000 Europe/San_Marino
|
||||||
|
+01:00 BA 1905798 Europe/Sarajevo
|
||||||
|
+04:00 RU 1705529 Europe/Saratov
|
||||||
|
+03:00 UA 1620906 Europe/Simferopol
|
||||||
|
+01:00 MK 1754303 Europe/Skopje
|
||||||
|
+02:00 BG 4111057 Europe/Sofia
|
||||||
|
+01:00 SE 7149541 Europe/Stockholm
|
||||||
|
+02:00 EE 1106943 Europe/Tallinn
|
||||||
|
+01:00 AL 1629643 Europe/Tirane
|
||||||
|
+04:00 RU 814189 Europe/Ulyanovsk
|
||||||
|
+01:00 LI 15000 Europe/Vaduz
|
||||||
|
+01:00 VA 15000 Europe/Vatican
|
||||||
|
+01:00 AT 5274040 Europe/Vienna
|
||||||
|
+02:00 LT 2103133 Europe/Vilnius
|
||||||
|
+03:00 RU 1837053 Europe/Volgograd
|
||||||
|
+01:00 PL 22720110 Europe/Warsaw
|
||||||
|
+01:00 HR 1650334 Europe/Zagreb
|
||||||
|
+01:00 CH 3461664 Europe/Zurich
|
||||||
|
+03:00 MG 6115943 Indian/Antananarivo
|
||||||
|
+06:00 IO 15000 Indian/Chagos
|
||||||
|
+07:00 CX 15000 Indian/Christmas
|
||||||
|
+06:30 CC 15000 Indian/Cocos
|
||||||
|
+03:00 KM 118353 Indian/Comoro
|
||||||
|
+05:00 TF 15000 Indian/Kerguelen
|
||||||
|
+04:00 SC 22881 Indian/Mahe
|
||||||
|
+05:00 MV 103693 Indian/Maldives
|
||||||
|
+04:00 MU 701493 Indian/Mauritius
|
||||||
|
+03:00 YT 138967 Indian/Mayotte
|
||||||
|
+04:00 RE 804329 Indian/Reunion
|
||||||
|
+13:00 WS 40407 Pacific/Apia
|
||||||
|
+12:00 NZ 5203989 Pacific/Auckland
|
||||||
|
+11:00 PG 40266 Pacific/Bougainville
|
||||||
|
+12:45 NZ 15000 Pacific/Chatham
|
||||||
|
+10:00 FM 15000 Pacific/Chuuk
|
||||||
|
-06:00 CL 15000 Pacific/Easter
|
||||||
|
+11:00 VU 35901 Pacific/Efate
|
||||||
|
+12:00 FJ 334403 Pacific/Fiji
|
||||||
|
+12:00 TV 15000 Pacific/Funafuti
|
||||||
|
-06:00 EC 15000 Pacific/Galapagos
|
||||||
|
-09:00 PF 15000 Pacific/Gambier
|
||||||
|
+11:00 SB 194707 Pacific/Guadalcanal
|
||||||
|
+10:00 GU 121094 Pacific/Guam
|
||||||
|
-10:00 US 1569453 Pacific/Honolulu
|
||||||
|
+13:00 KI 15000 Pacific/Kanton
|
||||||
|
+14:00 KI 15000 Pacific/Kiritimati
|
||||||
|
+11:00 FM 15000 Pacific/Kosrae
|
||||||
|
+12:00 MH 15000 Pacific/Kwajalein
|
||||||
|
+12:00 MH 45701 Pacific/Majuro
|
||||||
|
-09:30 PF 15000 Pacific/Marquesas
|
||||||
|
+12:00 NR 15000 Pacific/Nauru
|
||||||
|
-11:00 NU 15000 Pacific/Niue
|
||||||
|
+11:00 NF 15000 Pacific/Norfolk
|
||||||
|
+11:00 NC 137086 Pacific/Noumea
|
||||||
|
-11:00 AS 15000 Pacific/Pago_Pago
|
||||||
|
+09:00 PW 15000 Pacific/Palau
|
||||||
|
-08:00 PN 15000 Pacific/Pitcairn
|
||||||
|
+11:00 FM 15000 Pacific/Pohnpei
|
||||||
|
+10:00 PG 588589 Pacific/Port_Moresby
|
||||||
|
-10:00 CK 15000 Pacific/Rarotonga
|
||||||
|
+10:00 MP 48220 Pacific/Saipan
|
||||||
|
-10:00 PF 81958 Pacific/Tahiti
|
||||||
|
+12:00 KI 40311 Pacific/Tarawa
|
||||||
|
+13:00 TO 22400 Pacific/Tongatapu
|
||||||
|
+12:00 WF 15000 Pacific/Wallis
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{tld}", "rows": "tld.tsv", "key": "tld", "name": "unicode" }
|
||||||
+1439
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
|||||||
["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:123.0) Gecko/20100101 Firefox/123.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15", "Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0"]
|
{ "format": "{ua}", "rows": "useragent.tsv" }
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
browser device os ua
|
||||||
|
Chrome mobile Android Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Mobile Safari/537.36
|
||||||
|
Chrome mobile Android Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Mobile Safari/537.36
|
||||||
|
Chrome mobile Android Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Mobile Safari/537.36
|
||||||
|
Chrome mobile Android Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Mobile Safari/537.36
|
||||||
|
Chrome mobile Android Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Mobile Safari/537.36
|
||||||
|
Chrome mobile Android Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36
|
||||||
|
Chrome mobile Android Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Mobile Safari/537.36
|
||||||
|
Chrome mobile Android Mozilla/5.0 (Linux; Android 12; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36
|
||||||
|
Chrome desktop ChromeOS Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Linux Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Linux Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Linux Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Linux Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Linux Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Linux Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 YaBrowser/26.8.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.7922.34 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36
|
||||||
|
Chrome mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 26_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/152.0.7977.64 Mobile/15E148 Safari/604.1
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36
|
||||||
|
Chrome desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36
|
||||||
|
Edge desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 Edg/151.0.0.0
|
||||||
|
Edge desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36 Edg/152.0.0.0
|
||||||
|
Edge desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36 Edg/153.0.0.0
|
||||||
|
Edge desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36 Edg/152.0.0.0
|
||||||
|
Firefox desktop Linux Mozilla/5.0 (X11; Linux x86_64; rv:155.0) Gecko/20100101 Firefox/155.0
|
||||||
|
Firefox desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0
|
||||||
|
Firefox desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:154.0) Gecko/20100101 Firefox/154.0
|
||||||
|
Firefox desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:155.0) Gecko/20100101 Firefox/155.0
|
||||||
|
Firefox desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:154.0) Gecko/20100101 Firefox/154.0
|
||||||
|
Firefox desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:155.0) Gecko/20100101 Firefox/155.0
|
||||||
|
Opera desktop Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 OPR/135.0.0.0
|
||||||
|
Opera desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 OPR/134.0.0.0
|
||||||
|
Safari mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1
|
||||||
|
Safari mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.7.5 Mobile/15E148 Safari/604.1
|
||||||
|
Safari mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1
|
||||||
|
Safari mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.3 Mobile/15E148 Safari/604.1
|
||||||
|
Safari mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Mobile/15E148 Safari/604.1
|
||||||
|
Safari mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5.2 Mobile/15E148 Safari/604.1
|
||||||
|
Safari mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Mobile/15E148 Safari/604.1
|
||||||
|
Safari mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6.1 Mobile/15E148 Safari/604.1
|
||||||
|
Safari mobile iOS Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/27.0 Mobile/15E148 Safari/604.1
|
||||||
|
Safari desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15
|
||||||
|
Safari desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15
|
||||||
|
Safari desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Safari/605.1.15
|
||||||
|
Safari desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Safari/605.1.15
|
||||||
|
Safari desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5.2 Safari/605.1.15
|
||||||
|
Safari desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6 Safari/605.1.15
|
||||||
|
Safari desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6.1 Safari/605.1.15
|
||||||
|
Safari desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.6.2 Safari/605.1.15
|
||||||
|
Safari desktop macOS Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/27.0 Safari/605.1.15
|
||||||
|
Samsung Internet mobile Android Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/30.0 Chrome/143.0.0.0 Mobile Safari/537.36
|
||||||
|
+4
-18
@@ -1,21 +1,7 @@
|
|||||||
{
|
{
|
||||||
"format": "{street} {street-number}\n{postal-code} {locality}",
|
"format": "{street} {street-number}\n{postal-code} {locality}",
|
||||||
"street": [
|
"street": "{/geo.SE.address.street}",
|
||||||
{
|
"street-number": "{/geo.SE.address.street-number}",
|
||||||
"format": "{first}{last}",
|
"postal-code": "{/geo.SE.address.postal-code}",
|
||||||
"first": ["Ängs", "Bergs", "Björk", "Drottning", "Eke", "Furu", "Hamn", "Köpmans", "Kungs", "Linné", "Norra", "Nybro", "Oden", "Öster", "Park", "Skogs", "Skol", "Slotts", "Söder", "Stations", "Stor", "Strand", "Trädgårds", "Vasa", "Väster"],
|
"locality": "{/geo.SE.address.locality}"
|
||||||
"last": ["gatan", "vägen", "stigen", "gränd", "backen", "torget", "allén"]
|
|
||||||
},
|
|
||||||
["Avenyn", "Birger Jarlsgatan", "Promenaden", "Staby", "Sveavägen", "Vintjärn"]
|
|
||||||
],
|
|
||||||
"street-number": [
|
|
||||||
"{int(1,9)}",
|
|
||||||
"{int(10,99)}",
|
|
||||||
{ "format": "{int(100,999)}", "weight": 0.2 },
|
|
||||||
{ "format": "{int(1,9)}{upper(1)}", "weight": 0.2 },
|
|
||||||
{ "format": "{int(10,99)}{upper(1)}", "weight": 0.1 },
|
|
||||||
{ "format": "{int(100,999)}{upper(1)}", "weight": 0.05 }
|
|
||||||
],
|
|
||||||
"postal-code": "{int(100,999)} {int(10,99)}",
|
|
||||||
"locality": ["Alingsås", "Alvesta", "Ängelholm", "Arboga", "Arvika", "Avesta", "Boden", "Bollnäs", "Borås", "Borlänge", "Enköping", "Eskilstuna", "Eslöv", "Fagersta", "Falkenberg", "Falköping", "Falun", "Finspång", "Gällivare", "Gävle", "Göteborg", "Halmstad", "Haparanda", "Härnösand", "Hässleholm", "Helsingborg", "Huddinge", "Hudiksvall", "Jönköping", "Kalmar", "Karlshamn", "Karlskoga", "Karlskrona", "Karlstad", "Katrineholm", "Kiruna", "Köping", "Kramfors", "Kristianstad", "Kristinehamn", "Landskrona", "Lidingö", "Lidköping", "Lindesberg", "Linköping", "Ljungby", "Ludvika", "Luleå", "Lund", "Lycksele", "Malmö", "Mariestad", "Mjölby", "Mölndal", "Mora", "Motala", "Nacka", "Nässjö", "Norrköping", "Norrtälje", "Nyköping", "Nynäshamn", "Örebro", "Örnsköldsvik", "Oskarshamn", "Östersund", "Piteå", "Rabbalshede", "Ronneby", "Säffle", "Sandviken", "Sävsjö", "Sigtuna", "Skara", "Skellefteå", "Skövde", "Söderhamn", "Södertälje", "Sollentuna", "Solna", "Sölvesborg", "Stockholm", "Strängnäs", "Sundbyberg", "Sundsvall", "Täby", "Tierp", "Tranås", "Trelleborg", "Trollhättan", "Uddevalla", "Ulricehamn", "Umeå", "Upplands Väsby", "Uppsala", "Vänersborg", "Varberg", "Värnamo", "Västerås", "Västervik", "Växjö", "Vetlanda", "Vimmerby", "Visby", "Ystad"]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{number}", "rows": "birth-number.tsv", "parent": "sex" }
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
sex number
|
||||||
|
f 238
|
||||||
|
m 239
|
||||||
|
+1
-13
@@ -1,13 +1 @@
|
|||||||
{
|
"{date(1970-01-01,2029-12-31,'2006-01-02')}"
|
||||||
"format": "{year}-{month}-{day}",
|
|
||||||
"month": ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"],
|
|
||||||
"day": ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28"],
|
|
||||||
"year": [
|
|
||||||
"197{digits(1)}",
|
|
||||||
"198{digits(1)}",
|
|
||||||
{ "format": "199{digits(1)}", "weight": 2 },
|
|
||||||
{ "format": "200{digits(1)}", "weight": 3 },
|
|
||||||
{ "format": "201{digits(1)}", "weight": 3 },
|
|
||||||
{ "format": "202{digits(1)}", "weight": 2 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "first-name.tsv", "name": "name", "parent": "sex", "weight": "count" }
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
{ "format": "{name}", "rows": "last-name.tsv", "key": "name", "weight": "count" }
|
||||||
File diff suppressed because it is too large
Load Diff
+5
-30
@@ -1,32 +1,7 @@
|
|||||||
{
|
{
|
||||||
"format": "{prefix}{femalefirst|malefirst} {last}",
|
"format": "{prefix}{first} {last}",
|
||||||
"femalefirst": ["Agnes", "Alice", "Alicia", "Alma", "Amanda", "Anna", "Astrid", "Cornelia", "Ebba", "Elin", "Ella", "Ellen", "Elsa", "Emilia", "Emma", "Ester", "Eva", "Frida", "Hanna", "Hedda", "Ida", "Ingrid", "Isabelle", "Julia", "Karin", "Klara", "Kristina", "Lena", "Linnéa", "Lova", "Maja", "Maria", "Moa", "Molly", "Märta", "Nellie", "Nora", "Olivia", "Saga", "Sara", "Selma", "Signe", "Siri", "Sofia", "Stina", "Tilde", "Tuva", "Wilma", "Ylva", "Åsa"],
|
"first": "{.first-name.name}",
|
||||||
"malefirst": ["Adam", "Albin", "Alexander", "Alfred", "Anders", "Anton", "Arvid", "Axel", "Bengt", "Bo", "Carl", "David", "Edvin", "Elias", "Emil", "Erik", "Filip", "Folke", "Fredrik", "Gustav", "Göran", "Hampus", "Hans", "Henrik", "Hugo", "Isak", "Johan", "Jonas", "Karl", "Kjell", "Lars", "Leo", "Linus", "Love", "Magnus", "Mats", "Mattias", "Mikael", "Nils", "Olle", "Oskar", "Otto", "Patrik", "Per", "Pontus", "Rasmus", "Samuel", "Sixten", "Stefan", "Sten", "Sven", "Theodor", "Tobias", "Viktor", "William", "Åke"],
|
"last": "{.last-name.name}",
|
||||||
"last": [
|
"prefix": [null, { "format": "{.title.name} ", "weight": 0.05 }],
|
||||||
{
|
"sex": "{.sex.name}"
|
||||||
"format": "{first}sson",
|
|
||||||
"weight": 5,
|
|
||||||
"first": ["Ander", "Arvid", "Bengt", "Daniel", "David", "Erik", "Fredrik", "Gustaf", "Henrik", "Håkan", "Isak", "Jakob", "Johan", "Jon", "Jön", "Karl", "Lar", "Magnu", "Matt", "Mikael", "Mårten", "Nil", "Ol", "Per", "Petter", "Samuel", "Sven"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"format": "{first}{last}",
|
|
||||||
"weight": 3.6,
|
|
||||||
"first": ["Ahl", "Berg", "Blom", "Ceder", "Dahl", "Ek", "Eng", "Falk", "Fors", "Gran", "Hag", "Hed", "Holm", "Lind", "Lund", "Mal", "Ny", "Rosen", "Sand", "Sjö", "Skog", "Söder", "Sten", "Strand", "Sund", "Wik", "Öst"],
|
|
||||||
"last": ["berg", "blad", "crona", "dahl", "ed", "fors", "gren", "holm", "in", "kvist", "löf", "lund", "man", "mark", "qvist", "roth", "stedt", "sten", "strand", "ström", "vall"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"format": "{first}{last}",
|
|
||||||
"weight": 0.267,
|
|
||||||
"first": ["Hell", "Wall"],
|
|
||||||
"last": ["berg", "blad", "crona", "dahl", "ed", "fors", "gren", "holm", "in", "kvist", "man", "mark", "qvist", "roth", "stedt", "sten", "strand", "ström", "vall"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"format": "{first}{last}",
|
|
||||||
"weight": 0.133,
|
|
||||||
"first": "Norr",
|
|
||||||
"last": ["berg", "blad", "crona", "dahl", "ed", "fors", "gren", "holm", "in", "kvist", "löf", "lund", "man", "mark", "qvist", "stedt", "sten", "strand", "ström", "vall"]
|
|
||||||
},
|
|
||||||
["Berg", "Blom", "Eismar", "Falk", "Holm", "Lind", "Norberg", "Strand", "Ström", "von Flemming", "Åberg", "Öberg"]
|
|
||||||
],
|
|
||||||
"prefix": ["", { "format": "{string} ", "string": ["dr", "prof"], "weight": 0.05 }]
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user