@finbheara/domain 0.13.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/age.js +14 -4
- package/dist/chunks/{place-17e26rga.js → place-2hdp50r3.js} +351 -7
- package/dist/person.js +3 -3
- package/dist/place.js +1 -1
- package/dist/promotion.js +48 -1
- package/dist/school.js +3 -2
- package/dist/types/person.d.ts +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -271,7 +271,7 @@ Age.fromTitle("Beginner Adults Reel U40").token; // "adult u40": the adul
|
|
|
271
271
|
Age.fromTitle("Solo Championship - Adult O40").token; // "adult o40": adult, and 40 or over
|
|
272
272
|
Age.fromTitle("Adult Championship 18 - 29").token; // "adult 18-29": adult, and the range
|
|
273
273
|
Age.fromTitle("Adult / Child Reel Under 10").token; // "u10": no adult dances in it
|
|
274
|
-
Age.fromTitle("Senior Adult Ladies 19 & Over").token; // "
|
|
274
|
+
Age.fromTitle("Senior Adult Ladies 19 & Over").token; // "o19": TIDA's oldest youth championship
|
|
275
275
|
Age.fromTitle("Senior Adult Men 17 & Over").token; // "o17": it admits under-18s
|
|
276
276
|
Age.fromTitle("Championship (Adult) (A40U)").token; // "adult u40": a split adult code
|
|
277
277
|
Age.fromTitle("Traditional Set (A40O)").token; // "adult o40"
|
|
@@ -288,10 +288,10 @@ An adult word beside an and-over from 18 or a range from 18 reads both as well:
|
|
|
288
288
|
`adult 18-29` are adult (`isAdult()`), and their `kind`, interval and birth years are the ones the
|
|
289
289
|
band alone reads on the same ladder, a range floored at 18 where no rung sits below it. So
|
|
290
290
|
`Age.from("adult o40", { year: 2026 })` is born 1985 or earlier, as `o40` is. An and-over under
|
|
291
|
-
18 or a range opening under 18 (`Teen & Adult 13 & Over`) admits youth, and the band stands.
|
|
292
|
-
|
|
293
|
-
`Senior Adult Ladies 19 & Over` is `
|
|
294
|
-
`(A40U)` is `adult u40`, `(A40O)` and `(A40&O)` are `adult o40`.
|
|
291
|
+
18 or a range opening under 18 (`Teen & Adult 13 & Over`) admits youth, and the band stands. TIDA's
|
|
292
|
+
`Senior Adult` beside an and-over is its oldest youth championship, an open championship that
|
|
293
|
+
qualifies for the Worlds, so `Senior Adult Ladies 19 & Over` is `o19`. A closing split
|
|
294
|
+
adult code keeps its split: `(A40U)` is `adult u40`, `(A40O)` and `(A40&O)` are `adult o40`.
|
|
295
295
|
|
|
296
296
|
`adultBeside(band)` is that reading as one function, the band beside the adult word as one token,
|
|
297
297
|
or `undefined` where the band admits youth. A caller holding a band from another field asks it: a
|
package/dist/age.js
CHANGED
|
@@ -4,14 +4,16 @@ import {
|
|
|
4
4
|
|
|
5
5
|
var LEAD_ID = /^\s*(?:comp(?:etition)?\.?\s*)?\d+[a-z]*(?:[/-]\d*[a-z]*)*\s*[-:.]?\s*/i;
|
|
6
6
|
var PAREN = /\(([^)]*)\)/g;
|
|
7
|
-
var AND_OVER = /(?<![a-z0-9])(\d{1,2})\s*(?:years?\s*)?(?:&|\+|\band\b)\s*(?:over|older|up|o)(?![a-z])/i;
|
|
8
|
-
var OVER_WORD = /(?:\bover\s*|\bos\s+cionn\s*|(?<![a-z0-9])o
|
|
7
|
+
var AND_OVER = /(?<![0-9])(?<![0-9][a-z]*)(?<!(?:^|[^a-z0-9])[a-z])(\d{1,2})\s*(?:years?\s*)?(?:&|\+|\band\b)\s*(?:over|older|up|o)(?![a-z])/i;
|
|
8
|
+
var OVER_WORD = /(?:\bover\s*|\bos\s+cionn\s*|(?<![a-z0-9])o[./]?\s*)(\d{1,2})(?![a-z0-9])/i;
|
|
9
9
|
var OVER_GLUED = /(?<![a-z0-9])(\d{1,2})\s*o(?![a-z'’])/i;
|
|
10
10
|
var OVER_PLUS = /(?<![a-z0-9])(\d{1,2})\s*\+/;
|
|
11
|
-
var UNDER = /(?:\bunder\s
|
|
11
|
+
var UNDER = /(?:\bunder\s*(?:age\s*)?|\bfaoi\s*|(?<![a-z0-9])u\.?\s*)(\d{1,2})(?![0-9])(?![a-z][a-z0-9])/i;
|
|
12
12
|
var AND_UNDER = /(?<![a-z0-9])(\d{1,2})\s*(?:years?\s*)?(?:&|\/|\band\b)\s*u(?:nder)?(?![a-z])(?!\s*\d)/i;
|
|
13
13
|
var AND_UNDER_RANGE = /(?<![a-z0-9])(\d{1,2})\s*(?:&|\band\b)\s*under\s*(\d{1,2})(?![a-z0-9])/i;
|
|
14
14
|
var AND_RANGE = /(?<![a-z0-9])(?<!\b(?:under|und|over|faoi|cionn|u|o)\.?\s*)(?<!\d\s*,\s*)(?<!\(\s*)(\d{1,2})\s*(?:&|\band\b)\s*(\d{1,2})(?![a-z0-9])(?!\s*-?\s*hand)(?!\s*(?:&|\+|\/|,|\)|\band\b|\bor\b))/i;
|
|
15
|
+
var SLASH_RANGE = /(?<![a-z0-9/])(\d{1,2})\s*\/\s*(\d{1,2})(?=\s*(?:years?|yrs?|boys?|girls?|ladies|men)\b)/i;
|
|
16
|
+
var AGE_N = /(?<!\b(?:under|over)\s*)\bage\s*(\d{1,2})(?![a-z0-9])(?!\s*-?\s*hand)/i;
|
|
15
17
|
var YEARS = /(?<![a-z0-9])(?<!\d\s*(?:&|\/|\band\b|[-\u0096–—]|\bto\b)\s*)(\d{1,2})\s*(?:years?|yrs?)(?![a-z0-9])(?!\s*(?:&|\+|\/|\band\b|\bor\b|old))/i;
|
|
16
18
|
var RANGE_DASH = String.raw`(?:\u00c2?[-\u0096–—]|\bto\b)`;
|
|
17
19
|
var RANGE = new RegExp(String.raw`(?<![0-9])(?<![0-9][a-z]*)(?<!(?:^|[^a-z0-9])[a-z])(?:u\s*)?(\d{1,2})\s*${RANGE_DASH}\s*(\d{1,2})(?![a-z0-9])`, "i");
|
|
@@ -28,6 +30,8 @@ function at(title, offset, start, end, token) {
|
|
|
28
30
|
return { token, span: { start: a, end: b, text: title.slice(a, b) } };
|
|
29
31
|
}
|
|
30
32
|
function inFence(a, b) {
|
|
33
|
+
if (a.startsWith("0") || b.startsWith("0"))
|
|
34
|
+
return false;
|
|
31
35
|
const lo = Number(a);
|
|
32
36
|
const hi = Number(b);
|
|
33
37
|
return lo >= TITLE_RANGE_MIN && hi <= TITLE_RANGE_MAX && lo < hi;
|
|
@@ -44,6 +48,9 @@ function readAnchored(title, s, offset, aside = false) {
|
|
|
44
48
|
const j = aside ? null : AND_RANGE.exec(s);
|
|
45
49
|
if (j?.[1] !== undefined && j[2] !== undefined && inFence(j[1], j[2]))
|
|
46
50
|
return at(title, offset, j.index, j.index + j[0].length, `${Number(j[1])}-${Number(j[2])}`);
|
|
51
|
+
const sl = aside ? null : SLASH_RANGE.exec(s);
|
|
52
|
+
if (sl?.[1] !== undefined && sl[2] !== undefined && inFence(sl[1], sl[2]) && Number(sl[2]) === Number(sl[1]) + 1)
|
|
53
|
+
return at(title, offset, sl.index, sl.index + sl[0].length, `${Number(sl[1])}-${Number(sl[2])}`);
|
|
47
54
|
const l = LEAD_RANGE.exec(s);
|
|
48
55
|
if (l?.[1] !== undefined && l[2] !== undefined && inFence(l[1], l[2])) {
|
|
49
56
|
const lead = l[0].length - l[0].trimStart().length;
|
|
@@ -60,7 +67,7 @@ function readAnchored(title, s, offset, aside = false) {
|
|
|
60
67
|
const m = UNDER.exec(s);
|
|
61
68
|
if (m?.[1] !== undefined)
|
|
62
69
|
return at(title, offset, m.index, m.index + m[0].length, `u${Number(m[1])}`);
|
|
63
|
-
const y = YEARS.exec(s);
|
|
70
|
+
const y = YEARS.exec(s) ?? AGE_N.exec(s);
|
|
64
71
|
if (y?.[1] !== undefined)
|
|
65
72
|
return at(title, offset, y.index, y.index + y[0].length, `u${Number(y[1]) + 1}`);
|
|
66
73
|
const p = OVER_PLUS.exec(s);
|
|
@@ -111,6 +118,7 @@ function ageTitleToken(title) {
|
|
|
111
118
|
return adultAside !== null && (words.token === "" || words.token === "adult") ? adultAside : adultOverUnder(title, s, lead, words);
|
|
112
119
|
}
|
|
113
120
|
var ADULT_UNDER_MIN = 18;
|
|
121
|
+
var SENIOR_ADULT_OVER = /\bsenior\s+adult\b/i;
|
|
114
122
|
function adultBeside(band) {
|
|
115
123
|
const b = band.trim().toLowerCase();
|
|
116
124
|
if (b === "")
|
|
@@ -132,6 +140,8 @@ function adultOverUnder(title, s, lead, t) {
|
|
|
132
140
|
const a = ADULT.exec(s);
|
|
133
141
|
if (a === null)
|
|
134
142
|
return t;
|
|
143
|
+
if (/^o\d+$/.test(t.token) && SENIOR_ADULT_OVER.test(s))
|
|
144
|
+
return t;
|
|
135
145
|
const token = adultBeside(t.token);
|
|
136
146
|
if (token === undefined || token === t.token)
|
|
137
147
|
return t;
|
|
@@ -95,7 +95,7 @@ var PLACE_NODES = [
|
|
|
95
95
|
name: "Cúige Chonnacht / Connacht",
|
|
96
96
|
geo: "IRL",
|
|
97
97
|
admin: "world",
|
|
98
|
-
prints: ["chonnacht", "connacht", "connaght", "connaught", "cuige chonnacht"],
|
|
98
|
+
prints: ["chonnacht", "connacht", "connaght", "connaught", "cuige chonnacht", "cuige connacht"],
|
|
99
99
|
codes: ["CONNACHT"],
|
|
100
100
|
oireachtas: "CONNACHT"
|
|
101
101
|
},
|
|
@@ -381,7 +381,7 @@ var PLACE_NODES = [
|
|
|
381
381
|
name: "Cúige Uladh / Ulster",
|
|
382
382
|
geo: "IRL",
|
|
383
383
|
admin: "world",
|
|
384
|
-
prints: ["cuige uladh", "cuige uldah", "uladh", "ulster"],
|
|
384
|
+
prints: ["cuige uladh", "cuige uldah", "cuige ulster", "uladh", "ulster"],
|
|
385
385
|
codes: ["ULSTER"],
|
|
386
386
|
oireachtas: "ULSTER"
|
|
387
387
|
},
|
|
@@ -3575,6 +3575,276 @@ var PLACE_NODES = [
|
|
|
3575
3575
|
prints: ["warwickshire"],
|
|
3576
3576
|
codes: ["GB-WAR", "GBR-WAR"]
|
|
3577
3577
|
},
|
|
3578
|
+
{
|
|
3579
|
+
id: "GBR-BDF",
|
|
3580
|
+
kind: "subdivision",
|
|
3581
|
+
name: "Bedfordshire",
|
|
3582
|
+
geo: "GBR-ENG",
|
|
3583
|
+
admin: null,
|
|
3584
|
+
prints: ["bedfordshire"],
|
|
3585
|
+
codes: ["GB-BDF", "GBR-BDF"],
|
|
3586
|
+
listedCutsOnly: true
|
|
3587
|
+
},
|
|
3588
|
+
{
|
|
3589
|
+
id: "GBR-BKM",
|
|
3590
|
+
kind: "subdivision",
|
|
3591
|
+
name: "Buckinghamshire",
|
|
3592
|
+
geo: "GBR-ENG",
|
|
3593
|
+
admin: null,
|
|
3594
|
+
prints: ["buckinghamshire"],
|
|
3595
|
+
codes: ["GB-BKM", "GBR-BKM"],
|
|
3596
|
+
listedCutsOnly: true
|
|
3597
|
+
},
|
|
3598
|
+
{
|
|
3599
|
+
id: "GBR-BRK",
|
|
3600
|
+
kind: "subdivision",
|
|
3601
|
+
name: "Berkshire",
|
|
3602
|
+
geo: "GBR-ENG",
|
|
3603
|
+
admin: null,
|
|
3604
|
+
prints: ["berkshire"],
|
|
3605
|
+
codes: [],
|
|
3606
|
+
listedCutsOnly: true
|
|
3607
|
+
},
|
|
3608
|
+
{
|
|
3609
|
+
id: "GBR-CAM",
|
|
3610
|
+
kind: "subdivision",
|
|
3611
|
+
name: "Cambridgeshire",
|
|
3612
|
+
geo: "GBR-ENG",
|
|
3613
|
+
admin: null,
|
|
3614
|
+
prints: ["cambridgeshire"],
|
|
3615
|
+
codes: ["GB-CAM", "GBR-CAM"],
|
|
3616
|
+
listedCutsOnly: true
|
|
3617
|
+
},
|
|
3618
|
+
{
|
|
3619
|
+
id: "GBR-DUR",
|
|
3620
|
+
kind: "subdivision",
|
|
3621
|
+
name: "County Durham",
|
|
3622
|
+
geo: "GBR-ENG",
|
|
3623
|
+
admin: null,
|
|
3624
|
+
prints: ["co durham", "county durham", "durham"],
|
|
3625
|
+
codes: ["GB-DUR", "GBR-DUR"],
|
|
3626
|
+
listedCutsOnly: true
|
|
3627
|
+
},
|
|
3628
|
+
{
|
|
3629
|
+
id: "GBR-ERY",
|
|
3630
|
+
kind: "subdivision",
|
|
3631
|
+
name: "East Riding of Yorkshire",
|
|
3632
|
+
geo: "GBR-ENG",
|
|
3633
|
+
admin: null,
|
|
3634
|
+
prints: ["east riding", "east riding of yorkshire", "east riding yorkshire"],
|
|
3635
|
+
codes: ["GB-ERY", "GBR-ERY"],
|
|
3636
|
+
listedCutsOnly: true
|
|
3637
|
+
},
|
|
3638
|
+
{
|
|
3639
|
+
id: "GBR-ESX",
|
|
3640
|
+
kind: "subdivision",
|
|
3641
|
+
name: "East Sussex",
|
|
3642
|
+
geo: "GBR-ENG",
|
|
3643
|
+
admin: null,
|
|
3644
|
+
prints: ["east sussex"],
|
|
3645
|
+
codes: ["GB-ESX", "GBR-ESX"],
|
|
3646
|
+
listedCutsOnly: true
|
|
3647
|
+
},
|
|
3648
|
+
{
|
|
3649
|
+
id: "GBR-GTL",
|
|
3650
|
+
kind: "subdivision",
|
|
3651
|
+
name: "Greater London",
|
|
3652
|
+
geo: "GBR-ENG",
|
|
3653
|
+
admin: null,
|
|
3654
|
+
prints: ["greater london"],
|
|
3655
|
+
codes: [],
|
|
3656
|
+
listedCutsOnly: true
|
|
3657
|
+
},
|
|
3658
|
+
{
|
|
3659
|
+
id: "GBR-GTM",
|
|
3660
|
+
kind: "subdivision",
|
|
3661
|
+
name: "Greater Manchester",
|
|
3662
|
+
geo: "GBR-ENG",
|
|
3663
|
+
admin: null,
|
|
3664
|
+
prints: ["greater manchester"],
|
|
3665
|
+
codes: [],
|
|
3666
|
+
listedCutsOnly: true
|
|
3667
|
+
},
|
|
3668
|
+
{
|
|
3669
|
+
id: "GBR-HAM",
|
|
3670
|
+
kind: "subdivision",
|
|
3671
|
+
name: "Hampshire",
|
|
3672
|
+
geo: "GBR-ENG",
|
|
3673
|
+
admin: null,
|
|
3674
|
+
prints: ["hampshire"],
|
|
3675
|
+
codes: ["GB-HAM", "GBR-HAM"],
|
|
3676
|
+
listedCutsOnly: true
|
|
3677
|
+
},
|
|
3678
|
+
{
|
|
3679
|
+
id: "GBR-IOW",
|
|
3680
|
+
kind: "subdivision",
|
|
3681
|
+
name: "Isle of Wight",
|
|
3682
|
+
geo: "GBR-ENG",
|
|
3683
|
+
admin: null,
|
|
3684
|
+
prints: ["isle of wight"],
|
|
3685
|
+
codes: ["GB-IOW", "GBR-IOW"],
|
|
3686
|
+
listedCutsOnly: true
|
|
3687
|
+
},
|
|
3688
|
+
{
|
|
3689
|
+
id: "GBR-KEN",
|
|
3690
|
+
kind: "subdivision",
|
|
3691
|
+
name: "Kent",
|
|
3692
|
+
geo: "GBR-ENG",
|
|
3693
|
+
admin: null,
|
|
3694
|
+
prints: ["kent"],
|
|
3695
|
+
codes: ["GB-KEN", "GBR-KEN"],
|
|
3696
|
+
listedCutsOnly: true
|
|
3697
|
+
},
|
|
3698
|
+
{
|
|
3699
|
+
id: "GBR-LIN",
|
|
3700
|
+
kind: "subdivision",
|
|
3701
|
+
name: "Lincolnshire",
|
|
3702
|
+
geo: "GBR-ENG",
|
|
3703
|
+
admin: null,
|
|
3704
|
+
prints: ["lincolnshire"],
|
|
3705
|
+
codes: ["GB-LIN", "GBR-LIN"],
|
|
3706
|
+
listedCutsOnly: true
|
|
3707
|
+
},
|
|
3708
|
+
{
|
|
3709
|
+
id: "GBR-NBL",
|
|
3710
|
+
kind: "subdivision",
|
|
3711
|
+
name: "Northumberland",
|
|
3712
|
+
geo: "GBR-ENG",
|
|
3713
|
+
admin: null,
|
|
3714
|
+
prints: ["northumberland"],
|
|
3715
|
+
codes: ["GB-NBL", "GBR-NBL"],
|
|
3716
|
+
listedCutsOnly: true
|
|
3717
|
+
},
|
|
3718
|
+
{
|
|
3719
|
+
id: "GBR-NTH",
|
|
3720
|
+
kind: "subdivision",
|
|
3721
|
+
name: "Northamptonshire",
|
|
3722
|
+
geo: "GBR-ENG",
|
|
3723
|
+
admin: null,
|
|
3724
|
+
prints: ["northamptonshire", "northants"],
|
|
3725
|
+
codes: ["GB-NTH", "GBR-NTH"],
|
|
3726
|
+
listedCutsOnly: true
|
|
3727
|
+
},
|
|
3728
|
+
{
|
|
3729
|
+
id: "GBR-NTT",
|
|
3730
|
+
kind: "subdivision",
|
|
3731
|
+
name: "Nottinghamshire",
|
|
3732
|
+
geo: "GBR-ENG",
|
|
3733
|
+
admin: null,
|
|
3734
|
+
prints: ["nottinghamshire"],
|
|
3735
|
+
codes: ["GB-NTT", "GBR-NTT"],
|
|
3736
|
+
listedCutsOnly: true
|
|
3737
|
+
},
|
|
3738
|
+
{
|
|
3739
|
+
id: "GBR-NYK",
|
|
3740
|
+
kind: "subdivision",
|
|
3741
|
+
name: "North Yorkshire",
|
|
3742
|
+
geo: "GBR-ENG",
|
|
3743
|
+
admin: null,
|
|
3744
|
+
prints: ["n yorkshire", "north yorkshire"],
|
|
3745
|
+
codes: ["GB-NYK", "GBR-NYK"],
|
|
3746
|
+
listedCutsOnly: true
|
|
3747
|
+
},
|
|
3748
|
+
{
|
|
3749
|
+
id: "GBR-OXF",
|
|
3750
|
+
kind: "subdivision",
|
|
3751
|
+
name: "Oxfordshire",
|
|
3752
|
+
geo: "GBR-ENG",
|
|
3753
|
+
admin: null,
|
|
3754
|
+
prints: ["oxfordshire"],
|
|
3755
|
+
codes: ["GB-OXF", "GBR-OXF"],
|
|
3756
|
+
listedCutsOnly: true
|
|
3757
|
+
},
|
|
3758
|
+
{
|
|
3759
|
+
id: "GBR-RUT",
|
|
3760
|
+
kind: "subdivision",
|
|
3761
|
+
name: "Rutland",
|
|
3762
|
+
geo: "GBR-ENG",
|
|
3763
|
+
admin: null,
|
|
3764
|
+
prints: ["rutland"],
|
|
3765
|
+
codes: ["GB-RUT", "GBR-RUT"],
|
|
3766
|
+
listedCutsOnly: true
|
|
3767
|
+
},
|
|
3768
|
+
{
|
|
3769
|
+
id: "GBR-SOM",
|
|
3770
|
+
kind: "subdivision",
|
|
3771
|
+
name: "Somerset",
|
|
3772
|
+
geo: "GBR-ENG",
|
|
3773
|
+
admin: null,
|
|
3774
|
+
prints: ["somerset"],
|
|
3775
|
+
codes: ["GB-SOM", "GBR-SOM"],
|
|
3776
|
+
listedCutsOnly: true
|
|
3777
|
+
},
|
|
3778
|
+
{
|
|
3779
|
+
id: "GBR-SYK",
|
|
3780
|
+
kind: "subdivision",
|
|
3781
|
+
name: "South Yorkshire",
|
|
3782
|
+
geo: "GBR-ENG",
|
|
3783
|
+
admin: null,
|
|
3784
|
+
prints: ["s yorkshire", "south yorks", "south yorkshire"],
|
|
3785
|
+
codes: [],
|
|
3786
|
+
listedCutsOnly: true
|
|
3787
|
+
},
|
|
3788
|
+
{
|
|
3789
|
+
id: "GBR-TWR",
|
|
3790
|
+
kind: "subdivision",
|
|
3791
|
+
name: "Tyne and Wear",
|
|
3792
|
+
geo: "GBR-ENG",
|
|
3793
|
+
admin: null,
|
|
3794
|
+
prints: ["tyne and wear", "tyne wear"],
|
|
3795
|
+
codes: [],
|
|
3796
|
+
listedCutsOnly: true
|
|
3797
|
+
},
|
|
3798
|
+
{
|
|
3799
|
+
id: "GBR-WIL",
|
|
3800
|
+
kind: "subdivision",
|
|
3801
|
+
name: "Wiltshire",
|
|
3802
|
+
geo: "GBR-ENG",
|
|
3803
|
+
admin: null,
|
|
3804
|
+
prints: ["wiltshire"],
|
|
3805
|
+
codes: ["GB-WIL", "GBR-WIL"],
|
|
3806
|
+
listedCutsOnly: true
|
|
3807
|
+
},
|
|
3808
|
+
{
|
|
3809
|
+
id: "GBR-WMD",
|
|
3810
|
+
kind: "subdivision",
|
|
3811
|
+
name: "West Midlands",
|
|
3812
|
+
geo: "GBR-ENG",
|
|
3813
|
+
admin: null,
|
|
3814
|
+
prints: ["w midlands", "west midlands"],
|
|
3815
|
+
codes: [],
|
|
3816
|
+
listedCutsOnly: true
|
|
3817
|
+
},
|
|
3818
|
+
{
|
|
3819
|
+
id: "GBR-WOR",
|
|
3820
|
+
kind: "subdivision",
|
|
3821
|
+
name: "Worcestershire",
|
|
3822
|
+
geo: "GBR-ENG",
|
|
3823
|
+
admin: null,
|
|
3824
|
+
prints: ["worcestershire"],
|
|
3825
|
+
codes: ["GB-WOR", "GBR-WOR"],
|
|
3826
|
+
listedCutsOnly: true
|
|
3827
|
+
},
|
|
3828
|
+
{
|
|
3829
|
+
id: "GBR-WSX",
|
|
3830
|
+
kind: "subdivision",
|
|
3831
|
+
name: "West Sussex",
|
|
3832
|
+
geo: "GBR-ENG",
|
|
3833
|
+
admin: null,
|
|
3834
|
+
prints: ["west sussex"],
|
|
3835
|
+
codes: ["GB-WSX", "GBR-WSX"],
|
|
3836
|
+
listedCutsOnly: true
|
|
3837
|
+
},
|
|
3838
|
+
{
|
|
3839
|
+
id: "GBR-WYK",
|
|
3840
|
+
kind: "subdivision",
|
|
3841
|
+
name: "West Yorkshire",
|
|
3842
|
+
geo: "GBR-ENG",
|
|
3843
|
+
admin: null,
|
|
3844
|
+
prints: ["w yorkshire", "west yorkshire"],
|
|
3845
|
+
codes: [],
|
|
3846
|
+
listedCutsOnly: true
|
|
3847
|
+
},
|
|
3578
3848
|
{
|
|
3579
3849
|
id: "GBR-NIR",
|
|
3580
3850
|
kind: "subdivision",
|
|
@@ -6943,9 +7213,11 @@ function createPlaceReader2(options = {}) {
|
|
|
6943
7213
|
ancestorsOf.set(n.id, out);
|
|
6944
7214
|
}
|
|
6945
7215
|
const phrases = [...byPrint.keys()].filter((k) => k.includes(" ")).sort((a, b) => b.length - a.length);
|
|
7216
|
+
const printsSorted = [...byPrint.keys()].map((k, i) => [k, i]).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
6946
7217
|
return {
|
|
6947
7218
|
byId,
|
|
6948
7219
|
byPrint,
|
|
7220
|
+
printsSorted,
|
|
6949
7221
|
byCode,
|
|
6950
7222
|
byTruncation,
|
|
6951
7223
|
byCountryCode,
|
|
@@ -7190,13 +7462,32 @@ function createPlaceReader2(options = {}) {
|
|
|
7190
7462
|
function completions(folded) {
|
|
7191
7463
|
if (folded.length < MIN_STEM)
|
|
7192
7464
|
return [];
|
|
7465
|
+
const i = idx();
|
|
7466
|
+
const sorted = i.printsSorted;
|
|
7467
|
+
let lo = 0;
|
|
7468
|
+
let hi = sorted.length;
|
|
7469
|
+
while (lo < hi) {
|
|
7470
|
+
const mid = lo + hi >>> 1;
|
|
7471
|
+
if (sorted[mid][0] < folded)
|
|
7472
|
+
lo = mid + 1;
|
|
7473
|
+
else
|
|
7474
|
+
hi = mid;
|
|
7475
|
+
}
|
|
7476
|
+
const run = [];
|
|
7477
|
+
for (let k = lo;k < sorted.length; k++) {
|
|
7478
|
+
const at = sorted[k];
|
|
7479
|
+
if (!at[0].startsWith(folded))
|
|
7480
|
+
break;
|
|
7481
|
+
run.push(at);
|
|
7482
|
+
}
|
|
7483
|
+
run.sort((a, b) => a[1] - b[1]);
|
|
7193
7484
|
const out = [];
|
|
7194
|
-
for (const [key
|
|
7195
|
-
if (key.length <= folded.length
|
|
7485
|
+
for (const [key] of run) {
|
|
7486
|
+
if (key.length <= folded.length)
|
|
7196
7487
|
continue;
|
|
7197
7488
|
if (key[folded.length] === " ")
|
|
7198
7489
|
continue;
|
|
7199
|
-
for (const n of
|
|
7490
|
+
for (const n of i.byPrint.get(key))
|
|
7200
7491
|
if (n.kind !== "body" && n.listedCutsOnly !== true)
|
|
7201
7492
|
out.push({ node: n, length: key.length });
|
|
7202
7493
|
}
|
|
@@ -7288,6 +7579,10 @@ function createPlaceReader2(options = {}) {
|
|
|
7288
7579
|
return false;
|
|
7289
7580
|
if (a.kind === b.kind)
|
|
7290
7581
|
return true;
|
|
7582
|
+
const sub = a.kind === "subdivision" ? a : b.kind === "subdivision" ? b : undefined;
|
|
7583
|
+
const town = a.kind === "city" ? a : b.kind === "city" ? b : undefined;
|
|
7584
|
+
if (sub !== undefined && town !== undefined && town.geo !== null && town.geo === sub.geo)
|
|
7585
|
+
return true;
|
|
7291
7586
|
const ca = countryOf(a);
|
|
7292
7587
|
const cb = countryOf(b);
|
|
7293
7588
|
return ca === undefined || cb === undefined || ca.id !== cb.id;
|
|
@@ -7322,7 +7617,9 @@ function createPlaceReader2(options = {}) {
|
|
|
7322
7617
|
break;
|
|
7323
7618
|
}
|
|
7324
7619
|
if (!plural) {
|
|
7325
|
-
const
|
|
7620
|
+
const tail = reads[reads.length - 1]?.heads ?? [];
|
|
7621
|
+
const closes = (m) => m.kind === "subdivision" && tail.length === 1 && tail[0]?.id === m.id && members.length > 2 && members.every((o) => onTheMap(m, o));
|
|
7622
|
+
const spent = members.filter((m) => m.kind === "country" && members.some((o) => o.id !== m.id && isAncestor(m, o)) || closes(m));
|
|
7326
7623
|
const inner = members.filter((m) => !spent.includes(m));
|
|
7327
7624
|
let apart = inner.length > 1 && spent.length > 0;
|
|
7328
7625
|
for (let a = 0;a < inner.length && apart; a++)
|
|
@@ -7494,6 +7791,19 @@ function createPlaceReader2(options = {}) {
|
|
|
7494
7791
|
});
|
|
7495
7792
|
return abroad ? right : undefined;
|
|
7496
7793
|
}
|
|
7794
|
+
function townInCounty(left, right) {
|
|
7795
|
+
if (left.length === 0 || right.length === 0)
|
|
7796
|
+
return;
|
|
7797
|
+
if (!left.every((l) => l.kind === "city") || !right.every((r) => r.kind === "subdivision"))
|
|
7798
|
+
return;
|
|
7799
|
+
if (left.some((l) => right.some((r) => relates(l, r))))
|
|
7800
|
+
return;
|
|
7801
|
+
const kept = left.filter((l) => {
|
|
7802
|
+
const parent = l.geo === null ? undefined : idx().byId.get(l.geo);
|
|
7803
|
+
return parent !== undefined && right.some((r) => r.id !== parent.id && onTheMap(parent, r));
|
|
7804
|
+
});
|
|
7805
|
+
return kept.length === 0 ? undefined : kept;
|
|
7806
|
+
}
|
|
7497
7807
|
function read(print, declared = false, smushed = true) {
|
|
7498
7808
|
const core = unbracket(repair(print));
|
|
7499
7809
|
if (fold(core) === "")
|
|
@@ -7556,13 +7866,14 @@ function createPlaceReader2(options = {}) {
|
|
|
7556
7866
|
};
|
|
7557
7867
|
}
|
|
7558
7868
|
const qualified = (k) => k === "comma" || k === "space";
|
|
7869
|
+
const listed = (k) => k === "amp" || k === "and" || k === "slash";
|
|
7559
7870
|
const settled = reads.map((r, n) => {
|
|
7560
7871
|
const prev = reads[n - 1];
|
|
7561
7872
|
if (prev === undefined || !qualified(before[n]) || r.truncated)
|
|
7562
7873
|
return;
|
|
7563
7874
|
if (n - 1 > 0 && (qualified(before[n - 1]) || !qualified(before[n - 2])))
|
|
7564
7875
|
return;
|
|
7565
|
-
return qualifierAlone(prev.heads, r.heads);
|
|
7876
|
+
return qualifierAlone(prev.heads, r.heads) ?? (prev.truncated || before[n] !== "comma" || listed(before[n + 1]) ? undefined : townInCounty(prev.heads, r.heads));
|
|
7566
7877
|
});
|
|
7567
7878
|
settled.forEach((heads, n) => {
|
|
7568
7879
|
if (heads === undefined)
|
|
@@ -7820,8 +8131,41 @@ function createPlaceReader2(options = {}) {
|
|
|
7820
8131
|
const base = hit ?? built(print, declared, key);
|
|
7821
8132
|
if (hit !== undefined)
|
|
7822
8133
|
hits++;
|
|
8134
|
+
if (declared && typeof ctx === "object" && base.arm === "unread" && base.refusal === null) {
|
|
8135
|
+
const q = unheldQualifier(print, ctx);
|
|
8136
|
+
if (q !== undefined)
|
|
8137
|
+
return q.refine(ctx);
|
|
8138
|
+
}
|
|
7823
8139
|
return ctx === undefined ? base : base.refine(ctx);
|
|
7824
8140
|
}
|
|
8141
|
+
function unheldQualifier(print, ctx) {
|
|
8142
|
+
const within = [ctx.country, ctx.near].filter((w) => w !== undefined && w.trim() !== "").flatMap((w) => headsOf(w));
|
|
8143
|
+
if (within.length === 0)
|
|
8144
|
+
return;
|
|
8145
|
+
const core = unbracket(repair(print));
|
|
8146
|
+
const pieces = core.split(SEP);
|
|
8147
|
+
for (let k = 0;k < pieces.length; k += 2)
|
|
8148
|
+
if (pieces[k] === "")
|
|
8149
|
+
return;
|
|
8150
|
+
let at = -1;
|
|
8151
|
+
for (let k = pieces.length - 2;k >= 1 && at === -1; k -= 2)
|
|
8152
|
+
if (kindOf(pieces[k]) === "comma")
|
|
8153
|
+
at = k;
|
|
8154
|
+
if (at === -1)
|
|
8155
|
+
return;
|
|
8156
|
+
const tail = read(pieces.slice(at + 1).join(""), true);
|
|
8157
|
+
if (tail.heads.length > 0 || tail.refusal !== null)
|
|
8158
|
+
return;
|
|
8159
|
+
const town = read(pieces.slice(0, at).join(""), true);
|
|
8160
|
+
if (town.refusal !== null || town.truncated || town.members !== undefined)
|
|
8161
|
+
return;
|
|
8162
|
+
if (town.heads.length === 0 || !town.heads.every((n) => n.kind === "city"))
|
|
8163
|
+
return;
|
|
8164
|
+
const kept = town.heads.filter((h) => within.some((w) => isAncestor(w, h)));
|
|
8165
|
+
if (kept.length === 0)
|
|
8166
|
+
return;
|
|
8167
|
+
return build(print, chainsFor(kept), { ...town, heads: kept }, []);
|
|
8168
|
+
}
|
|
7825
8169
|
function heading(print, ctx) {
|
|
7826
8170
|
const held = idx().byHeading.get(fold(repair(print)));
|
|
7827
8171
|
if (held === undefined)
|
package/dist/person.js
CHANGED
|
@@ -106,8 +106,8 @@ class RoleRefusedName {
|
|
|
106
106
|
return true;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
function roleName(role, print, order) {
|
|
110
|
-
const read = personName(print, order);
|
|
109
|
+
function roleName(role, print, order, factory) {
|
|
110
|
+
const read = factory === undefined ? personName(print, order) : factory.parse(print, order);
|
|
111
111
|
const sentinel = MATCHERS[role](print);
|
|
112
112
|
return sentinel === undefined ? read : new RoleRefusedName(read, role, sentinel);
|
|
113
113
|
}
|
|
@@ -116,7 +116,7 @@ function rolePrintsNoName(role, print) {
|
|
|
116
116
|
}
|
|
117
117
|
var dancerPrintsNoName = (print) => rolePrintsNoName("dancer", print);
|
|
118
118
|
var seatName = (print) => roleName("adjudicator", print, "given-first");
|
|
119
|
-
var dancerName = (print, order) => roleName("dancer", print, order);
|
|
119
|
+
var dancerName = (print, order, factory) => roleName("dancer", print, order, factory);
|
|
120
120
|
var teacherName = (print, order) => roleName("teacher", print, order);
|
|
121
121
|
export {
|
|
122
122
|
ADJUDICATOR_SENTINELS,
|
package/dist/place.js
CHANGED
package/dist/promotion.js
CHANGED
|
@@ -46,7 +46,7 @@ function samePromotedRow(was, now) {
|
|
|
46
46
|
}
|
|
47
47
|
var STOOD_FOR = /^(?:'|(?![A-Za-z])\p{L})$/u;
|
|
48
48
|
function questionMarksRead(was, now) {
|
|
49
|
-
const a = [...collapse(mojibakeRead(was))];
|
|
49
|
+
const a = [...collapse(cp437Read(mojibakeRead(was), now))];
|
|
50
50
|
if (!a.includes("?"))
|
|
51
51
|
return a.join("");
|
|
52
52
|
const b = [...collapse(now)];
|
|
@@ -67,6 +67,47 @@ function questionMarksRead(was, now) {
|
|
|
67
67
|
}
|
|
68
68
|
return out.join("");
|
|
69
69
|
}
|
|
70
|
+
var CP437_LETTERS = new Map([
|
|
71
|
+
[128, "Ç"],
|
|
72
|
+
[129, "ü"],
|
|
73
|
+
[130, "é"],
|
|
74
|
+
[131, "â"],
|
|
75
|
+
[132, "ä"],
|
|
76
|
+
[133, "à"],
|
|
77
|
+
[134, "å"],
|
|
78
|
+
[135, "ç"],
|
|
79
|
+
[136, "ê"],
|
|
80
|
+
[137, "ë"],
|
|
81
|
+
[138, "è"],
|
|
82
|
+
[139, "ï"],
|
|
83
|
+
[140, "î"],
|
|
84
|
+
[141, "ì"],
|
|
85
|
+
[142, "Ä"],
|
|
86
|
+
[143, "Å"],
|
|
87
|
+
[144, "É"],
|
|
88
|
+
[145, "æ"],
|
|
89
|
+
[147, "ô"],
|
|
90
|
+
[148, "ö"],
|
|
91
|
+
[149, "ò"],
|
|
92
|
+
[150, "û"],
|
|
93
|
+
[151, "ù"],
|
|
94
|
+
[152, "ÿ"],
|
|
95
|
+
[153, "Ö"],
|
|
96
|
+
[154, "Ü"],
|
|
97
|
+
[160, "á"],
|
|
98
|
+
[161, "í"],
|
|
99
|
+
[162, "ó"],
|
|
100
|
+
[163, "ú"],
|
|
101
|
+
[164, "ñ"],
|
|
102
|
+
[165, "Ñ"]
|
|
103
|
+
].map(([byte, letter]) => [String.fromCodePoint(byte), letter]));
|
|
104
|
+
function cp437Read(was, now) {
|
|
105
|
+
const a = [...was];
|
|
106
|
+
const b = [...now];
|
|
107
|
+
if (a.length !== b.length)
|
|
108
|
+
return was;
|
|
109
|
+
return a.map((x, i) => CP437_LETTERS.get(x) === b[i] ? b[i] : x).join("");
|
|
110
|
+
}
|
|
70
111
|
function mojibakeRead(print) {
|
|
71
112
|
let out = print;
|
|
72
113
|
const codes = [...out].map((c) => c.codePointAt(0) ?? 0);
|
|
@@ -81,6 +122,12 @@ function mojibakeRead(print) {
|
|
|
81
122
|
return out.replace(/\uFFFD/gu, "?");
|
|
82
123
|
}
|
|
83
124
|
function samePromotedName(was, now) {
|
|
125
|
+
if (samePromotedNameRead(was, now))
|
|
126
|
+
return true;
|
|
127
|
+
const soft = was.replace(/\u00c3\u00ad/gu, "?").replace(/\u00ad/gu, "-");
|
|
128
|
+
return soft !== was && samePromotedNameRead(soft, now);
|
|
129
|
+
}
|
|
130
|
+
function samePromotedNameRead(was, now) {
|
|
84
131
|
const read = questionMarksRead(was, now);
|
|
85
132
|
if (read === null)
|
|
86
133
|
return false;
|
package/dist/school.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
areAllPlaceTokens2,
|
|
13
13
|
placeRelation2,
|
|
14
14
|
sameReading2
|
|
15
|
-
} from "./chunks/place-
|
|
15
|
+
} from "./chunks/place-2hdp50r3.js";
|
|
16
16
|
import {
|
|
17
17
|
validity
|
|
18
18
|
} from "./chunks/place-q9kwsmzd.js";
|
|
@@ -1142,8 +1142,9 @@ function createSchoolNameReader(options = {}) {
|
|
|
1142
1142
|
function readSpacingAcute(print) {
|
|
1143
1143
|
return print.replace(SPACING_ACUTE_AFTER_VOWEL, "$1́").replace(SPACING_ACUTE, "'");
|
|
1144
1144
|
}
|
|
1145
|
+
const INJECTED_LINK = /(?<=^|[\s([])(?:https?:\/\/|www\.)[^\s)\]]+/giu;
|
|
1145
1146
|
function renderSn1(print) {
|
|
1146
|
-
return normalizeApostrophes2(readSpacingAcute(repairMojibake(print)).normalize("NFKC")).replace(/\p{Cf}+/gu, "").replace(/\p{Cc}+/gu, " ").replace(/\s+/gu, " ").trim();
|
|
1147
|
+
return normalizeApostrophes2(readSpacingAcute(repairMojibake(print)).normalize("NFKC")).replace(/\p{Cf}+/gu, "").replace(/\p{Cc}+/gu, " ").replace(INJECTED_LINK, " ").replace(/\s+/gu, " ").trim();
|
|
1147
1148
|
}
|
|
1148
1149
|
const COMPOUND_OPENERS = new Set([
|
|
1149
1150
|
"hyphen",
|
package/dist/types/person.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ParseOrder, type PersonName } from "@finbheara/names/normalize";
|
|
1
|
+
import { type ParseOrder, type PersonName, type PersonNameFactory } from "@finbheara/names/normalize";
|
|
2
2
|
import { type RowSentinel } from "./row-sentinels.ts";
|
|
3
3
|
export { SHARED_ROW_SENTINELS, sentinelIn } from "./row-sentinels.ts";
|
|
4
4
|
export type { RowSentinel } from "./row-sentinels.ts";
|
|
@@ -8,9 +8,9 @@ export declare const DANCER_SENTINELS: readonly RowSentinel[];
|
|
|
8
8
|
export declare const TEACHER_SENTINELS: readonly RowSentinel[];
|
|
9
9
|
export declare const ROLE_SENTINELS: Readonly<Record<PersonRole, readonly RowSentinel[]>>;
|
|
10
10
|
export declare function roleSentinelOf(role: PersonRole, print: string): RowSentinel | undefined;
|
|
11
|
-
export declare function roleName(role: PersonRole, print: string, order?: ParseOrder): PersonName;
|
|
11
|
+
export declare function roleName(role: PersonRole, print: string, order?: ParseOrder, factory?: Pick<PersonNameFactory, "parse">): PersonName;
|
|
12
12
|
export declare function rolePrintsNoName(role: PersonRole, print: string): boolean;
|
|
13
13
|
export declare const dancerPrintsNoName: (print: string) => boolean;
|
|
14
14
|
export declare const seatName: (print: string) => PersonName;
|
|
15
|
-
export declare const dancerName: (print: string, order?: ParseOrder) => PersonName;
|
|
15
|
+
export declare const dancerName: (print: string, order?: ParseOrder, factory?: Pick<PersonNameFactory, "parse">) => PersonName;
|
|
16
16
|
export declare const teacherName: (print: string, order?: ParseOrder) => PersonName;
|
package/package.json
CHANGED