@finbheara/domain 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +273 -2
  3. package/dist/age.js +420 -0
  4. package/dist/ceili.js +15 -0
  5. package/dist/chunks/place-7gqecaxd.js +201 -0
  6. package/dist/chunks/place-g6yw4cq6.js +134 -0
  7. package/dist/chunks/place-kr42294h.js +267 -0
  8. package/dist/chunks/place-qbp3xfb4.js +7412 -0
  9. package/dist/clrg-regions.js +603 -0
  10. package/dist/dance-types.js +14 -0
  11. package/dist/dance.js +41 -0
  12. package/dist/noun-index.js +233 -0
  13. package/dist/place.js +36 -0
  14. package/dist/school.js +2269 -0
  15. package/dist/tune.js +23 -0
  16. package/dist/types/age-types.d.ts +31 -0
  17. package/dist/types/age.d.ts +84 -0
  18. package/dist/types/ceili.d.ts +53 -0
  19. package/dist/types/clrg-regions.d.ts +31 -0
  20. package/dist/types/dance-match.d.ts +28 -0
  21. package/dist/types/dance-types.d.ts +9 -0
  22. package/dist/types/dance.d.ts +14 -0
  23. package/dist/types/noun-index.d.ts +67 -0
  24. package/dist/types/place-tree.d.ts +4 -0
  25. package/dist/types/place-types.d.ts +24 -0
  26. package/dist/types/place.d.ts +98 -0
  27. package/dist/types/school-compare.d.ts +39 -0
  28. package/dist/types/school-encoder.d.ts +8 -0
  29. package/dist/types/school-exception-vocabulary.d.ts +23 -0
  30. package/dist/types/school-fluff-vocabulary.d.ts +16 -0
  31. package/dist/types/school-fused-prefix.d.ts +1 -0
  32. package/dist/types/school-identity.d.ts +9 -0
  33. package/dist/types/school-institution-vocabulary.d.ts +20 -0
  34. package/dist/types/school-location.d.ts +16 -0
  35. package/dist/types/school-match-key.d.ts +5 -0
  36. package/dist/types/school-name.d.ts +82 -0
  37. package/dist/types/school-tokens.d.ts +20 -0
  38. package/dist/types/school.d.ts +11 -0
  39. package/dist/types/tune.d.ts +63 -0
  40. package/package.json +73 -5
@@ -0,0 +1,134 @@
1
+ var FUZZY_FLOOR = 0.75;
2
+ var WITHIN_SCORE = 0.9;
3
+ var AROUND_SCORE = 0.85;
4
+ var STOPWORDS = new Set(["the", "a", "an", "of", "dancing"]);
5
+ function foldDancePrint(print) {
6
+ return print.normalize("NFD").replace(/\p{M}/gu, "").toLowerCase().replace(/['’‘´`]s\b/g, "").replace(/['’‘´`]/g, "").replace(/&/g, " and ").replace(/[^a-z0-9 ]/g, " ").split(/\s+/).filter((t) => t !== "" && !STOPWORDS.has(t)).join(" ");
7
+ }
8
+ function splitTempo(print, range = { min: 0, max: 999 }) {
9
+ const inRange = (n) => n >= range.min && n <= range.max;
10
+ const stated = /(?:\b(?:at|beat|speed)\b|@)\s*(\d{2,3})\b/i.exec(print);
11
+ if (stated && inRange(Number(stated[1]))) {
12
+ return {
13
+ rest: `${print.slice(0, stated.index)} ${print.slice(stated.index + stated[0].length)}`,
14
+ bpm: Number(stated[1])
15
+ };
16
+ }
17
+ if (stated)
18
+ return { rest: print, bpm: null };
19
+ const trailing = /(\S*)[\s,]+(\d{2,3})\s*[.!]?\s*$/.exec(print);
20
+ if (trailing && trailing.index >= 0 && (trailing[1] ?? "") !== "") {
21
+ const before = (trailing[1] ?? "").toLowerCase().replace(/[^a-z#]/g, "");
22
+ const label = ["number", "no", "#", "dancer", "competitor"].includes(before);
23
+ const n = Number(trailing[2]);
24
+ if (!label && inRange(n)) {
25
+ const cut = trailing.index + (trailing[1] ?? "").length;
26
+ return { rest: print.slice(0, cut), bpm: n };
27
+ }
28
+ }
29
+ return { rest: print, bpm: null };
30
+ }
31
+ function levenshtein(a, b) {
32
+ const m = a.length;
33
+ const n = b.length;
34
+ let prev = Array.from({ length: n + 1 }, (_, j) => j);
35
+ for (let i = 1;i <= m; i++) {
36
+ const cur = [i];
37
+ for (let j = 1;j <= n; j++) {
38
+ cur[j] = Math.min((prev[j] ?? 0) + 1, (cur[j - 1] ?? 0) + 1, (prev[j - 1] ?? 0) + (a[i - 1] === b[j - 1] ? 0 : 1));
39
+ }
40
+ prev = cur;
41
+ }
42
+ return prev[n] ?? 0;
43
+ }
44
+ function matchFolded(q, c) {
45
+ if (q === "" || c === "")
46
+ return null;
47
+ if (q === c)
48
+ return { kind: "exact", score: 1 };
49
+ const qt = q.split(" ");
50
+ const ct = c.split(" ");
51
+ const ratio = 1 - levenshtein(q, c) / Math.max(q.length, c.length);
52
+ const fuzzy = ratio >= FUZZY_FLOOR ? ratio : 0;
53
+ if (qt.every((w) => ct.includes(w)) && WITHIN_SCORE >= fuzzy)
54
+ return { kind: "within", score: WITHIN_SCORE };
55
+ if (ct.every((w) => qt.includes(w)) && AROUND_SCORE >= fuzzy)
56
+ return { kind: "around", score: AROUND_SCORE };
57
+ return fuzzy > 0 ? { kind: "fuzzy", score: fuzzy } : null;
58
+ }
59
+ function matchNodes(folded, nodes) {
60
+ const scored = [];
61
+ let top;
62
+ for (const node of nodes) {
63
+ let best = null;
64
+ let fuzzy = false;
65
+ for (const a of node.aliases) {
66
+ const fa = foldDancePrint(a);
67
+ const m = matchFolded(folded, fa);
68
+ if (m && (!best || m.score > best.score))
69
+ best = m;
70
+ if (fa !== "" && 1 - levenshtein(folded, fa) / Math.max(folded.length, fa.length) >= FUZZY_FLOOR)
71
+ fuzzy = true;
72
+ }
73
+ const row = { node, score: best?.score ?? 0, kind: best?.kind ?? null, fuzzy };
74
+ scored.push(row);
75
+ if (!top || row.score > top.score)
76
+ top = row;
77
+ }
78
+ if (!top || top.kind === null)
79
+ return { nodes: [], score: 0, kind: null };
80
+ const best = top;
81
+ const keep = scored.filter((x) => x.score >= best.score - 0.000000001 || best.kind === "around" && x.fuzzy);
82
+ return { nodes: keep.map((x) => x.node), score: best.score, kind: best.kind };
83
+ }
84
+ function candidateRelation(a, b) {
85
+ if (a.length === 0 || b.length === 0)
86
+ return "silent";
87
+ if (a.length === 1 && b.length === 1 && a[0] === b[0])
88
+ return "same";
89
+ return a.some((x) => b.includes(x)) ? "overlaps" : "conflict";
90
+ }
91
+
92
+ var DANCE_TYPES2 = Object.freeze([
93
+ "reel",
94
+ "light-jig",
95
+ "single-jig",
96
+ "slip-jig",
97
+ "treble-jig",
98
+ "hornpipe",
99
+ "traditional-set",
100
+ "set-dance"
101
+ ]);
102
+ function rhythmOfTime2(time) {
103
+ return time === "2/4" || time === "4/4" ? "hornpipe" : "jig";
104
+ }
105
+ var TYPE_PRINTS = new Map([
106
+ ["reel", ["reel"]],
107
+ ["light jig", ["light-jig"]],
108
+ ["single jig", ["single-jig"]],
109
+ ["slip jig", ["slip-jig"]],
110
+ ["hop jig", ["single-jig", "slip-jig"]],
111
+ ["double jig", ["light-jig", "treble-jig"]],
112
+ ["treble jig", ["treble-jig"]],
113
+ ["heavy jig", ["treble-jig"]],
114
+ ["hornpipe", ["hornpipe"]],
115
+ ["traditional set", ["traditional-set"]],
116
+ ["traditional set dance", ["traditional-set"]],
117
+ ["trad set", ["traditional-set"]],
118
+ ["set dance", ["set-dance"]],
119
+ ["contemporary set dance", ["set-dance"]],
120
+ ["modern set", ["set-dance"]],
121
+ ["modern set dance", ["set-dance"]]
122
+ ].map(([p, t]) => [foldDancePrint(p), t]));
123
+ function danceTypes2(print) {
124
+ const folded = foldDancePrint(print);
125
+ return TYPE_PRINTS.get(folded) ?? TYPE_PRINTS.get(folded.replace(/s$/, "")) ?? [];
126
+ }
127
+ function danceTypePrints2() {
128
+ return TYPE_PRINTS;
129
+ }
130
+ function isDanceTypePrint2(print) {
131
+ return danceTypes2(print).length > 0;
132
+ }
133
+
134
+ export { foldDancePrint, splitTempo, matchNodes, candidateRelation, DANCE_TYPES2, rhythmOfTime2, danceTypes2, danceTypePrints2, isDanceTypePrint2 };
@@ -0,0 +1,267 @@
1
+ import {
2
+ foldDancePrint,
3
+ splitTempo,
4
+ matchNodes,
5
+ candidateRelation,
6
+ rhythmOfTime2,
7
+ isDanceTypePrint2
8
+ } from "./place-g6yw4cq6.js";
9
+
10
+ var SET_MIN_SPEED2 = Object.freeze({
11
+ jig: 66,
12
+ hornpipe: 76
13
+ });
14
+ var PLAUSIBLE_SET_TEMPO_MAX2 = 150;
15
+ function node(id, name, irish, time, opts = {}) {
16
+ return Object.freeze({
17
+ id,
18
+ name,
19
+ irish,
20
+ prints: Object.freeze(opts.prints ?? []),
21
+ irishPrints: Object.freeze(opts.irishPrints ?? []),
22
+ time,
23
+ traditionalSpeed: opts.traditionalSpeed ?? null,
24
+ maxSpeed: null
25
+ });
26
+ }
27
+ var TUNE_NODES2 = Object.freeze([
28
+ node("blackbird", "The Blackbird", "An Lon Dubh", "2/4", {
29
+ prints: ["Blackbird", "Blackbird (Traditional)"],
30
+ irishPrints: ["An Londubh"],
31
+ traditionalSpeed: 144
32
+ }),
33
+ node("lodge-road", "The Lodge Road", "Bóthar an Lóiste", "2/4", {
34
+ irishPrints: ["Bóthar An Lóiste"]
35
+ }),
36
+ node("downfall-of-paris", "Downfall of Paris", "Titim Phárais", "2/4", {
37
+ prints: ["The Downfall of Paris"],
38
+ irishPrints: ["Titim Paris", "Titim Páras"]
39
+ }),
40
+ node("planxty-davis", "Planxty Davis", "Plancstaí Dáibhéis", "2/4", {
41
+ irishPrints: ["Plancstaí Daibhéis"]
42
+ }),
43
+ node("king-of-the-fairies", "King of the Fairies", "Rí na Síog", "2/4", {
44
+ traditionalSpeed: 130
45
+ }),
46
+ node("rodneys-glory", "Rodney's Glory", "Glóir Rodney", "2/4", {
47
+ irishPrints: ["Glór Rodnaí"]
48
+ }),
49
+ node("ace-and-deuce-of-pipering", "Ace and Deuce of Pipering", "Aon agus dó na Píobaireachta", "4/4", {
50
+ prints: ["Ace & Deuce of Pipering"],
51
+ irishPrints: ["Aon agus Dó na Píobaireachta"]
52
+ }),
53
+ node("kilkenny-races", "Kilkenny Races", "Rásaí Chill Choinnigh", "4/4", {
54
+ prints: ["Killkenny Races"]
55
+ }),
56
+ node("blue-eyed-rascal", "The Blue-Eyed Rascal", "Cladhaire na Súile Gorma", "4/4", {
57
+ prints: ["Blue Eyed Rascal"]
58
+ }),
59
+ node("madame-bonaparte", "Madame Bonaparte", "Madame Bonaparte", "4/4"),
60
+ node("bonapartes-retreat", "Bonaparte's Retreat", "Cúlú Bhonaparte", "4/4", {
61
+ irishPrints: ["Cúlú Bonaparte"]
62
+ }),
63
+ node("piper", "The Piper Through the Meadow Astraying", "An Píobaire sa Mhóinéar ar Strae/Fáin", "4/4", {
64
+ prints: ["The Piper", "The Piper thro' the Meadow Straying"],
65
+ irishPrints: ["An Píobaire"]
66
+ }),
67
+ node("four-masters", "The Four Masters", "Na Ceithre Máistrí", "4/4"),
68
+ node("rambling-rake", "Rambling Rake", "An Réice Fáin", "4/4", {
69
+ prints: ["The Rambling Rake"]
70
+ }),
71
+ node("garden-of-daisies", "Garden of Daisies", "Gáirdíní na Nóinín", "4/4", {
72
+ irishPrints: ["Gairdín na Nóiníní", "Gáirdíní na Nóiníní"],
73
+ traditionalSpeed: 138
74
+ }),
75
+ node("roving-pedlar", "The Roving Pedlar", "An Mangaire Fáin", "4/4"),
76
+ node("hunt", "The Hunt", "An Fiach", "4/4"),
77
+ node("white-blanket", "White Blanket", "An Súisín Bán", "4/4", {
78
+ prints: ["The White Blanket"]
79
+ }),
80
+ node("job-of-journeywork", "Job of Journeywork", "An Greas Giúrnála", "4/4", {
81
+ irishPrints: ["Greas Giúrnála"],
82
+ traditionalSpeed: 138
83
+ }),
84
+ node("youghal-harbour", "Youghal Harbour", "Cuan Eochaille", "4/4"),
85
+ node("blackthorn-stick", "Blackthorn Stick", "An Maide Droighneáin", "6/8", {
86
+ prints: ["The Blackthorn Stick"],
87
+ irishPrints: ["An Maide Droighnéan"]
88
+ }),
89
+ node("planxty-drury", "Planxty Drury", "Plancstaí Drúirí", "6/8", {
90
+ prints: ["Planxy Drury"]
91
+ }),
92
+ node("charlady", "The Charlady", "An Bhean Ghlantacháin", "6/8", {
93
+ irishPrints: ["Bean an Ghlantacháin"]
94
+ }),
95
+ node("planxty-hugh-odonnell", "Planxty Hugh O'Donnell", "Plancstaí Aodh Uí Dhomhnaill", "6/8", {
96
+ irishPrints: ["Plancstaí Aodh Ó Domhnaill"]
97
+ }),
98
+ node("drunken-gauger", "Drunken Gauger", "An Gaueger Meisceach", "6/8", {
99
+ prints: ["The Drunken Gauger", "The Funny Tailor"]
100
+ }),
101
+ node("rub-the-bag", "Rub the Bag", "Cuimil an Mála", "6/8"),
102
+ node("fiddler-around-the-fairy-green", "The Fiddler Around the Fairy Green", "An Bheidhleadóir ag an Crann Sí", "6/8", { prints: ["The Fiddler 'Round the Fairy Tree", "The Fiddler Around the Fairy Tree"] }),
103
+ node("st-patricks-day", "St. Patrick's Day", "Lá Fhéile Phádraig", "6/8", {
104
+ irishPrints: ["Lá Fhéile Pádraig", "Lá Féile Phádraig"],
105
+ traditionalSpeed: 94
106
+ }),
107
+ node("humours-of-bandon", "Humours of Bandon", "Pléarácha na Banndon", "6/8", {
108
+ prints: ["Humour's of Bandon"],
109
+ irishPrints: ["Pléaracha na Bandan"]
110
+ }),
111
+ node("story-teller", "The Story-Teller", "An Scéalaí", "6/8", {
112
+ prints: ["The Storyteller"]
113
+ }),
114
+ node("hurling-boys", "The Hurling Boys", "Na Buachaillí Báire", "6/8", {
115
+ prints: ["The Hurling Boy"]
116
+ }),
117
+ node("sprig-of-shillelagh", "The Sprig of Shillelagh", "An Ghéag Sail Éille", "6/8", {
118
+ prints: ["The Spring of Shillelagh"],
119
+ irishPrints: ["An Geag Síléaladh"]
120
+ }),
121
+ node("hurry-the-jug", "Hurry the Jug", "Cuir Thart an Crúsca", "6/8"),
122
+ node("three-sea-captains", "The Three Sea Captains", "An Triúr Chaptaen Mara", "6/8", {
123
+ prints: ["Three Sea Captains"],
124
+ irishPrints: ["Na Trí Captéin Maraí", "Triúr Captaen Mara"],
125
+ traditionalSpeed: 96
126
+ }),
127
+ node("jockey-to-the-fair", "Jockey to the Fair", "An Marcach Chuig an Aonach", "6/8", {
128
+ traditionalSpeed: 90
129
+ }),
130
+ node("vanishing-lake", "Vanishing Lake", "An Loch Mhadhma", "6/8", {
131
+ prints: ["The Vanishing Lake"],
132
+ irishPrints: ["Luch An Mhadhma"]
133
+ }),
134
+ node("miss-browns-fancy", "Miss Brown's Fancy", "Rogha Iníon De Brún", "6/8"),
135
+ node("wandering-musician", "The Wandering Musician", "An Ceoltóir Fáin", "6/8", {
136
+ prints: ["Wandering Musicianr"]
137
+ }),
138
+ node("orange-rogue", "Orange Rogue", "An Rógaire Buí", "6/8", {
139
+ prints: ["The Orange Rogue"]
140
+ }),
141
+ node("is-the-big-man-within", "Is the Big Man Within?", "An bhfuil an Fear Mór Istigh?", "6/8+9/8", {
142
+ irishPrints: ["An ‘Bhfuil an Fear Mór Istigh?"]
143
+ })
144
+ ]);
145
+ function makeTune(n) {
146
+ const range = Object.freeze({
147
+ min: SET_MIN_SPEED2[rhythmOfTime2(n.time)],
148
+ max: n.maxSpeed
149
+ });
150
+ return Object.freeze({
151
+ [Symbol.toStringTag]: "Tune",
152
+ id: n.id,
153
+ name: n.name,
154
+ irish: n.irish,
155
+ node: n,
156
+ toString: () => n.name,
157
+ isTraditional: () => n.traditionalSpeed !== null,
158
+ isContemporary: () => true,
159
+ time: () => n.time,
160
+ rhythm: () => rhythmOfTime2(n.time),
161
+ speed(setting) {
162
+ if (setting === "contemporary")
163
+ return range;
164
+ if (n.traditionalSpeed !== null)
165
+ return n.traditionalSpeed;
166
+ return setting === "traditional" ? null : range;
167
+ }
168
+ });
169
+ }
170
+ var TUNES = Object.freeze(TUNE_NODES2.map(makeTune));
171
+ var TUNE_BY_ID = new Map(TUNES.map((t) => [t.id, t]));
172
+ var MATCHABLE = TUNES.map((t) => ({
173
+ id: t.id,
174
+ tune: t,
175
+ aliases: [t.name, ...t.node.prints, ...t.irish ? [t.irish] : [], ...t.node.irishPrints]
176
+ }));
177
+ function allTunes2() {
178
+ return TUNES;
179
+ }
180
+ function tuneById2(id) {
181
+ return TUNE_BY_ID.get(id);
182
+ }
183
+ function tempoLegal2(tune, bpm, setting) {
184
+ if (!Number.isFinite(bpm))
185
+ return false;
186
+ if ("candidates" in tune)
187
+ return tune.candidates.some((t) => tempoLegal2(t, bpm, setting));
188
+ const fixed = tune.node.traditionalSpeed;
189
+ const traditional = fixed !== null && bpm === fixed;
190
+ const range = tune.speed("contemporary");
191
+ const contemporary = bpm >= range.min && (range.max === null || bpm <= range.max);
192
+ if (setting === "traditional")
193
+ return traditional;
194
+ if (setting === "contemporary")
195
+ return contemporary;
196
+ return traditional || contemporary;
197
+ }
198
+ function settingAt2(tune, bpm) {
199
+ if (tempoLegal2(tune, bpm, "traditional"))
200
+ return "traditional";
201
+ if (tempoLegal2(tune, bpm, "contemporary"))
202
+ return "contemporary";
203
+ return null;
204
+ }
205
+ function narrow(cands, ctx, misses) {
206
+ let out = cands;
207
+ const step = (label, keep) => {
208
+ const next = out.filter(keep);
209
+ if (next.length > 0)
210
+ out = next;
211
+ else if (out.length > 0)
212
+ misses.push(label);
213
+ };
214
+ if (ctx.setting === "traditional")
215
+ step("setting:traditional", (t) => t.isTraditional());
216
+ if (ctx.rhythm)
217
+ step(`rhythm:${ctx.rhythm}`, (t) => t.rhythm() === ctx.rhythm);
218
+ if (ctx.time)
219
+ step(`time:${ctx.time}`, (t) => t.time() === ctx.time);
220
+ if (ctx.bpm !== undefined)
221
+ step(`bpm:${ctx.bpm}`, (t) => tempoLegal2(t, ctx.bpm, ctx.setting));
222
+ return out;
223
+ }
224
+ function reading(print, folded, bpm, candidates, score, match, refusal, misses) {
225
+ const self = Object.freeze({
226
+ [Symbol.toStringTag]: "TuneReading",
227
+ print,
228
+ folded,
229
+ bpm,
230
+ candidates: Object.freeze([...candidates]),
231
+ score,
232
+ match,
233
+ refusal,
234
+ misses: Object.freeze([...misses]),
235
+ tune: candidates.length === 1 ? candidates[0] : undefined,
236
+ isTune: () => candidates.length > 0,
237
+ isSingular: () => candidates.length === 1,
238
+ isAmbiguous: () => candidates.length > 1,
239
+ refine(ctx) {
240
+ const m = [...misses];
241
+ const next = narrow(candidates, ctx, m);
242
+ return reading(print, folded, bpm, next, score, match, refusal, m);
243
+ },
244
+ toString: () => candidates.length === 1 ? candidates[0].name : `${print}?`
245
+ });
246
+ return self;
247
+ }
248
+ function tune2(print, ctx = {}) {
249
+ const { rest, bpm } = splitTempo(print, { min: SET_MIN_SPEED2.jig, max: PLAUSIBLE_SET_TEMPO_MAX2 });
250
+ const folded = foldDancePrint(rest);
251
+ if (folded === "")
252
+ return reading(print, folded, bpm, [], 0, null, "empty", []);
253
+ if (isDanceTypePrint2(rest))
254
+ return reading(print, folded, bpm, [], 0, null, "dance-type", []);
255
+ const m = matchNodes(folded, MATCHABLE);
256
+ if (m.nodes.length === 0)
257
+ return reading(print, folded, bpm, [], m.score, null, "unmatched", []);
258
+ const misses = [];
259
+ const effective = ctx.bpm === undefined && bpm !== null ? { ...ctx, bpm } : ctx;
260
+ const cands = narrow(m.nodes.map((x) => x.tune), effective, misses);
261
+ return reading(print, folded, bpm, cands, m.score, m.kind, null, misses);
262
+ }
263
+ function tuneRelation2(a, b) {
264
+ return candidateRelation(a.candidates.map((t) => t.id), b.candidates.map((t) => t.id));
265
+ }
266
+
267
+ export { SET_MIN_SPEED2, PLAUSIBLE_SET_TEMPO_MAX2, TUNE_NODES2, allTunes2, tuneById2, tempoLegal2, settingAt2, tune2, tuneRelation2 };