vehicles 0.4.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +164 -0
  3. data/CHANGELOG.md +321 -0
  4. data/README.md +88 -15
  5. data/data/PROVENANCE-vehicles.md +12 -0
  6. data/data/plates/PROVENANCE.md +10 -0
  7. data/data/plates/_decode/at-districts.yml +287 -0
  8. data/data/plates/_decode/ch-cantons.yml +110 -0
  9. data/data/plates/_decode/cn-issuing-offices.yml +463 -0
  10. data/data/plates/_decode/cn-provinces.yml +614 -0
  11. data/data/plates/_decode/cz-kraj.yml +159 -0
  12. data/data/plates/_decode/dk-serial-blocks.yml +327 -0
  13. data/data/plates/_decode/es-provinces.yml +116 -0
  14. data/data/plates/_decode/fr-departements.yml +191 -0
  15. data/data/plates/_decode/gb-age-identifiers.yml +170 -0
  16. data/data/plates/_decode/gb-memory-tags.yml +202 -0
  17. data/data/plates/_decode/gr-prefectures.yml +1408 -0
  18. data/data/plates/_decode/hr-cities.yml +315 -0
  19. data/data/plates/_decode/ie-counties.yml +227 -0
  20. data/data/plates/_decode/in-state-codes.yml +169 -0
  21. data/data/plates/_decode/is-districts-1938.yml +116 -0
  22. data/data/plates/_decode/it-provinces.yml +348 -0
  23. data/data/plates/_decode/jp-office-marks.yml +960 -0
  24. data/data/plates/_decode/jp-use-marks.yml +205 -0
  25. data/data/plates/_decode/kr-authority-marks.yml +146 -0
  26. data/data/plates/_decode/kr-use-syllables.yml +194 -0
  27. data/data/plates/_decode/lu-series-order.yml +638 -0
  28. data/data/plates/_decode/mx-entity-series.yml +380 -0
  29. data/data/plates/_decode/my-index-marks.yml +271 -0
  30. data/data/plates/_decode/no-counties-1913.yml +148 -0
  31. data/data/plates/_decode/no-districts.yml +901 -0
  32. data/data/plates/_decode/pl-powiats.yml +567 -0
  33. data/data/plates/_decode/pt-trailer-services.yml +96 -0
  34. data/data/plates/_decode/ro-counties.yml +213 -0
  35. data/data/plates/_decode/se-diplomatic.yml +220 -0
  36. data/data/plates/_decode/si-regions.yml +123 -0
  37. data/data/plates/_decode/sk-districts.yml +314 -0
  38. data/data/plates/_decode/th-registration-elements.yml +208 -0
  39. data/data/plates/_decode/ua-regions.yml +393 -0
  40. data/data/plates/_decode/za-licence-marks.yml +215 -0
  41. data/data/plates/_meta/classes.yml +26 -0
  42. data/data/plates/_meta/separators.yml +102 -0
  43. data/data/plates/ad.yml +961 -0
  44. data/data/plates/ar.yml +762 -0
  45. data/data/plates/at.yml +1424 -0
  46. data/data/plates/au-act.yml +472 -0
  47. data/data/plates/au-nsw.yml +282 -0
  48. data/data/plates/au-nt.yml +431 -0
  49. data/data/plates/au-qld.yml +272 -0
  50. data/data/plates/au-sa.yml +248 -0
  51. data/data/plates/au-tas.yml +302 -0
  52. data/data/plates/au-vic.yml +215 -0
  53. data/data/plates/au-wa.yml +309 -0
  54. data/data/plates/be.yml +1840 -0
  55. data/data/plates/br.yml +1152 -0
  56. data/data/plates/ca-ab.yml +430 -0
  57. data/data/plates/ca-bc.yml +697 -0
  58. data/data/plates/ca-mb.yml +499 -0
  59. data/data/plates/ca-nb.yml +537 -0
  60. data/data/plates/ca-nl.yml +743 -0
  61. data/data/plates/ca-ns.yml +808 -0
  62. data/data/plates/ca-nt.yml +610 -0
  63. data/data/plates/ca-nu.yml +280 -0
  64. data/data/plates/ca-on.yml +881 -0
  65. data/data/plates/ca-pe.yml +592 -0
  66. data/data/plates/ca-qc.yml +1036 -0
  67. data/data/plates/ca-sk.yml +256 -0
  68. data/data/plates/ca-yt.yml +656 -0
  69. data/data/plates/ch.yml +1273 -0
  70. data/data/plates/cn.yml +1431 -0
  71. data/data/plates/cy.yml +688 -0
  72. data/data/plates/cz.yml +1179 -0
  73. data/data/plates/de.yml +1107 -0
  74. data/data/plates/dk.yml +1647 -0
  75. data/data/plates/ee.yml +1275 -0
  76. data/data/plates/es.yml +888 -0
  77. data/data/plates/fi.yml +1271 -0
  78. data/data/plates/fr.yml +1265 -0
  79. data/data/plates/gb.yml +1188 -0
  80. data/data/plates/gr.yml +721 -0
  81. data/data/plates/hr.yml +860 -0
  82. data/data/plates/hu.yml +959 -0
  83. data/data/plates/ie.yml +775 -0
  84. data/data/plates/in.yml +1172 -0
  85. data/data/plates/is.yml +667 -0
  86. data/data/plates/it.yml +1317 -0
  87. data/data/plates/jp.yml +3650 -0
  88. data/data/plates/kr.yml +1375 -0
  89. data/data/plates/li.yml +1010 -0
  90. data/data/plates/lt.yml +879 -0
  91. data/data/plates/lu.yml +842 -0
  92. data/data/plates/lv.yml +924 -0
  93. data/data/plates/mc.yml +1024 -0
  94. data/data/plates/mt.yml +854 -0
  95. data/data/plates/mx.yml +1372 -0
  96. data/data/plates/my.yml +685 -0
  97. data/data/plates/nl.yml +1016 -0
  98. data/data/plates/no.yml +1018 -0
  99. data/data/plates/nz.yml +1699 -0
  100. data/data/plates/pl.yml +1296 -0
  101. data/data/plates/pt.yml +847 -0
  102. data/data/plates/ro.yml +785 -0
  103. data/data/plates/se.yml +1091 -0
  104. data/data/plates/si.yml +1105 -0
  105. data/data/plates/sk.yml +1439 -0
  106. data/data/plates/sm.yml +1119 -0
  107. data/data/plates/th.yml +1150 -0
  108. data/data/plates/ua.yml +1672 -0
  109. data/data/plates/us-ak.yml +763 -0
  110. data/data/plates/us-al.yml +457 -0
  111. data/data/plates/us-ar.yml +427 -0
  112. data/data/plates/us-as.yml +454 -0
  113. data/data/plates/us-az.yml +430 -0
  114. data/data/plates/us-ca.yml +892 -0
  115. data/data/plates/us-co.yml +452 -0
  116. data/data/plates/us-ct.yml +427 -0
  117. data/data/plates/us-dc.yml +614 -0
  118. data/data/plates/us-de.yml +551 -0
  119. data/data/plates/us-fl.yml +741 -0
  120. data/data/plates/us-ga.yml +644 -0
  121. data/data/plates/us-gu.yml +658 -0
  122. data/data/plates/us-hi.yml +585 -0
  123. data/data/plates/us-ia.yml +438 -0
  124. data/data/plates/us-id.yml +531 -0
  125. data/data/plates/us-il.yml +516 -0
  126. data/data/plates/us-in.yml +324 -0
  127. data/data/plates/us-ks.yml +351 -0
  128. data/data/plates/us-ky.yml +770 -0
  129. data/data/plates/us-la.yml +568 -0
  130. data/data/plates/us-ma.yml +379 -0
  131. data/data/plates/us-md.yml +536 -0
  132. data/data/plates/us-me.yml +445 -0
  133. data/data/plates/us-mi.yml +408 -0
  134. data/data/plates/us-mn.yml +411 -0
  135. data/data/plates/us-mo.yml +356 -0
  136. data/data/plates/us-mp.yml +402 -0
  137. data/data/plates/us-ms.yml +432 -0
  138. data/data/plates/us-mt.yml +619 -0
  139. data/data/plates/us-nc.yml +602 -0
  140. data/data/plates/us-nd.yml +419 -0
  141. data/data/plates/us-ne.yml +483 -0
  142. data/data/plates/us-nh.yml +394 -0
  143. data/data/plates/us-nj.yml +547 -0
  144. data/data/plates/us-nm.yml +574 -0
  145. data/data/plates/us-nv.yml +655 -0
  146. data/data/plates/us-ny.yml +592 -0
  147. data/data/plates/us-oh.yml +404 -0
  148. data/data/plates/us-ok.yml +513 -0
  149. data/data/plates/us-or.yml +392 -0
  150. data/data/plates/us-pa.yml +506 -0
  151. data/data/plates/us-pr.yml +507 -0
  152. data/data/plates/us-ri.yml +445 -0
  153. data/data/plates/us-sc.yml +605 -0
  154. data/data/plates/us-sd.yml +428 -0
  155. data/data/plates/us-tn.yml +471 -0
  156. data/data/plates/us-tx.yml +535 -0
  157. data/data/plates/us-ut.yml +384 -0
  158. data/data/plates/us-va.yml +567 -0
  159. data/data/plates/us-vi.yml +489 -0
  160. data/data/plates/us-vt.yml +458 -0
  161. data/data/plates/us-wa.yml +484 -0
  162. data/data/plates/us-wi.yml +509 -0
  163. data/data/plates/us-wv.yml +446 -0
  164. data/data/plates/us-wy.yml +523 -0
  165. data/data/plates/va.yml +604 -0
  166. data/data/plates/za.yml +1141 -0
  167. data/data/vehicles.json +160653 -105090
  168. data/lib/vehicles/configuration.rb +18 -2
  169. data/lib/vehicles/dataset.rb +73 -18
  170. data/lib/vehicles/fuzzy.rb +115 -0
  171. data/lib/vehicles/http.rb +48 -0
  172. data/lib/vehicles/make.rb +36 -6
  173. data/lib/vehicles/mcp_server.rb +5 -5
  174. data/lib/vehicles/model.rb +42 -6
  175. data/lib/vehicles/plates/jurisdiction.rb +32 -0
  176. data/lib/vehicles/plates/series.rb +291 -0
  177. data/lib/vehicles/plates/template_fill.rb +188 -0
  178. data/lib/vehicles/plates/templates.rb +162 -0
  179. data/lib/vehicles/plates.rb +122 -0
  180. data/lib/vehicles/providers/hosted_provider.rb +49 -58
  181. data/lib/vehicles/providers/local_provider.rb +4 -3
  182. data/lib/vehicles/validators/vehicle_make_validator.rb +3 -1
  183. data/lib/vehicles/validators/vehicle_model_validator.rb +1 -1
  184. data/lib/vehicles/version.rb +1 -1
  185. data/lib/vehicles.rb +53 -16
  186. data/rakelib/data_refresh.rake +109 -0
  187. data/rakelib/plates_refresh.rake +29 -0
  188. data/sig/vehicles.rbs +18 -0
  189. metadata +174 -2
@@ -0,0 +1,847 @@
1
+ # plates/pt.yml — Portugal (PRD-PLATES gate L1, EU/EEA wave 2).
2
+ #
3
+ # ONE INSTRUMENT CARRIES ALMOST THIS WHOLE FILE, and it is not the one the
4
+ # secondary web cites. The Portuguese plate is governed by the REGULAMENTO DO
5
+ # NÚMERO E CHAPA DE MATRÍCULA, annexed to Decreto-Lei n.º 54/2005, de 3 de
6
+ # março (DR I-A n.º 44, pp. 1892-1897), amended by Decreto-Lei n.º 106/2006,
7
+ # de 8 de junho (DR I-A n.º 111, pp. 4052-4060), Decreto-Lei n.º 112/2009, de
8
+ # 18 de maio, Lei n.º 46/2010, de 7 de setembro, and Decreto-Lei n.º 2/2020,
9
+ # de 14 de janeiro (DR 1.ª série n.º 9, pp. 4-12). All fetched from
10
+ # files.diariodarepublica.pt on 2026-08-02, text AND page images.
11
+ #
12
+ # THE FOUR FORMAT WINDOWS ARE ENACTED LAW, NOT FOLKLORE. Regulamento art. 3.º
13
+ # n.º 2, verbatim, in one paragraph, with the dates in the statute itself:
14
+ #
15
+ # "2 — O grupo de duas letras posiciona-se da seguinte forma:
16
+ # a) Matrículas atribuídas até 29 de Fevereiro de 1992 — AA-00-00;
17
+ # b) Matrículas atribuídas a partir de 1 de Março de 1992 — 00-00-AA;
18
+ # c) Matrículas atribuídas a partir do fim da utilização do modelo
19
+ # referido na alínea anterior — 00-AA-00."
20
+ #
21
+ # and n.º 3 (renumbered n.º 4 by DL 2/2020) adds the fourth:
22
+ #
23
+ # "Após o esgotamento dos números de matrícula correspondentes à alínea c)
24
+ # do número anterior, o número de matrícula ... passa a ser constituído
25
+ # por dois grupos de duas letras e um grupo central de dois algarismos."
26
+ #
27
+ # READ THAT AGAIN, BECAUSE IT IS THE WHOLE JOB. Two of the four boundaries are
28
+ # CALENDAR DATES fixed by statute (29-02-1992 / 01-03-1992). The other two are
29
+ # not dates at all — they are EXHAUSTION EVENTS. The statute says the next
30
+ # format begins when the previous one runs out, and it says so twice. So:
31
+ #
32
+ # * es.yml's trap does not arise here in its usual form, but its MIRROR
33
+ # IMAGE does. There, an instrument's own window was shipped as a series
34
+ # period. Here, an instrument's own in-force date would be shipped as a
35
+ # series START — and it would be wrong by seven weeks. DL 2/2020 entered
36
+ # into force on 15-01-2020 (art. 11.º, "no dia seguinte ao da sua
37
+ # publicação"). The AA-00-AA SERIES did not start then. Its own art. 3.º
38
+ # is explicit that the new models "passam a ser obrigatórios para todas as
39
+ # matrículas atribuídas a partir da data em que se esgotar a atual série".
40
+ # pt.wikipedia states "15 de janeiro de 2020" for the format change; that
41
+ # is the INSTRUMENT date, and it is the error this dataset exists to not
42
+ # make. en.wikipedia states 3 March 2020, which is a first-issue date.
43
+ # Both Wikipedias were read; they disagree; the disagreement is RECORDED
44
+ # on the series, not averaged.
45
+ # * The ENABLING instrument for AA-00-AA is therefore NOT DL 2/2020. It is
46
+ # DL 54/2005 itself, whose art. 3.º n.º 3 legislated the fourth format
47
+ # fifteen years before it was needed. DL 2/2020 only approved the plate
48
+ # MODELS for it (a new Anexo V) and removed the date strip. Every
49
+ # secondary source that calls DL 2/2020 "the law that created the new
50
+ # plates" has the mechanism backwards.
51
+ #
52
+ # THE SIDE LABEL IS NOT THE FORMAT, and Portugal is the country where that
53
+ # confusion is easiest to make. From 01-01-1998 to the AA-00-AA cutover, the
54
+ # right-hand end of a Portuguese car plate carried a YELLOW BOX with the YEAR
55
+ # over the MONTH of first registration (Regulamento art. 5.º n.º 4). It is a
56
+ # registration DATE, printed beside the serial, never inside it — no character
57
+ # of a Portuguese registration number has ever encoded time or place. DL
58
+ # 2/2020's preamble gives the reason it was abolished, and it is a good one:
59
+ # "esta menção gera interpretações incorretas por parte das entidades
60
+ # fiscalizadoras do trânsito de outros Estados-Membros ... uma vez que diversos
61
+ # países utilizam a referida solução não para a indicação da data da primeira
62
+ # matrícula do veículo, mas para inscrever a data limite de validade da
63
+ # matrícula". Portugal's own registration date was being read abroad as an
64
+ # EXPIRY date. The preamble also records that Portugal was alone in the Union
65
+ # in printing it, Italy excepted.
66
+ #
67
+ # COLOUR POLICY, and it differs from Spain's on purpose. Anexo XVIII gave
68
+ # Spain four-corner CIE boxes; the Portuguese Regulamento gives COLOUR NAMES
69
+ # and nothing else — "fundo de cor branca", "a preto", "fundo amarelo", "fundo
70
+ # vermelho", "azul retrorrefletor". A name constrains far less than a gamut,
71
+ # so every hex in this file is `hex_basis: observed` and no `color_spec` is
72
+ # claimed, because there is none to cite. What IS cited is the retroreflectivity
73
+ # requirement and the colour NAME, per series.
74
+ #
75
+ # DIMENSIONS COME FROM THE ANNEX DRAWINGS, which are page images in the DR
76
+ # PDF and not text-extractable. They were rendered at 150 dpi and read
77
+ # (dl54.pdf pp. 1896-1897; dl2020.pdf pp. 10-12). Values legible at that
78
+ # resolution are recorded with `dimension_basis: statutory-drawing`; values
79
+ # that were not legible are ABSENT rather than guessed.
80
+ #
81
+ # GEOGRAPHY: there is none on a Portuguese car plate, ever, and that is a
82
+ # sourced negative rather than a missing table — art. 3.º composes the number
83
+ # from digits and letters with no locational element in any of the four
84
+ # windows. Geography survives in exactly two places, both of them statutory
85
+ # lists and both authored: the TRAILER issuing-service prefix
86
+ # (plates/_decode/pt-trailer-services.yml) and the EXPORT customs-office letter (inline on
87
+ # pt-export). A third, the three-letter câmara municipal code on the
88
+ # transitional moped plate, is authored as a mechanism without its table,
89
+ # because the table is not in the instrument.
90
+ jurisdiction: pt
91
+ authority:
92
+ name: "Instituto da Mobilidade e dos Transportes, I. P. (IMT) — Regulamento do Número e Chapa de Matrícula, anexo ao Decreto-Lei n.º 54/2005, de 3 de março, na redação atual"
93
+ url: "https://diariodarepublica.pt/dr/legislacao-consolidada/decreto-lei/2005-128100380"
94
+ binding: vehicle
95
+ binding_note: >-
96
+ Regulamento art. 8.º n.º 1, verbatim: "A cada veículo em condições de circular
97
+ só pode ser atribuído um número de matrícula." The number is the vehicle's for
98
+ life and does not follow an owner — the opposite of Belgium (be.yml,
99
+ `binding: owner`) and of Luxembourg's personalised numbers (lu.yml). Art. 8.º
100
+ n.os 2-4 carve out the one exception, and it is narrow and non-transferable:
101
+ on the request of security, military, diplomatic or judicial authorities the
102
+ registrar may issue up to FOUR SUPPLEMENTARY numbers to an operationally
103
+ sensitive vehicle, and may even issue one to a vehicle registered in another
104
+ country. A parse API must therefore not assume plate-to-vehicle is injective
105
+ in Portugal, only that vehicle-to-base-number is.
106
+
107
+ charset_defaults:
108
+ letters: "A-Z"
109
+ excluded_letters_note: >-
110
+ NONE ARE EXCLUDED BY THE INSTRUMENT — and that is a finding, not an
111
+ omission. The Regulamento composes the number from "duas letras" and
112
+ "algarismos" and prescribes no alphabet restriction anywhere, in contrast
113
+ to Spain (vowels, Ñ, Q struck out by name in Anexo XVIII) and Luxembourg
114
+ (I and O struck out, plus ten named pairs). The only hint that Portugal
115
+ filters combinations at all is in DL 2/2020's own preamble, which prices
116
+ the AA-00-AA series at "cerca de 74 anos" of theoretical life reduced to
117
+ "45 anos" in practice, "nomeadamente pela não utilização de combinações que
118
+ possam formar palavras ou siglas que se entenda dever evitar". So an
119
+ avoid-list EXISTS as a matter of administrative practice and its effect is
120
+ quantified in a statutory preamble — but its MEMBERS are published nowhere
121
+ located in this pass. Recorded gap; no `regex_strict` is offered for the
122
+ ordinary series, because inventing the excluded set would be worse than
123
+ having none.
124
+ source: "https://files.diariodarepublica.pt/1s/2020/01/00900/0000400012.pdf # DL 2/2020 preamble: the 74-year/45-year estimate and the reason for the difference"
125
+
126
+ display_rules:
127
+ two_plates: "automóveis e máquinas industriais: one front, one rear (Regulamento art. 7.º n.º 1)"
128
+ one_plate_rear_only: "motociclos, ciclomotores, triciclos, quadriciclos, reboques e máquinas industriais rebocáveis — rear only (art. 7.º n.º 2)"
129
+ mounting: "principal axis horizontal, perpendicular and centred on the vehicle's median longitudinal plane or, failing that, to its LEFT; lower edge not below 200 mm and upper edge not above 1200 mm from the ground (art. 7.º n.os 3-4)"
130
+ machinery_exception: "on máquinas industriais where construction or function forbids it, a SINGLE plate may be mounted laterally on the RIGHT-HAND side, and removable plates may be authorised (art. 7.º n.º 7, added by DL 106/2006)"
131
+ minimum_character_height: "where reduced-size plates are authorised for constructive or functional reasons, characters may not fall below 60 mm (art. 9.º n.º 3, in the DL 2/2020 wording — the 2005 original set no floor, so this is a 2020 tightening)"
132
+ source: "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # Regulamento art. 7.º; https://files.diariodarepublica.pt/1s/2006/06/111a00/40524060.pdf # art. 7.º n.º 7; https://files.diariodarepublica.pt/1s/2020/01/00900/0000400012.pdf # art. 9.º n.º 3"
133
+
134
+ pre_1937_history_note: >-
135
+ BEFORE THE 1937 NATIONAL SERIES, tagged `secondary-wikipedia` in its entirety
136
+ and deliberately NOT authored as series. The Portuguese-language Wikipedia
137
+ article dates the plate obligation itself to a Decreto de 3 de outubro de 1901
138
+ requiring every car to carry a metal plate at the rear, and describes an
139
+ intermediate 1911-1936 arrangement built on zone letters rather than a single
140
+ national run. Neither the 1901 decree nor any 1911 instrument was reached on
141
+ dre.pt in this pass — the DRE search interface is a single-page application
142
+ whose backend is not fetchable, and the pre-1910 Diário do Governo is not on
143
+ the files service under the modern path scheme. Formats for those eras are
144
+ therefore NOT recorded: a series entry needs a grammar, and a grammar taken
145
+ from an encyclopedia paragraph without an instrument behind it is exactly the
146
+ confident guess this dataset prefers a gap to.
147
+ Source (locator and sole authority for the two dates above):
148
+ https://pt.wikipedia.org/wiki/Matr%C3%ADculas_de_autom%C3%B3veis_em_Portugal
149
+
150
+ series:
151
+
152
+ # =========================================================================
153
+ # THE CURRENT SERIES — AA-00-AA. Enabled 2005, modelled 2020, issued from
154
+ # the exhaustion of 00-AA-00.
155
+ # =========================================================================
156
+ - id: pt-national-2020
157
+ class: standard
158
+ categories: [car, van, truck, bus, motorcycle, moped, tricycle, quadricycle]
159
+ period: { start: 2020 }
160
+ period_evidence: secondary-first-issue
161
+ matching: strict
162
+ format:
163
+ pattern: "LL 99 LL"
164
+ regex: '\A[A-Z]{2}[- ]\d{2}[- ][A-Z]{2}\z'
165
+ separator_note: >-
166
+ THE DASHES ARE GONE, and the deletion is legible in two independent
167
+ places in the same instrument. (1) TEXT: DL 54/2005's art. 3.º n.º 1
168
+ and n.º 3 both ended "sendo os grupos separados entre si por traços";
169
+ when DL 2/2020 rewrote n.º 3 as the new n.º 4 it reproduced the
170
+ composition and DROPPED that clause. (2) DRAWING: the Anexo V Modelo I
171
+ dimension chain prescribes only spacing — 10 mm between characters
172
+ inside a group and 20 mm between groups — and draws no separator glyph,
173
+ where the Anexo IV Modelo I drawing it replaces plainly draws one. The
174
+ canonical printed form in `pattern` is therefore the GAP. `regex` still
175
+ spells the position as the sanctioned separator-only class `[- ]`
176
+ (PRD-PLATES §2.8) because the instrument now prescribes millimetres and
177
+ no glyph, which is precisely the es-consular-cc-1999 situation: with no
178
+ glyph mandated, both members of the emitted set are inside the grammar,
179
+ so the class is `strict` rather than a widening. FLAGGED FOR THE
180
+ VERIFIER: this reading rests on the statutory drawing plus a deletion,
181
+ and a photograph of an issued plate would settle it in one look.
182
+ progression: >-
183
+ Nationally sequential and non-geographic, like every Portuguese series
184
+ since 1937. The known anchor is the first number, AA-01-AA, so the two
185
+ letter pairs and the central digits advance from there; the exact
186
+ odometer order (which of the three groups rolls first) is not stated by
187
+ the instrument and is not asserted here. DL 2/2020's preamble prices the
188
+ space at "cerca de 74 anos" theoretical and "45 anos" practical, and
189
+ notes the design deliberately leaves room to go to THREE central digits
190
+ later — so a future AA-000-AA is contemplated in the enacting text
191
+ itself and should not surprise a consumer.
192
+ design:
193
+ plate: { w: 520, h: 110, unit: mm }
194
+ plate_variants:
195
+ - { w: 340, h: 220, unit: mm, note: "Modelo II — automóveis, rear only, two rows (letters over digits+letters)" }
196
+ - { note: "Modelo IV — motociclos de cilindrada superior a 50 cm3 e triciclos" }
197
+ - { note: "Modelo V — ciclomotores, motociclos até 50 cm3 e quadriciclos" }
198
+ - { note: "Modelo VI — ciclomotores de três rodas e quadriciclos" }
199
+ dimension_basis: statutory-drawing
200
+ characters: { h: [75, 80], stroke: "1/7 h", gap: 10, group_gap: 20, unit: mm, note: "character height is a RANGE in the drawing (75 a 80), not a single value; widths are marked 6/7h for letters and 4/7h for digits, i.e. proportional to height rather than absolute" }
201
+ plate_construction: { border: 5, corner_radius: 10, unit: mm, note: "5 mm black peripheral border; R=10 corner radius; band field 45 mm wide, internally 7.5 + 30 + 7.5" }
202
+ background: { color: "#FFFFFF", finish: retroreflective, hex_basis: observed }
203
+ foreground: "#000000"
204
+ band:
205
+ side: left
206
+ color: "#003399"
207
+ hex_basis: observed
208
+ content: eu-stars+P
209
+ note: >-
210
+ Blue retroreflective field, 45 mm wide, carrying the twelve yellow
211
+ retroreflective stars above and the white letter P below. The annex
212
+ labels the three colours in words on the drawing itself — "Azul
213
+ retrorrefletor", "Amarelo retrorrefletor", "Branco retrorrefletor" —
214
+ which is the only colour specification Portuguese law gives.
215
+ emblem: { present: false }
216
+ rear_differs: false
217
+ date_strip: { present: false, note: "ABOLISHED with this model. See the file header." }
218
+ region_encoding: none
219
+ sources:
220
+ - "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # THE ENABLING INSTRUMENT: Regulamento art. 3.º n.º 3 as originally enacted — 'dois grupos de duas letras e um grupo central de dois algarismos', triggered by exhaustion of the 00-AA-00 series. DL 54/2005, DR I-A n.º 44, 03-03-2005. Accessed 2026-08-02"
221
+ - "https://files.diariodarepublica.pt/1s/2020/01/00900/0000400012.pdf # DL 2/2020 (DR 1.ª série n.º 9, 14-01-2020): art. 3.º renumbers that rule as art. 3.º n.º 4 and drops the 'traços' clause; art. 4.º adds ANEXO V (the models drawn for this format); art. 5.º n.º 1 d) maps this window to Anexo V; art. 11.º in force 15-01-2020. Accessed 2026-08-02"
222
+ - "https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Portugal # secondary-wikipedia: first issue AA-01-AA on 3 March 2020, and 99-ZZ-99 as the last number of the preceding series. Read 2026-08-02"
223
+ - "https://www.motojornal.pt/diploma-que-regula-as-matriculas-foi-publicado/ # contemporaneous Portuguese motoring press, 15-01-2020: reports the preceding series as due to run out 'at the end of next February', i.e. a March 2020 start — independent of Wikipedia and consistent with it"
224
+ notes: >-
225
+ THE CURRENT PORTUGUESE SERIES. Period start is `secondary-first-issue`
226
+ and not `instrument-in-force`, deliberately: the statutory trigger is the
227
+ EXHAUSTION of the previous series, an event no instrument dates, so the
228
+ only possible evidence for the start is a first-issue report. Two
229
+ independent secondaries agree on March 2020 — Wikipedia gives 3 March
230
+ 2020 with the first number AA-01-AA, and the Portuguese motoring press on
231
+ 15-01-2020 expected exhaustion at the end of February. FOLKLORE FLAG,
232
+ recorded not averaged: pt.wikipedia gives 15 January 2020 for the same
233
+ change; that is DL 2/2020's own entry into force and it is an instrument
234
+ date masquerading as a series start — the two Wikipedias contradict each
235
+ other and only one of them is describing the series. Old plates stay on
236
+ the road: DL 2/2020's own preamble provides that existing plates "podem
237
+ manter-se em uso, sem necessidade de substituição", optionally replaceable
238
+ at the owner's choice, and Regulamento art. 5.º n.º 12 says the same in
239
+ enacting terms. Vehicles of historic interest may be authorised to carry
240
+ the model in use at their own first registration (art. 9.º n.º 3 of DL
241
+ 2/2020's transitional article) — Portugal has no historic-plate SERIES,
242
+ only a historic-plate PERMISSION, which is why no `historic` entry appears
243
+ in this file.
244
+
245
+ # =========================================================================
246
+ # 00-AA-00 — the third window.
247
+ # =========================================================================
248
+ - id: pt-national-2005
249
+ class: standard
250
+ categories: [car, van, truck, bus, motorcycle, moped, tricycle, quadricycle]
251
+ period: { start: 2005, end: 2020 }
252
+ period_evidence: secondary-first-issue
253
+ matching: strict
254
+ format:
255
+ pattern: "99-LL-99"
256
+ regex: '\A\d{2}-[A-Z]{2}-\d{2}\z'
257
+ separator_note: >-
258
+ The hyphen IS statutory in this window: art. 3.º n.º 1, verbatim,
259
+ "sendo os grupos separados entre si por traços", and the Anexo IV
260
+ Modelo I drawing draws the glyph between groups. Contrast the 2020
261
+ model, where the clause was deleted. ON ISSUED PLATES the traço
262
+ prints as a small embossed SQUARE DOT at digit mid-height — settled
263
+ by dated reference photographs (render-program pass, 2026-08-03);
264
+ depiction consumers should draw the square dot, never an ASCII
265
+ hyphen. The 2020 note’s photograph question remains open for ITS
266
+ model.
267
+ progression: "sequential and non-geographic; the letter pair advances as the digit groups roll"
268
+ design:
269
+ plate: { w: 520, h: 110, unit: mm }
270
+ plate_variants:
271
+ - { w: 340, h: 220, unit: mm, note: "Modelo II — automóveis, rear only, two rows" }
272
+ - { note: "Modelo IV/V — motociclos de cilindrada superior a 50 cm3 e triciclos; from 01-01-2007 Modelo V, in PLASTIC (art. 5.º n.º 10). DL 106/2006 first set that date at 01-01-2006 and DL 112/2009 moved it to 01-01-2007 — a one-year slip visible only by reading both amendments" }
273
+ dimension_basis: statutory-drawing
274
+ background: { color: "#FFFFFF", finish: retroreflective, hex_basis: observed }
275
+ foreground: "#000000"
276
+ band: { side: left, color: "#003399", hex_basis: observed, content: eu-stars+P }
277
+ date_strip:
278
+ present: true
279
+ side: right
280
+ color: "#F9B700"
281
+ hex_basis: observed
282
+ content: year-over-month
283
+ note: >-
284
+ The yellow box at the right-hand end carries the YEAR above and the
285
+ MONTH below, of FIRST REGISTRATION — the Anexo IV Modelo I drawing
286
+ renders it as "98 / 01" (January 1998). It is not an expiry date and
287
+ not part of the serial. Present on Modelos I and II (cars) only;
288
+ the trailer model has never carried it.
289
+ rear_differs: false
290
+ region_encoding: none
291
+ sources:
292
+ - "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # THE ENABLING INSTRUMENT: DL 54/2005 art. 3.º n.º 2 c) — '00-AA-00' for numbers issued from the end of the use of the preceding model; preamble states the reason: 'As actuais séries de matrícula dos automóveis encontram-se praticamente esgotadas'. Art. 5.º n.º 1 c) + n.os 3-4: white retroreflective ground, black characters, plus the year/month indication at the right-hand end. Accessed 2026-08-02"
293
+ - "https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Portugal # secondary-wikipedia: 00-AA-00 introduced 2005 and running to 99-ZZ-99 in March 2020. Read 2026-08-02"
294
+ - "https://www.pgdlisboa.pt/leis/lei_mostra_articulado.php?nid=1103&tabela=leis # Decreto-Lei n.º 112/2009, de 18 de maio, as carried by the Procuradoria-Geral Distrital de Lisboa database: the amendment that moves the plastic-motorcycle-plate date from 01-01-2006 (DL 106/2006) to 01-01-2007, and that inserts the electronic-identification device into the Regulamento. Consulted as a SECONDARY carrier of the text — the Diário da República original for this one amendment was not reached. Accessed 2026-08-02"
295
+ notes: >-
296
+ THE 2005-2020 WINDOW. Both ends are exhaustion events rather than
297
+ instrument dates, so both are `secondary-first-issue`: this format began
298
+ when 99-99-ZZ ran out and ended when 99-ZZ-99 ran out. DL 54/2005 is the
299
+ enabling instrument and its own dates are known precisely — published
300
+ 03-03-2005, no entry-into-force clause of its own, so the general 5-day
301
+ vacatio of Lei n.º 74/98 puts it in force on 08-03-2005 (DERIVED from the
302
+ default rule, not stated; flagged) except for Regulamento arts. 11.º,
303
+ 15.º and 16.º, which its art. 6.º delays to 01-01-2006. NOT USED AS THE
304
+ SERIES START, on the instrument-date rule. THE MONTH IS THE GAP: no
305
+ source located in this pass gives the day, or even the month, on which
306
+ the first 00-AA-00 number was issued, and the enthusiast monthly-series
307
+ tables that would settle it are dead links. A consumer needing better than
308
+ year granularity here should treat 2005 as approximate.
309
+
310
+ # =========================================================================
311
+ # 00-00-AA — the second window. BOTH ENDS ARE CALENDAR DATES IN A STATUTE.
312
+ # =========================================================================
313
+ - id: pt-national-1992
314
+ class: standard
315
+ categories: [car, van, truck, bus, motorcycle]
316
+ period: { start: 1992, end: 2005 }
317
+ period_evidence: statutory-date-start-secondary-end
318
+ matching: strict
319
+ format:
320
+ pattern: "99-99-LL"
321
+ regex: '\A\d{2}-\d{2}-[A-Z]{2}\z'
322
+ separator_note: "statutory hyphens (art. 3.º n.º 1, 'separados entre si por traços')"
323
+ design:
324
+ plate: { w: 520, h: 110, unit: mm }
325
+ plate_variants:
326
+ - { note: "Anexo III Modelo II — automóveis, rear, two rows; Modelo III — reboques; Modelo IV — motociclos, triciclos e quadriciclos > 50 cm3, drawn at 170 mm wide" }
327
+ dimension_basis: statutory-drawing
328
+ background: { color: "#FFFFFF", finish: retroreflective, hex_basis: observed }
329
+ foreground: "#000000"
330
+ band: { side: left, color: "#003399", hex_basis: observed, content: eu-stars+P }
331
+ band_caveat: >-
332
+ READ THIS BEFORE TRUSTING THE BAND ON A 1992-1997 PLATE. The band is
333
+ drawn on the Anexo III models — the drawing labels "AZUL
334
+ RETRORREFLECTOR", "AMARELO RETRORREFLECTOR" and shows the P — but
335
+ Anexo III as read here was published in 2005 and REPLACED again in 2006,
336
+ so it is a re-enactment of the 1992 model, not the 1992 instrument. The
337
+ EU distinguishing-sign band rests on Regulation (EC) 2411/98 of
338
+ 3 November 1998, which postdates this window's opening by six years. So
339
+ either the band was on Portuguese plates before the Regulation, or the
340
+ 2005 re-enactment modernised the drawing. This pass could not reach the
341
+ 1992 instrument to tell them apart. The band is recorded because the
342
+ primary in hand draws it; the caveat is recorded because the primary in
343
+ hand cannot date it.
344
+ date_strip: { present: false, note: "the year/month box arrives with the NEXT model window, on 01-01-1998 — Anexo IV, not Anexo III" }
345
+ region_encoding: none
346
+ sources:
347
+ - "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # DL 54/2005 Regulamento art. 3.º n.º 2 a)-b): AA-00-00 for numbers issued 'até 29 de Fevereiro de 1992' and 00-00-AA 'a partir de 1 de Março de 1992' — both boundary dates enacted verbatim. Art. 5.º n.º 1 b) + n.º 3: for numbers issued between 01-01-1992 and 31-12-1997 the plate is Anexo III — retroreflective, white ground, black letters, digits, dashes and peripheral border. Accessed 2026-08-02"
348
+ notes: >-
349
+ THE 1992-2005 WINDOW, and the one place in this file where a boundary is
350
+ dated TO THE DAY by a statute: numbers up to 29-02-1992 are AA-00-00,
351
+ numbers from 01-03-1992 are 00-00-AA. Its far end is an exhaustion event
352
+ (see pt-national-2005). A PRECISION WORTH KEEPING, because it is a real
353
+ two-month seam and secondary sources collapse it: the NUMBER format
354
+ changed on 01-03-1992, but the PLATE MODEL changed on 01-01-1992 — art.
355
+ 5.º n.º 1 puts Anexo II (black) on everything up to 31-12-1991 and
356
+ Anexo III (white retroreflective) on everything from 01-01-1992. So
357
+ registrations made in January and February 1992 carry an OLD-FORMAT
358
+ AA-00-00 number on a NEW white reflective plate, and that combination is
359
+ lawful, sourced, and invisible in every secondary account of the change.
360
+ The instrument that actually made the 1992 change was not reached: DL
361
+ 54/2005 states the dates but revokes only arts. 1.º-3.º of Decreto
362
+ Regulamentar n.º 13/98, de 15 de junho and arts. 35.º and 37.º of the
363
+ Regulamento do Código da Estrada (Decreto n.º 39 987, de 22 de dezembro de
364
+ 1954), so the 1992 amendment lives somewhere in the chain between those
365
+ two and is a recorded gap.
366
+
367
+ # =========================================================================
368
+ # AA-00-00 — the first modern national series.
369
+ # =========================================================================
370
+ - id: pt-national-1937
371
+ class: standard
372
+ categories: [car, van, truck, bus, motorcycle]
373
+ period: { start: 1937, end: 1992 }
374
+ period_evidence: statutory-date-end-secondary-start
375
+ matching: strict
376
+ format:
377
+ pattern: "LL-99-99"
378
+ regex: '\A[A-Z]{2}-\d{2}-\d{2}\z'
379
+ progression: >-
380
+ Reported to have run from AA-10-00 to ZZ-99-99 across fifty-five years,
381
+ i.e. the letter pair advances as the four digits roll and the series
382
+ did NOT start at AA-00-00 itself. That range is `secondary-wikipedia`;
383
+ the STATUTE gives only the shape.
384
+ separator_note: "hyphens, drawn in the Anexo II models ('ML-79-08', 'MF-09-78')"
385
+ design:
386
+ plate: { w: 460, h: 100, unit: mm, note: "Anexo II Modelo I — automóveis, FRONT" }
387
+ plate_variants:
388
+ - { w: 340, h: 230, unit: mm, note: "Modelo II — automóveis, rear, two rows (letters over digits)" }
389
+ - { w: 520, h: 120, unit: mm, note: "Modelo III — automóveis, rear, single row" }
390
+ - { note: "Modelo IV — motociclos, drawn at 230 mm wide" }
391
+ - { w: 520, h: 120, unit: mm, note: "Modelo V — reboques" }
392
+ dimension_basis: statutory-drawing
393
+ background: { color: "#000000", finish: painted, hex_basis: observed }
394
+ foreground: "#FFFFFF"
395
+ band: { side: none }
396
+ note: >-
397
+ WHITE ON BLACK, and unlike Spain this is not collector folklore but
398
+ enacted text: Regulamento art. 5.º n.º 2, verbatim, "As chapas de
399
+ matrícula dos modelos constantes do anexo II têm fundo de cor preta e
400
+ letras, algarismos e traços de cor branca". No retroreflectivity is
401
+ required for this model — the requirement appears for the first time in
402
+ n.º 3, for Anexo III. The drawings label the two colours "BRANCO" and
403
+ "PRETO" and nothing else, so `finish: painted` is an inference from the
404
+ ABSENCE of the retroreflector requirement rather than a positive claim.
405
+ date_strip: { present: false }
406
+ region_encoding: none
407
+ sources:
408
+ - "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # DL 54/2005 Regulamento art. 3.º n.º 2 a) — 'Matrículas atribuídas até 29 de Fevereiro de 1992 — AA-00-00'; art. 5.º n.º 1 a) + n.º 2 — Anexo II for numbers issued up to 31-12-1991, black ground, white characters; Anexo II Modelos I-V drawings. Accessed 2026-08-02"
409
+ - "https://pt.wikipedia.org/wiki/Matr%C3%ADculas_de_autom%C3%B3veis_em_Portugal # secondary-wikipedia: the second national registration system entered into force on 1 January 1937. Read 2026-08-02"
410
+ - "https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Portugal # secondary-wikipedia: the run AA-10-00 to ZZ-99-99, and black plates with white characters through 1992. Read 2026-08-02"
411
+ notes: >-
412
+ THE FIFTY-FIVE-YEAR SERIES. Its END is enacted law, to the day
413
+ (29-02-1992, DL 54/2005 art. 3.º n.º 2 a)). Its START is not: 1 January
414
+ 1937 is `secondary-wikipedia` and the instrument behind it was not
415
+ reached, so `period_evidence: statutory-date` describes the END only and
416
+ the note is where the asymmetry is declared. Anyone re-verifying should
417
+ start from the Regulamento do Código da Estrada (Decreto n.º 39 987, de
418
+ 22 de dezembro de 1954) arts. 35.º and 37.º, which DL 54/2005 revokes by
419
+ name and which therefore carried the plate rules for the bulk of this
420
+ window — but 1954 is itself mid-series, so the 1937 instrument is a
421
+ third link back and remains unlocated. NOT the pre-1937 systems: those
422
+ are described in the file's `pre_1937_history_note` and are not authored.
423
+
424
+ # =========================================================================
425
+ # TRAILERS — the one geographic decode on a Portuguese plate.
426
+ # =========================================================================
427
+ - id: pt-trailer
428
+ class: trailer
429
+ categories: [trailer, semitrailer]
430
+ period: { start: 2005 }
431
+ period_evidence: instrument-in-force
432
+ matching: strict
433
+ format:
434
+ pattern: "L-999999"
435
+ regex: '\A[A-Z]{1,2}[- ]\d{1,6}\z'
436
+ regex_strict: '\A(?:AV|BE|BR|BN|CB|FA|GD|LE|PT|SA|SE|VC|VR|VI|VS|AN|A|C|E|H|L|M|P)[- ]\d{1,6}\z'
437
+ charset:
438
+ notes: >-
439
+ The prefix is the ISSUING SERVICE, one or two letters, and the list is
440
+ enumerated twice — DL 54/2005 Anexo I and, replacing it, DL 106/2006
441
+ Anexo I. `regex_strict` is the UNION of both vintages (VS and VI both
442
+ appear, for Viseu before and after the 2006 replacement), because
443
+ trailers were lawfully plated under each. Longest-match first in the
444
+ alternation, because single-letter codes are prefixes of two-letter
445
+ ones. The SERIAL is "um número de ordem" with no width fixed by the
446
+ instrument; the 6-digit bound in `regex` is taken from the widest
447
+ serial the annex drawings actually print ("L-10978" in Anexo II,
448
+ "L 807890" in Anexo IV, "L 808970" in Anexo V) and is a narrowing, not
449
+ a statutory claim — which keeps the series `strict` under §2.7.
450
+ separator_note: "the pre-2020 drawings show a dash; the 2020 Anexo V Modelo III drawing shows a gap, as on the car plate. `[- ]` covers both vintages of this one continuing series."
451
+ design:
452
+ plate: { w: 520, h: 110, unit: mm }
453
+ dimension_basis: statutory-drawing
454
+ background: { color: "#FFFFFF", finish: retroreflective, hex_basis: observed }
455
+ foreground: "#000000"
456
+ band: { side: left, color: "#003399", hex_basis: observed, content: eu-stars+P }
457
+ date_strip: { present: false, note: "trailers never carried the year/month box — art. 5.º n.º 4 confines it to Modelos I and II, the car plates" }
458
+ region_encoding: "plates/_decode/pt-trailer-services.yml"
459
+ region_encoding_file: pt-trailer-services.yml
460
+ sources:
461
+ - "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # DL 54/2005 Regulamento art. 4.º n.os 1-2: 'O número de matrícula dos reboques é constituído por uma ou duas letras identificadoras do serviço regional que procedeu à matrícula, seguidas de um número de ordem', with the table at Anexo I; Anexo II Modelo V, Anexo III Modelo III and Anexo IV Modelo III drawings. Accessed 2026-08-02"
462
+ - "https://files.diariodarepublica.pt/1s/2006/06/111a00/40524060.pdf # DL 106/2006 art. 1.º n.º 3: replaces Anexo I — the current code list. Accessed 2026-08-02"
463
+ - "https://files.diariodarepublica.pt/1s/2020/01/00900/0000400012.pdf # DL 2/2020 Anexo, ANEXO V Modelo III — Reboques: the current trailer plate model, drawn as 'L 808970' with the EU band and no dash. Accessed 2026-08-02"
464
+ notes: >-
465
+ PORTUGUESE TRAILERS ARE DECODABLE AND PORTUGUESE CARS ARE NOT. The prefix
466
+ names the district office that issued the registration — not the trailer's
467
+ base, not the towing vehicle's plate. PERIOD HONESTY: 2005 is the vintage
468
+ of the instrument that ENACTS the rule read here, exactly as in
469
+ es-provinces.yml, and not the date the composition began. The composition
470
+ is demonstrably older, and the proof is inside the same instrument: Anexo
471
+ II Modelo V — the model governing numbers issued UP TO 31-12-1991 — is
472
+ drawn as "L-10978". So trailers were numbered letter-plus-serial before
473
+ 1992 and the enacting instrument for that is a recorded gap. Contrast
474
+ Spain, where the trailer letter is a fixed R prefix and the province code
475
+ trails; here the letter IS the geography and there is no fixed prefix.
476
+
477
+ # =========================================================================
478
+ # EXPORT — yellow, with its own four-member customs-office letter set.
479
+ # =========================================================================
480
+ - id: pt-export
481
+ class: export
482
+ categories: [car, van, truck, bus, motorcycle, trailer]
483
+ period: { start: 2005 }
484
+ period_evidence: instrument-in-force
485
+ matching: strict
486
+ format:
487
+ pattern: "99999 L"
488
+ regex: '\A\d{1,6}[- ][A-Z]\z'
489
+ regex_strict: '\A\d{1,6}[- ][LPAM]\z'
490
+ charset:
491
+ letters: [L, P, A, M]
492
+ notes: >-
493
+ Art. 4.º n.º 3, verbatim: the export number is "um número de ordem,
494
+ seguido da letra inicial de Lisboa, Porto, Açores ou Madeira,
495
+ consoante o serviço alfandegário que a processe" — the INITIAL of the
496
+ customs service that processed it. Four members, inline here rather
497
+ than in a decode file because it is a different statutory list from
498
+ the trailer table, in a different article, with different members
499
+ (the trailer table has no Açores row at all — it splits the Azores
500
+ into three district codes AN/H/A).
501
+ progression: "sequential per customs office; the drawing prints five digits ('24783 L') but the instrument fixes no width"
502
+ design:
503
+ plate: { w: 520, h: 110, unit: mm, note: "Anexo V Modelo I as enacted in 2005; renumbered ANEXO VI by DL 2/2020 art. 7.º b) without change of content" }
504
+ plate_variants:
505
+ - { w: 340, h: 220, unit: mm, note: "Modelo II — two rows" }
506
+ dimension_basis: statutory-drawing
507
+ background: { color: "#F9B700", finish: retroreflective, hex_basis: observed }
508
+ foreground: "#000000"
509
+ band: { side: left, color: "#003399", hex_basis: observed, content: eu-stars+P }
510
+ expiry_box:
511
+ side: right
512
+ content: "EXP over expiry"
513
+ note: >-
514
+ The right-hand box carries the letters EXP above the validity limit —
515
+ the drawing renders it as "EXP / 91 5". This is the one Portuguese
516
+ plate that has always carried a date on its face, and it is an EXPIRY
517
+ date, not a registration date. Note the irony recorded in DL 2/2020's
518
+ preamble: foreign enforcement bodies were reading the ORDINARY plate's
519
+ registration strip as if it were this one.
520
+ region_encoding: inline
521
+ sources:
522
+ - "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # DL 54/2005 Regulamento art. 4.º n.º 3 (the number) and art. 6.º n.º 1 (the plate): 'Nos veículos destinados à exportação, a chapa de matrícula é de um dos modelos constantes do anexo V, tendo cor amarela e letras, algarismos, traços e rebordo periférico a preto'; Anexo V Modelos I-II drawings. Accessed 2026-08-02"
523
+ - "https://files.diariodarepublica.pt/1s/2020/01/00900/0000400012.pdf # DL 2/2020 art. 7.º b): 'O anexo V é renumerado como anexo VI' — the export annex moves, its content does not. Accessed 2026-08-02"
524
+ notes: >-
525
+ EXPORT PLATES — yellow ground, black characters, EXP box. A trap for a
526
+ parse API and the reason this entry exists as its own series rather than a
527
+ colour variant: the export letter is a SUFFIX drawn from {L, P, A, M},
528
+ while the trailer letter is a PREFIX drawn from a 21-code table that also
529
+ contains L, P, A and M with DIFFERENT meanings — L is Lisboa in both, but
530
+ A is Ponta Delgada on a trailer and the whole of the Açores on an export
531
+ plate, and M is Funchal on a trailer and the whole of Madeira here.
532
+ Disambiguation is by POSITION, never by letter.
533
+
534
+ # =========================================================================
535
+ # DIPLOMATIC — a primary colour rule, a secondary number grammar.
536
+ # =========================================================================
537
+ - id: pt-diplomatic
538
+ class: diplomatic
539
+ categories: [car, van, motorcycle]
540
+ period: { start: 2005 }
541
+ period_evidence: instrument-in-force
542
+ matching: recall-only
543
+ format:
544
+ pattern: "999-CD999"
545
+ regex: '\A\d{1,3}-(?:CD|CC|FM)\d{1,3}\z'
546
+ pattern_note: >-
547
+ THE GRAMMAR HERE IS SECONDARY AND THE COLOUR IS PRIMARY — an unusual
548
+ split, and the reason this series is `recall-only`. DL 54/2005 art. 6.º
549
+ n.º 2 prescribes only that the CHARACTERS, dashes and border be red on
550
+ the plates of diplomatic-corps members, career consuls, non-resident
551
+ administrative and technical staff of foreign missions, and bodies
552
+ covered by the Protocol on the Privileges and Immunities of the European
553
+ Communities. It composes no number. The CD / CC / FM group letters and
554
+ the surrounding digit groups are taken from Wikipedia
555
+ (`secondary-wikipedia`); the group widths are unverified, which is why
556
+ the regex bounds them loosely and no `regex_strict` is offered.
557
+ design:
558
+ background: { color: "#FFFFFF", finish: retroreflective, hex_basis: observed }
559
+ foreground: "#CE1126"
560
+ foreground_note: >-
561
+ Art. 6.º n.º 2, verbatim: "os caracteres, traços e rebordo periférico das
562
+ chapas de matrícula são de cor vermelha". The instrument names the
563
+ colour and nothing more — no gamut, no RAL, no CIE. hex_basis observed.
564
+ band: { side: left, color: "#003399", hex_basis: observed, content: eu-stars+P }
565
+ region_encoding: none
566
+ sources:
567
+ - "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # DL 54/2005 Regulamento art. 6.º n.º 2 — the RED characters rule and the exact list of who gets them. Accessed 2026-08-02"
568
+ - "https://pt.wikipedia.org/wiki/Matr%C3%ADculas_de_autom%C3%B3veis_em_Portugal # secondary-wikipedia: white plates with red characters, and the CD / CC / FM group letters with digits either side. Read 2026-08-02"
569
+ notes: >-
570
+ CORPO DIPLOMÁTICO E CONSULAR. Recorded as `diplomatic` although the
571
+ statutory provision is one sentence covering diplomats, career consuls,
572
+ mission staff AND European-institution personnel in a single breath — the
573
+ controlled vocabulary would split those across `diplomatic`, `consular`
574
+ and something it does not have. One series, because the instrument makes
575
+ one rule. CLASS CAVEAT flagged rather than resolved. THE REAL GAP: the
576
+ body that assigns the CD/CC/FM prefixes and their per-mission numbering is
577
+ the Ministério dos Negócios Estrangeiros, not the IMT, and no MNE
578
+ instrument was reached — so no mission decode table exists here and none
579
+ was invented. PRD-PLATES puts diplomatic decode tables at gate L4.
580
+
581
+ # =========================================================================
582
+ # TEMPORARY IMPORT — the blue-character plate.
583
+ # =========================================================================
584
+ - id: pt-temporary-import
585
+ class: temporary
586
+ categories: [car, van, truck, bus, trailer]
587
+ period: { start: 2005 }
588
+ period_evidence: instrument-in-force
589
+ matching: recall-only
590
+ format:
591
+ pattern: "99-99-LL"
592
+ regex: '\A(?:[A-Z]{2}[- ]\d{2}[- ][A-Z]{2}|\d{2}-[A-Z]{2}-\d{2}|\d{2}-\d{2}-[A-Z]{2}|[A-Z]{2}-\d{2}-\d{2})\z'
593
+ pattern_note: >-
594
+ NO NUMBER GRAMMAR IS ASSERTED, and the regex is the union of the four
595
+ ordinary Portuguese shapes purely so a consumer gets a shape hit — hence
596
+ `recall-only`, in the same spirit as nl-export. DL 54/2005 establishes
597
+ this plate only by penalising its absence: art. 2.º n.º 1 a) v) fines
598
+ "Circulação de automóvel ou de reboque importado temporariamente com
599
+ chapa de matrícula provisória não possuindo caracteres, traço e rebordo
600
+ periférico de cor azul". That sentence proves the plate exists and proves
601
+ its colour; it composes no number, and neither does anything else in the
602
+ Regulamento. `pattern` shows an ordinary shape only because the schema
603
+ requires one.
604
+ design:
605
+ background: { color: "#FFFFFF", finish: retroreflective, hex_basis: observed }
606
+ foreground: "#003399"
607
+ foreground_note: "characters, dashes and peripheral border in BLUE — the only Portuguese plate so coloured. hex_basis observed; the instrument names the colour and gives no spec."
608
+ region_encoding: none
609
+ sources:
610
+ - "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # DL 54/2005 art. 2.º n.º 1 a) v): the temporarily-imported vehicle's provisional plate must carry BLUE characters, dashes and peripheral border. Accessed 2026-08-02"
611
+ notes: >-
612
+ MATRÍCULA PROVISÓRIA for temporarily imported vehicles — blue characters.
613
+ An honest half-entry: the colour is primary and precise, the grammar is
614
+ absent from the instrument, and rather than borrow a grammar from a
615
+ secondary this series is marked `recall-only` and says so. The entry earns
616
+ its place because the blue-character rule is otherwise unrecorded anywhere
617
+ machine-readable, and because a parse API that meets a blue Portuguese
618
+ plate should be able to name it.
619
+
620
+ # =========================================================================
621
+ # MOPEDS AND SMALL QUADRICYCLES — yellow, and conditionally commenced.
622
+ # =========================================================================
623
+ - id: pt-moped-2006
624
+ class: moped
625
+ categories: [moped, motorcycle, quadricycle, tricycle]
626
+ period: { start: 2006 }
627
+ period_evidence: enabling-instrument
628
+ matching: strict
629
+ format:
630
+ pattern: "99-LL-99"
631
+ regex: '\A(?:\d{2}-[A-Z]{2}-\d{2}|[A-Z]{2}[- ]\d{2}[- ][A-Z]{2})\z'
632
+ pattern_note: >-
633
+ Mopeds carry the ORDINARY national number, not a series of their own —
634
+ art. 3.º n.º 1 composes one number for "automóveis, motociclos,
635
+ ciclomotores, triciclos e quadriciclos" together. This series exists
636
+ because the PLATE differs (yellow, its own models), not because the
637
+ serial does, and the regex is therefore the union of the two national
638
+ formats in force across its period.
639
+ design:
640
+ plate: { note: "Modelo VI of Anexo IV (2006-2020), replaced by Modelo V of Anexo V from the AA-00-AA cutover; Modelo VII / Modelo VI for three-wheeled mopeds and quadricycles with room for a wider plate" }
641
+ dimension_basis: statutory-drawing
642
+ background: { color: "#F9B700", finish: retroreflective, hex_basis: observed }
643
+ foreground: "#000000"
644
+ band:
645
+ side: left
646
+ color: "#003399"
647
+ hex_basis: observed
648
+ content: eu-stars+P
649
+ note: >-
650
+ THE BAND ARRIVED HERE IN 2020, NOT 2006, and DL 2/2020's preamble says
651
+ why in terms: it harmonises "os modelos das chapas de matrícula dos
652
+ ciclomotores e motociclos com o dos restantes veículos, no que se
653
+ refere à inclusão do dístico identificador do Estado-Membro de
654
+ matrícula, previsto no Regulamento (CE) n.º 2411/98 ... facilitando a
655
+ circulação internacional destes veículos". So a Portuguese moped plate
656
+ issued before the cutover has no EU band and one issued after does.
657
+ region_encoding: none
658
+ sources:
659
+ - "https://files.diariodarepublica.pt/1s/2006/06/111a00/40524060.pdf # DL 106/2006: extends the Regulamento to ciclomotores and quadriciclos; new art. 5.º n.º 8 — 'A chapa de matrícula dos motociclos de cilindrada não superior a 50 cm3, dos ciclomotores e dos quadriciclos ... deve obedecer às características e dimensões do modelo VI do anexo IV ..., apresentando fundo a amarelo e letras, algarismos, traços e rebordo periférico a preto'; art. 2.º n.º 1 — conditional commencement. Accessed 2026-08-02"
660
+ - "https://files.diariodarepublica.pt/1s/2020/01/00900/0000400012.pdf # DL 2/2020: art. 5.º n.º 6 as amended moves this class to Modelo V of the new Anexo V from the cutover date, and the preamble states the EU-band harmonisation reason. Accessed 2026-08-02"
661
+ notes: >-
662
+ CICLOMOTORES, MOTOCICLOS ATÉ 50 cm3 E QUADRICICLOS — yellow ground, black
663
+ characters. `period_evidence: enabling-instrument` and NOT
664
+ `instrument-in-force`, because DL 106/2006's art. 2.º n.º 1 gives this
665
+ class a CONDITIONAL commencement and not a date: its provisions "entram em
666
+ vigor conjuntamente com a regulamentação relativa ao registo de propriedade
667
+ destes veículos". The instrument that carried that property-registration
668
+ regime, and therefore the real day this series began, was not reached in
669
+ this pass — a recorded gap, and the reason 2006 is the enabling
670
+ instrument's year rather than a first-issue claim. Until that condition
671
+ was met the transitional municipal scheme applied — see
672
+ pt-moped-municipal-2006, which is the series a Portuguese moped plate of
673
+ that era actually bears.
674
+
675
+ - id: pt-moped-municipal-2006
676
+ class: moped
677
+ categories: [moped, motorcycle]
678
+ period: { start: 2006, ended: true, year_end_min: 2006 }
679
+ period_evidence: transitional-provision
680
+ matching: recall-only
681
+ format:
682
+ pattern: "9-LLL-99-99"
683
+ regex: '\A\d{1,3}-[A-Z]{3}-\d{2}-\d{2}\z'
684
+ pattern_note: >-
685
+ THE ONLY PORTUGUESE PLATE THAT EVER ENCODED A MUNICIPALITY. DL 106/2006
686
+ art. 2.º n.º 1 a), in substance: the number is a group of three letters
687
+ standing for the CÂMARA MUNICIPAL that registered the vehicle, preceded
688
+ by a per-series order number starting at 1, and followed by two groups
689
+ of two digits giving the order of registration. The Anexo II drawings
690
+ render it on two rows, as "4-ETZ" over "12-30". `recall-only` because
691
+ the width of the leading order number is not fixed by the instrument and
692
+ because the three-letter municipal codes are NOT enumerated anywhere in
693
+ it — the mechanism is statutory, the table is not, so no decode file was
694
+ built and none was reconstructed from elsewhere.
695
+ design:
696
+ plate: { note: "Modelo 1 (ciclomotores) and Modelo 2 (motociclos até 50 cm3) of Anexo II to DL 106/2006, both drawn as two-row plates" }
697
+ dimension_basis: statutory-drawing
698
+ background: { color: "#F9B700", finish: retroreflective, hex_basis: observed }
699
+ foreground: "#000000"
700
+ band: { side: none }
701
+ variant_colour_note: >-
702
+ TWO GROUNDS, ONE FORMAT, split by engine size — art. 2.º n.º 1 d):
703
+ ciclomotores get a YELLOW ground and motociclos up to 50 cm3 a WHITE
704
+ one, with black letters, digits, dashes and border on both. The yellow
705
+ is recorded as the entry's background because ciclomotores are the
706
+ dominant population; the white variant is a colour-only difference on
707
+ the same format and period, hence a note per PRD-PLATES §2.3 rather than
708
+ a second series.
709
+ region_encoding: "câmara municipal — three-letter codes not enumerated by the instrument; no decode table authored"
710
+ sources:
711
+ - "https://files.diariodarepublica.pt/1s/2006/06/111a00/40524060.pdf # DL 106/2006 art. 2.º n.º 1 a)-e) and ANEXO II Modelos 1-2: the transitional municipal moped number, its two grounds, the retroreflectivity requirement, and the rule that the number survives the owner's move to another concelho. Accessed 2026-08-02"
712
+ notes: >-
713
+ THE TRANSITIONAL MUNICIPAL MOPED SERIES — issued by câmaras municipais
714
+ while the national moped register was being stood up. `ended: true` with
715
+ `year_end_min: 2006` rather than a hard end, which is the schema's
716
+ known-over-undated shape: the scheme was expressly transitional and is
717
+ certainly closed, but no instrument closing it was reached, so the dataset
718
+ states that it ended without asserting when. Worth keeping for a parse API
719
+ because these plates are still on the road and nothing else in the
720
+ Portuguese system looks remotely like them. One human detail preserved
721
+ from the instrument, because it explains why the codes cannot be treated
722
+ as a live geography: art. 2.º n.º 1 b) freezes the number when the owner
723
+ moves to another municipality or sells to someone in one — so the
724
+ municipal code records where the moped was FIRST registered and may have
725
+ been wrong about its whereabouts for twenty years.
726
+
727
+ # =========================================================================
728
+ # INDUSTRIAL MACHINERY — where the enacted text and the enacted drawing
729
+ # disagree, and the disagreement is recorded rather than resolved.
730
+ # =========================================================================
731
+ - id: pt-machinery-2006
732
+ class: agricultural
733
+ categories: [machine, trailer]
734
+ period: { start: 2006 }
735
+ period_evidence: enabling-instrument
736
+ matching: strict
737
+ format:
738
+ pattern: "99-LL-99 L"
739
+ regex: '\A(?:\d{2}-[A-Z]{2}-\d{2}|[A-Z]{2}[- ]\d{2}[- ][A-Z]{2})[- ][A-Z]\z'
740
+ charset:
741
+ notes: >-
742
+ Art. 3.º n.º 3 (added by DL 106/2006): the machinery number follows the
743
+ ordinary composition "sendo o número de matrícula seguido de uma letra
744
+ identificativa da classe de circulação definida nos termos do anexo II
745
+ do regulamento para atribuição de matrícula a máquinas industriais". So
746
+ the trailing letter is a CIRCULATION-CLASS code, and its value set
747
+ lives in a different regulation which was not reached — recorded gap,
748
+ and the reason there is no `regex_strict`. The drawings render it in
749
+ its own box at the right-hand end, separated by a gap rather than a
750
+ dash, which is why `pattern` spells that position with a space.
751
+ design:
752
+ plate: { note: "Modelos VIII (front/rear/side) and IX (rear/side) of Anexo IV; replaced by Modelos VII and VIII of Anexo V from the AA-00-AA cutover" }
753
+ dimension_basis: statutory-drawing
754
+ background: { color: "#FFFFFF", finish: retroreflective, hex_basis: observed }
755
+ foreground: "#000000"
756
+ colour_conflict:
757
+ text_says: "fundo a vermelho e letras, algarismos, traços e rebordo periférico a preto — a RED ground with black characters (art. 5.º n.º 11)"
758
+ drawing_says: "the Anexo IV Modelo VIII and IX drawings label the plate ground BRANCO RETRORREFLECTOR and add VERMELHO RETRORREFLECTOR as a separate label, apparently for the right-hand class-letter box only"
759
+ recorded: >-
760
+ THE INSTRUMENT CONTRADICTS ITSELF and this dataset does not pick a
761
+ winner. Both readings are from the same Diário da República: the
762
+ enacting sentence in art. 5.º n.º 11 and the annexed drawing it
763
+ points at. `design.background` is recorded as WHITE because that is
764
+ what the drawing — the thing a manufacturer builds from — labels, with
765
+ the red confined to the class-letter field; the enacting sentence is
766
+ preserved verbatim here so a verifier can overturn that choice with one
767
+ look at a photograph. PRD-PLATES §5.3: record disagreements, never
768
+ average them.
769
+ region_encoding: none
770
+ sources:
771
+ - "https://files.diariodarepublica.pt/1s/2006/06/111a00/40524060.pdf # DL 106/2006: art. 3.º n.º 3 (the class letter), art. 5.º n.º 11 (the red-ground sentence), ANEXO IV Modelos VIII-IX (the drawings that label the ground white), art. 2.º n.º 2 (conditional commencement: 'entram em vigor conjuntamente com a sua regulamentação'). Accessed 2026-08-02"
772
+ - "https://files.diariodarepublica.pt/1s/2020/01/00900/0000400012.pdf # DL 2/2020 art. 5.º n.º 11 as amended: the same red-ground wording, models moved to Anexo V VII-VIII. Accessed 2026-08-02"
773
+ notes: >-
774
+ MÁQUINAS INDUSTRIAIS E MÁQUINAS INDUSTRIAIS REBOCÁVEIS. CLASS CAVEAT: the
775
+ controlled vocabulary has no works/industrial-machinery class, and
776
+ `agricultural` is the same compromise es-special-vehicles-1999 records for
777
+ the same reason — the statutory category is broader than farming. Flagged
778
+ as a vocabulary gap, and the second file in this dataset to flag it, which
779
+ is the point at which it becomes worth a vocabulary PR. Commencement is
780
+ conditional in the same way as the moped series ("entram em vigor
781
+ conjuntamente com a sua regulamentação"), hence `enabling-instrument`.
782
+
783
+ # =========================================================================
784
+ # STATE FLEETS — no primary reached. Authored from a secondary, tagged.
785
+ # =========================================================================
786
+ - id: pt-military
787
+ class: military
788
+ categories: [car, van, truck, bus, motorcycle, trailer]
789
+ period: { start: 2005 }
790
+ period_evidence: secondary-wikipedia
791
+ matching: recall-only
792
+ format:
793
+ pattern: "MG-99-99"
794
+ regex: '\A(?:MG|ME|MX|AM|AP)[- ]\d{2}[- ]\d{2}\z'
795
+ pattern_note: >-
796
+ `pattern` spells one branch of the prefix alternation (MG, the Army)
797
+ because the human-pattern DSL has no alternation and the lint
798
+ round-trips every pattern-generated serial against `regex`; the other
799
+ four prefixes are equally in `regex` and equally representative.
800
+ WHOLLY `secondary-wikipedia`. The Portuguese armed forces register
801
+ outside the Regulamento de Matrícula — DL 54/2005 art. 8.º n.º 2 shows
802
+ the civil registrar dealing with "entidades militares" as an external
803
+ applicant, and no Defence instrument was reached in this pass. Wikipedia
804
+ gives the branch prefixes as MG, ME and MX for the Army, AP for the Navy
805
+ and AM for the Air Force; it gives no digit grammar, so the two-by-two
806
+ digit shape here is this dataset's own conservative rendering and NOT a
807
+ claim. `recall-only`, and a match means only "this looks like a
808
+ Portuguese military prefix".
809
+ design:
810
+ note: "no colour, dimension or model is recorded — the Regulamento does not cover these plates and no Defence instrument was reached. Deliberately absent rather than guessed."
811
+ region_encoding: none
812
+ sources:
813
+ - "https://pt.wikipedia.org/wiki/Matr%C3%ADculas_de_autom%C3%B3veis_em_Portugal # secondary-wikipedia: MG / ME / MX (Exército), AP (Marinha), AM (Força Aérea). Read 2026-08-02"
814
+ - "https://files.diariodarepublica.pt/1s/2005/03/044a00/18921897.pdf # DL 54/2005 art. 8.º n.º 2 — the civil register treats military entities as external applicants for supplementary numbers, which is the primary evidence that a separate military register exists"
815
+ notes: >-
816
+ ARMED FORCES. The whole entry is a tagged secondary and it says so three
817
+ times, because the alternative was to omit a class every other L1
818
+ jurisdiction in this dataset carries. Period start 2005 is the DATASET's
819
+ observation window, not a claim about when military prefixes began — the
820
+ series is certainly far older. A verifier should treat every field here as
821
+ unconfirmed and start from the Ministério da Defesa Nacional's own
822
+ regulations, which are the missing primary.
823
+
824
+ - id: pt-police-gnr
825
+ class: police
826
+ categories: [car, van, truck, motorcycle]
827
+ period: { start: 2005 }
828
+ period_evidence: secondary-wikipedia
829
+ matching: recall-only
830
+ format:
831
+ pattern: "GNR L-99"
832
+ regex: '\AGNR[- ][A-Z][- ]\d{2,4}\z'
833
+ pattern_note: >-
834
+ `secondary-wikipedia`: the Guarda Nacional Republicana is reported to
835
+ plate its vehicles as the letters GNR followed by a single letter and a
836
+ two-, three- or four-digit serial. No primary was reached. `recall-only`.
837
+ design:
838
+ note: "not recorded — no primary. See pt-military."
839
+ region_encoding: none
840
+ sources:
841
+ - "https://pt.wikipedia.org/wiki/Matr%C3%ADculas_de_autom%C3%B3veis_em_Portugal # secondary-wikipedia: GNR plates as GNR + letter + 2-4 digits. Read 2026-08-02"
842
+ notes: >-
843
+ GUARDA NACIONAL REPUBLICANA. Same posture as pt-military: tagged
844
+ secondary, recall-only, design absent. Note what is NOT here — the PSP
845
+ (Polícia de Segurança Pública) and the municipal police forces, for which
846
+ no source of any tier was located. Their absence is a gap, not a claim
847
+ that they use ordinary plates.