windsor-bot 0.1.7 → 0.1.8
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 +329 -77
- package/assets/wordsearches/animals.txt +404 -0
- package/assets/wordsearches/colors.txt +404 -0
- package/assets/wordsearches/food.txt +404 -0
- package/assets/wordsearches/fruits.txt +404 -0
- package/assets/wordsearches/household.txt +404 -0
- package/assets/wordsearches/music.txt +404 -0
- package/assets/wordsearches/nature.txt +404 -0
- package/assets/wordsearches/space.txt +404 -0
- package/assets/wordsearches/sports.txt +404 -0
- package/assets/wordsearches/travel.txt +404 -0
- package/dist/ai.js +6 -4
- package/dist/bot.js +87 -14
- package/dist/commands/index.js +2 -0
- package/dist/commands/pokemon.js +1 -1
- package/dist/commands/retry.js +17 -0
- package/dist/commands/wordsearch.js +111 -89
- package/dist/reactions.js +2 -1
- package/dist/web/app.bundle.js +23 -4
- package/dist/web/app.js +20 -1
- package/package.json +3 -2
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
WORDSEARCH 1
|
|
2
|
+
THEME Travel
|
|
3
|
+
SIZE 15
|
|
4
|
+
COUNT 20
|
|
5
|
+
|
|
6
|
+
PUZZLE 1
|
|
7
|
+
WORDS SIGHTSEEING,SUITCASE,CAMPING,LUGGAGE,ISLAND,TRAVEL,TICKET,PILOT,FERRY,TRIP
|
|
8
|
+
GRID
|
|
9
|
+
P L V Q D Y F N X Y D X X Q B
|
|
10
|
+
I A E X S N D N A L S I F P S
|
|
11
|
+
L T Q X G N I P M A C E I Q M
|
|
12
|
+
O N E G T A L P D G T R K L Q
|
|
13
|
+
T V T K N U Q Y N R T M O H N
|
|
14
|
+
L H J D C I I M P O V F U C V
|
|
15
|
+
H U H K F I E I W Q D T L V M
|
|
16
|
+
N L G E E H T E I I D K O O O
|
|
17
|
+
P X R G N W H T S X J S X T T
|
|
18
|
+
Y R X C A K O A I T Q M G F X
|
|
19
|
+
Y A T K C G V Q Z Z H X F K F
|
|
20
|
+
I C L F R K E L V H L G C A L
|
|
21
|
+
J Y X V R V R C L Z O T I C E
|
|
22
|
+
K B V H T R A V E L T B L S I
|
|
23
|
+
A T L O S U I T C A S E F E N
|
|
24
|
+
END
|
|
25
|
+
|
|
26
|
+
PUZZLE 2
|
|
27
|
+
WORDS CAMPING,FLIGHT,DESERT,RESORT,TRAVEL,TICKET,SAFARI,HOTEL,TRIP,MAP
|
|
28
|
+
GRID
|
|
29
|
+
R S W D U Z J M H T R P T O J
|
|
30
|
+
E N G R A Y V Y K T U E G Y C
|
|
31
|
+
W L W X N X C L P T I S B G P
|
|
32
|
+
C E L L K L H I R E S O R T Y
|
|
33
|
+
Y T E Y N T R O N S O K X B O
|
|
34
|
+
L O B K W T E I L D V V J M C
|
|
35
|
+
K H E B L M J K R E T Y X S F
|
|
36
|
+
V C G N I P M A C A V N C U L
|
|
37
|
+
Y J X D B M X E N I F A M W I
|
|
38
|
+
M L I E G N F K E G T A R A G
|
|
39
|
+
M L W S M Q L Y N C P R S T H
|
|
40
|
+
L L F E Q S M W G V G J C U T
|
|
41
|
+
V V F R G S E V A U M B J K J
|
|
42
|
+
L H F T T T Q O C S A E H Z P
|
|
43
|
+
U U L I P C R E T N P S A X B
|
|
44
|
+
END
|
|
45
|
+
|
|
46
|
+
PUZZLE 3
|
|
47
|
+
WORDS SOFTBALL,AIRPORT,LUGGAGE,CAMPING,TOURIST,ISLAND,BEACH,FERRY,PILOT,ROAD
|
|
48
|
+
GRID
|
|
49
|
+
X O N A O T V T H W P A F I Z
|
|
50
|
+
E M G E E C O I E D J R K T Z
|
|
51
|
+
I W A K J G T L L R A F I M R
|
|
52
|
+
Y X Q A X O A O I Y E U W T D
|
|
53
|
+
S K D N U I C G J P D Y I D Q
|
|
54
|
+
B Q C R H O J A G U S O I N T
|
|
55
|
+
Q K I K F X J F M U L E T Z G
|
|
56
|
+
I S E K T Y R L I P L V M D T
|
|
57
|
+
T V C B G Z O D K I I G D D D
|
|
58
|
+
D A O R Y E N X Z W V N Z S A
|
|
59
|
+
C V Q O H A T I H E Y C G P A
|
|
60
|
+
A W F C L G Y F E R R Y A S E
|
|
61
|
+
Y F A S C C Y A J I D G C L G
|
|
62
|
+
V E I S L L L A B T F O S H P
|
|
63
|
+
B N S T Z T R O P R I A T T M
|
|
64
|
+
END
|
|
65
|
+
|
|
66
|
+
PUZZLE 4
|
|
67
|
+
WORDS BACKPACK,CAMPING,TOURIST,LUGGAGE,DESERT,ISLAND,TICKET,HOTEL,CABIN,ROAD
|
|
68
|
+
GRID
|
|
69
|
+
I D E S E R T Y S F B Q F B O
|
|
70
|
+
R S L B E L X I P E A J G A Q
|
|
71
|
+
O N L M K S Y J Q M C T D M E
|
|
72
|
+
S B E A D N M G Y G K O S O S
|
|
73
|
+
W N W L N L E T O H P X J A D
|
|
74
|
+
V C T P A D T S J D A P B H R
|
|
75
|
+
N N A S D S E N W E C F O O A
|
|
76
|
+
L A P B I E S X G P K I A M J
|
|
77
|
+
G L H R I U B A Z N I D I G C
|
|
78
|
+
T A U U G N G L A J U J N T N
|
|
79
|
+
J O K Z S G S K K Q S I I Z H
|
|
80
|
+
T Z B E U J J S A N P C W T F
|
|
81
|
+
O E U L K P J X P M K W I Z I
|
|
82
|
+
U P E E A T D W A E A L N U Z
|
|
83
|
+
M Q H W X W B C T U X F X R T
|
|
84
|
+
END
|
|
85
|
+
|
|
86
|
+
PUZZLE 5
|
|
87
|
+
WORDS VACATION,SUITCASE,SOFTBALL,RAILWAY,TOURIST,AIRPORT,SAFARI,TRAVEL,CRUISE,ISLAND
|
|
88
|
+
GRID
|
|
89
|
+
F C W Z I W I Y N L W X F J V
|
|
90
|
+
H P O T P O Q R U H C Y L H U
|
|
91
|
+
G D L R W T V Y Z D K E X P V
|
|
92
|
+
W J O O U T A D A Y C N B U T
|
|
93
|
+
T Y Y P O L N B U W L U V C E
|
|
94
|
+
J Q C R Y N C E Y I L A G S T
|
|
95
|
+
K I S I V R T R V L C I A R E
|
|
96
|
+
E M T A C V Z R U A I C A T P
|
|
97
|
+
P T G U I I G Q T I T N V R T
|
|
98
|
+
I O C D W F B I B I S X O R J
|
|
99
|
+
R U P N X H O E U G Q E C T W
|
|
100
|
+
A R G A B N K S K X B J X B A
|
|
101
|
+
F I Z L I T H L E V A R T Z N
|
|
102
|
+
A S A S L X P Y F C V H P C N
|
|
103
|
+
S T D I Y K C L L A B T F O S
|
|
104
|
+
END
|
|
105
|
+
|
|
106
|
+
PUZZLE 6
|
|
107
|
+
WORDS SIGHTSEEING,BACKPACK,TOURIST,RAILWAY,LUGGAGE,CAMPING,FLIGHT,TRAVEL,FERRY,TRIP
|
|
108
|
+
GRID
|
|
109
|
+
G D N K W F U X G X N F F Z F
|
|
110
|
+
I L D U G D Z G E M M G S O U
|
|
111
|
+
B B B A C K P A C K D C Q T C
|
|
112
|
+
S F A H E Y Z A U Q L X R H I
|
|
113
|
+
U J L Y U G E A A M K I S N F
|
|
114
|
+
J X U I S F W C R Y P I L M H
|
|
115
|
+
I F U B G C K A Q O G G U W R
|
|
116
|
+
C S P Y X H I P N H L N G M G
|
|
117
|
+
O C S K R L T J T E Y I G P B
|
|
118
|
+
P P V O W R O S V N N P A O H
|
|
119
|
+
K R J A H D E A W Z U M G Q Y
|
|
120
|
+
O P Y D H E R F I M W A E M D
|
|
121
|
+
K K F P I T F Q V F B C L L F
|
|
122
|
+
N S V N F M R E Y J J C I U K
|
|
123
|
+
Q C G C Y T S I R U O T T J P
|
|
124
|
+
END
|
|
125
|
+
|
|
126
|
+
PUZZLE 7
|
|
127
|
+
WORDS SIGHTSEEING,BACKPACK,ISLAND,TICKET,BEACH,TRAIN,CABIN,TRIP,ROAD,MAP
|
|
128
|
+
GRID
|
|
129
|
+
P D G I P G F A V Q F Z W B A
|
|
130
|
+
E Z K I L N O N G G Q J L Q A
|
|
131
|
+
A S R W T I C K E T R E W X P
|
|
132
|
+
T T C W M E K L U I S L A N D
|
|
133
|
+
T K J G M E N D U W P H B T U
|
|
134
|
+
Y F W K H S G L P O J E D O S
|
|
135
|
+
A Z Z W Y T K C G A A Y C T Y
|
|
136
|
+
W F W F P H Q G R C M V R V P
|
|
137
|
+
R W Y X E G Q C H H Y A T B F
|
|
138
|
+
T X P L K I Z K G N I B A C K
|
|
139
|
+
I X P I Q S D X A N F F W U T
|
|
140
|
+
N F N W P K C A P K C A B D Q
|
|
141
|
+
P H L S E A X Q N O M W I P M
|
|
142
|
+
C K V D K D A O R F X X W K L
|
|
143
|
+
M Z O A M J U I L V F P Q K S
|
|
144
|
+
END
|
|
145
|
+
|
|
146
|
+
PUZZLE 8
|
|
147
|
+
WORDS SIGHTSEEING,RAILWAY,TOURIST,TRAVEL,FLIGHT,TICKET,CRUISE,TRAIN,FERRY,ROAD
|
|
148
|
+
GRID
|
|
149
|
+
A G H P Q V W S P K C U K P V
|
|
150
|
+
D H I G K A J V W J E R A Q G
|
|
151
|
+
A N L N H T S I R U O T Q N X
|
|
152
|
+
O C F I Q H E R V Q H Y Z Y C
|
|
153
|
+
R I X E Z A R W Y R X K S R H
|
|
154
|
+
E F S E B E Z A C M U C U P W
|
|
155
|
+
V W E S F Q A I I F T I P J Y
|
|
156
|
+
E U F T T W A N E L S A Y Z H
|
|
157
|
+
T I L H B Y V R Q E W I D L Z
|
|
158
|
+
E S I G Y S R R L M R A W G R
|
|
159
|
+
K C G I U Y C R Y S Z W Y R T
|
|
160
|
+
C W H S F L Q B W R X H I R O
|
|
161
|
+
I H T P W P C P K R L Y A Z J
|
|
162
|
+
T L D T R A V E L F G I M S O
|
|
163
|
+
D I S L P S Y M J L N O H N K
|
|
164
|
+
END
|
|
165
|
+
|
|
166
|
+
PUZZLE 9
|
|
167
|
+
WORDS SIGHTSEEING,PASSPORT,JOURNEY,AIRPORT,FLIGHT,DESERT,FERRY,BOAT,ROAD,MAP
|
|
168
|
+
GRID
|
|
169
|
+
E W K T I Y R R E F S K K V S
|
|
170
|
+
D V C W U T C J H Y G U M K V
|
|
171
|
+
G N I E E S T H G I S T E D Q
|
|
172
|
+
G H J T A P A S S P O R T W J
|
|
173
|
+
D W D M P I T D P Z S J X H K
|
|
174
|
+
F E U I Y I R L P D L Z A F R
|
|
175
|
+
E P S M I X D P M Z U X W M F
|
|
176
|
+
Z R P E O S T E O A U T S Q Q
|
|
177
|
+
A T V V R B M J M R I H J Y F
|
|
178
|
+
H F W G N T O S E R T G E E S
|
|
179
|
+
Z A U K W U M D V E U I D L H
|
|
180
|
+
Q Z I W R R R A C W T L J L L
|
|
181
|
+
W A G N V O O Y P A R F U X D
|
|
182
|
+
C L E U Q X L A O M Z H D Q X
|
|
183
|
+
S Y T Z K I W B D Z Z R Z G T
|
|
184
|
+
END
|
|
185
|
+
|
|
186
|
+
PUZZLE 10
|
|
187
|
+
WORDS JOURNEY,AIRPORT,SAFARI,TICKET,ISLAND,CRUISE,CABIN,TRIP,BOAT,ROAD
|
|
188
|
+
GRID
|
|
189
|
+
T E G G K J G R C C A B I N V
|
|
190
|
+
I N A J J H A V I E N O N E I
|
|
191
|
+
P P D J F G A I S L A N D W T
|
|
192
|
+
Y E N R U O J C P I R T R Y V
|
|
193
|
+
M B P D S F F K W F C G B P Q
|
|
194
|
+
G Q I R A F A S Z K E C Y K H
|
|
195
|
+
T A S Z H R D V V E S H M W T
|
|
196
|
+
G C I Q C R K O B T E K C I T
|
|
197
|
+
P C G R S R U E B U W L X C J
|
|
198
|
+
J N S T P R U G G C P I Y U Q
|
|
199
|
+
T K S D J O N I O Y K U L E Y
|
|
200
|
+
O A S P I T R T S Q I I O O K
|
|
201
|
+
D A O R I Y A T U E A Y L Y P
|
|
202
|
+
Z E T L A O R V A O X X F D Y
|
|
203
|
+
O X Q C B S X B N D E T A Y Q
|
|
204
|
+
END
|
|
205
|
+
|
|
206
|
+
PUZZLE 11
|
|
207
|
+
WORDS PASSPORT,SOFTBALL,BACKPACK,JOURNEY,TRAVEL,TICKET,DESERT,TRAIN,FERRY,MAP
|
|
208
|
+
GRID
|
|
209
|
+
M D E S R L C H T O G O L Q P
|
|
210
|
+
V X F D K Y E N R U O J D U R
|
|
211
|
+
R R E V C N J R T A L U N W M
|
|
212
|
+
K C R S A I H B A A Y G M B A
|
|
213
|
+
D M R Q P A Y Z U Y M C N L P
|
|
214
|
+
F C Y X K R I W S A W D L G N
|
|
215
|
+
V B O Q C T Y C U L R A F V S
|
|
216
|
+
A J L G A B T L E M B N K D Q
|
|
217
|
+
W T S J B E M V K T N F A E Z
|
|
218
|
+
X F X F K R A R F B G O L S C
|
|
219
|
+
H I P C P R I O N O V N B E E
|
|
220
|
+
L X I C T R S G X J Y K B R G
|
|
221
|
+
A T L F W S J N L B Y L C T D
|
|
222
|
+
D O V R P A S S P O R T V U X
|
|
223
|
+
K P Z I V K U G B X P X K B C
|
|
224
|
+
END
|
|
225
|
+
|
|
226
|
+
PUZZLE 12
|
|
227
|
+
WORDS SIGHTSEEING,SUITCASE,TOURIST,CRUISE,SAFARI,ISLAND,RESORT,FERRY,CABIN,PILOT
|
|
228
|
+
GRID
|
|
229
|
+
H C E Q J X Q L Z U R V V O C
|
|
230
|
+
Z N A B P E I G O B T O L I P
|
|
231
|
+
O S D B S G B S P T R O S E R
|
|
232
|
+
S Z E I I B K V D L H F D W L
|
|
233
|
+
L I U U F N E H N R Q Y O P E
|
|
234
|
+
A R G E G W N R A E O W U S T
|
|
235
|
+
C T R H T O E A L G M N A A O
|
|
236
|
+
R R P T T Z C F S M T C O K U
|
|
237
|
+
Y A Y I X S B C I P T R D N R
|
|
238
|
+
M V E W D F E O V I Y L C X I
|
|
239
|
+
I S L S K V O E U I T J C R S
|
|
240
|
+
X T E A L T R S I H T X C C T
|
|
241
|
+
J J M G K I E I Z N S I X C T
|
|
242
|
+
F X J C G H C Z R Y G L U S C
|
|
243
|
+
S A F A R I X Q R I M S Y N O
|
|
244
|
+
END
|
|
245
|
+
|
|
246
|
+
PUZZLE 13
|
|
247
|
+
WORDS SUITCASE,SOFTBALL,AIRPORT,JOURNEY,LUGGAGE,CAMPING,TICKET,PILOT,BEACH,BOAT
|
|
248
|
+
GRID
|
|
249
|
+
R L T N Q T X G T F S H R J R
|
|
250
|
+
L D D A R Q Z Y Z O I V W T C
|
|
251
|
+
N U L B O L J H F P G H Z I B
|
|
252
|
+
A Y G G O B F T W A C P I C D
|
|
253
|
+
H O O G B B B J Z A C S O K S
|
|
254
|
+
V A G T A A U H E B U V F E O
|
|
255
|
+
I W Q I L G O B I I K J B T W
|
|
256
|
+
V F D L R C E H T A D N W C F
|
|
257
|
+
J Y G H D C F C O L A C W N N
|
|
258
|
+
V O Z M F W A J J G A K Q K U
|
|
259
|
+
F R U B O S P U R M Q A S V R
|
|
260
|
+
A P I R E A I R P O R T Y K P
|
|
261
|
+
J I T B N F I I T F T O L I P
|
|
262
|
+
T D M V E E N W V C Y R D D L
|
|
263
|
+
I Y R Q S G Y Y K P V G T Y P
|
|
264
|
+
END
|
|
265
|
+
|
|
266
|
+
PUZZLE 14
|
|
267
|
+
WORDS SIGHTSEEING,BACKPACK,SUITCASE,CAMPING,TOURIST,RAILWAY,JOURNEY,AIRPORT,TICKET,TRIP
|
|
268
|
+
GRID
|
|
269
|
+
X F N R M F T K Y A W L I A R
|
|
270
|
+
Q Y T G H T E I C S O M F B S
|
|
271
|
+
W E R B N W R F C L M W Y W C
|
|
272
|
+
U P O I D I M I F K Z J E Y H
|
|
273
|
+
A D P S E Q E T P N E E N H T
|
|
274
|
+
C B R N T I G E A O E T R Z L
|
|
275
|
+
V A I U W Q O A S S P G U P Y
|
|
276
|
+
K C A B B R W M A T K F O N G
|
|
277
|
+
W K A O M P L C U K H P J N T
|
|
278
|
+
S P Z R M L T E P D K G I S Z
|
|
279
|
+
W A K W Q I Y D L K N P I F G
|
|
280
|
+
P C V J U F W E K H M R G S U
|
|
281
|
+
E K S S R C L P X A U I X G Z
|
|
282
|
+
A Y N S D M Q Y C O C C O J R
|
|
283
|
+
D N V O B R T Y T B B J G J L
|
|
284
|
+
END
|
|
285
|
+
|
|
286
|
+
PUZZLE 15
|
|
287
|
+
WORDS VACATION,LUGGAGE,RAILWAY,TOURIST,CAMPING,RESORT,TRAVEL,BOAT,TRIP,MAP
|
|
288
|
+
GRID
|
|
289
|
+
E I S Q Q P O X A U R O P O G
|
|
290
|
+
G F E Y K I C L O Z Q P L D J
|
|
291
|
+
I N V H G Z B T D Y A H N L Z
|
|
292
|
+
X E I Y T I Z S L M Q P X C Q
|
|
293
|
+
N X O P T A Y I U L J G G O N
|
|
294
|
+
U T E T M U H R G D E J J O B
|
|
295
|
+
Q N M X E A S U G N S D I U N
|
|
296
|
+
F I N Y L I C O A D X T C R V
|
|
297
|
+
V T Z J H C C T G Z A J A A I
|
|
298
|
+
R R N Z T P X D E C Z I E T J
|
|
299
|
+
R A R N I P D O A H L B R R L
|
|
300
|
+
W V R R A R Y V W W D N K T U
|
|
301
|
+
H E T X T P H Y A Y Z T K M S
|
|
302
|
+
D L S L J S L Y X Q T A O B E
|
|
303
|
+
A O C R E S O R T Y F A Q I F
|
|
304
|
+
END
|
|
305
|
+
|
|
306
|
+
PUZZLE 16
|
|
307
|
+
WORDS JOURNEY,LUGGAGE,CAMPING,RESORT,FERRY,BEACH,CABIN,TRAIN,PILOT,TRIP
|
|
308
|
+
GRID
|
|
309
|
+
P F G I I F Q U L O Y Z Z W T
|
|
310
|
+
S L S E E X E L E G Q I F R K
|
|
311
|
+
V W G R F S R V O J Q H I F R
|
|
312
|
+
R N R T N E U B V F E P Z E Y
|
|
313
|
+
D Y Q I S H D D J T L Q Q G A
|
|
314
|
+
O U A O V Z U G E O Q L X Q I
|
|
315
|
+
V R R R N E N R D I U J N J L
|
|
316
|
+
T T G Y N I B A C G N R D T X
|
|
317
|
+
Q P O I P C O P G W H I N S G
|
|
318
|
+
Q C C M W F Q A H F C D Z E T
|
|
319
|
+
W L A P N H G J O D A Y N D Y
|
|
320
|
+
L C X I B E T Q L P E P C N R
|
|
321
|
+
O K G L H L E X Y W B R T M L
|
|
322
|
+
M W E O L U P S F G U Y D F Z
|
|
323
|
+
Y C D T L G Y B X O Z Y N P G
|
|
324
|
+
END
|
|
325
|
+
|
|
326
|
+
PUZZLE 17
|
|
327
|
+
WORDS VACATION,SUITCASE,TOURIST,TICKET,DESERT,RESORT,HOTEL,TRAIN,ROAD,MAP
|
|
328
|
+
GRID
|
|
329
|
+
V V A R L L B I I V B U A R S
|
|
330
|
+
D T Q O W D E H S A R G I N D
|
|
331
|
+
F O P G J Y T T X R E S O R T
|
|
332
|
+
P U Q M Q D W U O K Y I N S U
|
|
333
|
+
O R N W A Q Q B F H T R V X Q
|
|
334
|
+
Y I E M O M M Y F A T E X G T
|
|
335
|
+
U S L V J Z X M C R S S C K I
|
|
336
|
+
P T A U D Z V A E Y O A L D C
|
|
337
|
+
R U X A J I V S V M D C I D K
|
|
338
|
+
R F O V F V E H M P I T L Z E
|
|
339
|
+
A R B N V D U H O A W I Z M T
|
|
340
|
+
N F J C R F J A O P N U X W U
|
|
341
|
+
M Y S B R Y Y G J K L S O F Z
|
|
342
|
+
I Q D V O G M A P F G C F R K
|
|
343
|
+
Q X N F I T R A I N G T I K P
|
|
344
|
+
END
|
|
345
|
+
|
|
346
|
+
PUZZLE 18
|
|
347
|
+
WORDS SIGHTSEEING,BACKPACK,VACATION,SOFTBALL,TOURIST,AIRPORT,DESERT,TICKET,TRIP,MAP
|
|
348
|
+
GRID
|
|
349
|
+
J C N N O F L Q T R E S E D E
|
|
350
|
+
K T F N G H B M I C O T L Q S
|
|
351
|
+
Q B B I J N D L V K K Z Q O A
|
|
352
|
+
T T C A Z B O J F U V C F P N
|
|
353
|
+
R X S B C Z S I G F B T B P K
|
|
354
|
+
O W J I L K Y W T R B S P P O
|
|
355
|
+
P B N Y R A P I N A Y S S D Z
|
|
356
|
+
R D M V O U C A L F C P D F E
|
|
357
|
+
I D Z S W K O L C Q H A I V T
|
|
358
|
+
A G A K E T B T O K P U V R Z
|
|
359
|
+
A D A T H C Z K D T B T S I T
|
|
360
|
+
L Z Q T S I G H T S E E I N G
|
|
361
|
+
I Q P B K G H P C F A A F W N
|
|
362
|
+
I L A C P H O W Z M N U J I W
|
|
363
|
+
L S M H R U U I V L U T D R H
|
|
364
|
+
END
|
|
365
|
+
|
|
366
|
+
PUZZLE 19
|
|
367
|
+
WORDS PASSPORT,VACATION,BACKPACK,LUGGAGE,JOURNEY,DESERT,CRUISE,FLIGHT,TRAIN,MAP
|
|
368
|
+
GRID
|
|
369
|
+
Y W H Q E M U Y I R P W A K E
|
|
370
|
+
L F A Z N L D X E D J F S D Y
|
|
371
|
+
Y R E S I U R C D Y R Z P W Z
|
|
372
|
+
T C S V A C A T I O N A G N I
|
|
373
|
+
O H T U Z B G Z B Z S R I Z R
|
|
374
|
+
Y C G P T Z Q A V S K A H H P
|
|
375
|
+
L E L I M W C Y P U R S J I Z
|
|
376
|
+
A D N I L K D O U T A H K X N
|
|
377
|
+
F T E R P F R L U G G A G E D
|
|
378
|
+
Q M J A U T N D P B L X E E I
|
|
379
|
+
K P C I B O S L S O J P S F M
|
|
380
|
+
F K X N Z A J T N G Z E E A I
|
|
381
|
+
D O X Z H A N D M W R E P Q V
|
|
382
|
+
T Y Q X X F Y K N T X Z N W E
|
|
383
|
+
W Z N T J M T Z X X C A K L Q
|
|
384
|
+
END
|
|
385
|
+
|
|
386
|
+
PUZZLE 20
|
|
387
|
+
WORDS VACATION,RAILWAY,CRUISE,ISLAND,FLIGHT,FERRY,CABIN,PILOT,ROAD,TRIP
|
|
388
|
+
GRID
|
|
389
|
+
A V O S G Y W U D U G E Q M D
|
|
390
|
+
G R T P Y B M X T R D T Z X W
|
|
391
|
+
X L I R D C E Z C P A M M R D
|
|
392
|
+
X R R Y R A V E G C O D G O O
|
|
393
|
+
T E B U D S C X B S R V E W V
|
|
394
|
+
F H I L F N W Q Q S R C J I A
|
|
395
|
+
H S W N W X A S W A D A M G I
|
|
396
|
+
E N W V P Q K L P J U B C W H
|
|
397
|
+
M O I W H Q L Z S H C I K R P
|
|
398
|
+
Y I E A Y X L C G I T N A K S
|
|
399
|
+
U T P W P U T S D H U I M V X
|
|
400
|
+
G A V I U B R Q G O L F W H X
|
|
401
|
+
N C H A L J K I H W V L A E L
|
|
402
|
+
X A D W N O L O A X N W H G O
|
|
403
|
+
W V W M A F T Y R V N D Z I L
|
|
404
|
+
END
|
package/dist/ai.js
CHANGED
|
@@ -58,7 +58,7 @@ function parseOccurrenceDate(str) {
|
|
|
58
58
|
}
|
|
59
59
|
return null;
|
|
60
60
|
}
|
|
61
|
-
export async function parseRecurringSchedule(userMessage, now) {
|
|
61
|
+
export async function parseRecurringSchedule(userMessage, now, onRemoteStart) {
|
|
62
62
|
const client = getClient();
|
|
63
63
|
if (!client)
|
|
64
64
|
return null;
|
|
@@ -68,6 +68,7 @@ export async function parseRecurringSchedule(userMessage, now) {
|
|
|
68
68
|
const prompt = `The user has asked for a recurring printout. It is currently ${nowStr}. Tell me the next time that I should do this, and what the non-schedule part of the message was (verbatim). If the user didn't specify a time of day, use 8:00 AM. Here's the user's message: ${userMessage}`;
|
|
69
69
|
const results = [];
|
|
70
70
|
const ATTEMPTS = 5;
|
|
71
|
+
await onRemoteStart?.();
|
|
71
72
|
for (let i = 0; i < ATTEMPTS; i++) {
|
|
72
73
|
try {
|
|
73
74
|
const completion = await client.chat.completions.create({
|
|
@@ -130,11 +131,11 @@ function formatScheduleDate(date) {
|
|
|
130
131
|
return `${year}-${month}-${day} ${hours}:${minutes} ${ampm}`;
|
|
131
132
|
}
|
|
132
133
|
export { formatScheduleDate };
|
|
133
|
-
export async function getNextOccurrence(originalMessage, now) {
|
|
134
|
-
const result = await parseRecurringSchedule(originalMessage, now);
|
|
134
|
+
export async function getNextOccurrence(originalMessage, now, onRemoteStart) {
|
|
135
|
+
const result = await parseRecurringSchedule(originalMessage, now, onRemoteStart);
|
|
135
136
|
return result ? result.nextOccurrence : null;
|
|
136
137
|
}
|
|
137
|
-
export async function generateIcon(text, cacheDir) {
|
|
138
|
+
export async function generateIcon(text, cacheDir, onRemoteStart) {
|
|
138
139
|
const prompt = `Black-on-transparent line drawing icon for the TODO item: "${text}". Do not produce any text. Use big, thick lines. No fine detailing.`;
|
|
139
140
|
const hash = createHash('sha1').update(prompt).digest('hex').slice(0, 9);
|
|
140
141
|
const filename = `${hash}.png`;
|
|
@@ -152,6 +153,7 @@ export async function generateIcon(text, cacheDir) {
|
|
|
152
153
|
return null;
|
|
153
154
|
if (await isOverTokenLimit())
|
|
154
155
|
return null;
|
|
156
|
+
await onRemoteStart?.();
|
|
155
157
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
156
158
|
try {
|
|
157
159
|
const response = await client.images.generate({
|
package/dist/bot.js
CHANGED
|
@@ -55,22 +55,42 @@ async function hasReaction(message, emoji) {
|
|
|
55
55
|
return Boolean(reaction?.me);
|
|
56
56
|
}
|
|
57
57
|
async function hasAnyReaction(message) {
|
|
58
|
-
try {
|
|
59
|
-
await message.fetch();
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
// ignore
|
|
63
|
-
}
|
|
64
58
|
for (const v of Object.values(Reaction)) {
|
|
59
|
+
if (v === Reaction.thinking)
|
|
60
|
+
continue;
|
|
65
61
|
if (message.reactions.cache.get(v)) {
|
|
66
62
|
return true;
|
|
67
63
|
}
|
|
68
64
|
}
|
|
69
65
|
return false;
|
|
70
66
|
}
|
|
67
|
+
async function refreshMessage(message) {
|
|
68
|
+
try {
|
|
69
|
+
await message.fetch();
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// continue with the cached message if refresh fails
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function removeReactionSafe(message, emoji) {
|
|
76
|
+
try {
|
|
77
|
+
const reaction = message.reactions.cache.get(emoji);
|
|
78
|
+
if (reaction?.me)
|
|
79
|
+
await reaction.users.remove();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// ignore
|
|
83
|
+
}
|
|
84
|
+
}
|
|
71
85
|
async function reactSafe(message, emoji) {
|
|
72
86
|
try {
|
|
73
87
|
await message.react(emoji);
|
|
88
|
+
if (emoji !== Reaction.thinking) {
|
|
89
|
+
await removeReactionSafe(message, Reaction.thinking);
|
|
90
|
+
}
|
|
91
|
+
if (emoji === Reaction.ok) {
|
|
92
|
+
await removeReactionSafe(message, Reaction.fail);
|
|
93
|
+
}
|
|
74
94
|
}
|
|
75
95
|
catch {
|
|
76
96
|
// ignore
|
|
@@ -87,6 +107,10 @@ async function replySafe(message, content) {
|
|
|
87
107
|
function isPrintTrigger(content) {
|
|
88
108
|
return content.replace(/[^a-zA-Z0-9]/g, '').toLowerCase() === 'print';
|
|
89
109
|
}
|
|
110
|
+
function isCommandMessage(content) {
|
|
111
|
+
const trimmed = content.trim();
|
|
112
|
+
return trimmed.startsWith('!') || trimmed.startsWith('/');
|
|
113
|
+
}
|
|
90
114
|
export function createWindsorBot() {
|
|
91
115
|
const client = new Client({
|
|
92
116
|
intents: [
|
|
@@ -199,6 +223,10 @@ export function createWindsorBot() {
|
|
|
199
223
|
continue;
|
|
200
224
|
if (msg.author.id === botId)
|
|
201
225
|
continue;
|
|
226
|
+
if (isCommandMessage(msg.content)) {
|
|
227
|
+
await handleOnDemand(msg);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
202
230
|
if (await hasAnyReaction(msg))
|
|
203
231
|
continue;
|
|
204
232
|
await handleImmediatePrint(msg, config);
|
|
@@ -286,7 +314,12 @@ export function createWindsorBot() {
|
|
|
286
314
|
return;
|
|
287
315
|
switch (mapping.config.type) {
|
|
288
316
|
case 'immediate-print':
|
|
289
|
-
|
|
317
|
+
if (isCommandMessage(message.content)) {
|
|
318
|
+
await handleOnDemand(message);
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
await handleImmediatePrint(message, mapping.config);
|
|
322
|
+
}
|
|
290
323
|
break;
|
|
291
324
|
case 'accumulating-list': {
|
|
292
325
|
if (isPrintTrigger(message.content)) {
|
|
@@ -305,7 +338,7 @@ export function createWindsorBot() {
|
|
|
305
338
|
break;
|
|
306
339
|
}
|
|
307
340
|
}
|
|
308
|
-
async function handleImmediatePrint(message, config) {
|
|
341
|
+
async function handleImmediatePrint(message, config, retryFailed = false) {
|
|
309
342
|
const rawContent = message.content;
|
|
310
343
|
const urls = extractUrls(rawContent);
|
|
311
344
|
const textWithLinkLabels = replaceUrlsInText(rawContent, urls);
|
|
@@ -329,10 +362,17 @@ export function createWindsorBot() {
|
|
|
329
362
|
}
|
|
330
363
|
if (config.includeIcon) {
|
|
331
364
|
const iconCacheDir = getCurrentConfig().iconCacheDir ?? './icon-cache';
|
|
332
|
-
const iconPath = await generateIcon(strippedText, iconCacheDir);
|
|
365
|
+
const iconPath = await generateIcon(strippedText, iconCacheDir, () => reactSafe(message, Reaction.thinking));
|
|
333
366
|
if (iconPath)
|
|
334
367
|
job.iconPath = iconPath;
|
|
335
368
|
}
|
|
369
|
+
await refreshMessage(message);
|
|
370
|
+
if (await hasAnyReaction(message)) {
|
|
371
|
+
if (!retryFailed || !message.reactions.cache.get(Reaction.fail)?.me) {
|
|
372
|
+
await removeReactionSafe(message, Reaction.thinking);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
336
376
|
try {
|
|
337
377
|
await printJob(job);
|
|
338
378
|
await reactSafe(message, Reaction.ok);
|
|
@@ -390,6 +430,9 @@ export function createWindsorBot() {
|
|
|
390
430
|
if (config.includeMetadata) {
|
|
391
431
|
job.metadataLines = [`Printed at ${formatTimestamp(new Date())}`];
|
|
392
432
|
}
|
|
433
|
+
await refreshMessage(triggerMessage);
|
|
434
|
+
if (await hasAnyReaction(triggerMessage))
|
|
435
|
+
return;
|
|
393
436
|
try {
|
|
394
437
|
await printJob(job);
|
|
395
438
|
await reactSafe(triggerMessage, Reaction.ok);
|
|
@@ -404,7 +447,7 @@ export function createWindsorBot() {
|
|
|
404
447
|
async function handleRecurringSetup(message, config) {
|
|
405
448
|
const rawContent = message.content;
|
|
406
449
|
try {
|
|
407
|
-
const parsed = await parseRecurringSchedule(rawContent, new Date());
|
|
450
|
+
const parsed = await parseRecurringSchedule(rawContent, new Date(), () => reactSafe(message, Reaction.thinking));
|
|
408
451
|
if (!parsed) {
|
|
409
452
|
await reactSafe(message, Reaction.what);
|
|
410
453
|
await replySafe(message, '⁉️ Could not parse a schedule from your message. Please try again with a clearer schedule.');
|
|
@@ -443,21 +486,27 @@ export function createWindsorBot() {
|
|
|
443
486
|
}
|
|
444
487
|
if (config.includeIcon) {
|
|
445
488
|
const iconCacheDir = getCurrentConfig().iconCacheDir ?? './icon-cache';
|
|
446
|
-
const iconPath = await generateIcon(strippedText, iconCacheDir);
|
|
489
|
+
const iconPath = await generateIcon(strippedText, iconCacheDir, () => reactSafe(scheduleReply, Reaction.thinking));
|
|
447
490
|
if (iconPath)
|
|
448
491
|
job.iconPath = iconPath;
|
|
449
492
|
}
|
|
493
|
+
await refreshMessage(scheduleReply);
|
|
494
|
+
if (await hasAnyReaction(scheduleReply)) {
|
|
495
|
+
await removeReactionSafe(scheduleReply, Reaction.thinking);
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
450
498
|
const printedAt = formatTimestamp(new Date());
|
|
451
499
|
try {
|
|
452
500
|
await printJob(job);
|
|
453
501
|
}
|
|
454
502
|
catch (err) {
|
|
503
|
+
await removeReactionSafe(scheduleReply, Reaction.thinking);
|
|
455
504
|
logEvent('error', `Recurring print failed: ${err}`);
|
|
456
505
|
return;
|
|
457
506
|
}
|
|
458
507
|
logEvent('print', `Printed recurring task: ${text}`);
|
|
459
508
|
const originalUserMessage = scheduleReply.content.replace(/^Got it\. I will print ⟪.+?⟫ at /, '');
|
|
460
|
-
const nextOccurrence = await getNextOccurrence(originalUserMessage, new Date());
|
|
509
|
+
const nextOccurrence = await getNextOccurrence(originalUserMessage, new Date(), () => reactSafe(scheduleReply, Reaction.thinking));
|
|
461
510
|
let statusReply;
|
|
462
511
|
if (!nextOccurrence) {
|
|
463
512
|
statusReply = await replySafe(scheduleReply, 'This occurrence has expired and no more prints are scheduled');
|
|
@@ -469,6 +518,7 @@ export function createWindsorBot() {
|
|
|
469
518
|
if (statusReply) {
|
|
470
519
|
await reactSafe(statusReply, Reaction.ok);
|
|
471
520
|
}
|
|
521
|
+
await removeReactionSafe(scheduleReply, Reaction.thinking);
|
|
472
522
|
if (nextOccurrence && statusReply) {
|
|
473
523
|
scheduleRecurringTask(scheduleReply, nextOccurrence, config, bot);
|
|
474
524
|
}
|
|
@@ -477,9 +527,10 @@ export function createWindsorBot() {
|
|
|
477
527
|
const match = /⟪(.+?)⟫/.exec(scheduleReply.content);
|
|
478
528
|
if (!match?.[1])
|
|
479
529
|
return;
|
|
480
|
-
const nextOccurrence = await getNextOccurrence(match[1], new Date());
|
|
530
|
+
const nextOccurrence = await getNextOccurrence(match[1], new Date(), () => reactSafe(latestStatusReply, Reaction.thinking));
|
|
481
531
|
if (!nextOccurrence) {
|
|
482
532
|
await replySafe(latestStatusReply, 'This occurrence has expired and no more prints are scheduled');
|
|
533
|
+
await removeReactionSafe(latestStatusReply, Reaction.thinking);
|
|
483
534
|
return;
|
|
484
535
|
}
|
|
485
536
|
const nextStr = formatScheduleDate(nextOccurrence);
|
|
@@ -487,6 +538,22 @@ export function createWindsorBot() {
|
|
|
487
538
|
await reactSafe(latestStatusReply, Reaction.ok);
|
|
488
539
|
scheduleRecurringTask(scheduleReply, nextOccurrence, config, bot);
|
|
489
540
|
}
|
|
541
|
+
async function retryFailedMessages(message) {
|
|
542
|
+
const mapping = getCurrentConfig().channels.find(m => m.channelId === message.channelId);
|
|
543
|
+
if (!mapping || mapping.config.type !== 'immediate-print') {
|
|
544
|
+
throw new Error('!retry is only available in immediate-print channels');
|
|
545
|
+
}
|
|
546
|
+
const channel = message.channel;
|
|
547
|
+
const messages = await channel.messages.fetch({ limit: 20, before: message.id });
|
|
548
|
+
const failed = [...messages.values()].filter(msg => !msg.author.bot &&
|
|
549
|
+
!msg.reference &&
|
|
550
|
+
!isCommandMessage(msg.content) &&
|
|
551
|
+
msg.reactions.cache.get(Reaction.fail)?.me);
|
|
552
|
+
for (const failedMessage of failed) {
|
|
553
|
+
await handleImmediatePrint(failedMessage, mapping.config, true);
|
|
554
|
+
}
|
|
555
|
+
return failed.length;
|
|
556
|
+
}
|
|
490
557
|
async function handleOnDemand(message) {
|
|
491
558
|
const content = message.content.trim();
|
|
492
559
|
if (!content.startsWith('!') && !content.startsWith('/'))
|
|
@@ -500,7 +567,13 @@ export function createWindsorBot() {
|
|
|
500
567
|
if (cmd.aliases.some(a => commandName.localeCompare(a, undefined, { sensitivity: "base" }) == 0)) {
|
|
501
568
|
foundCommand = true;
|
|
502
569
|
logEvent('command', `Command '${commandName}' invoked by ${message.author.username}`);
|
|
503
|
-
|
|
570
|
+
await refreshMessage(message);
|
|
571
|
+
if (await hasAnyReaction(message))
|
|
572
|
+
return;
|
|
573
|
+
const ctx = {
|
|
574
|
+
printJob,
|
|
575
|
+
retryFailedMessages: () => retryFailedMessages(message),
|
|
576
|
+
};
|
|
504
577
|
const result = await cmd.invoke(args, ctx);
|
|
505
578
|
if (result.kind === 'pass') {
|
|
506
579
|
await reactSafe(message, "✅");
|
package/dist/commands/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { debugFail } from "./debug-fail.js";
|
|
2
2
|
import { helloWorld } from "./hello-world.js";
|
|
3
3
|
import { printPokemon } from "./pokemon.js";
|
|
4
|
+
import { retry } from "./retry.js";
|
|
4
5
|
import { printSudoku } from "./sudoku.js";
|
|
5
6
|
import { printWordsearch } from "./wordsearch.js";
|
|
6
7
|
export const Commands = [
|
|
@@ -8,5 +9,6 @@ export const Commands = [
|
|
|
8
9
|
printSudoku,
|
|
9
10
|
printWordsearch,
|
|
10
11
|
printPokemon,
|
|
12
|
+
retry,
|
|
11
13
|
debugFail
|
|
12
14
|
];
|
package/dist/commands/pokemon.js
CHANGED
|
@@ -131,7 +131,7 @@ async function pokemonWorker(args, ctx) {
|
|
|
131
131
|
iconPath: spritePath,
|
|
132
132
|
};
|
|
133
133
|
await ctx.printJob(job);
|
|
134
|
-
return { kind: 'pass'
|
|
134
|
+
return { kind: 'pass' };
|
|
135
135
|
}
|
|
136
136
|
export const printPokemon = {
|
|
137
137
|
aliases: ['pokemon', 'kanto'],
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { tryExecCommandFunction } from "./util.js";
|
|
2
|
+
async function retryWorker(_args, ctx) {
|
|
3
|
+
if (!ctx.retryFailedMessages) {
|
|
4
|
+
throw new Error("The retry command is not available in this channel");
|
|
5
|
+
}
|
|
6
|
+
const count = await ctx.retryFailedMessages();
|
|
7
|
+
return {
|
|
8
|
+
kind: "pass",
|
|
9
|
+
reply: count === 0
|
|
10
|
+
? "No failed messages found in the previous 20 messages."
|
|
11
|
+
: `Retried ${count} failed message${count === 1 ? "" : "s"}.`,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export const retry = {
|
|
15
|
+
aliases: ["retry"],
|
|
16
|
+
invoke: tryExecCommandFunction(retryWorker),
|
|
17
|
+
};
|