@finbheara/domain 0.6.2 → 0.7.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 -3
- package/dist/age.js +13 -2
- package/dist/school.js +8 -1
- package/dist/types/age-types.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -265,12 +265,14 @@ Age.fromTitle("Junior Boys 12 Years").token; // "u13"
|
|
|
265
265
|
Age.fromTitle("10-11 Single Jig").token; // "10-11", a band, not a number
|
|
266
266
|
Age.fromTitle("Competition 001-013 - Reel").token; // "", a competition number
|
|
267
267
|
Age.fromTitle("Senior Boys Reel 15&16").token; // "15-16": a range beats the word
|
|
268
|
-
Age.fromTitle("Beginner Adults Reel U40").token; // "adult":
|
|
268
|
+
Age.fromTitle("Beginner Adults Reel U40").token; // "adult u40": the adult band under 40
|
|
269
269
|
Age.fromTitle("Adult / Child Reel Under 10").token; // "u10": no adult dances in it
|
|
270
270
|
```
|
|
271
271
|
|
|
272
|
-
An adult word beside an `Under N`
|
|
273
|
-
floor
|
|
272
|
+
An adult word beside an `Under N` above 18 reads both: `adult u40` is adult (`isAdult()`), with
|
|
273
|
+
the adult floor of 18 and a ceiling of 40, so `Age.from("adult u40", { year: 2026 })` is born
|
|
274
|
+
1986 to 2007. At `Under 18` the ceiling meets the floor and the word alone is read. Below 18 the
|
|
275
|
+
youth band stands.
|
|
274
276
|
|
|
275
277
|
An age group is the age on the first of January, so a title that admits the dancer who is
|
|
276
278
|
`N` (`7 & Under`, `7/U`, `7 Years`) is the `Under N+1` group.
|
package/dist/age.js
CHANGED
|
@@ -104,7 +104,8 @@ function adultOverUnder(title, s, lead, t) {
|
|
|
104
104
|
if (n === undefined || Number(n) < ADULT_UNDER_MIN)
|
|
105
105
|
return t;
|
|
106
106
|
const a = ADULT.exec(s);
|
|
107
|
-
|
|
107
|
+
const token = Number(n) > ADULT_UNDER_MIN ? `adult u${n}` : "adult";
|
|
108
|
+
return a === null ? t : at(title, lead, a.index, a.index + a[0].length, token);
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
var YOUNGEST_FLOOR = 0;
|
|
@@ -125,6 +126,7 @@ var OVER = /^(?:o|over\s*)(\d+)$/i;
|
|
|
125
126
|
var AND_OVER2 = /^(\d+)\s*(?:&|and\b)\s*(?:over|o)$/i;
|
|
126
127
|
var RANGE2 = /^u?(\d+)\s*[-–]\s*(\d+)$/i;
|
|
127
128
|
var ADULT_WORD = /^(?:adults?|ad|advanced|masters?)$/i;
|
|
129
|
+
var ADULT_UNDER = /^(?:adults?|ad)[\s-]*(?:u|under\s*)(\d+)$/i;
|
|
128
130
|
var SENIOR_WORD = /^seniors?$/i;
|
|
129
131
|
var NO_LADDER = Object.freeze({ caps: [], overs: [], ranges: [] });
|
|
130
132
|
function maxWhere(xs, pred) {
|
|
@@ -182,7 +184,16 @@ function read(token, ladder, top) {
|
|
|
182
184
|
const r = RANGE2.exec(token);
|
|
183
185
|
if (r !== null)
|
|
184
186
|
return readRange(Number(r[1]), Number(r[2]), ladder);
|
|
185
|
-
|
|
187
|
+
const au = ADULT_UNDER.exec(token);
|
|
188
|
+
if (au !== null && Number(au[1]) > ADULT_FLOOR)
|
|
189
|
+
return {
|
|
190
|
+
kind: "adult",
|
|
191
|
+
interval: { lo: ADULT_FLOOR, hi: Number(au[1]) },
|
|
192
|
+
refusal: null,
|
|
193
|
+
clauses: ["adult-under-ceiling"],
|
|
194
|
+
parts: [Number(au[1])]
|
|
195
|
+
};
|
|
196
|
+
if (au !== null || ADULT_WORD.test(token))
|
|
186
197
|
return {
|
|
187
198
|
kind: "adult",
|
|
188
199
|
interval: { lo: ADULT_FLOOR, hi: Number.POSITIVE_INFINITY },
|
package/dist/school.js
CHANGED
|
@@ -1019,6 +1019,13 @@ function createSchoolNameReader(options = {}) {
|
|
|
1019
1019
|
const CP1252_HIGH = "€‚ƒ„…†‡ˆ‰Š‹Œ" + "Ž‘’“”•–—˜™š›" + "œžŸ";
|
|
1020
1020
|
const BYTE_OF_CP1252 = new Map([...CP1252_HIGH].map((ch, i) => [ch.codePointAt(0), 128 + i]));
|
|
1021
1021
|
const MOJIBAKE = /[Â-ßà-ï][-¿‚-›ŒŠŽ]/u;
|
|
1022
|
+
const MOJIBAKE_ALL = new RegExp(MOJIBAKE.source, "gu");
|
|
1023
|
+
const NON_LATIN_LETTER = /(?!\p{Script=Latin})\p{L}/u;
|
|
1024
|
+
function isRepair(before, after) {
|
|
1025
|
+
if (!NON_LATIN_LETTER.test(after))
|
|
1026
|
+
return true;
|
|
1027
|
+
return (before.match(MOJIBAKE_ALL)?.length ?? 0) >= 2;
|
|
1028
|
+
}
|
|
1022
1029
|
function undoMojibake(s) {
|
|
1023
1030
|
const bytes = new Uint8Array(s.length);
|
|
1024
1031
|
for (let i = 0;i < s.length; i++) {
|
|
@@ -1038,7 +1045,7 @@ function createSchoolNameReader(options = {}) {
|
|
|
1038
1045
|
let s = print;
|
|
1039
1046
|
for (let round = 0;round < 3 && MOJIBAKE.test(s); round++) {
|
|
1040
1047
|
const undone = undoMojibake(s);
|
|
1041
|
-
if (undone === undefined || undone === s)
|
|
1048
|
+
if (undone === undefined || undone === s || !isRepair(s, undone))
|
|
1042
1049
|
return s;
|
|
1043
1050
|
s = undone;
|
|
1044
1051
|
}
|
|
@@ -25,7 +25,7 @@ export type AgeArm = "band" | "yob" | "open" | "empty";
|
|
|
25
25
|
export type AgeKind = "under" | "over" | "range" | "adult" | "senior" | "yob";
|
|
26
26
|
export type AgeRefusal = "not-a-band" | "backwards-range" | "overlapping-ranges" | "senior-without-ladder" | "below-youngest-band" | "year-out-of-range";
|
|
27
27
|
export type AgeSource = "sibling-narrowed" | "printed-band" | "printed-range" | "printed-yob" | "open";
|
|
28
|
-
export type AgeClause = "under-floored-on-rung" | "youngest-absorbs" | "over-ceiling-from-next-over" | "over-ceiling-refused-gap" | "and-over-no-ceiling" | "range-overlapping" | "range-as-under" | "range-top-meets-over" | "range-adult-floor";
|
|
28
|
+
export type AgeClause = "under-floored-on-rung" | "youngest-absorbs" | "over-ceiling-from-next-over" | "over-ceiling-refused-gap" | "and-over-no-ceiling" | "adult-under-ceiling" | "range-overlapping" | "range-as-under" | "range-top-meets-over" | "range-adult-floor";
|
|
29
29
|
export type AgeRelation = "same" | "contains" | "overlaps" | "disjoint" | "silent";
|
|
30
30
|
export type AgeRelationReason = "equal" | "a-contains-b" | "b-contains-a" | "partial" | "a-older" | "a-younger" | "a-not-a-band" | "b-not-a-band";
|
|
31
31
|
export interface AgeComparison {
|