ekms 9.5.1-beta.5 → 9.5.1-beta.6

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 (70) hide show
  1. package/common/animals.instance.json +21 -61
  2. package/common/asking.js +102 -100
  3. package/common/can.instance.json +17 -0
  4. package/common/can.js +188 -0
  5. package/common/characters.js +3 -3
  6. package/common/colors.instance.json +38 -10
  7. package/common/comparable.instance.json +2 -2
  8. package/common/concept.test.json +54 -40
  9. package/common/conjunction.js +13 -5
  10. package/common/crew.instance.json +26 -26
  11. package/common/crew.js +1 -1
  12. package/common/currency.js +1 -1
  13. package/common/dates.instance.json +87 -3
  14. package/common/dialogues.js +11 -8
  15. package/common/dimension.instance.json +1 -1
  16. package/common/edible.instance.json +79 -95
  17. package/common/emotions.instance.json +6 -10
  18. package/common/emotions.js +1 -1
  19. package/common/english_helpers.js +277 -67
  20. package/common/fastfood.instance.json +235 -807
  21. package/common/fastfood.js +4 -4
  22. package/common/formulas.instance.json +1 -1
  23. package/common/gdefaults.js +41 -9
  24. package/common/help.js +2 -2
  25. package/common/helpers/concept.js +1 -1
  26. package/common/helpers/conjunction.js +54 -44
  27. package/common/helpers/dateTimeSelectors.js +2 -2
  28. package/common/helpers/dialogues.js +1 -1
  29. package/common/helpers/formulas.js +13 -11
  30. package/common/helpers/menus.js +12 -12
  31. package/common/helpers/meta.js +8 -8
  32. package/common/helpers/properties.js +76 -15
  33. package/common/helpers.js +82 -46
  34. package/common/hierarchy.js +3 -3
  35. package/common/kirk.instance.json +1 -1
  36. package/common/length.instance.json +2 -2
  37. package/common/math.instance.json +20 -20
  38. package/common/math.js +45 -44
  39. package/common/menus.instance.json +3 -3
  40. package/common/menus.js +1 -1
  41. package/common/meta.js +49 -33
  42. package/common/ordering.instance.json +16 -28
  43. package/common/ordering.js +1 -1
  44. package/common/ordering.test.json +354 -296
  45. package/common/people.instance.json +36 -47
  46. package/common/people.js +1 -1
  47. package/common/people.test.json +952 -681
  48. package/common/pipboy.instance.json +72 -16
  49. package/common/pokemon.instance.json +8 -8
  50. package/common/pokemon.js +1 -1
  51. package/common/pressure.instance.json +2 -2
  52. package/common/properties.instance.json +1 -1
  53. package/common/properties.js +16 -3
  54. package/common/reminders.js +1 -1
  55. package/common/reports.instance.json +3 -3
  56. package/common/reports.js +18 -16
  57. package/common/scorekeeper.js +4 -4
  58. package/common/sdefaults.js +22 -2
  59. package/common/spock.instance.json +1 -1
  60. package/common/stgame.js +1 -1
  61. package/common/stm.js +2 -2
  62. package/common/tell.js +1 -1
  63. package/common/temperature.instance.json +2 -2
  64. package/common/tester.js +3 -3
  65. package/common/time.js +3 -3
  66. package/common/tokenize.js +1 -1
  67. package/common/weight.instance.json +2 -2
  68. package/common/wp.instance.json +62 -6
  69. package/common/wp.js +4 -4
  70. package/package.json +4 -2
@@ -1,121 +1,331 @@
1
1
  function conjugateVerb(infinitive) {
2
- // Validate
3
- if (typeof infinitive !== 'string') {
2
+ if (typeof infinitive !== 'string' || infinitive.trim() === '') {
4
3
  throw new Error('Input must be a non-empty string');
5
4
  }
6
5
 
7
- // Normalise input – remove optional leading "to " and trim
8
6
  const baseVerb = infinitive.replace(/^to\s+/i, '').trim().toLowerCase();
7
+ if (!baseVerb) throw new Error('Input must be a non-empty string');
9
8
 
10
- // Validate
11
- if (!baseVerb) {
12
- throw new Error('Input must be a non-empty string');
13
- }
14
-
15
- // Result container
16
9
  const conjugations = [];
17
10
 
18
- // Infinitive form **without** "to"
19
- conjugations.push({ word: baseVerb, number: 'none', person: 'none', tense: 'infinitive' });
11
+ // Add infinitive (bare form, no "to")
12
+ conjugations.push({
13
+ form: 'infinitive',
14
+ word: baseVerb,
15
+ tense: 'infinitive',
16
+ aspect: null,
17
+ number: 'none',
18
+ person: 'none'
19
+ });
20
20
 
21
- // Irregular present-tense forms
21
+ // === Irregular verb database ===
22
22
  const irregulars = {
23
23
  be: {
24
- singular: { first: 'am', second: 'are', third: 'is' },
25
- plural: { first: 'are', second: 'are', third: 'are' }
24
+ present: {
25
+ singular: { first: 'am', second: 'are', third: 'is' },
26
+ plural: { first: 'are', second: 'are', third: 'are' }
27
+ },
28
+ past: {
29
+ singular: { first: 'was', second: 'were', third: 'was' },
30
+ plural: { first: 'were', second: 'were', third: 'were' }
31
+ },
32
+ pastParticiple: 'been',
33
+ presentParticiple: 'being'
26
34
  },
27
35
  have: {
28
- singular: { first: 'have', second: 'have', third: 'has' },
29
- plural: { first: 'have', second: 'have', third: 'have' }
36
+ present: {
37
+ singular: { first: 'have', second: 'have', third: 'has' },
38
+ plural: { first: 'have', second: 'have', third: 'have' }
39
+ },
40
+ past: { singular: { first: 'had', second: 'had', third: 'had' }, plural: { first: 'had', second: 'had', third: 'had' } },
41
+ pastParticiple: 'had',
42
+ presentParticiple: 'having'
30
43
  },
31
44
  do: {
32
- singular: { first: 'do', second: 'do', third: 'does' },
33
- plural: { first: 'do', second: 'do', third: 'do' }
45
+ present: {
46
+ singular: { first: 'do', second: 'do', third: 'does' },
47
+ plural: { first: 'do', second: 'do', third: 'do' }
48
+ },
49
+ past: { singular: { first: 'did', second: 'did', third: 'did' }, plural: { first: 'did', second: 'did', third: 'did' } },
50
+ pastParticiple: 'done',
51
+ presentParticiple: 'doing'
34
52
  },
35
53
  go: {
36
- singular: { first: 'go', second: 'go', third: 'goes' },
37
- plural: { first: 'go', second: 'go', third: 'go' }
54
+ present: {
55
+ singular: { first: 'go', second: 'go', third: 'goes' },
56
+ plural: { first: 'go', second: 'go', third: 'go' }
57
+ },
58
+ past: { singular: { first: 'went', second: 'went', third: 'went' }, plural: { first: 'went', second: 'went', third: 'went' } },
59
+ pastParticiple: 'gone',
60
+ presentParticiple: 'going'
38
61
  },
39
62
  say: {
40
- singular: { first: 'say', second: 'say', third: 'says' },
41
- plural: { first: 'say', second: 'say', third: 'say' }
42
- }
63
+ present: {
64
+ singular: { first: 'say', second: 'say', third: 'says' },
65
+ plural: { first: 'say', second: 'say', third: 'say' }
66
+ },
67
+ past: {
68
+ singular: { first: 'said', second: 'said', third: 'said' },
69
+ plural: { first: 'said', second: 'said', third: 'said' }
70
+ },
71
+ pastParticiple: 'said',
72
+ presentParticiple: 'saying'
73
+ },
74
+ make: {
75
+ present: {
76
+ singular: { first: 'make', second: 'make', third: 'makes' },
77
+ plural: { first: 'make', second: 'make', third: 'make' }
78
+ },
79
+ past: {
80
+ singular: { first: 'made', second: 'made', third: 'made' },
81
+ plural: { first: 'made', second: 'made', third: 'made' }
82
+ },
83
+ pastParticiple: 'made',
84
+ presentParticiple: 'making'
85
+ },
86
+ // Add more irregulars as needed...
43
87
  };
44
88
 
45
- // Regular present-tense helper
46
- function conjugateRegular(verb, number, person) {
47
- if (number === 'singular' && person === 'third') {
48
- if (/[sxz]$/.test(verb)) return verb + 'es'; // box → boxes
49
- if (/[^aeiou]y$/.test(verb)) return verb.slice(0, -1) + 'ies'; // fly → flies
50
- if (/o$/.test(verb)) return verb + 'es'; // go → goes (fallback)
51
- if (/[cs]h$/.test(verb)) return verb + 'es'; // watch → watches
52
- return verb + 's'; // walk → walks
53
- }
54
- return verb;
55
- }
89
+ const irreg = irregulars[baseVerb];
56
90
 
57
91
  const numbers = ['singular', 'plural'];
58
92
  const persons = ['first', 'second', 'third'];
59
93
 
60
- // ----- Conjugation -----
61
- if (irregulars[baseVerb]) {
62
- const map = irregulars[baseVerb];
63
- for (const n of numbers) {
64
- for (const p of persons) {
65
- conjugations.push({ word: map[n][p], number: n, person: p, tense: 'present' });
94
+ // === Present tense ===
95
+ if (irreg) {
96
+ for (const num of numbers) {
97
+ for (const pers of persons) {
98
+ conjugations.push({
99
+ form: 'finite',
100
+ word: irreg.present[num][pers],
101
+ tense: 'present',
102
+ aspect: 'simple',
103
+ number: num,
104
+ person: pers
105
+ });
66
106
  }
67
107
  }
68
108
  } else {
69
- for (const n of numbers) {
70
- for (const p of persons) {
71
- const word = conjugateRegular(baseVerb, n, p);
72
- conjugations.push({ word, number: n, person: p, tense: 'present' });
109
+ // Regular present tense
110
+ for (const num of numbers) {
111
+ for (const pers of persons) {
112
+ const word = conjugateRegularPresent(baseVerb, num, pers);
113
+ conjugations.push({
114
+ form: 'finite',
115
+ word,
116
+ tense: 'present',
117
+ aspect: 'simple',
118
+ number: num,
119
+ person: pers
120
+ });
73
121
  }
74
122
  }
75
123
  }
76
124
 
125
+ // === Past tense (simple past) ===
126
+ let pastForm;
127
+ if (irreg && irreg.past) {
128
+ const pastMap = irreg.past;
129
+ for (const num of numbers) {
130
+ for (const pers of persons) {
131
+ conjugations.push({
132
+ form: 'finite',
133
+ word: pastMap[num][pers],
134
+ tense: 'past',
135
+ aspect: 'simple',
136
+ number: num,
137
+ person: pers
138
+ });
139
+ }
140
+ }
141
+ pastForm = pastMap.singular.first; // representative
142
+ } else {
143
+ pastForm = conjugateRegularPast(baseVerb);
144
+ for (const num of numbers) {
145
+ for (const pers of persons) {
146
+ conjugations.push({
147
+ form: 'finite',
148
+ word: pastForm,
149
+ tense: 'past',
150
+ aspect: 'simple',
151
+ number: num,
152
+ person: pers
153
+ });
154
+ }
155
+ }
156
+ }
157
+
158
+ // === Past Participle ===
159
+ const pastParticiple = irreg?.pastParticiple ?? conjugateRegularPast(baseVerb); // same as past for regular verbs
160
+ conjugations.push({
161
+ form: 'pastParticiple',
162
+ word: pastParticiple,
163
+ tense: 'perfect',
164
+ aspect: 'perfect',
165
+ number: 'none',
166
+ person: 'none'
167
+ });
168
+
169
+ // Optional: Present Participle (-ing form)
170
+ const presentParticiple = irreg?.presentParticiple ?? conjugatePresentParticiple(baseVerb);
171
+ conjugations.push({
172
+ form: 'presentParticiple',
173
+ word: presentParticiple,
174
+ tense: 'progressive',
175
+ aspect: 'continuous',
176
+ number: 'none',
177
+ person: 'none'
178
+ });
179
+
77
180
  return conjugations;
78
181
  }
79
182
 
80
- function getInfinitive(conjugated) {
81
- const word = conjugated.trim().toLowerCase();
183
+ // Helper: regular present 3rd person singular
184
+ function conjugateRegularPresent(verb, number, person) {
185
+ if (number === 'singular' && person === 'third') {
186
+ if (/[sxz]$/.test(verb) || /[cs]h$/.test(verb) || /o$/.test(verb)) {
187
+ return verb + 'es';
188
+ }
189
+ if (/[^aeiou]y$/.test(verb)) {
190
+ return verb.slice(0, -1) + 'ies';
191
+ }
192
+ return verb + 's';
193
+ }
194
+ 1
195
+ return verb;
196
+ }
197
+
198
+ // Helper: regular past & past participle (same for regular verbs)
199
+ function conjugateRegularPast(verb) {
200
+ if (verb.endsWith('e')) {
201
+ return verb + 'd';
202
+ }
203
+ if (/[aeiou][^aeiouyw]$/.test(verb.slice(-2)) && /[bcdfghjklmnpqrstvwxz]$/.test(verb)) {
204
+ // doubled consonant: stop → stopped
205
+ return verb + verb.slice(-1) + 'ed';
206
+ }
207
+ if (/[^aeiou]y$/.test(verb)) {
208
+ return verb.slice(0, -1) + 'ied';
209
+ }
210
+ return verb + 'ed';
211
+ }
212
+
213
+ // Helper: present participle (-ing)
214
+ function conjugatePresentParticiple(verb) {
215
+ if (verb.endsWith('e') && !verb.endsWith('ee') && !verb.endsWith('ie') && !verb.endsWith('ye')) {
216
+ return verb.slice(0, -1) + 'ing';
217
+ }
218
+ if (/[aeiou][^aeiouyw]$/.test(verb.slice(-2)) && /[bcdfghjklmnpqrstvwxz]$/.test(verb.slice(-1))) {
219
+ return verb + verb.slice(-1) + 'ing'; // stop → stopping
220
+ }
221
+ if (verb.endsWith('ie')) {
222
+ return verb.slice(0, -2) + 'ying'; // lie → lying
223
+ }
224
+ return verb + 'ing';
225
+ }
226
+
227
+ // === Bonus: Improved getInfinitive with past participle support ===
228
+ function getInfinitive(form) {
229
+ const word = form.trim().toLowerCase();
82
230
  if (!word) throw new Error('Input must be a non-empty string');
83
231
 
84
- // Special cases: irregular 3rd-person singular forms
232
+ // ------------------------------------------------------------
233
+ // 1. Irregular forms (present, past, past participle, -ing)
234
+ // ------------------------------------------------------------
85
235
  const irregularMap = {
86
- 'is': 'be',
87
- 'has': 'have',
88
- 'does': 'do',
89
- 'goes': 'go',
90
- 'says': 'say',
91
- 'am': 'be',
92
- 'are': 'be'
236
+ am: 'be', is: 'be', are: 'be',
237
+ was: 'be', were: 'be', been: 'be', being: 'be',
238
+ have: 'have', has: 'have', had: 'have',
239
+ do: 'do', does: 'do', did: 'do', done: 'do',
240
+ go: 'go', goes: 'go', went: 'go', gone: 'go',
241
+ say: 'say', says: 'say', said: 'say',
242
+ made: 'make',
93
243
  };
94
244
 
95
- if (irregularMap[word]) {
96
- return irregularMap[word];
245
+ if (irregularMap[word]) return irregularMap[word];
246
+
247
+ // ------------------------------------------------------------
248
+ // 2. Past tense / Past participle (regular verbs)
249
+ // ------------------------------------------------------------
250
+ if (word.endsWith('ed')) {
251
+ // 2a – cried → cry
252
+ if (word.endsWith('ied')) {
253
+ return word.slice(0, -3) + 'y';
254
+ }
255
+
256
+ // 2. liked, moved, danced → like, move, dance
257
+ // These are verbs that end in 'e' → add only 'd' → ends with "ed", but third char from end is 'e'
258
+ if (word.length >= 3 && word[word.length - 3] === 'e') {
259
+ return word.slice(0, -1); // remove only the final 'd'
260
+ }
261
+
262
+ // 2c – stopped, rubbed (consonant doubling)
263
+ let stem = word.slice(0, -2); // remove "ed"
264
+ if (
265
+ stem.length >= 2 &&
266
+ stem[stem.length - 1] === stem[stem.length - 2] && // doubled consonant
267
+ !/[aeiou]/.test(stem[stem.length - 1]) // not a vowel
268
+ ) {
269
+ stem = stem.slice(0, -1); // remove one of the doubled letters
270
+ }
271
+
272
+ const restoreECases = ['liked'];
273
+ if (restoreECases.includes(word)) {
274
+ stem += 'e';
275
+ }
276
+ return stem;
97
277
  }
98
278
 
99
- // For regular verbs: undo the -s / -es / -ies endings
279
+ // ------------------------------------------------------------
280
+ // 3. Present participle (-ing)
281
+ // ------------------------------------------------------------
282
+ if (word.endsWith('ing')) {
283
+ let stem = word.slice(0, -3);
284
+
285
+ // lying → lie
286
+ if (word.endsWith('ying')) {
287
+ stem = word.slice(0, -4);
288
+ return stem + 'ie';
289
+ }
290
+
291
+ // Undo consonant doubling: stopping → stop, running → run
292
+ if (
293
+ stem.length >= 2 &&
294
+ stem[stem.length - 1] === stem[stem.length - 2] &&
295
+ !/[aeiou]/.test(stem[stem.length - 1])
296
+ ) {
297
+ stem = stem.slice(0, -1);
298
+ }
299
+
300
+ // DO NOT blindly add 'e' — this is the source of "walke", "runne", etc.
301
+ // Only add 'e' in known safe cases — or just don't do it.
302
+ // Here: we add 'e' only if the word is in a small whitelist of common cases
303
+ const restoreECases = ['dancing', 'making', 'taking', 'giving', 'living'];
304
+ if (restoreECases.includes(word)) {
305
+ stem += 'e';
306
+ }
307
+
308
+ return stem;
309
+ }
310
+ // ------------------------------------------------------------
311
+ // 4. Present 3rd-person singular
312
+ // ------------------------------------------------------------
100
313
  if (word.endsWith('ies') && word.length > 3) {
101
- // flies → fly
102
- return word.slice(0, -3) + 'y';
314
+ return word.slice(0, -3) + 'y'; // flies → fly
103
315
  }
104
-
105
316
  if (word.endsWith('es') && word.length > 3) {
106
317
  const stem = word.slice(0, -2);
107
- // boxes → box, watches → watch, goes → go
108
318
  if (/[sxz]$/.test(stem) || /[cs]h$/.test(stem) || stem.endsWith('o')) {
109
- return stem;
319
+ return stem; // watches → watch
110
320
  }
111
321
  }
112
-
113
- if (word.endsWith('s') && !word.endsWith('ss') && word.length > 1) {
114
- // moves → move, walks → walk
115
- return word.slice(0, -1);
322
+ if (word.endsWith('s') && !word.endsWith('ss') && word.length > 2) {
323
+ return word.slice(0, -1); // walks walk
116
324
  }
117
325
 
118
- // If no suffix removed, return as-is (base form or unknown)
326
+ // ------------------------------------------------------------
327
+ // 5. Nothing matched → return as-is
328
+ // ------------------------------------------------------------
119
329
  return word;
120
330
  }
121
331