spectrum-ts 4.1.0 → 5.0.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 (46) hide show
  1. package/README.md +29 -67
  2. package/dist/authoring.d.ts +1 -6
  3. package/dist/authoring.js +2 -36
  4. package/dist/elysia.d.ts +1 -0
  5. package/dist/elysia.js +2 -0
  6. package/dist/express.d.ts +1 -0
  7. package/dist/express.js +2 -0
  8. package/dist/hono.d.ts +1 -0
  9. package/dist/hono.js +2 -0
  10. package/dist/index.d.ts +1 -2837
  11. package/dist/index.js +2 -3373
  12. package/dist/manifest.json +5 -5
  13. package/dist/providers/imessage/index.d.ts +1 -222
  14. package/dist/providers/imessage/index.js +2 -25
  15. package/dist/providers/index.d.ts +6 -19
  16. package/dist/providers/index.js +6 -34
  17. package/dist/providers/slack/index.d.ts +1 -46
  18. package/dist/providers/slack/index.js +2 -11
  19. package/dist/providers/telegram/index.d.ts +1 -45
  20. package/dist/providers/telegram/index.js +2 -13
  21. package/dist/providers/terminal/index.d.ts +1 -119
  22. package/dist/providers/terminal/index.js +2 -13
  23. package/dist/providers/whatsapp-business/index.d.ts +1 -27
  24. package/dist/providers/whatsapp-business/index.js +2 -14
  25. package/package.json +23 -26
  26. package/dist/attachment-CnivEhr6.d.ts +0 -29
  27. package/dist/authoring-b9AhXgPI.d.ts +0 -304
  28. package/dist/chunk-2D27WW5B.js +0 -63
  29. package/dist/chunk-34FQGGD7.js +0 -34
  30. package/dist/chunk-3GEJYGZK.js +0 -84
  31. package/dist/chunk-3KWFP4L2.js +0 -864
  32. package/dist/chunk-5XEFJBN2.js +0 -197
  33. package/dist/chunk-6UZFVXQF.js +0 -374
  34. package/dist/chunk-A37PM5N2.js +0 -91
  35. package/dist/chunk-B52VPQO3.js +0 -1379
  36. package/dist/chunk-DMT6BFJV.js +0 -2980
  37. package/dist/chunk-FAIFTUV2.js +0 -139
  38. package/dist/chunk-IM5ADDZS.js +0 -887
  39. package/dist/chunk-LZXPLXZF.js +0 -35
  40. package/dist/chunk-U3QQ56YZ.js +0 -929
  41. package/dist/chunk-UXAKIXVM.js +0 -409
  42. package/dist/chunk-WXLQNANA.js +0 -539
  43. package/dist/chunk-ZR3TKZMT.js +0 -129
  44. package/dist/read-C4uvozGX.d.ts +0 -53
  45. package/dist/types-BIta6Kxi.d.ts +0 -82
  46. package/dist/types-CyfLJXgu.d.ts +0 -1530
package/dist/index.js CHANGED
@@ -1,3373 +1,2 @@
1
- import { createRequire as __spectrumCreateRequire } from "node:module"; const require = __spectrumCreateRequire(import.meta.url);
2
- import {
3
- richlink
4
- } from "./chunk-ZR3TKZMT.js";
5
- import {
6
- FUSOR_MESSAGES_CHANNEL,
7
- fusor,
8
- fusorEvent,
9
- isFusorClient,
10
- isFusorEvent
11
- } from "./chunk-34FQGGD7.js";
12
- import {
13
- group
14
- } from "./chunk-LZXPLXZF.js";
15
- import {
16
- voice
17
- } from "./chunk-FAIFTUV2.js";
18
- import {
19
- option,
20
- poll
21
- } from "./chunk-2D27WW5B.js";
22
- import {
23
- SpectrumCloudError,
24
- cloud
25
- } from "./chunk-3GEJYGZK.js";
26
- import {
27
- contact
28
- } from "./chunk-A37PM5N2.js";
29
- import {
30
- broadcast,
31
- createAsyncQueue,
32
- mergeStreams,
33
- stream
34
- } from "./chunk-5XEFJBN2.js";
35
- import {
36
- fromVCard,
37
- toVCard
38
- } from "./chunk-6UZFVXQF.js";
39
- import {
40
- UnsupportedError,
41
- avatar,
42
- buildSpace,
43
- contentAttrs,
44
- definePlatform,
45
- edit,
46
- markdown,
47
- read,
48
- rename,
49
- reply,
50
- senderAttrs,
51
- typing,
52
- unsend,
53
- wrapProviderMessage
54
- } from "./chunk-B52VPQO3.js";
55
- import {
56
- attachment,
57
- custom,
58
- reaction,
59
- resolveContents,
60
- text
61
- } from "./chunk-UXAKIXVM.js";
62
-
63
- // src/emoji/generated.ts
64
- var GeneratedEmoji = {
65
- _1stPlaceMedal: "\u{1F947}",
66
- _2ndPlaceMedal: "\u{1F948}",
67
- _3rdPlaceMedal: "\u{1F949}",
68
- abacus: "\u{1F9EE}",
69
- abButton: "\u{1F18E}",
70
- aButton: "\u{1F170}\uFE0F",
71
- accordion: "\u{1FA97}",
72
- adhesiveBandage: "\u{1FA79}",
73
- admissionTickets: "\u{1F39F}\uFE0F",
74
- aerialTramway: "\u{1F6A1}",
75
- airplane: "\u2708\uFE0F",
76
- airplaneArrival: "\u{1F6EC}",
77
- airplaneDeparture: "\u{1F6EB}",
78
- alarmClock: "\u23F0",
79
- alembic: "\u2697\uFE0F",
80
- alien: "\u{1F47D}",
81
- alienMonster: "\u{1F47E}",
82
- ambulance: "\u{1F691}",
83
- americanFootball: "\u{1F3C8}",
84
- amphora: "\u{1F3FA}",
85
- anatomicalHeart: "\u{1FAC0}",
86
- anchor: "\u2693",
87
- angerSymbol: "\u{1F4A2}",
88
- angryFace: "\u{1F620}",
89
- angryFaceWithHorns: "\u{1F47F}",
90
- anguishedFace: "\u{1F627}",
91
- ant: "\u{1F41C}",
92
- antennaBars: "\u{1F4F6}",
93
- anxiousFaceWithSweat: "\u{1F630}",
94
- aquarius: "\u2652",
95
- aries: "\u2648",
96
- articulatedLorry: "\u{1F69B}",
97
- artist: "\u{1F9D1}\u200D\u{1F3A8}",
98
- artistPalette: "\u{1F3A8}",
99
- astonishedFace: "\u{1F632}",
100
- astronaut: "\u{1F9D1}\u200D\u{1F680}",
101
- atmSign: "\u{1F3E7}",
102
- atomSymbol: "\u269B\uFE0F",
103
- automobile: "\u{1F697}",
104
- autoRickshaw: "\u{1F6FA}",
105
- avocado: "\u{1F951}",
106
- axe: "\u{1FA93}",
107
- baby: "\u{1F476}",
108
- babyAngel: "\u{1F47C}",
109
- babyBottle: "\u{1F37C}",
110
- babyChick: "\u{1F424}",
111
- babySymbol: "\u{1F6BC}",
112
- backArrow: "\u{1F519}",
113
- backhandIndexPointingDown: "\u{1F447}",
114
- backhandIndexPointingLeft: "\u{1F448}",
115
- backhandIndexPointingRight: "\u{1F449}",
116
- backhandIndexPointingUp: "\u{1F446}",
117
- backpack: "\u{1F392}",
118
- bacon: "\u{1F953}",
119
- badger: "\u{1F9A1}",
120
- badminton: "\u{1F3F8}",
121
- bagel: "\u{1F96F}",
122
- baggageClaim: "\u{1F6C4}",
123
- baguetteBread: "\u{1F956}",
124
- balanceScale: "\u2696\uFE0F",
125
- balletDancer: "\u{1F9D1}\u200D\u{1FA70}",
126
- balletShoes: "\u{1FA70}",
127
- balloon: "\u{1F388}",
128
- ballotBoxWithBallot: "\u{1F5F3}\uFE0F",
129
- banana: "\u{1F34C}",
130
- banjo: "\u{1FA95}",
131
- bank: "\u{1F3E6}",
132
- barberPole: "\u{1F488}",
133
- barChart: "\u{1F4CA}",
134
- baseball: "\u26BE",
135
- basket: "\u{1F9FA}",
136
- basketball: "\u{1F3C0}",
137
- bat: "\u{1F987}",
138
- bathtub: "\u{1F6C1}",
139
- battery: "\u{1F50B}",
140
- bButton: "\u{1F171}\uFE0F",
141
- beachWithUmbrella: "\u{1F3D6}\uFE0F",
142
- beamingFaceWithSmilingEyes: "\u{1F601}",
143
- beans: "\u{1FAD8}",
144
- bear: "\u{1F43B}",
145
- beatingHeart: "\u{1F493}",
146
- beaver: "\u{1F9AB}",
147
- bed: "\u{1F6CF}\uFE0F",
148
- beerMug: "\u{1F37A}",
149
- beetle: "\u{1FAB2}",
150
- bell: "\u{1F514}",
151
- bellhopBell: "\u{1F6CE}\uFE0F",
152
- bellPepper: "\u{1FAD1}",
153
- bellWithSlash: "\u{1F515}",
154
- bentoBox: "\u{1F371}",
155
- beverageBox: "\u{1F9C3}",
156
- bicycle: "\u{1F6B2}",
157
- bikini: "\u{1F459}",
158
- billedCap: "\u{1F9E2}",
159
- biohazard: "\u2623\uFE0F",
160
- bird: "\u{1F426}",
161
- birthdayCake: "\u{1F382}",
162
- bison: "\u{1F9AC}",
163
- bitingLip: "\u{1FAE6}",
164
- blackBird: "\u{1F426}\u200D\u2B1B",
165
- blackCat: "\u{1F408}\u200D\u2B1B",
166
- blackCircle: "\u26AB",
167
- blackFlag: "\u{1F3F4}",
168
- blackHeart: "\u{1F5A4}",
169
- blackLargeSquare: "\u2B1B",
170
- blackMediumSmallSquare: "\u25FE",
171
- blackMediumSquare: "\u25FC\uFE0F",
172
- blackNib: "\u2712\uFE0F",
173
- blackSmallSquare: "\u25AA\uFE0F",
174
- blackSquareButton: "\u{1F532}",
175
- blossom: "\u{1F33C}",
176
- blowfish: "\u{1F421}",
177
- blueberries: "\u{1FAD0}",
178
- blueBook: "\u{1F4D8}",
179
- blueCircle: "\u{1F535}",
180
- blueHeart: "\u{1F499}",
181
- blueSquare: "\u{1F7E6}",
182
- boar: "\u{1F417}",
183
- bomb: "\u{1F4A3}",
184
- bone: "\u{1F9B4}",
185
- bookmark: "\u{1F516}",
186
- bookmarkTabs: "\u{1F4D1}",
187
- books: "\u{1F4DA}",
188
- boomerang: "\u{1FA83}",
189
- bottleWithPoppingCork: "\u{1F37E}",
190
- bouquet: "\u{1F490}",
191
- bowAndArrow: "\u{1F3F9}",
192
- bowling: "\u{1F3B3}",
193
- bowlWithSpoon: "\u{1F963}",
194
- boxingGlove: "\u{1F94A}",
195
- boy: "\u{1F466}",
196
- brain: "\u{1F9E0}",
197
- bread: "\u{1F35E}",
198
- breastFeeding: "\u{1F931}",
199
- brick: "\u{1F9F1}",
200
- bridgeAtNight: "\u{1F309}",
201
- briefcase: "\u{1F4BC}",
202
- briefs: "\u{1FA72}",
203
- brightButton: "\u{1F506}",
204
- broccoli: "\u{1F966}",
205
- brokenChain: "\u26D3\uFE0F\u200D\u{1F4A5}",
206
- brokenHeart: "\u{1F494}",
207
- broom: "\u{1F9F9}",
208
- brownCircle: "\u{1F7E4}",
209
- brownHeart: "\u{1F90E}",
210
- brownMushroom: "\u{1F344}\u200D\u{1F7EB}",
211
- brownSquare: "\u{1F7EB}",
212
- bubbles: "\u{1FAE7}",
213
- bubbleTea: "\u{1F9CB}",
214
- bucket: "\u{1FAA3}",
215
- bug: "\u{1F41B}",
216
- buildingConstruction: "\u{1F3D7}\uFE0F",
217
- bulletTrain: "\u{1F685}",
218
- bullseye: "\u{1F3AF}",
219
- burrito: "\u{1F32F}",
220
- bus: "\u{1F68C}",
221
- busStop: "\u{1F68F}",
222
- bustInSilhouette: "\u{1F464}",
223
- bustsInSilhouette: "\u{1F465}",
224
- butter: "\u{1F9C8}",
225
- butterfly: "\u{1F98B}",
226
- cactus: "\u{1F335}",
227
- calendar: "\u{1F4C5}",
228
- callMeHand: "\u{1F919}",
229
- camel: "\u{1F42A}",
230
- camera: "\u{1F4F7}",
231
- cameraWithFlash: "\u{1F4F8}",
232
- camping: "\u{1F3D5}\uFE0F",
233
- cancer: "\u264B",
234
- candle: "\u{1F56F}\uFE0F",
235
- candy: "\u{1F36C}",
236
- cannedFood: "\u{1F96B}",
237
- canoe: "\u{1F6F6}",
238
- capricorn: "\u2651",
239
- cardFileBox: "\u{1F5C3}\uFE0F",
240
- cardIndex: "\u{1F4C7}",
241
- cardIndexDividers: "\u{1F5C2}\uFE0F",
242
- carouselHorse: "\u{1F3A0}",
243
- carpentrySaw: "\u{1FA9A}",
244
- carpStreamer: "\u{1F38F}",
245
- carrot: "\u{1F955}",
246
- castle: "\u{1F3F0}",
247
- cat: "\u{1F408}",
248
- catFace: "\u{1F431}",
249
- catWithTearsOfJoy: "\u{1F639}",
250
- catWithWrySmile: "\u{1F63C}",
251
- chains: "\u26D3\uFE0F",
252
- chair: "\u{1FA91}",
253
- chartDecreasing: "\u{1F4C9}",
254
- chartIncreasing: "\u{1F4C8}",
255
- chartIncreasingWithYen: "\u{1F4B9}",
256
- checkBoxWithCheck: "\u2611\uFE0F",
257
- checkMark: "\u2714\uFE0F",
258
- checkMarkButton: "\u2705",
259
- cheeseWedge: "\u{1F9C0}",
260
- chequeredFlag: "\u{1F3C1}",
261
- cherries: "\u{1F352}",
262
- cherryBlossom: "\u{1F338}",
263
- chessPawn: "\u265F\uFE0F",
264
- chestnut: "\u{1F330}",
265
- chicken: "\u{1F414}",
266
- child: "\u{1F9D2}",
267
- childrenCrossing: "\u{1F6B8}",
268
- chipmunk: "\u{1F43F}\uFE0F",
269
- chocolateBar: "\u{1F36B}",
270
- chopsticks: "\u{1F962}",
271
- christmasTree: "\u{1F384}",
272
- church: "\u26EA",
273
- cigarette: "\u{1F6AC}",
274
- cinema: "\u{1F3A6}",
275
- circledM: "\u24C2\uFE0F",
276
- circusTent: "\u{1F3AA}",
277
- cityscape: "\u{1F3D9}\uFE0F",
278
- cityscapeAtDusk: "\u{1F306}",
279
- clamp: "\u{1F5DC}\uFE0F",
280
- clapperBoard: "\u{1F3AC}",
281
- clappingHands: "\u{1F44F}",
282
- classicalBuilding: "\u{1F3DB}\uFE0F",
283
- clButton: "\u{1F191}",
284
- clinkingBeerMugs: "\u{1F37B}",
285
- clinkingGlasses: "\u{1F942}",
286
- clipboard: "\u{1F4CB}",
287
- clockwiseVerticalArrows: "\u{1F503}",
288
- closedBook: "\u{1F4D5}",
289
- closedMailboxWithLoweredFlag: "\u{1F4EA}",
290
- closedMailboxWithRaisedFlag: "\u{1F4EB}",
291
- closedUmbrella: "\u{1F302}",
292
- cloud: "\u2601\uFE0F",
293
- cloudWithLightning: "\u{1F329}\uFE0F",
294
- cloudWithLightningAndRain: "\u26C8\uFE0F",
295
- cloudWithRain: "\u{1F327}\uFE0F",
296
- cloudWithSnow: "\u{1F328}\uFE0F",
297
- clownFace: "\u{1F921}",
298
- clubSuit: "\u2663\uFE0F",
299
- clutchBag: "\u{1F45D}",
300
- coat: "\u{1F9E5}",
301
- cockroach: "\u{1FAB3}",
302
- cocktailGlass: "\u{1F378}",
303
- coconut: "\u{1F965}",
304
- coffin: "\u26B0\uFE0F",
305
- coin: "\u{1FA99}",
306
- coldFace: "\u{1F976}",
307
- collision: "\u{1F4A5}",
308
- comet: "\u2604\uFE0F",
309
- compass: "\u{1F9ED}",
310
- computerDisk: "\u{1F4BD}",
311
- computerMouse: "\u{1F5B1}\uFE0F",
312
- confettiBall: "\u{1F38A}",
313
- confoundedFace: "\u{1F616}",
314
- confusedFace: "\u{1F615}",
315
- construction: "\u{1F6A7}",
316
- constructionWorker: "\u{1F477}",
317
- controlKnobs: "\u{1F39B}\uFE0F",
318
- convenienceStore: "\u{1F3EA}",
319
- cook: "\u{1F9D1}\u200D\u{1F373}",
320
- cookedRice: "\u{1F35A}",
321
- cookie: "\u{1F36A}",
322
- cooking: "\u{1F373}",
323
- coolButton: "\u{1F192}",
324
- copyright: "\xA9\uFE0F",
325
- coral: "\u{1FAB8}",
326
- couchAndLamp: "\u{1F6CB}\uFE0F",
327
- counterclockwiseArrowsButton: "\u{1F504}",
328
- coupleWithHeart: "\u{1F491}",
329
- coupleWithHeartManMan: "\u{1F468}\u200D\u2764\uFE0F\u200D\u{1F468}",
330
- coupleWithHeartWomanMan: "\u{1F469}\u200D\u2764\uFE0F\u200D\u{1F468}",
331
- coupleWithHeartWomanWoman: "\u{1F469}\u200D\u2764\uFE0F\u200D\u{1F469}",
332
- cow: "\u{1F404}",
333
- cowboyHatFace: "\u{1F920}",
334
- cowFace: "\u{1F42E}",
335
- crab: "\u{1F980}",
336
- crayon: "\u{1F58D}\uFE0F",
337
- creditCard: "\u{1F4B3}",
338
- crescentMoon: "\u{1F319}",
339
- cricket: "\u{1F997}",
340
- cricketGame: "\u{1F3CF}",
341
- crocodile: "\u{1F40A}",
342
- croissant: "\u{1F950}",
343
- crossedFingers: "\u{1F91E}",
344
- crossedFlags: "\u{1F38C}",
345
- crossedSwords: "\u2694\uFE0F",
346
- crossMark: "\u274C",
347
- crossMarkButton: "\u274E",
348
- crown: "\u{1F451}",
349
- crutch: "\u{1FA7C}",
350
- cryingCat: "\u{1F63F}",
351
- cryingFace: "\u{1F622}",
352
- crystalBall: "\u{1F52E}",
353
- cucumber: "\u{1F952}",
354
- cupcake: "\u{1F9C1}",
355
- cupWithStraw: "\u{1F964}",
356
- curlingStone: "\u{1F94C}",
357
- curlyLoop: "\u27B0",
358
- currencyExchange: "\u{1F4B1}",
359
- curryRice: "\u{1F35B}",
360
- custard: "\u{1F36E}",
361
- customs: "\u{1F6C3}",
362
- cutOfMeat: "\u{1F969}",
363
- cyclone: "\u{1F300}",
364
- dagger: "\u{1F5E1}\uFE0F",
365
- dango: "\u{1F361}",
366
- dashingAway: "\u{1F4A8}",
367
- deafMan: "\u{1F9CF}\u200D\u2642\uFE0F",
368
- deafPerson: "\u{1F9CF}",
369
- deafWoman: "\u{1F9CF}\u200D\u2640\uFE0F",
370
- deciduousTree: "\u{1F333}",
371
- deer: "\u{1F98C}",
372
- deliveryTruck: "\u{1F69A}",
373
- departmentStore: "\u{1F3EC}",
374
- derelictHouse: "\u{1F3DA}\uFE0F",
375
- desert: "\u{1F3DC}\uFE0F",
376
- desertIsland: "\u{1F3DD}\uFE0F",
377
- desktopComputer: "\u{1F5A5}\uFE0F",
378
- detective: "\u{1F575}\uFE0F",
379
- diamondSuit: "\u2666\uFE0F",
380
- diamondWithADot: "\u{1F4A0}",
381
- dimButton: "\u{1F505}",
382
- disappointedFace: "\u{1F61E}",
383
- disguisedFace: "\u{1F978}",
384
- distortedFace: "\u{1FAEA}",
385
- divide: "\u2797",
386
- divingMask: "\u{1F93F}",
387
- diyaLamp: "\u{1FA94}",
388
- dizzy: "\u{1F4AB}",
389
- dna: "\u{1F9EC}",
390
- dodo: "\u{1F9A4}",
391
- dog: "\u{1F415}",
392
- dogFace: "\u{1F436}",
393
- dollarBanknote: "\u{1F4B5}",
394
- dolphin: "\u{1F42C}",
395
- donkey: "\u{1FACF}",
396
- door: "\u{1F6AA}",
397
- dottedLineFace: "\u{1FAE5}",
398
- dottedSixPointedStar: "\u{1F52F}",
399
- doubleCurlyLoop: "\u27BF",
400
- doubleExclamationMark: "\u203C\uFE0F",
401
- doughnut: "\u{1F369}",
402
- dove: "\u{1F54A}\uFE0F",
403
- downArrow: "\u2B07\uFE0F",
404
- downcastFaceWithSweat: "\u{1F613}",
405
- downLeftArrow: "\u2199\uFE0F",
406
- downRightArrow: "\u2198\uFE0F",
407
- downwardsButton: "\u{1F53D}",
408
- dragon: "\u{1F409}",
409
- dragonFace: "\u{1F432}",
410
- dress: "\u{1F457}",
411
- droolingFace: "\u{1F924}",
412
- droplet: "\u{1F4A7}",
413
- dropOfBlood: "\u{1FA78}",
414
- drum: "\u{1F941}",
415
- duck: "\u{1F986}",
416
- dumpling: "\u{1F95F}",
417
- dvd: "\u{1F4C0}",
418
- eagle: "\u{1F985}",
419
- ear: "\u{1F442}",
420
- earOfCorn: "\u{1F33D}",
421
- earWithHearingAid: "\u{1F9BB}",
422
- egg: "\u{1F95A}",
423
- eggplant: "\u{1F346}",
424
- eightOClock: "\u{1F557}",
425
- eightPointedStar: "\u2734\uFE0F",
426
- eightSpokedAsterisk: "\u2733\uFE0F",
427
- eightThirty: "\u{1F563}",
428
- ejectButton: "\u23CF\uFE0F",
429
- electricPlug: "\u{1F50C}",
430
- elephant: "\u{1F418}",
431
- elevator: "\u{1F6D7}",
432
- elevenOClock: "\u{1F55A}",
433
- elevenThirty: "\u{1F566}",
434
- elf: "\u{1F9DD}",
435
- eMail: "\u{1F4E7}",
436
- emptyNest: "\u{1FAB9}",
437
- endArrow: "\u{1F51A}",
438
- enragedFace: "\u{1F621}",
439
- envelope: "\u2709\uFE0F",
440
- envelopeWithArrow: "\u{1F4E9}",
441
- euroBanknote: "\u{1F4B6}",
442
- evergreenTree: "\u{1F332}",
443
- ewe: "\u{1F411}",
444
- exclamationQuestionMark: "\u2049\uFE0F",
445
- explodingHead: "\u{1F92F}",
446
- expressionlessFace: "\u{1F611}",
447
- eye: "\u{1F441}\uFE0F",
448
- eyeInSpeechBubble: "\u{1F441}\uFE0F\u200D\u{1F5E8}\uFE0F",
449
- eyes: "\u{1F440}",
450
- faceBlowingAKiss: "\u{1F618}",
451
- faceExhaling: "\u{1F62E}\u200D\u{1F4A8}",
452
- faceHoldingBackTears: "\u{1F979}",
453
- faceInClouds: "\u{1F636}\u200D\u{1F32B}\uFE0F",
454
- faceSavoringFood: "\u{1F60B}",
455
- faceScreamingInFear: "\u{1F631}",
456
- faceVomiting: "\u{1F92E}",
457
- faceWithBagsUnderEyes: "\u{1FAE9}",
458
- faceWithCrossedOutEyes: "\u{1F635}",
459
- faceWithDiagonalMouth: "\u{1FAE4}",
460
- faceWithHandOverMouth: "\u{1F92D}",
461
- faceWithHeadBandage: "\u{1F915}",
462
- faceWithMedicalMask: "\u{1F637}",
463
- faceWithMonocle: "\u{1F9D0}",
464
- faceWithOpenEyesAndHandOverMouth: "\u{1FAE2}",
465
- faceWithOpenMouth: "\u{1F62E}",
466
- faceWithoutMouth: "\u{1F636}",
467
- faceWithPeekingEye: "\u{1FAE3}",
468
- faceWithRaisedEyebrow: "\u{1F928}",
469
- faceWithRollingEyes: "\u{1F644}",
470
- faceWithSpiralEyes: "\u{1F635}\u200D\u{1F4AB}",
471
- faceWithSteamFromNose: "\u{1F624}",
472
- faceWithSymbolsOnMouth: "\u{1F92C}",
473
- faceWithTearsOfJoy: "\u{1F602}",
474
- faceWithThermometer: "\u{1F912}",
475
- faceWithTongue: "\u{1F61B}",
476
- factory: "\u{1F3ED}",
477
- factoryWorker: "\u{1F9D1}\u200D\u{1F3ED}",
478
- fairy: "\u{1F9DA}",
479
- falafel: "\u{1F9C6}",
480
- fallenLeaf: "\u{1F342}",
481
- family: "\u{1F46A}",
482
- familyAdultAdultChild: "\u{1F9D1}\u200D\u{1F9D1}\u200D\u{1F9D2}",
483
- familyAdultAdultChildChild: "\u{1F9D1}\u200D\u{1F9D1}\u200D\u{1F9D2}\u200D\u{1F9D2}",
484
- familyAdultChild: "\u{1F9D1}\u200D\u{1F9D2}",
485
- familyAdultChildChild: "\u{1F9D1}\u200D\u{1F9D2}\u200D\u{1F9D2}",
486
- familyManBoy: "\u{1F468}\u200D\u{1F466}",
487
- familyManBoyBoy: "\u{1F468}\u200D\u{1F466}\u200D\u{1F466}",
488
- familyManGirl: "\u{1F468}\u200D\u{1F467}",
489
- familyManGirlBoy: "\u{1F468}\u200D\u{1F467}\u200D\u{1F466}",
490
- familyManGirlGirl: "\u{1F468}\u200D\u{1F467}\u200D\u{1F467}",
491
- familyManManBoy: "\u{1F468}\u200D\u{1F468}\u200D\u{1F466}",
492
- familyManManBoyBoy: "\u{1F468}\u200D\u{1F468}\u200D\u{1F466}\u200D\u{1F466}",
493
- familyManManGirl: "\u{1F468}\u200D\u{1F468}\u200D\u{1F467}",
494
- familyManManGirlBoy: "\u{1F468}\u200D\u{1F468}\u200D\u{1F467}\u200D\u{1F466}",
495
- familyManManGirlGirl: "\u{1F468}\u200D\u{1F468}\u200D\u{1F467}\u200D\u{1F467}",
496
- familyManWomanBoy: "\u{1F468}\u200D\u{1F469}\u200D\u{1F466}",
497
- familyManWomanBoyBoy: "\u{1F468}\u200D\u{1F469}\u200D\u{1F466}\u200D\u{1F466}",
498
- familyManWomanGirl: "\u{1F468}\u200D\u{1F469}\u200D\u{1F467}",
499
- familyManWomanGirlBoy: "\u{1F468}\u200D\u{1F469}\u200D\u{1F467}\u200D\u{1F466}",
500
- familyManWomanGirlGirl: "\u{1F468}\u200D\u{1F469}\u200D\u{1F467}\u200D\u{1F467}",
501
- familyWomanBoy: "\u{1F469}\u200D\u{1F466}",
502
- familyWomanBoyBoy: "\u{1F469}\u200D\u{1F466}\u200D\u{1F466}",
503
- familyWomanGirl: "\u{1F469}\u200D\u{1F467}",
504
- familyWomanGirlBoy: "\u{1F469}\u200D\u{1F467}\u200D\u{1F466}",
505
- familyWomanGirlGirl: "\u{1F469}\u200D\u{1F467}\u200D\u{1F467}",
506
- familyWomanWomanBoy: "\u{1F469}\u200D\u{1F469}\u200D\u{1F466}",
507
- familyWomanWomanBoyBoy: "\u{1F469}\u200D\u{1F469}\u200D\u{1F466}\u200D\u{1F466}",
508
- familyWomanWomanGirl: "\u{1F469}\u200D\u{1F469}\u200D\u{1F467}",
509
- familyWomanWomanGirlBoy: "\u{1F469}\u200D\u{1F469}\u200D\u{1F467}\u200D\u{1F466}",
510
- familyWomanWomanGirlGirl: "\u{1F469}\u200D\u{1F469}\u200D\u{1F467}\u200D\u{1F467}",
511
- farmer: "\u{1F9D1}\u200D\u{1F33E}",
512
- fastDownButton: "\u23EC",
513
- fastForwardButton: "\u23E9",
514
- fastReverseButton: "\u23EA",
515
- fastUpButton: "\u23EB",
516
- faxMachine: "\u{1F4E0}",
517
- fearfulFace: "\u{1F628}",
518
- feather: "\u{1FAB6}",
519
- femaleSign: "\u2640\uFE0F",
520
- ferrisWheel: "\u{1F3A1}",
521
- ferry: "\u26F4\uFE0F",
522
- fieldHockey: "\u{1F3D1}",
523
- fightCloud: "\u{1FAEF}",
524
- fileCabinet: "\u{1F5C4}\uFE0F",
525
- fileFolder: "\u{1F4C1}",
526
- filmFrames: "\u{1F39E}\uFE0F",
527
- filmProjector: "\u{1F4FD}\uFE0F",
528
- fingerprint: "\u{1FAC6}",
529
- fire: "\u{1F525}",
530
- firecracker: "\u{1F9E8}",
531
- fireEngine: "\u{1F692}",
532
- fireExtinguisher: "\u{1F9EF}",
533
- firefighter: "\u{1F9D1}\u200D\u{1F692}",
534
- fireworks: "\u{1F386}",
535
- firstQuarterMoon: "\u{1F313}",
536
- firstQuarterMoonFace: "\u{1F31B}",
537
- fish: "\u{1F41F}",
538
- fishCakeWithSwirl: "\u{1F365}",
539
- fishingPole: "\u{1F3A3}",
540
- fiveOClock: "\u{1F554}",
541
- fiveThirty: "\u{1F560}",
542
- flagAfghanistan: "\u{1F1E6}\u{1F1EB}",
543
- flagAlandIslands: "\u{1F1E6}\u{1F1FD}",
544
- flagAlbania: "\u{1F1E6}\u{1F1F1}",
545
- flagAlgeria: "\u{1F1E9}\u{1F1FF}",
546
- flagAmericanSamoa: "\u{1F1E6}\u{1F1F8}",
547
- flagAndorra: "\u{1F1E6}\u{1F1E9}",
548
- flagAngola: "\u{1F1E6}\u{1F1F4}",
549
- flagAnguilla: "\u{1F1E6}\u{1F1EE}",
550
- flagAntarctica: "\u{1F1E6}\u{1F1F6}",
551
- flagAntiguaBarbuda: "\u{1F1E6}\u{1F1EC}",
552
- flagArgentina: "\u{1F1E6}\u{1F1F7}",
553
- flagArmenia: "\u{1F1E6}\u{1F1F2}",
554
- flagAruba: "\u{1F1E6}\u{1F1FC}",
555
- flagAscensionIsland: "\u{1F1E6}\u{1F1E8}",
556
- flagAustralia: "\u{1F1E6}\u{1F1FA}",
557
- flagAustria: "\u{1F1E6}\u{1F1F9}",
558
- flagAzerbaijan: "\u{1F1E6}\u{1F1FF}",
559
- flagBahamas: "\u{1F1E7}\u{1F1F8}",
560
- flagBahrain: "\u{1F1E7}\u{1F1ED}",
561
- flagBangladesh: "\u{1F1E7}\u{1F1E9}",
562
- flagBarbados: "\u{1F1E7}\u{1F1E7}",
563
- flagBelarus: "\u{1F1E7}\u{1F1FE}",
564
- flagBelgium: "\u{1F1E7}\u{1F1EA}",
565
- flagBelize: "\u{1F1E7}\u{1F1FF}",
566
- flagBenin: "\u{1F1E7}\u{1F1EF}",
567
- flagBermuda: "\u{1F1E7}\u{1F1F2}",
568
- flagBhutan: "\u{1F1E7}\u{1F1F9}",
569
- flagBolivia: "\u{1F1E7}\u{1F1F4}",
570
- flagBosniaHerzegovina: "\u{1F1E7}\u{1F1E6}",
571
- flagBotswana: "\u{1F1E7}\u{1F1FC}",
572
- flagBouvetIsland: "\u{1F1E7}\u{1F1FB}",
573
- flagBrazil: "\u{1F1E7}\u{1F1F7}",
574
- flagBritishIndianOceanTerritory: "\u{1F1EE}\u{1F1F4}",
575
- flagBritishVirginIslands: "\u{1F1FB}\u{1F1EC}",
576
- flagBrunei: "\u{1F1E7}\u{1F1F3}",
577
- flagBulgaria: "\u{1F1E7}\u{1F1EC}",
578
- flagBurkinaFaso: "\u{1F1E7}\u{1F1EB}",
579
- flagBurundi: "\u{1F1E7}\u{1F1EE}",
580
- flagCambodia: "\u{1F1F0}\u{1F1ED}",
581
- flagCameroon: "\u{1F1E8}\u{1F1F2}",
582
- flagCanada: "\u{1F1E8}\u{1F1E6}",
583
- flagCanaryIslands: "\u{1F1EE}\u{1F1E8}",
584
- flagCapeVerde: "\u{1F1E8}\u{1F1FB}",
585
- flagCaribbeanNetherlands: "\u{1F1E7}\u{1F1F6}",
586
- flagCaymanIslands: "\u{1F1F0}\u{1F1FE}",
587
- flagCentralAfricanRepublic: "\u{1F1E8}\u{1F1EB}",
588
- flagCeutaMelilla: "\u{1F1EA}\u{1F1E6}",
589
- flagChad: "\u{1F1F9}\u{1F1E9}",
590
- flagChile: "\u{1F1E8}\u{1F1F1}",
591
- flagChina: "\u{1F1E8}\u{1F1F3}",
592
- flagChristmasIsland: "\u{1F1E8}\u{1F1FD}",
593
- flagClippertonIsland: "\u{1F1E8}\u{1F1F5}",
594
- flagCocosIslands: "\u{1F1E8}\u{1F1E8}",
595
- flagColombia: "\u{1F1E8}\u{1F1F4}",
596
- flagComoros: "\u{1F1F0}\u{1F1F2}",
597
- flagCongoBrazzaville: "\u{1F1E8}\u{1F1EC}",
598
- flagCongoKinshasa: "\u{1F1E8}\u{1F1E9}",
599
- flagCookIslands: "\u{1F1E8}\u{1F1F0}",
600
- flagCostaRica: "\u{1F1E8}\u{1F1F7}",
601
- flagCoteDIvoire: "\u{1F1E8}\u{1F1EE}",
602
- flagCroatia: "\u{1F1ED}\u{1F1F7}",
603
- flagCuba: "\u{1F1E8}\u{1F1FA}",
604
- flagCuracao: "\u{1F1E8}\u{1F1FC}",
605
- flagCyprus: "\u{1F1E8}\u{1F1FE}",
606
- flagCzechia: "\u{1F1E8}\u{1F1FF}",
607
- flagDenmark: "\u{1F1E9}\u{1F1F0}",
608
- flagDiegoGarcia: "\u{1F1E9}\u{1F1EC}",
609
- flagDjibouti: "\u{1F1E9}\u{1F1EF}",
610
- flagDominica: "\u{1F1E9}\u{1F1F2}",
611
- flagDominicanRepublic: "\u{1F1E9}\u{1F1F4}",
612
- flagEcuador: "\u{1F1EA}\u{1F1E8}",
613
- flagEgypt: "\u{1F1EA}\u{1F1EC}",
614
- flagElSalvador: "\u{1F1F8}\u{1F1FB}",
615
- flagEngland: "\u{1F3F4}\u{E0067}\u{E0062}\u{E0065}\u{E006E}\u{E0067}\u{E007F}",
616
- flagEquatorialGuinea: "\u{1F1EC}\u{1F1F6}",
617
- flagEritrea: "\u{1F1EA}\u{1F1F7}",
618
- flagEstonia: "\u{1F1EA}\u{1F1EA}",
619
- flagEswatini: "\u{1F1F8}\u{1F1FF}",
620
- flagEthiopia: "\u{1F1EA}\u{1F1F9}",
621
- flagEuropeanUnion: "\u{1F1EA}\u{1F1FA}",
622
- flagFalklandIslands: "\u{1F1EB}\u{1F1F0}",
623
- flagFaroeIslands: "\u{1F1EB}\u{1F1F4}",
624
- flagFiji: "\u{1F1EB}\u{1F1EF}",
625
- flagFinland: "\u{1F1EB}\u{1F1EE}",
626
- flagFrance: "\u{1F1EB}\u{1F1F7}",
627
- flagFrenchGuiana: "\u{1F1EC}\u{1F1EB}",
628
- flagFrenchPolynesia: "\u{1F1F5}\u{1F1EB}",
629
- flagFrenchSouthernTerritories: "\u{1F1F9}\u{1F1EB}",
630
- flagGabon: "\u{1F1EC}\u{1F1E6}",
631
- flagGambia: "\u{1F1EC}\u{1F1F2}",
632
- flagGeorgia: "\u{1F1EC}\u{1F1EA}",
633
- flagGermany: "\u{1F1E9}\u{1F1EA}",
634
- flagGhana: "\u{1F1EC}\u{1F1ED}",
635
- flagGibraltar: "\u{1F1EC}\u{1F1EE}",
636
- flagGreece: "\u{1F1EC}\u{1F1F7}",
637
- flagGreenland: "\u{1F1EC}\u{1F1F1}",
638
- flagGrenada: "\u{1F1EC}\u{1F1E9}",
639
- flagGuadeloupe: "\u{1F1EC}\u{1F1F5}",
640
- flagGuam: "\u{1F1EC}\u{1F1FA}",
641
- flagGuatemala: "\u{1F1EC}\u{1F1F9}",
642
- flagGuernsey: "\u{1F1EC}\u{1F1EC}",
643
- flagGuinea: "\u{1F1EC}\u{1F1F3}",
644
- flagGuineaBissau: "\u{1F1EC}\u{1F1FC}",
645
- flagGuyana: "\u{1F1EC}\u{1F1FE}",
646
- flagHaiti: "\u{1F1ED}\u{1F1F9}",
647
- flagHeardMcdonaldIslands: "\u{1F1ED}\u{1F1F2}",
648
- flagHonduras: "\u{1F1ED}\u{1F1F3}",
649
- flagHongKongSarChina: "\u{1F1ED}\u{1F1F0}",
650
- flagHungary: "\u{1F1ED}\u{1F1FA}",
651
- flagIceland: "\u{1F1EE}\u{1F1F8}",
652
- flagIndia: "\u{1F1EE}\u{1F1F3}",
653
- flagIndonesia: "\u{1F1EE}\u{1F1E9}",
654
- flagInHole: "\u26F3",
655
- flagIran: "\u{1F1EE}\u{1F1F7}",
656
- flagIraq: "\u{1F1EE}\u{1F1F6}",
657
- flagIreland: "\u{1F1EE}\u{1F1EA}",
658
- flagIsleOfMan: "\u{1F1EE}\u{1F1F2}",
659
- flagIsrael: "\u{1F1EE}\u{1F1F1}",
660
- flagItaly: "\u{1F1EE}\u{1F1F9}",
661
- flagJamaica: "\u{1F1EF}\u{1F1F2}",
662
- flagJapan: "\u{1F1EF}\u{1F1F5}",
663
- flagJersey: "\u{1F1EF}\u{1F1EA}",
664
- flagJordan: "\u{1F1EF}\u{1F1F4}",
665
- flagKazakhstan: "\u{1F1F0}\u{1F1FF}",
666
- flagKenya: "\u{1F1F0}\u{1F1EA}",
667
- flagKiribati: "\u{1F1F0}\u{1F1EE}",
668
- flagKosovo: "\u{1F1FD}\u{1F1F0}",
669
- flagKuwait: "\u{1F1F0}\u{1F1FC}",
670
- flagKyrgyzstan: "\u{1F1F0}\u{1F1EC}",
671
- flagLaos: "\u{1F1F1}\u{1F1E6}",
672
- flagLatvia: "\u{1F1F1}\u{1F1FB}",
673
- flagLebanon: "\u{1F1F1}\u{1F1E7}",
674
- flagLesotho: "\u{1F1F1}\u{1F1F8}",
675
- flagLiberia: "\u{1F1F1}\u{1F1F7}",
676
- flagLibya: "\u{1F1F1}\u{1F1FE}",
677
- flagLiechtenstein: "\u{1F1F1}\u{1F1EE}",
678
- flagLithuania: "\u{1F1F1}\u{1F1F9}",
679
- flagLuxembourg: "\u{1F1F1}\u{1F1FA}",
680
- flagMacaoSarChina: "\u{1F1F2}\u{1F1F4}",
681
- flagMadagascar: "\u{1F1F2}\u{1F1EC}",
682
- flagMalawi: "\u{1F1F2}\u{1F1FC}",
683
- flagMalaysia: "\u{1F1F2}\u{1F1FE}",
684
- flagMaldives: "\u{1F1F2}\u{1F1FB}",
685
- flagMali: "\u{1F1F2}\u{1F1F1}",
686
- flagMalta: "\u{1F1F2}\u{1F1F9}",
687
- flagMarshallIslands: "\u{1F1F2}\u{1F1ED}",
688
- flagMartinique: "\u{1F1F2}\u{1F1F6}",
689
- flagMauritania: "\u{1F1F2}\u{1F1F7}",
690
- flagMauritius: "\u{1F1F2}\u{1F1FA}",
691
- flagMayotte: "\u{1F1FE}\u{1F1F9}",
692
- flagMexico: "\u{1F1F2}\u{1F1FD}",
693
- flagMicronesia: "\u{1F1EB}\u{1F1F2}",
694
- flagMoldova: "\u{1F1F2}\u{1F1E9}",
695
- flagMonaco: "\u{1F1F2}\u{1F1E8}",
696
- flagMongolia: "\u{1F1F2}\u{1F1F3}",
697
- flagMontenegro: "\u{1F1F2}\u{1F1EA}",
698
- flagMontserrat: "\u{1F1F2}\u{1F1F8}",
699
- flagMorocco: "\u{1F1F2}\u{1F1E6}",
700
- flagMozambique: "\u{1F1F2}\u{1F1FF}",
701
- flagMyanmar: "\u{1F1F2}\u{1F1F2}",
702
- flagNamibia: "\u{1F1F3}\u{1F1E6}",
703
- flagNauru: "\u{1F1F3}\u{1F1F7}",
704
- flagNepal: "\u{1F1F3}\u{1F1F5}",
705
- flagNetherlands: "\u{1F1F3}\u{1F1F1}",
706
- flagNewCaledonia: "\u{1F1F3}\u{1F1E8}",
707
- flagNewZealand: "\u{1F1F3}\u{1F1FF}",
708
- flagNicaragua: "\u{1F1F3}\u{1F1EE}",
709
- flagNiger: "\u{1F1F3}\u{1F1EA}",
710
- flagNigeria: "\u{1F1F3}\u{1F1EC}",
711
- flagNiue: "\u{1F1F3}\u{1F1FA}",
712
- flagNorfolkIsland: "\u{1F1F3}\u{1F1EB}",
713
- flagNorthernMarianaIslands: "\u{1F1F2}\u{1F1F5}",
714
- flagNorthKorea: "\u{1F1F0}\u{1F1F5}",
715
- flagNorthMacedonia: "\u{1F1F2}\u{1F1F0}",
716
- flagNorway: "\u{1F1F3}\u{1F1F4}",
717
- flagOman: "\u{1F1F4}\u{1F1F2}",
718
- flagPakistan: "\u{1F1F5}\u{1F1F0}",
719
- flagPalau: "\u{1F1F5}\u{1F1FC}",
720
- flagPalestinianTerritories: "\u{1F1F5}\u{1F1F8}",
721
- flagPanama: "\u{1F1F5}\u{1F1E6}",
722
- flagPapuaNewGuinea: "\u{1F1F5}\u{1F1EC}",
723
- flagParaguay: "\u{1F1F5}\u{1F1FE}",
724
- flagPeru: "\u{1F1F5}\u{1F1EA}",
725
- flagPhilippines: "\u{1F1F5}\u{1F1ED}",
726
- flagPitcairnIslands: "\u{1F1F5}\u{1F1F3}",
727
- flagPoland: "\u{1F1F5}\u{1F1F1}",
728
- flagPortugal: "\u{1F1F5}\u{1F1F9}",
729
- flagPuertoRico: "\u{1F1F5}\u{1F1F7}",
730
- flagQatar: "\u{1F1F6}\u{1F1E6}",
731
- flagReunion: "\u{1F1F7}\u{1F1EA}",
732
- flagRomania: "\u{1F1F7}\u{1F1F4}",
733
- flagRussia: "\u{1F1F7}\u{1F1FA}",
734
- flagRwanda: "\u{1F1F7}\u{1F1FC}",
735
- flagSamoa: "\u{1F1FC}\u{1F1F8}",
736
- flagSanMarino: "\u{1F1F8}\u{1F1F2}",
737
- flagSaoTomePrincipe: "\u{1F1F8}\u{1F1F9}",
738
- flagSark: "\u{1F1E8}\u{1F1F6}",
739
- flagSaudiArabia: "\u{1F1F8}\u{1F1E6}",
740
- flagScotland: "\u{1F3F4}\u{E0067}\u{E0062}\u{E0073}\u{E0063}\u{E0074}\u{E007F}",
741
- flagSenegal: "\u{1F1F8}\u{1F1F3}",
742
- flagSerbia: "\u{1F1F7}\u{1F1F8}",
743
- flagSeychelles: "\u{1F1F8}\u{1F1E8}",
744
- flagSierraLeone: "\u{1F1F8}\u{1F1F1}",
745
- flagSingapore: "\u{1F1F8}\u{1F1EC}",
746
- flagSintMaarten: "\u{1F1F8}\u{1F1FD}",
747
- flagSlovakia: "\u{1F1F8}\u{1F1F0}",
748
- flagSlovenia: "\u{1F1F8}\u{1F1EE}",
749
- flagSolomonIslands: "\u{1F1F8}\u{1F1E7}",
750
- flagSomalia: "\u{1F1F8}\u{1F1F4}",
751
- flagSouthAfrica: "\u{1F1FF}\u{1F1E6}",
752
- flagSouthGeorgiaSouthSandwichIslands: "\u{1F1EC}\u{1F1F8}",
753
- flagSouthKorea: "\u{1F1F0}\u{1F1F7}",
754
- flagSouthSudan: "\u{1F1F8}\u{1F1F8}",
755
- flagSpain: "\u{1F1EA}\u{1F1F8}",
756
- flagSriLanka: "\u{1F1F1}\u{1F1F0}",
757
- flagStBarthelemy: "\u{1F1E7}\u{1F1F1}",
758
- flagStHelena: "\u{1F1F8}\u{1F1ED}",
759
- flagStKittsNevis: "\u{1F1F0}\u{1F1F3}",
760
- flagStLucia: "\u{1F1F1}\u{1F1E8}",
761
- flagStMartin: "\u{1F1F2}\u{1F1EB}",
762
- flagStPierreMiquelon: "\u{1F1F5}\u{1F1F2}",
763
- flagStVincentGrenadines: "\u{1F1FB}\u{1F1E8}",
764
- flagSudan: "\u{1F1F8}\u{1F1E9}",
765
- flagSuriname: "\u{1F1F8}\u{1F1F7}",
766
- flagSvalbardJanMayen: "\u{1F1F8}\u{1F1EF}",
767
- flagSweden: "\u{1F1F8}\u{1F1EA}",
768
- flagSwitzerland: "\u{1F1E8}\u{1F1ED}",
769
- flagSyria: "\u{1F1F8}\u{1F1FE}",
770
- flagTaiwan: "\u{1F1F9}\u{1F1FC}",
771
- flagTajikistan: "\u{1F1F9}\u{1F1EF}",
772
- flagTanzania: "\u{1F1F9}\u{1F1FF}",
773
- flagThailand: "\u{1F1F9}\u{1F1ED}",
774
- flagTimorLeste: "\u{1F1F9}\u{1F1F1}",
775
- flagTogo: "\u{1F1F9}\u{1F1EC}",
776
- flagTokelau: "\u{1F1F9}\u{1F1F0}",
777
- flagTonga: "\u{1F1F9}\u{1F1F4}",
778
- flagTrinidadTobago: "\u{1F1F9}\u{1F1F9}",
779
- flagTristanDaCunha: "\u{1F1F9}\u{1F1E6}",
780
- flagTunisia: "\u{1F1F9}\u{1F1F3}",
781
- flagTurkiye: "\u{1F1F9}\u{1F1F7}",
782
- flagTurkmenistan: "\u{1F1F9}\u{1F1F2}",
783
- flagTurksCaicosIslands: "\u{1F1F9}\u{1F1E8}",
784
- flagTuvalu: "\u{1F1F9}\u{1F1FB}",
785
- flagUganda: "\u{1F1FA}\u{1F1EC}",
786
- flagUkraine: "\u{1F1FA}\u{1F1E6}",
787
- flagUnitedArabEmirates: "\u{1F1E6}\u{1F1EA}",
788
- flagUnitedKingdom: "\u{1F1EC}\u{1F1E7}",
789
- flagUnitedNations: "\u{1F1FA}\u{1F1F3}",
790
- flagUnitedStates: "\u{1F1FA}\u{1F1F8}",
791
- flagUruguay: "\u{1F1FA}\u{1F1FE}",
792
- flagUSOutlyingIslands: "\u{1F1FA}\u{1F1F2}",
793
- flagUSVirginIslands: "\u{1F1FB}\u{1F1EE}",
794
- flagUzbekistan: "\u{1F1FA}\u{1F1FF}",
795
- flagVanuatu: "\u{1F1FB}\u{1F1FA}",
796
- flagVaticanCity: "\u{1F1FB}\u{1F1E6}",
797
- flagVenezuela: "\u{1F1FB}\u{1F1EA}",
798
- flagVietnam: "\u{1F1FB}\u{1F1F3}",
799
- flagWales: "\u{1F3F4}\u{E0067}\u{E0062}\u{E0077}\u{E006C}\u{E0073}\u{E007F}",
800
- flagWallisFutuna: "\u{1F1FC}\u{1F1EB}",
801
- flagWesternSahara: "\u{1F1EA}\u{1F1ED}",
802
- flagYemen: "\u{1F1FE}\u{1F1EA}",
803
- flagZambia: "\u{1F1FF}\u{1F1F2}",
804
- flagZimbabwe: "\u{1F1FF}\u{1F1FC}",
805
- flamingo: "\u{1F9A9}",
806
- flashlight: "\u{1F526}",
807
- flatbread: "\u{1FAD3}",
808
- flatShoe: "\u{1F97F}",
809
- fleurDeLis: "\u269C\uFE0F",
810
- flexedBiceps: "\u{1F4AA}",
811
- floppyDisk: "\u{1F4BE}",
812
- flowerPlayingCards: "\u{1F3B4}",
813
- flushedFace: "\u{1F633}",
814
- flute: "\u{1FA88}",
815
- fly: "\u{1FAB0}",
816
- flyingDisc: "\u{1F94F}",
817
- flyingSaucer: "\u{1F6F8}",
818
- fog: "\u{1F32B}\uFE0F",
819
- foggy: "\u{1F301}",
820
- foldedHands: "\u{1F64F}",
821
- foldingHandFan: "\u{1FAAD}",
822
- fondue: "\u{1FAD5}",
823
- foot: "\u{1F9B6}",
824
- footprints: "\u{1F463}",
825
- forkAndKnife: "\u{1F374}",
826
- forkAndKnifeWithPlate: "\u{1F37D}\uFE0F",
827
- fortuneCookie: "\u{1F960}",
828
- fountain: "\u26F2",
829
- fountainPen: "\u{1F58B}\uFE0F",
830
- fourLeafClover: "\u{1F340}",
831
- fourOClock: "\u{1F553}",
832
- fourThirty: "\u{1F55F}",
833
- fox: "\u{1F98A}",
834
- framedPicture: "\u{1F5BC}\uFE0F",
835
- freeButton: "\u{1F193}",
836
- frenchFries: "\u{1F35F}",
837
- friedShrimp: "\u{1F364}",
838
- frog: "\u{1F438}",
839
- frontFacingBabyChick: "\u{1F425}",
840
- frowningFace: "\u2639\uFE0F",
841
- frowningFaceWithOpenMouth: "\u{1F626}",
842
- fuelPump: "\u26FD",
843
- fullMoon: "\u{1F315}",
844
- fullMoonFace: "\u{1F31D}",
845
- funeralUrn: "\u26B1\uFE0F",
846
- gameDie: "\u{1F3B2}",
847
- garlic: "\u{1F9C4}",
848
- gear: "\u2699\uFE0F",
849
- gemini: "\u264A",
850
- gemStone: "\u{1F48E}",
851
- genie: "\u{1F9DE}",
852
- ghost: "\u{1F47B}",
853
- gingerRoot: "\u{1FADA}",
854
- giraffe: "\u{1F992}",
855
- girl: "\u{1F467}",
856
- glasses: "\u{1F453}",
857
- glassOfMilk: "\u{1F95B}",
858
- globeShowingAmericas: "\u{1F30E}",
859
- globeShowingAsiaAustralia: "\u{1F30F}",
860
- globeShowingEuropeAfrica: "\u{1F30D}",
861
- globeWithMeridians: "\u{1F310}",
862
- gloves: "\u{1F9E4}",
863
- glowingStar: "\u{1F31F}",
864
- goalNet: "\u{1F945}",
865
- goat: "\u{1F410}",
866
- goblin: "\u{1F47A}",
867
- goggles: "\u{1F97D}",
868
- goose: "\u{1FABF}",
869
- gorilla: "\u{1F98D}",
870
- graduationCap: "\u{1F393}",
871
- grapes: "\u{1F347}",
872
- greenApple: "\u{1F34F}",
873
- greenBook: "\u{1F4D7}",
874
- greenCircle: "\u{1F7E2}",
875
- greenHeart: "\u{1F49A}",
876
- greenSalad: "\u{1F957}",
877
- greenSquare: "\u{1F7E9}",
878
- greyHeart: "\u{1FA76}",
879
- grimacingFace: "\u{1F62C}",
880
- grinningCat: "\u{1F63A}",
881
- grinningCatWithSmilingEyes: "\u{1F638}",
882
- grinningFace: "\u{1F600}",
883
- grinningFaceWithBigEyes: "\u{1F603}",
884
- grinningFaceWithSmilingEyes: "\u{1F604}",
885
- grinningFaceWithSweat: "\u{1F605}",
886
- grinningSquintingFace: "\u{1F606}",
887
- growingHeart: "\u{1F497}",
888
- guard: "\u{1F482}",
889
- guideDog: "\u{1F9AE}",
890
- guitar: "\u{1F3B8}",
891
- hairPick: "\u{1FAAE}",
892
- hairyCreature: "\u{1FAC8}",
893
- hamburger: "\u{1F354}",
894
- hammer: "\u{1F528}",
895
- hammerAndPick: "\u2692\uFE0F",
896
- hammerAndWrench: "\u{1F6E0}\uFE0F",
897
- hamsa: "\u{1FAAC}",
898
- hamster: "\u{1F439}",
899
- handbag: "\u{1F45C}",
900
- handshake: "\u{1F91D}",
901
- handWithFingersSplayed: "\u{1F590}\uFE0F",
902
- handWithIndexFingerAndThumbCrossed: "\u{1FAF0}",
903
- harp: "\u{1FA89}",
904
- hatchingChick: "\u{1F423}",
905
- headphone: "\u{1F3A7}",
906
- headShakingHorizontally: "\u{1F642}\u200D\u2194\uFE0F",
907
- headShakingVertically: "\u{1F642}\u200D\u2195\uFE0F",
908
- headstone: "\u{1FAA6}",
909
- healthWorker: "\u{1F9D1}\u200D\u2695\uFE0F",
910
- hearNoEvilMonkey: "\u{1F649}",
911
- heartDecoration: "\u{1F49F}",
912
- heartExclamation: "\u2763\uFE0F",
913
- heartHands: "\u{1FAF6}",
914
- heartOnFire: "\u2764\uFE0F\u200D\u{1F525}",
915
- heartSuit: "\u2665\uFE0F",
916
- heartWithArrow: "\u{1F498}",
917
- heartWithRibbon: "\u{1F49D}",
918
- heavyDollarSign: "\u{1F4B2}",
919
- heavyEqualsSign: "\u{1F7F0}",
920
- hedgehog: "\u{1F994}",
921
- helicopter: "\u{1F681}",
922
- herb: "\u{1F33F}",
923
- hibiscus: "\u{1F33A}",
924
- highHeeledShoe: "\u{1F460}",
925
- highSpeedTrain: "\u{1F684}",
926
- highVoltage: "\u26A1",
927
- hikingBoot: "\u{1F97E}",
928
- hinduTemple: "\u{1F6D5}",
929
- hippopotamus: "\u{1F99B}",
930
- hole: "\u{1F573}\uFE0F",
931
- hollowRedCircle: "\u2B55",
932
- honeybee: "\u{1F41D}",
933
- honeyPot: "\u{1F36F}",
934
- hook: "\u{1FA9D}",
935
- horizontalTrafficLight: "\u{1F6A5}",
936
- horse: "\u{1F40E}",
937
- horseFace: "\u{1F434}",
938
- horseRacing: "\u{1F3C7}",
939
- hospital: "\u{1F3E5}",
940
- hotBeverage: "\u2615",
941
- hotDog: "\u{1F32D}",
942
- hotel: "\u{1F3E8}",
943
- hotFace: "\u{1F975}",
944
- hotPepper: "\u{1F336}\uFE0F",
945
- hotSprings: "\u2668\uFE0F",
946
- hourglassDone: "\u231B",
947
- hourglassNotDone: "\u23F3",
948
- house: "\u{1F3E0}",
949
- houses: "\u{1F3D8}\uFE0F",
950
- houseWithGarden: "\u{1F3E1}",
951
- hundredPoints: "\u{1F4AF}",
952
- hushedFace: "\u{1F62F}",
953
- hut: "\u{1F6D6}",
954
- hyacinth: "\u{1FABB}",
955
- ice: "\u{1F9CA}",
956
- iceCream: "\u{1F368}",
957
- iceHockey: "\u{1F3D2}",
958
- iceSkate: "\u26F8\uFE0F",
959
- idButton: "\u{1F194}",
960
- identificationCard: "\u{1FAAA}",
961
- inboxTray: "\u{1F4E5}",
962
- incomingEnvelope: "\u{1F4E8}",
963
- indexPointingAtTheViewer: "\u{1FAF5}",
964
- indexPointingUp: "\u261D\uFE0F",
965
- infinity: "\u267E\uFE0F",
966
- information: "\u2139\uFE0F",
967
- inputLatinLetters: "\u{1F524}",
968
- inputLatinLowercase: "\u{1F521}",
969
- inputLatinUppercase: "\u{1F520}",
970
- inputNumbers: "\u{1F522}",
971
- inputSymbols: "\u{1F523}",
972
- jackOLantern: "\u{1F383}",
973
- japaneseAcceptableButton: "\u{1F251}",
974
- japaneseApplicationButton: "\u{1F238}",
975
- japaneseBargainButton: "\u{1F250}",
976
- japaneseCastle: "\u{1F3EF}",
977
- japaneseCongratulationsButton: "\u3297\uFE0F",
978
- japaneseDiscountButton: "\u{1F239}",
979
- japaneseDolls: "\u{1F38E}",
980
- japaneseFreeOfChargeButton: "\u{1F21A}",
981
- japaneseHereButton: "\u{1F201}",
982
- japaneseMonthlyAmountButton: "\u{1F237}\uFE0F",
983
- japaneseNotFreeOfChargeButton: "\u{1F236}",
984
- japaneseNoVacancyButton: "\u{1F235}",
985
- japaneseOpenForBusinessButton: "\u{1F23A}",
986
- japanesePassingGradeButton: "\u{1F234}",
987
- japanesePostOffice: "\u{1F3E3}",
988
- japaneseProhibitedButton: "\u{1F232}",
989
- japaneseReservedButton: "\u{1F22F}",
990
- japaneseSecretButton: "\u3299\uFE0F",
991
- japaneseServiceChargeButton: "\u{1F202}\uFE0F",
992
- japaneseSymbolForBeginner: "\u{1F530}",
993
- japaneseVacancyButton: "\u{1F233}",
994
- jar: "\u{1FAD9}",
995
- jeans: "\u{1F456}",
996
- jellyfish: "\u{1FABC}",
997
- joker: "\u{1F0CF}",
998
- joystick: "\u{1F579}\uFE0F",
999
- judge: "\u{1F9D1}\u200D\u2696\uFE0F",
1000
- kaaba: "\u{1F54B}",
1001
- kangaroo: "\u{1F998}",
1002
- key: "\u{1F511}",
1003
- keyboard: "\u2328\uFE0F",
1004
- keycap0: "0\uFE0F\u20E3",
1005
- keycap1: "1\uFE0F\u20E3",
1006
- keycap10: "\u{1F51F}",
1007
- keycap2: "2\uFE0F\u20E3",
1008
- keycap3: "3\uFE0F\u20E3",
1009
- keycap4: "4\uFE0F\u20E3",
1010
- keycap5: "5\uFE0F\u20E3",
1011
- keycap6: "6\uFE0F\u20E3",
1012
- keycap7: "7\uFE0F\u20E3",
1013
- keycap8: "8\uFE0F\u20E3",
1014
- keycap9: "9\uFE0F\u20E3",
1015
- keycapAsterisk: "*\uFE0F\u20E3",
1016
- keycapNumberSign: "#\uFE0F\u20E3",
1017
- khanda: "\u{1FAAF}",
1018
- kickScooter: "\u{1F6F4}",
1019
- kimono: "\u{1F458}",
1020
- kiss: "\u{1F48F}",
1021
- kissingCat: "\u{1F63D}",
1022
- kissingFace: "\u{1F617}",
1023
- kissingFaceWithClosedEyes: "\u{1F61A}",
1024
- kissingFaceWithSmilingEyes: "\u{1F619}",
1025
- kissManMan: "\u{1F468}\u200D\u2764\uFE0F\u200D\u{1F48B}\u200D\u{1F468}",
1026
- kissMark: "\u{1F48B}",
1027
- kissWomanMan: "\u{1F469}\u200D\u2764\uFE0F\u200D\u{1F48B}\u200D\u{1F468}",
1028
- kissWomanWoman: "\u{1F469}\u200D\u2764\uFE0F\u200D\u{1F48B}\u200D\u{1F469}",
1029
- kitchenKnife: "\u{1F52A}",
1030
- kite: "\u{1FA81}",
1031
- kiwiFruit: "\u{1F95D}",
1032
- knot: "\u{1FAA2}",
1033
- koala: "\u{1F428}",
1034
- labCoat: "\u{1F97C}",
1035
- label: "\u{1F3F7}\uFE0F",
1036
- lacrosse: "\u{1F94D}",
1037
- ladder: "\u{1FA9C}",
1038
- ladyBeetle: "\u{1F41E}",
1039
- landslide: "\u{1F6D8}",
1040
- laptop: "\u{1F4BB}",
1041
- largeBlueDiamond: "\u{1F537}",
1042
- largeOrangeDiamond: "\u{1F536}",
1043
- lastQuarterMoon: "\u{1F317}",
1044
- lastQuarterMoonFace: "\u{1F31C}",
1045
- lastTrackButton: "\u23EE\uFE0F",
1046
- latinCross: "\u271D\uFE0F",
1047
- leafFlutteringInWind: "\u{1F343}",
1048
- leaflessTree: "\u{1FABE}",
1049
- leafyGreen: "\u{1F96C}",
1050
- ledger: "\u{1F4D2}",
1051
- leftArrow: "\u2B05\uFE0F",
1052
- leftArrowCurvingRight: "\u21AA\uFE0F",
1053
- leftFacingFist: "\u{1F91B}",
1054
- leftLuggage: "\u{1F6C5}",
1055
- leftRightArrow: "\u2194\uFE0F",
1056
- leftSpeechBubble: "\u{1F5E8}\uFE0F",
1057
- leftwardsHand: "\u{1FAF2}",
1058
- leftwardsPushingHand: "\u{1FAF7}",
1059
- leg: "\u{1F9B5}",
1060
- lemon: "\u{1F34B}",
1061
- leo: "\u264C",
1062
- leopard: "\u{1F406}",
1063
- levelSlider: "\u{1F39A}\uFE0F",
1064
- libra: "\u264E",
1065
- lightBlueHeart: "\u{1FA75}",
1066
- lightBulb: "\u{1F4A1}",
1067
- lightRail: "\u{1F688}",
1068
- lime: "\u{1F34B}\u200D\u{1F7E9}",
1069
- link: "\u{1F517}",
1070
- linkedPaperclips: "\u{1F587}\uFE0F",
1071
- lion: "\u{1F981}",
1072
- lipstick: "\u{1F484}",
1073
- litterInBinSign: "\u{1F6AE}",
1074
- lizard: "\u{1F98E}",
1075
- llama: "\u{1F999}",
1076
- lobster: "\u{1F99E}",
1077
- locked: "\u{1F512}",
1078
- lockedWithKey: "\u{1F510}",
1079
- lockedWithPen: "\u{1F50F}",
1080
- locomotive: "\u{1F682}",
1081
- lollipop: "\u{1F36D}",
1082
- longDrum: "\u{1FA98}",
1083
- lotionBottle: "\u{1F9F4}",
1084
- lotus: "\u{1FAB7}",
1085
- loudlyCryingFace: "\u{1F62D}",
1086
- loudspeaker: "\u{1F4E2}",
1087
- loveHotel: "\u{1F3E9}",
1088
- loveLetter: "\u{1F48C}",
1089
- loveYouGesture: "\u{1F91F}",
1090
- lowBattery: "\u{1FAAB}",
1091
- luggage: "\u{1F9F3}",
1092
- lungs: "\u{1FAC1}",
1093
- lyingFace: "\u{1F925}",
1094
- mage: "\u{1F9D9}",
1095
- magicWand: "\u{1FA84}",
1096
- magnet: "\u{1F9F2}",
1097
- magnifyingGlassTiltedLeft: "\u{1F50D}",
1098
- magnifyingGlassTiltedRight: "\u{1F50E}",
1099
- mahjongRedDragon: "\u{1F004}",
1100
- maleSign: "\u2642\uFE0F",
1101
- mammoth: "\u{1F9A3}",
1102
- man: "\u{1F468}",
1103
- manArtist: "\u{1F468}\u200D\u{1F3A8}",
1104
- manAstronaut: "\u{1F468}\u200D\u{1F680}",
1105
- manBald: "\u{1F468}\u200D\u{1F9B2}",
1106
- manBeard: "\u{1F9D4}\u200D\u2642\uFE0F",
1107
- manBiking: "\u{1F6B4}\u200D\u2642\uFE0F",
1108
- manBlondHair: "\u{1F471}\u200D\u2642\uFE0F",
1109
- manBouncingBall: "\u26F9\uFE0F\u200D\u2642\uFE0F",
1110
- manBowing: "\u{1F647}\u200D\u2642\uFE0F",
1111
- manCartwheeling: "\u{1F938}\u200D\u2642\uFE0F",
1112
- manClimbing: "\u{1F9D7}\u200D\u2642\uFE0F",
1113
- manConstructionWorker: "\u{1F477}\u200D\u2642\uFE0F",
1114
- manCook: "\u{1F468}\u200D\u{1F373}",
1115
- manCurlyHair: "\u{1F468}\u200D\u{1F9B1}",
1116
- manDancing: "\u{1F57A}",
1117
- manDetective: "\u{1F575}\uFE0F\u200D\u2642\uFE0F",
1118
- manElf: "\u{1F9DD}\u200D\u2642\uFE0F",
1119
- manFacepalming: "\u{1F926}\u200D\u2642\uFE0F",
1120
- manFactoryWorker: "\u{1F468}\u200D\u{1F3ED}",
1121
- manFairy: "\u{1F9DA}\u200D\u2642\uFE0F",
1122
- manFarmer: "\u{1F468}\u200D\u{1F33E}",
1123
- manFeedingBaby: "\u{1F468}\u200D\u{1F37C}",
1124
- manFirefighter: "\u{1F468}\u200D\u{1F692}",
1125
- manFrowning: "\u{1F64D}\u200D\u2642\uFE0F",
1126
- manGenie: "\u{1F9DE}\u200D\u2642\uFE0F",
1127
- manGesturingNo: "\u{1F645}\u200D\u2642\uFE0F",
1128
- manGesturingOk: "\u{1F646}\u200D\u2642\uFE0F",
1129
- manGettingHaircut: "\u{1F487}\u200D\u2642\uFE0F",
1130
- manGettingMassage: "\u{1F486}\u200D\u2642\uFE0F",
1131
- mango: "\u{1F96D}",
1132
- manGolfing: "\u{1F3CC}\uFE0F\u200D\u2642\uFE0F",
1133
- manGuard: "\u{1F482}\u200D\u2642\uFE0F",
1134
- manHealthWorker: "\u{1F468}\u200D\u2695\uFE0F",
1135
- manInLotusPosition: "\u{1F9D8}\u200D\u2642\uFE0F",
1136
- manInManualWheelchair: "\u{1F468}\u200D\u{1F9BD}",
1137
- manInManualWheelchairFacingRight: "\u{1F468}\u200D\u{1F9BD}\u200D\u27A1\uFE0F",
1138
- manInMotorizedWheelchair: "\u{1F468}\u200D\u{1F9BC}",
1139
- manInMotorizedWheelchairFacingRight: "\u{1F468}\u200D\u{1F9BC}\u200D\u27A1\uFE0F",
1140
- manInSteamyRoom: "\u{1F9D6}\u200D\u2642\uFE0F",
1141
- manInTuxedo: "\u{1F935}\u200D\u2642\uFE0F",
1142
- manJudge: "\u{1F468}\u200D\u2696\uFE0F",
1143
- manJuggling: "\u{1F939}\u200D\u2642\uFE0F",
1144
- manKneeling: "\u{1F9CE}\u200D\u2642\uFE0F",
1145
- manKneelingFacingRight: "\u{1F9CE}\u200D\u2642\uFE0F\u200D\u27A1\uFE0F",
1146
- manLiftingWeights: "\u{1F3CB}\uFE0F\u200D\u2642\uFE0F",
1147
- manMage: "\u{1F9D9}\u200D\u2642\uFE0F",
1148
- manMechanic: "\u{1F468}\u200D\u{1F527}",
1149
- manMountainBiking: "\u{1F6B5}\u200D\u2642\uFE0F",
1150
- manOfficeWorker: "\u{1F468}\u200D\u{1F4BC}",
1151
- manPilot: "\u{1F468}\u200D\u2708\uFE0F",
1152
- manPlayingHandball: "\u{1F93E}\u200D\u2642\uFE0F",
1153
- manPlayingWaterPolo: "\u{1F93D}\u200D\u2642\uFE0F",
1154
- manPoliceOfficer: "\u{1F46E}\u200D\u2642\uFE0F",
1155
- manPouting: "\u{1F64E}\u200D\u2642\uFE0F",
1156
- manRaisingHand: "\u{1F64B}\u200D\u2642\uFE0F",
1157
- manRedHair: "\u{1F468}\u200D\u{1F9B0}",
1158
- manRowingBoat: "\u{1F6A3}\u200D\u2642\uFE0F",
1159
- manRunning: "\u{1F3C3}\u200D\u2642\uFE0F",
1160
- manRunningFacingRight: "\u{1F3C3}\u200D\u2642\uFE0F\u200D\u27A1\uFE0F",
1161
- manScientist: "\u{1F468}\u200D\u{1F52C}",
1162
- manShrugging: "\u{1F937}\u200D\u2642\uFE0F",
1163
- manSinger: "\u{1F468}\u200D\u{1F3A4}",
1164
- manSShoe: "\u{1F45E}",
1165
- manStanding: "\u{1F9CD}\u200D\u2642\uFE0F",
1166
- manStudent: "\u{1F468}\u200D\u{1F393}",
1167
- manSuperhero: "\u{1F9B8}\u200D\u2642\uFE0F",
1168
- manSupervillain: "\u{1F9B9}\u200D\u2642\uFE0F",
1169
- manSurfing: "\u{1F3C4}\u200D\u2642\uFE0F",
1170
- manSwimming: "\u{1F3CA}\u200D\u2642\uFE0F",
1171
- manTeacher: "\u{1F468}\u200D\u{1F3EB}",
1172
- manTechnologist: "\u{1F468}\u200D\u{1F4BB}",
1173
- mantelpieceClock: "\u{1F570}\uFE0F",
1174
- manTippingHand: "\u{1F481}\u200D\u2642\uFE0F",
1175
- manualWheelchair: "\u{1F9BD}",
1176
- manVampire: "\u{1F9DB}\u200D\u2642\uFE0F",
1177
- manWalking: "\u{1F6B6}\u200D\u2642\uFE0F",
1178
- manWalkingFacingRight: "\u{1F6B6}\u200D\u2642\uFE0F\u200D\u27A1\uFE0F",
1179
- manWearingTurban: "\u{1F473}\u200D\u2642\uFE0F",
1180
- manWhiteHair: "\u{1F468}\u200D\u{1F9B3}",
1181
- manWithVeil: "\u{1F470}\u200D\u2642\uFE0F",
1182
- manWithWhiteCane: "\u{1F468}\u200D\u{1F9AF}",
1183
- manWithWhiteCaneFacingRight: "\u{1F468}\u200D\u{1F9AF}\u200D\u27A1\uFE0F",
1184
- manZombie: "\u{1F9DF}\u200D\u2642\uFE0F",
1185
- mapleLeaf: "\u{1F341}",
1186
- mapOfJapan: "\u{1F5FE}",
1187
- maracas: "\u{1FA87}",
1188
- martialArtsUniform: "\u{1F94B}",
1189
- mate: "\u{1F9C9}",
1190
- meatOnBone: "\u{1F356}",
1191
- mechanic: "\u{1F9D1}\u200D\u{1F527}",
1192
- mechanicalArm: "\u{1F9BE}",
1193
- mechanicalLeg: "\u{1F9BF}",
1194
- medicalSymbol: "\u2695\uFE0F",
1195
- megaphone: "\u{1F4E3}",
1196
- melon: "\u{1F348}",
1197
- meltingFace: "\u{1FAE0}",
1198
- memo: "\u{1F4DD}",
1199
- mendingHeart: "\u2764\uFE0F\u200D\u{1FA79}",
1200
- menHoldingHands: "\u{1F46C}",
1201
- menorah: "\u{1F54E}",
1202
- menSRoom: "\u{1F6B9}",
1203
- menWithBunnyEars: "\u{1F46F}\u200D\u2642\uFE0F",
1204
- menWrestling: "\u{1F93C}\u200D\u2642\uFE0F",
1205
- mermaid: "\u{1F9DC}\u200D\u2640\uFE0F",
1206
- merman: "\u{1F9DC}\u200D\u2642\uFE0F",
1207
- merperson: "\u{1F9DC}",
1208
- metro: "\u{1F687}",
1209
- microbe: "\u{1F9A0}",
1210
- microphone: "\u{1F3A4}",
1211
- microscope: "\u{1F52C}",
1212
- middleFinger: "\u{1F595}",
1213
- militaryHelmet: "\u{1FA96}",
1214
- militaryMedal: "\u{1F396}\uFE0F",
1215
- milkyWay: "\u{1F30C}",
1216
- minibus: "\u{1F690}",
1217
- minus: "\u2796",
1218
- mirror: "\u{1FA9E}",
1219
- mirrorBall: "\u{1FAA9}",
1220
- moai: "\u{1F5FF}",
1221
- mobilePhone: "\u{1F4F1}",
1222
- mobilePhoneOff: "\u{1F4F4}",
1223
- mobilePhoneWithArrow: "\u{1F4F2}",
1224
- moneyBag: "\u{1F4B0}",
1225
- moneyMouthFace: "\u{1F911}",
1226
- moneyWithWings: "\u{1F4B8}",
1227
- monkey: "\u{1F412}",
1228
- monkeyFace: "\u{1F435}",
1229
- monorail: "\u{1F69D}",
1230
- moonCake: "\u{1F96E}",
1231
- moonViewingCeremony: "\u{1F391}",
1232
- moose: "\u{1FACE}",
1233
- mosque: "\u{1F54C}",
1234
- mosquito: "\u{1F99F}",
1235
- motorBoat: "\u{1F6E5}\uFE0F",
1236
- motorcycle: "\u{1F3CD}\uFE0F",
1237
- motorizedWheelchair: "\u{1F9BC}",
1238
- motorScooter: "\u{1F6F5}",
1239
- motorway: "\u{1F6E3}\uFE0F",
1240
- mountain: "\u26F0\uFE0F",
1241
- mountainCableway: "\u{1F6A0}",
1242
- mountainRailway: "\u{1F69E}",
1243
- mountFuji: "\u{1F5FB}",
1244
- mouse: "\u{1F401}",
1245
- mouseFace: "\u{1F42D}",
1246
- mouseTrap: "\u{1FAA4}",
1247
- mouth: "\u{1F444}",
1248
- movieCamera: "\u{1F3A5}",
1249
- mrsClaus: "\u{1F936}",
1250
- multiply: "\u2716\uFE0F",
1251
- mushroom: "\u{1F344}",
1252
- musicalKeyboard: "\u{1F3B9}",
1253
- musicalNote: "\u{1F3B5}",
1254
- musicalNotes: "\u{1F3B6}",
1255
- musicalScore: "\u{1F3BC}",
1256
- mutedSpeaker: "\u{1F507}",
1257
- mxClaus: "\u{1F9D1}\u200D\u{1F384}",
1258
- nailPolish: "\u{1F485}",
1259
- nameBadge: "\u{1F4DB}",
1260
- nationalPark: "\u{1F3DE}\uFE0F",
1261
- nauseatedFace: "\u{1F922}",
1262
- nazarAmulet: "\u{1F9FF}",
1263
- necktie: "\u{1F454}",
1264
- nerdFace: "\u{1F913}",
1265
- nestingDolls: "\u{1FA86}",
1266
- nestWithEggs: "\u{1FABA}",
1267
- neutralFace: "\u{1F610}",
1268
- newButton: "\u{1F195}",
1269
- newMoon: "\u{1F311}",
1270
- newMoonFace: "\u{1F31A}",
1271
- newspaper: "\u{1F4F0}",
1272
- nextTrackButton: "\u23ED\uFE0F",
1273
- ngButton: "\u{1F196}",
1274
- nightWithStars: "\u{1F303}",
1275
- nineOClock: "\u{1F558}",
1276
- nineThirty: "\u{1F564}",
1277
- ninja: "\u{1F977}",
1278
- noBicycles: "\u{1F6B3}",
1279
- noEntry: "\u26D4",
1280
- noLittering: "\u{1F6AF}",
1281
- noMobilePhones: "\u{1F4F5}",
1282
- nonPotableWater: "\u{1F6B1}",
1283
- noOneUnderEighteen: "\u{1F51E}",
1284
- noPedestrians: "\u{1F6B7}",
1285
- nose: "\u{1F443}",
1286
- noSmoking: "\u{1F6AD}",
1287
- notebook: "\u{1F4D3}",
1288
- notebookWithDecorativeCover: "\u{1F4D4}",
1289
- nutAndBolt: "\u{1F529}",
1290
- oButton: "\u{1F17E}\uFE0F",
1291
- octopus: "\u{1F419}",
1292
- oden: "\u{1F362}",
1293
- officeBuilding: "\u{1F3E2}",
1294
- officeWorker: "\u{1F9D1}\u200D\u{1F4BC}",
1295
- ogre: "\u{1F479}",
1296
- oilDrum: "\u{1F6E2}\uFE0F",
1297
- okButton: "\u{1F197}",
1298
- okHand: "\u{1F44C}",
1299
- olderPerson: "\u{1F9D3}",
1300
- oldKey: "\u{1F5DD}\uFE0F",
1301
- oldMan: "\u{1F474}",
1302
- oldWoman: "\u{1F475}",
1303
- olive: "\u{1FAD2}",
1304
- om: "\u{1F549}\uFE0F",
1305
- onArrow: "\u{1F51B}",
1306
- oncomingAutomobile: "\u{1F698}",
1307
- oncomingBus: "\u{1F68D}",
1308
- oncomingFist: "\u{1F44A}",
1309
- oncomingPoliceCar: "\u{1F694}",
1310
- oncomingTaxi: "\u{1F696}",
1311
- oneOClock: "\u{1F550}",
1312
- onePieceSwimsuit: "\u{1FA71}",
1313
- oneThirty: "\u{1F55C}",
1314
- onion: "\u{1F9C5}",
1315
- openBook: "\u{1F4D6}",
1316
- openFileFolder: "\u{1F4C2}",
1317
- openHands: "\u{1F450}",
1318
- openMailboxWithLoweredFlag: "\u{1F4ED}",
1319
- openMailboxWithRaisedFlag: "\u{1F4EC}",
1320
- ophiuchus: "\u26CE",
1321
- opticalDisk: "\u{1F4BF}",
1322
- orangeBook: "\u{1F4D9}",
1323
- orangeCircle: "\u{1F7E0}",
1324
- orangeHeart: "\u{1F9E1}",
1325
- orangeSquare: "\u{1F7E7}",
1326
- orangutan: "\u{1F9A7}",
1327
- orca: "\u{1FACD}",
1328
- orthodoxCross: "\u2626\uFE0F",
1329
- otter: "\u{1F9A6}",
1330
- outboxTray: "\u{1F4E4}",
1331
- owl: "\u{1F989}",
1332
- ox: "\u{1F402}",
1333
- oyster: "\u{1F9AA}",
1334
- package_: "\u{1F4E6}",
1335
- pageFacingUp: "\u{1F4C4}",
1336
- pager: "\u{1F4DF}",
1337
- pageWithCurl: "\u{1F4C3}",
1338
- paintbrush: "\u{1F58C}\uFE0F",
1339
- palmDownHand: "\u{1FAF3}",
1340
- palmsUpTogether: "\u{1F932}",
1341
- palmTree: "\u{1F334}",
1342
- palmUpHand: "\u{1FAF4}",
1343
- pancakes: "\u{1F95E}",
1344
- panda: "\u{1F43C}",
1345
- paperclip: "\u{1F4CE}",
1346
- parachute: "\u{1FA82}",
1347
- parrot: "\u{1F99C}",
1348
- partAlternationMark: "\u303D\uFE0F",
1349
- partyingFace: "\u{1F973}",
1350
- partyPopper: "\u{1F389}",
1351
- passengerShip: "\u{1F6F3}\uFE0F",
1352
- passportControl: "\u{1F6C2}",
1353
- pauseButton: "\u23F8\uFE0F",
1354
- pawPrints: "\u{1F43E}",
1355
- pButton: "\u{1F17F}\uFE0F",
1356
- peaceSymbol: "\u262E\uFE0F",
1357
- peach: "\u{1F351}",
1358
- peacock: "\u{1F99A}",
1359
- peanuts: "\u{1F95C}",
1360
- peaPod: "\u{1FADB}",
1361
- pear: "\u{1F350}",
1362
- pen: "\u{1F58A}\uFE0F",
1363
- pencil: "\u270F\uFE0F",
1364
- penguin: "\u{1F427}",
1365
- pensiveFace: "\u{1F614}",
1366
- peopleHoldingHands: "\u{1F9D1}\u200D\u{1F91D}\u200D\u{1F9D1}",
1367
- peopleHugging: "\u{1FAC2}",
1368
- peopleWithBunnyEars: "\u{1F46F}",
1369
- peopleWrestling: "\u{1F93C}",
1370
- performingArts: "\u{1F3AD}",
1371
- perseveringFace: "\u{1F623}",
1372
- person: "\u{1F9D1}",
1373
- personBald: "\u{1F9D1}\u200D\u{1F9B2}",
1374
- personBeard: "\u{1F9D4}",
1375
- personBiking: "\u{1F6B4}",
1376
- personBlondHair: "\u{1F471}",
1377
- personBouncingBall: "\u26F9\uFE0F",
1378
- personBowing: "\u{1F647}",
1379
- personCartwheeling: "\u{1F938}",
1380
- personClimbing: "\u{1F9D7}",
1381
- personCurlyHair: "\u{1F9D1}\u200D\u{1F9B1}",
1382
- personFacepalming: "\u{1F926}",
1383
- personFeedingBaby: "\u{1F9D1}\u200D\u{1F37C}",
1384
- personFencing: "\u{1F93A}",
1385
- personFrowning: "\u{1F64D}",
1386
- personGesturingNo: "\u{1F645}",
1387
- personGesturingOk: "\u{1F646}",
1388
- personGettingHaircut: "\u{1F487}",
1389
- personGettingMassage: "\u{1F486}",
1390
- personGolfing: "\u{1F3CC}\uFE0F",
1391
- personInBed: "\u{1F6CC}",
1392
- personInLotusPosition: "\u{1F9D8}",
1393
- personInManualWheelchair: "\u{1F9D1}\u200D\u{1F9BD}",
1394
- personInManualWheelchairFacingRight: "\u{1F9D1}\u200D\u{1F9BD}\u200D\u27A1\uFE0F",
1395
- personInMotorizedWheelchair: "\u{1F9D1}\u200D\u{1F9BC}",
1396
- personInMotorizedWheelchairFacingRight: "\u{1F9D1}\u200D\u{1F9BC}\u200D\u27A1\uFE0F",
1397
- personInSteamyRoom: "\u{1F9D6}",
1398
- personInSuitLevitating: "\u{1F574}\uFE0F",
1399
- personInTuxedo: "\u{1F935}",
1400
- personJuggling: "\u{1F939}",
1401
- personKneeling: "\u{1F9CE}",
1402
- personKneelingFacingRight: "\u{1F9CE}\u200D\u27A1\uFE0F",
1403
- personLiftingWeights: "\u{1F3CB}\uFE0F",
1404
- personMountainBiking: "\u{1F6B5}",
1405
- personPlayingHandball: "\u{1F93E}",
1406
- personPlayingWaterPolo: "\u{1F93D}",
1407
- personPouting: "\u{1F64E}",
1408
- personRaisingHand: "\u{1F64B}",
1409
- personRedHair: "\u{1F9D1}\u200D\u{1F9B0}",
1410
- personRowingBoat: "\u{1F6A3}",
1411
- personRunning: "\u{1F3C3}",
1412
- personRunningFacingRight: "\u{1F3C3}\u200D\u27A1\uFE0F",
1413
- personShrugging: "\u{1F937}",
1414
- personStanding: "\u{1F9CD}",
1415
- personSurfing: "\u{1F3C4}",
1416
- personSwimming: "\u{1F3CA}",
1417
- personTakingBath: "\u{1F6C0}",
1418
- personTippingHand: "\u{1F481}",
1419
- personWalking: "\u{1F6B6}",
1420
- personWalkingFacingRight: "\u{1F6B6}\u200D\u27A1\uFE0F",
1421
- personWearingTurban: "\u{1F473}",
1422
- personWhiteHair: "\u{1F9D1}\u200D\u{1F9B3}",
1423
- personWithCrown: "\u{1FAC5}",
1424
- personWithSkullcap: "\u{1F472}",
1425
- personWithVeil: "\u{1F470}",
1426
- personWithWhiteCane: "\u{1F9D1}\u200D\u{1F9AF}",
1427
- personWithWhiteCaneFacingRight: "\u{1F9D1}\u200D\u{1F9AF}\u200D\u27A1\uFE0F",
1428
- petriDish: "\u{1F9EB}",
1429
- phoenix: "\u{1F426}\u200D\u{1F525}",
1430
- pick: "\u26CF\uFE0F",
1431
- pickupTruck: "\u{1F6FB}",
1432
- pie: "\u{1F967}",
1433
- pig: "\u{1F416}",
1434
- pigFace: "\u{1F437}",
1435
- pigNose: "\u{1F43D}",
1436
- pileOfPoo: "\u{1F4A9}",
1437
- pill: "\u{1F48A}",
1438
- pilot: "\u{1F9D1}\u200D\u2708\uFE0F",
1439
- pinata: "\u{1FA85}",
1440
- pinchedFingers: "\u{1F90C}",
1441
- pinchingHand: "\u{1F90F}",
1442
- pineapple: "\u{1F34D}",
1443
- pineDecoration: "\u{1F38D}",
1444
- pingPong: "\u{1F3D3}",
1445
- pinkHeart: "\u{1FA77}",
1446
- pirateFlag: "\u{1F3F4}\u200D\u2620\uFE0F",
1447
- pisces: "\u2653",
1448
- pizza: "\u{1F355}",
1449
- placard: "\u{1FAA7}",
1450
- placeOfWorship: "\u{1F6D0}",
1451
- playButton: "\u25B6\uFE0F",
1452
- playgroundSlide: "\u{1F6DD}",
1453
- playOrPauseButton: "\u23EF\uFE0F",
1454
- pleadingFace: "\u{1F97A}",
1455
- plunger: "\u{1FAA0}",
1456
- plus: "\u2795",
1457
- polarBear: "\u{1F43B}\u200D\u2744\uFE0F",
1458
- policeCar: "\u{1F693}",
1459
- policeCarLight: "\u{1F6A8}",
1460
- policeOfficer: "\u{1F46E}",
1461
- poodle: "\u{1F429}",
1462
- pool8Ball: "\u{1F3B1}",
1463
- popcorn: "\u{1F37F}",
1464
- postalHorn: "\u{1F4EF}",
1465
- postbox: "\u{1F4EE}",
1466
- postOffice: "\u{1F3E4}",
1467
- potableWater: "\u{1F6B0}",
1468
- potato: "\u{1F954}",
1469
- potOfFood: "\u{1F372}",
1470
- pottedPlant: "\u{1FAB4}",
1471
- poultryLeg: "\u{1F357}",
1472
- poundBanknote: "\u{1F4B7}",
1473
- pouringLiquid: "\u{1FAD7}",
1474
- poutingCat: "\u{1F63E}",
1475
- prayerBeads: "\u{1F4FF}",
1476
- pregnantMan: "\u{1FAC3}",
1477
- pregnantPerson: "\u{1FAC4}",
1478
- pregnantWoman: "\u{1F930}",
1479
- pretzel: "\u{1F968}",
1480
- prince: "\u{1F934}",
1481
- princess: "\u{1F478}",
1482
- printer: "\u{1F5A8}\uFE0F",
1483
- prohibited: "\u{1F6AB}",
1484
- purpleCircle: "\u{1F7E3}",
1485
- purpleHeart: "\u{1F49C}",
1486
- purpleSquare: "\u{1F7EA}",
1487
- purse: "\u{1F45B}",
1488
- pushpin: "\u{1F4CC}",
1489
- puzzlePiece: "\u{1F9E9}",
1490
- rabbit: "\u{1F407}",
1491
- rabbitFace: "\u{1F430}",
1492
- raccoon: "\u{1F99D}",
1493
- racingCar: "\u{1F3CE}\uFE0F",
1494
- radio: "\u{1F4FB}",
1495
- radioactive: "\u2622\uFE0F",
1496
- radioButton: "\u{1F518}",
1497
- railwayCar: "\u{1F683}",
1498
- railwayTrack: "\u{1F6E4}\uFE0F",
1499
- rainbow: "\u{1F308}",
1500
- rainbowFlag: "\u{1F3F3}\uFE0F\u200D\u{1F308}",
1501
- raisedBackOfHand: "\u{1F91A}",
1502
- raisedFist: "\u270A",
1503
- raisedHand: "\u270B",
1504
- raisingHands: "\u{1F64C}",
1505
- ram: "\u{1F40F}",
1506
- rat: "\u{1F400}",
1507
- razor: "\u{1FA92}",
1508
- receipt: "\u{1F9FE}",
1509
- recordButton: "\u23FA\uFE0F",
1510
- recyclingSymbol: "\u267B\uFE0F",
1511
- redApple: "\u{1F34E}",
1512
- redCircle: "\u{1F534}",
1513
- redEnvelope: "\u{1F9E7}",
1514
- redExclamationMark: "\u2757",
1515
- redHeart: "\u2764\uFE0F",
1516
- redPaperLantern: "\u{1F3EE}",
1517
- redQuestionMark: "\u2753",
1518
- redSquare: "\u{1F7E5}",
1519
- redTrianglePointedDown: "\u{1F53B}",
1520
- redTrianglePointedUp: "\u{1F53A}",
1521
- registered: "\xAE\uFE0F",
1522
- relievedFace: "\u{1F60C}",
1523
- reminderRibbon: "\u{1F397}\uFE0F",
1524
- repeatButton: "\u{1F501}",
1525
- repeatSingleButton: "\u{1F502}",
1526
- rescueWorkerSHelmet: "\u26D1\uFE0F",
1527
- restroom: "\u{1F6BB}",
1528
- reverseButton: "\u25C0\uFE0F",
1529
- revolvingHearts: "\u{1F49E}",
1530
- rhinoceros: "\u{1F98F}",
1531
- ribbon: "\u{1F380}",
1532
- riceBall: "\u{1F359}",
1533
- riceCracker: "\u{1F358}",
1534
- rightAngerBubble: "\u{1F5EF}\uFE0F",
1535
- rightArrow: "\u27A1\uFE0F",
1536
- rightArrowCurvingDown: "\u2935\uFE0F",
1537
- rightArrowCurvingLeft: "\u21A9\uFE0F",
1538
- rightArrowCurvingUp: "\u2934\uFE0F",
1539
- rightFacingFist: "\u{1F91C}",
1540
- rightwardsHand: "\u{1FAF1}",
1541
- rightwardsPushingHand: "\u{1FAF8}",
1542
- ring: "\u{1F48D}",
1543
- ringBuoy: "\u{1F6DF}",
1544
- ringedPlanet: "\u{1FA90}",
1545
- roastedSweetPotato: "\u{1F360}",
1546
- robot: "\u{1F916}",
1547
- rock: "\u{1FAA8}",
1548
- rocket: "\u{1F680}",
1549
- rolledUpNewspaper: "\u{1F5DE}\uFE0F",
1550
- rollerCoaster: "\u{1F3A2}",
1551
- rollerSkate: "\u{1F6FC}",
1552
- rollingOnTheFloorLaughing: "\u{1F923}",
1553
- rollOfPaper: "\u{1F9FB}",
1554
- rooster: "\u{1F413}",
1555
- rootVegetable: "\u{1FADC}",
1556
- rose: "\u{1F339}",
1557
- rosette: "\u{1F3F5}\uFE0F",
1558
- roundPushpin: "\u{1F4CD}",
1559
- rugbyFootball: "\u{1F3C9}",
1560
- runningShirt: "\u{1F3BD}",
1561
- runningShoe: "\u{1F45F}",
1562
- sadButRelievedFace: "\u{1F625}",
1563
- safetyPin: "\u{1F9F7}",
1564
- safetyVest: "\u{1F9BA}",
1565
- sagittarius: "\u2650",
1566
- sailboat: "\u26F5",
1567
- sake: "\u{1F376}",
1568
- salt: "\u{1F9C2}",
1569
- salutingFace: "\u{1FAE1}",
1570
- sandwich: "\u{1F96A}",
1571
- santaClaus: "\u{1F385}",
1572
- sari: "\u{1F97B}",
1573
- satellite: "\u{1F6F0}\uFE0F",
1574
- satelliteAntenna: "\u{1F4E1}",
1575
- sauropod: "\u{1F995}",
1576
- saxophone: "\u{1F3B7}",
1577
- scarf: "\u{1F9E3}",
1578
- school: "\u{1F3EB}",
1579
- scientist: "\u{1F9D1}\u200D\u{1F52C}",
1580
- scissors: "\u2702\uFE0F",
1581
- scorpio: "\u264F",
1582
- scorpion: "\u{1F982}",
1583
- screwdriver: "\u{1FA9B}",
1584
- scroll: "\u{1F4DC}",
1585
- seal: "\u{1F9AD}",
1586
- seat: "\u{1F4BA}",
1587
- seedling: "\u{1F331}",
1588
- seeNoEvilMonkey: "\u{1F648}",
1589
- selfie: "\u{1F933}",
1590
- serviceDog: "\u{1F415}\u200D\u{1F9BA}",
1591
- sevenOClock: "\u{1F556}",
1592
- sevenThirty: "\u{1F562}",
1593
- sewingNeedle: "\u{1FAA1}",
1594
- shakingFace: "\u{1FAE8}",
1595
- shallowPanOfFood: "\u{1F958}",
1596
- shamrock: "\u2618\uFE0F",
1597
- shark: "\u{1F988}",
1598
- shavedIce: "\u{1F367}",
1599
- sheafOfRice: "\u{1F33E}",
1600
- shield: "\u{1F6E1}\uFE0F",
1601
- shintoShrine: "\u26E9\uFE0F",
1602
- ship: "\u{1F6A2}",
1603
- shootingStar: "\u{1F320}",
1604
- shoppingBags: "\u{1F6CD}\uFE0F",
1605
- shoppingCart: "\u{1F6D2}",
1606
- shortcake: "\u{1F370}",
1607
- shorts: "\u{1FA73}",
1608
- shovel: "\u{1FA8F}",
1609
- shower: "\u{1F6BF}",
1610
- shrimp: "\u{1F990}",
1611
- shuffleTracksButton: "\u{1F500}",
1612
- shushingFace: "\u{1F92B}",
1613
- signOfTheHorns: "\u{1F918}",
1614
- singer: "\u{1F9D1}\u200D\u{1F3A4}",
1615
- sixOClock: "\u{1F555}",
1616
- sixThirty: "\u{1F561}",
1617
- skateboard: "\u{1F6F9}",
1618
- skier: "\u26F7\uFE0F",
1619
- skis: "\u{1F3BF}",
1620
- skull: "\u{1F480}",
1621
- skullAndCrossbones: "\u2620\uFE0F",
1622
- skunk: "\u{1F9A8}",
1623
- sled: "\u{1F6F7}",
1624
- sleepingFace: "\u{1F634}",
1625
- sleepyFace: "\u{1F62A}",
1626
- slightlyFrowningFace: "\u{1F641}",
1627
- slightlySmilingFace: "\u{1F642}",
1628
- sloth: "\u{1F9A5}",
1629
- slotMachine: "\u{1F3B0}",
1630
- smallAirplane: "\u{1F6E9}\uFE0F",
1631
- smallBlueDiamond: "\u{1F539}",
1632
- smallOrangeDiamond: "\u{1F538}",
1633
- smilingCatWithHeartEyes: "\u{1F63B}",
1634
- smilingFace: "\u263A\uFE0F",
1635
- smilingFaceWithHalo: "\u{1F607}",
1636
- smilingFaceWithHeartEyes: "\u{1F60D}",
1637
- smilingFaceWithHearts: "\u{1F970}",
1638
- smilingFaceWithHorns: "\u{1F608}",
1639
- smilingFaceWithOpenHands: "\u{1F917}",
1640
- smilingFaceWithSmilingEyes: "\u{1F60A}",
1641
- smilingFaceWithSunglasses: "\u{1F60E}",
1642
- smilingFaceWithTear: "\u{1F972}",
1643
- smirkingFace: "\u{1F60F}",
1644
- snail: "\u{1F40C}",
1645
- snake: "\u{1F40D}",
1646
- sneezingFace: "\u{1F927}",
1647
- snowboarder: "\u{1F3C2}",
1648
- snowCappedMountain: "\u{1F3D4}\uFE0F",
1649
- snowflake: "\u2744\uFE0F",
1650
- snowman: "\u2603\uFE0F",
1651
- snowmanWithoutSnow: "\u26C4",
1652
- soap: "\u{1F9FC}",
1653
- soccerBall: "\u26BD",
1654
- socks: "\u{1F9E6}",
1655
- softball: "\u{1F94E}",
1656
- softIceCream: "\u{1F366}",
1657
- soonArrow: "\u{1F51C}",
1658
- sosButton: "\u{1F198}",
1659
- spadeSuit: "\u2660\uFE0F",
1660
- spaghetti: "\u{1F35D}",
1661
- sparkle: "\u2747\uFE0F",
1662
- sparkler: "\u{1F387}",
1663
- sparkles: "\u2728",
1664
- sparklingHeart: "\u{1F496}",
1665
- speakerHighVolume: "\u{1F50A}",
1666
- speakerLowVolume: "\u{1F508}",
1667
- speakerMediumVolume: "\u{1F509}",
1668
- speakingHead: "\u{1F5E3}\uFE0F",
1669
- speakNoEvilMonkey: "\u{1F64A}",
1670
- speechBalloon: "\u{1F4AC}",
1671
- speedboat: "\u{1F6A4}",
1672
- spider: "\u{1F577}\uFE0F",
1673
- spiderWeb: "\u{1F578}\uFE0F",
1674
- spiralCalendar: "\u{1F5D3}\uFE0F",
1675
- spiralNotepad: "\u{1F5D2}\uFE0F",
1676
- spiralShell: "\u{1F41A}",
1677
- splatter: "\u{1FADF}",
1678
- sponge: "\u{1F9FD}",
1679
- spoon: "\u{1F944}",
1680
- sportsMedal: "\u{1F3C5}",
1681
- sportUtilityVehicle: "\u{1F699}",
1682
- spoutingWhale: "\u{1F433}",
1683
- squid: "\u{1F991}",
1684
- squintingFaceWithTongue: "\u{1F61D}",
1685
- stadium: "\u{1F3DF}\uFE0F",
1686
- star: "\u2B50",
1687
- starAndCrescent: "\u262A\uFE0F",
1688
- starOfDavid: "\u2721\uFE0F",
1689
- starStruck: "\u{1F929}",
1690
- station: "\u{1F689}",
1691
- statueOfLiberty: "\u{1F5FD}",
1692
- steamingBowl: "\u{1F35C}",
1693
- stethoscope: "\u{1FA7A}",
1694
- stopButton: "\u23F9\uFE0F",
1695
- stopSign: "\u{1F6D1}",
1696
- stopwatch: "\u23F1\uFE0F",
1697
- straightRuler: "\u{1F4CF}",
1698
- strawberry: "\u{1F353}",
1699
- student: "\u{1F9D1}\u200D\u{1F393}",
1700
- studioMicrophone: "\u{1F399}\uFE0F",
1701
- stuffedFlatbread: "\u{1F959}",
1702
- sun: "\u2600\uFE0F",
1703
- sunBehindCloud: "\u26C5",
1704
- sunBehindLargeCloud: "\u{1F325}\uFE0F",
1705
- sunBehindRainCloud: "\u{1F326}\uFE0F",
1706
- sunBehindSmallCloud: "\u{1F324}\uFE0F",
1707
- sunflower: "\u{1F33B}",
1708
- sunglasses: "\u{1F576}\uFE0F",
1709
- sunrise: "\u{1F305}",
1710
- sunriseOverMountains: "\u{1F304}",
1711
- sunset: "\u{1F307}",
1712
- sunWithFace: "\u{1F31E}",
1713
- superhero: "\u{1F9B8}",
1714
- supervillain: "\u{1F9B9}",
1715
- sushi: "\u{1F363}",
1716
- suspensionRailway: "\u{1F69F}",
1717
- swan: "\u{1F9A2}",
1718
- sweatDroplets: "\u{1F4A6}",
1719
- synagogue: "\u{1F54D}",
1720
- syringe: "\u{1F489}",
1721
- taco: "\u{1F32E}",
1722
- takeoutBox: "\u{1F961}",
1723
- tamale: "\u{1FAD4}",
1724
- tanabataTree: "\u{1F38B}",
1725
- tangerine: "\u{1F34A}",
1726
- taurus: "\u2649",
1727
- taxi: "\u{1F695}",
1728
- teacher: "\u{1F9D1}\u200D\u{1F3EB}",
1729
- teacupWithoutHandle: "\u{1F375}",
1730
- teapot: "\u{1FAD6}",
1731
- tearOffCalendar: "\u{1F4C6}",
1732
- technologist: "\u{1F9D1}\u200D\u{1F4BB}",
1733
- teddyBear: "\u{1F9F8}",
1734
- telephone: "\u260E\uFE0F",
1735
- telephoneReceiver: "\u{1F4DE}",
1736
- telescope: "\u{1F52D}",
1737
- television: "\u{1F4FA}",
1738
- tennis: "\u{1F3BE}",
1739
- tenOClock: "\u{1F559}",
1740
- tent: "\u26FA",
1741
- tenThirty: "\u{1F565}",
1742
- testTube: "\u{1F9EA}",
1743
- thermometer: "\u{1F321}\uFE0F",
1744
- thinkingFace: "\u{1F914}",
1745
- thongSandal: "\u{1FA74}",
1746
- thoughtBalloon: "\u{1F4AD}",
1747
- thread: "\u{1F9F5}",
1748
- threeOClock: "\u{1F552}",
1749
- threeThirty: "\u{1F55E}",
1750
- thumbsDown: "\u{1F44E}",
1751
- thumbsUp: "\u{1F44D}",
1752
- ticket: "\u{1F3AB}",
1753
- tiger: "\u{1F405}",
1754
- tigerFace: "\u{1F42F}",
1755
- timerClock: "\u23F2\uFE0F",
1756
- tiredFace: "\u{1F62B}",
1757
- toilet: "\u{1F6BD}",
1758
- tokyoTower: "\u{1F5FC}",
1759
- tomato: "\u{1F345}",
1760
- tongue: "\u{1F445}",
1761
- toolbox: "\u{1F9F0}",
1762
- tooth: "\u{1F9B7}",
1763
- toothbrush: "\u{1FAA5}",
1764
- topArrow: "\u{1F51D}",
1765
- topHat: "\u{1F3A9}",
1766
- tornado: "\u{1F32A}\uFE0F",
1767
- trackball: "\u{1F5B2}\uFE0F",
1768
- tractor: "\u{1F69C}",
1769
- tradeMark: "\u2122\uFE0F",
1770
- train: "\u{1F686}",
1771
- tram: "\u{1F68A}",
1772
- tramCar: "\u{1F68B}",
1773
- transgenderFlag: "\u{1F3F3}\uFE0F\u200D\u26A7\uFE0F",
1774
- transgenderSymbol: "\u26A7\uFE0F",
1775
- treasureChest: "\u{1FA8E}",
1776
- tRex: "\u{1F996}",
1777
- triangularFlag: "\u{1F6A9}",
1778
- triangularRuler: "\u{1F4D0}",
1779
- tridentEmblem: "\u{1F531}",
1780
- troll: "\u{1F9CC}",
1781
- trolleybus: "\u{1F68E}",
1782
- trombone: "\u{1FA8A}",
1783
- trophy: "\u{1F3C6}",
1784
- tropicalDrink: "\u{1F379}",
1785
- tropicalFish: "\u{1F420}",
1786
- trumpet: "\u{1F3BA}",
1787
- tShirt: "\u{1F455}",
1788
- tulip: "\u{1F337}",
1789
- tumblerGlass: "\u{1F943}",
1790
- turkey: "\u{1F983}",
1791
- turtle: "\u{1F422}",
1792
- twelveOClock: "\u{1F55B}",
1793
- twelveThirty: "\u{1F567}",
1794
- twoHearts: "\u{1F495}",
1795
- twoHumpCamel: "\u{1F42B}",
1796
- twoOClock: "\u{1F551}",
1797
- twoThirty: "\u{1F55D}",
1798
- umbrella: "\u2602\uFE0F",
1799
- umbrellaOnGround: "\u26F1\uFE0F",
1800
- umbrellaWithRainDrops: "\u2614",
1801
- unamusedFace: "\u{1F612}",
1802
- unicorn: "\u{1F984}",
1803
- unlocked: "\u{1F513}",
1804
- upArrow: "\u2B06\uFE0F",
1805
- upButton: "\u{1F199}",
1806
- upDownArrow: "\u2195\uFE0F",
1807
- upLeftArrow: "\u2196\uFE0F",
1808
- upRightArrow: "\u2197\uFE0F",
1809
- upsideDownFace: "\u{1F643}",
1810
- upwardsButton: "\u{1F53C}",
1811
- vampire: "\u{1F9DB}",
1812
- verticalTrafficLight: "\u{1F6A6}",
1813
- vibrationMode: "\u{1F4F3}",
1814
- victoryHand: "\u270C\uFE0F",
1815
- videoCamera: "\u{1F4F9}",
1816
- videocassette: "\u{1F4FC}",
1817
- videoGame: "\u{1F3AE}",
1818
- violin: "\u{1F3BB}",
1819
- virgo: "\u264D",
1820
- volcano: "\u{1F30B}",
1821
- volleyball: "\u{1F3D0}",
1822
- vsButton: "\u{1F19A}",
1823
- vulcanSalute: "\u{1F596}",
1824
- waffle: "\u{1F9C7}",
1825
- waningCrescentMoon: "\u{1F318}",
1826
- waningGibbousMoon: "\u{1F316}",
1827
- warning: "\u26A0\uFE0F",
1828
- wastebasket: "\u{1F5D1}\uFE0F",
1829
- watch: "\u231A",
1830
- waterBuffalo: "\u{1F403}",
1831
- waterCloset: "\u{1F6BE}",
1832
- watermelon: "\u{1F349}",
1833
- waterPistol: "\u{1F52B}",
1834
- waterWave: "\u{1F30A}",
1835
- wavingHand: "\u{1F44B}",
1836
- wavyDash: "\u3030\uFE0F",
1837
- waxingCrescentMoon: "\u{1F312}",
1838
- waxingGibbousMoon: "\u{1F314}",
1839
- wearyCat: "\u{1F640}",
1840
- wearyFace: "\u{1F629}",
1841
- wedding: "\u{1F492}",
1842
- whale: "\u{1F40B}",
1843
- wheel: "\u{1F6DE}",
1844
- wheelchairSymbol: "\u267F",
1845
- wheelOfDharma: "\u2638\uFE0F",
1846
- whiteCane: "\u{1F9AF}",
1847
- whiteCircle: "\u26AA",
1848
- whiteExclamationMark: "\u2755",
1849
- whiteFlag: "\u{1F3F3}\uFE0F",
1850
- whiteFlower: "\u{1F4AE}",
1851
- whiteHeart: "\u{1F90D}",
1852
- whiteLargeSquare: "\u2B1C",
1853
- whiteMediumSmallSquare: "\u25FD",
1854
- whiteMediumSquare: "\u25FB\uFE0F",
1855
- whiteQuestionMark: "\u2754",
1856
- whiteSmallSquare: "\u25AB\uFE0F",
1857
- whiteSquareButton: "\u{1F533}",
1858
- wiltedFlower: "\u{1F940}",
1859
- windChime: "\u{1F390}",
1860
- windFace: "\u{1F32C}\uFE0F",
1861
- window: "\u{1FA9F}",
1862
- wineGlass: "\u{1F377}",
1863
- wing: "\u{1FABD}",
1864
- winkingFace: "\u{1F609}",
1865
- winkingFaceWithTongue: "\u{1F61C}",
1866
- wireless: "\u{1F6DC}",
1867
- wolf: "\u{1F43A}",
1868
- woman: "\u{1F469}",
1869
- womanAndManHoldingHands: "\u{1F46B}",
1870
- womanArtist: "\u{1F469}\u200D\u{1F3A8}",
1871
- womanAstronaut: "\u{1F469}\u200D\u{1F680}",
1872
- womanBald: "\u{1F469}\u200D\u{1F9B2}",
1873
- womanBeard: "\u{1F9D4}\u200D\u2640\uFE0F",
1874
- womanBiking: "\u{1F6B4}\u200D\u2640\uFE0F",
1875
- womanBlondHair: "\u{1F471}\u200D\u2640\uFE0F",
1876
- womanBouncingBall: "\u26F9\uFE0F\u200D\u2640\uFE0F",
1877
- womanBowing: "\u{1F647}\u200D\u2640\uFE0F",
1878
- womanCartwheeling: "\u{1F938}\u200D\u2640\uFE0F",
1879
- womanClimbing: "\u{1F9D7}\u200D\u2640\uFE0F",
1880
- womanConstructionWorker: "\u{1F477}\u200D\u2640\uFE0F",
1881
- womanCook: "\u{1F469}\u200D\u{1F373}",
1882
- womanCurlyHair: "\u{1F469}\u200D\u{1F9B1}",
1883
- womanDancing: "\u{1F483}",
1884
- womanDetective: "\u{1F575}\uFE0F\u200D\u2640\uFE0F",
1885
- womanElf: "\u{1F9DD}\u200D\u2640\uFE0F",
1886
- womanFacepalming: "\u{1F926}\u200D\u2640\uFE0F",
1887
- womanFactoryWorker: "\u{1F469}\u200D\u{1F3ED}",
1888
- womanFairy: "\u{1F9DA}\u200D\u2640\uFE0F",
1889
- womanFarmer: "\u{1F469}\u200D\u{1F33E}",
1890
- womanFeedingBaby: "\u{1F469}\u200D\u{1F37C}",
1891
- womanFirefighter: "\u{1F469}\u200D\u{1F692}",
1892
- womanFrowning: "\u{1F64D}\u200D\u2640\uFE0F",
1893
- womanGenie: "\u{1F9DE}\u200D\u2640\uFE0F",
1894
- womanGesturingNo: "\u{1F645}\u200D\u2640\uFE0F",
1895
- womanGesturingOk: "\u{1F646}\u200D\u2640\uFE0F",
1896
- womanGettingHaircut: "\u{1F487}\u200D\u2640\uFE0F",
1897
- womanGettingMassage: "\u{1F486}\u200D\u2640\uFE0F",
1898
- womanGolfing: "\u{1F3CC}\uFE0F\u200D\u2640\uFE0F",
1899
- womanGuard: "\u{1F482}\u200D\u2640\uFE0F",
1900
- womanHealthWorker: "\u{1F469}\u200D\u2695\uFE0F",
1901
- womanInLotusPosition: "\u{1F9D8}\u200D\u2640\uFE0F",
1902
- womanInManualWheelchair: "\u{1F469}\u200D\u{1F9BD}",
1903
- womanInManualWheelchairFacingRight: "\u{1F469}\u200D\u{1F9BD}\u200D\u27A1\uFE0F",
1904
- womanInMotorizedWheelchair: "\u{1F469}\u200D\u{1F9BC}",
1905
- womanInMotorizedWheelchairFacingRight: "\u{1F469}\u200D\u{1F9BC}\u200D\u27A1\uFE0F",
1906
- womanInSteamyRoom: "\u{1F9D6}\u200D\u2640\uFE0F",
1907
- womanInTuxedo: "\u{1F935}\u200D\u2640\uFE0F",
1908
- womanJudge: "\u{1F469}\u200D\u2696\uFE0F",
1909
- womanJuggling: "\u{1F939}\u200D\u2640\uFE0F",
1910
- womanKneeling: "\u{1F9CE}\u200D\u2640\uFE0F",
1911
- womanKneelingFacingRight: "\u{1F9CE}\u200D\u2640\uFE0F\u200D\u27A1\uFE0F",
1912
- womanLiftingWeights: "\u{1F3CB}\uFE0F\u200D\u2640\uFE0F",
1913
- womanMage: "\u{1F9D9}\u200D\u2640\uFE0F",
1914
- womanMechanic: "\u{1F469}\u200D\u{1F527}",
1915
- womanMountainBiking: "\u{1F6B5}\u200D\u2640\uFE0F",
1916
- womanOfficeWorker: "\u{1F469}\u200D\u{1F4BC}",
1917
- womanPilot: "\u{1F469}\u200D\u2708\uFE0F",
1918
- womanPlayingHandball: "\u{1F93E}\u200D\u2640\uFE0F",
1919
- womanPlayingWaterPolo: "\u{1F93D}\u200D\u2640\uFE0F",
1920
- womanPoliceOfficer: "\u{1F46E}\u200D\u2640\uFE0F",
1921
- womanPouting: "\u{1F64E}\u200D\u2640\uFE0F",
1922
- womanRaisingHand: "\u{1F64B}\u200D\u2640\uFE0F",
1923
- womanRedHair: "\u{1F469}\u200D\u{1F9B0}",
1924
- womanRowingBoat: "\u{1F6A3}\u200D\u2640\uFE0F",
1925
- womanRunning: "\u{1F3C3}\u200D\u2640\uFE0F",
1926
- womanRunningFacingRight: "\u{1F3C3}\u200D\u2640\uFE0F\u200D\u27A1\uFE0F",
1927
- womanSBoot: "\u{1F462}",
1928
- womanScientist: "\u{1F469}\u200D\u{1F52C}",
1929
- womanSClothes: "\u{1F45A}",
1930
- womanSHat: "\u{1F452}",
1931
- womanShrugging: "\u{1F937}\u200D\u2640\uFE0F",
1932
- womanSinger: "\u{1F469}\u200D\u{1F3A4}",
1933
- womanSSandal: "\u{1F461}",
1934
- womanStanding: "\u{1F9CD}\u200D\u2640\uFE0F",
1935
- womanStudent: "\u{1F469}\u200D\u{1F393}",
1936
- womanSuperhero: "\u{1F9B8}\u200D\u2640\uFE0F",
1937
- womanSupervillain: "\u{1F9B9}\u200D\u2640\uFE0F",
1938
- womanSurfing: "\u{1F3C4}\u200D\u2640\uFE0F",
1939
- womanSwimming: "\u{1F3CA}\u200D\u2640\uFE0F",
1940
- womanTeacher: "\u{1F469}\u200D\u{1F3EB}",
1941
- womanTechnologist: "\u{1F469}\u200D\u{1F4BB}",
1942
- womanTippingHand: "\u{1F481}\u200D\u2640\uFE0F",
1943
- womanVampire: "\u{1F9DB}\u200D\u2640\uFE0F",
1944
- womanWalking: "\u{1F6B6}\u200D\u2640\uFE0F",
1945
- womanWalkingFacingRight: "\u{1F6B6}\u200D\u2640\uFE0F\u200D\u27A1\uFE0F",
1946
- womanWearingTurban: "\u{1F473}\u200D\u2640\uFE0F",
1947
- womanWhiteHair: "\u{1F469}\u200D\u{1F9B3}",
1948
- womanWithHeadscarf: "\u{1F9D5}",
1949
- womanWithVeil: "\u{1F470}\u200D\u2640\uFE0F",
1950
- womanWithWhiteCane: "\u{1F469}\u200D\u{1F9AF}",
1951
- womanWithWhiteCaneFacingRight: "\u{1F469}\u200D\u{1F9AF}\u200D\u27A1\uFE0F",
1952
- womanZombie: "\u{1F9DF}\u200D\u2640\uFE0F",
1953
- womenHoldingHands: "\u{1F46D}",
1954
- womenSRoom: "\u{1F6BA}",
1955
- womenWithBunnyEars: "\u{1F46F}\u200D\u2640\uFE0F",
1956
- womenWrestling: "\u{1F93C}\u200D\u2640\uFE0F",
1957
- wood: "\u{1FAB5}",
1958
- woozyFace: "\u{1F974}",
1959
- worldMap: "\u{1F5FA}\uFE0F",
1960
- worm: "\u{1FAB1}",
1961
- worriedFace: "\u{1F61F}",
1962
- wrappedGift: "\u{1F381}",
1963
- wrench: "\u{1F527}",
1964
- writingHand: "\u270D\uFE0F",
1965
- xRay: "\u{1FA7B}",
1966
- yarn: "\u{1F9F6}",
1967
- yawningFace: "\u{1F971}",
1968
- yellowCircle: "\u{1F7E1}",
1969
- yellowHeart: "\u{1F49B}",
1970
- yellowSquare: "\u{1F7E8}",
1971
- yenBanknote: "\u{1F4B4}",
1972
- yinYang: "\u262F\uFE0F",
1973
- yoYo: "\u{1FA80}",
1974
- zanyFace: "\u{1F92A}",
1975
- zebra: "\u{1F993}",
1976
- zipperMouthFace: "\u{1F910}",
1977
- zombie: "\u{1F9DF}",
1978
- zzz: "\u{1F4A4}"
1979
- };
1980
-
1981
- // src/emoji/index.ts
1982
- var aliases = {
1983
- love: GeneratedEmoji.redHeart,
1984
- like: GeneratedEmoji.thumbsUp,
1985
- dislike: GeneratedEmoji.thumbsDown,
1986
- laugh: GeneratedEmoji.faceWithTearsOfJoy,
1987
- emphasize: GeneratedEmoji.doubleExclamationMark,
1988
- question: GeneratedEmoji.redQuestionMark
1989
- };
1990
- var Emoji = { ...GeneratedEmoji, ...aliases };
1991
-
1992
- // src/spectrum.ts
1993
- import {
1994
- createLogger as createLogger3,
1995
- setupOtel,
1996
- withSpan
1997
- } from "@photon-ai/otel";
1998
- import { RawInboundEvent } from "@photon-ai/proto/photon/fusor/v1/inbound";
1999
- import z from "zod";
2000
-
2001
- // src/build-env.ts
2002
- var SPECTRUM_SDK_VERSION = "local";
2003
- var SPECTRUM_BUILD_ENV = "development";
2004
-
2005
- // src/fusor/core.ts
2006
- import { createLogger as createLogger2 } from "@photon-ai/otel";
2007
-
2008
- // src/fusor/auth.ts
2009
- var RENEWAL_RATIO = 0.8;
2010
- var EXPIRY_BUFFER_MS = 3e4;
2011
- var RETRY_DELAY_MS = 3e4;
2012
- function createFusorTokenProvider(projectId, projectSecret) {
2013
- return (async () => {
2014
- let tokenData = await cloud.issueFusorToken(projectId, projectSecret);
2015
- let tokenExpiresAt = Date.now() + tokenData.expiresIn * 1e3;
2016
- let disposed = false;
2017
- let renewalTimer;
2018
- const clearRenewalTimer = () => {
2019
- if (renewalTimer !== void 0) {
2020
- clearTimeout(renewalTimer);
2021
- renewalTimer = void 0;
2022
- }
2023
- };
2024
- const refresh = async () => {
2025
- tokenData = await cloud.issueFusorToken(projectId, projectSecret);
2026
- tokenExpiresAt = Date.now() + tokenData.expiresIn * 1e3;
2027
- };
2028
- const scheduleRetry = () => {
2029
- if (disposed) {
2030
- return;
2031
- }
2032
- clearRenewalTimer();
2033
- renewalTimer = setTimeout(async () => {
2034
- if (disposed) {
2035
- return;
2036
- }
2037
- try {
2038
- await refresh();
2039
- scheduleRenewal();
2040
- } catch (retryErr) {
2041
- console.warn(
2042
- `[spectrum-ts] Fusor token refresh failed; retrying in ${RETRY_DELAY_MS}ms.`,
2043
- retryErr
2044
- );
2045
- scheduleRetry();
2046
- }
2047
- }, RETRY_DELAY_MS);
2048
- renewalTimer?.unref?.();
2049
- };
2050
- const scheduleRenewal = () => {
2051
- if (disposed) {
2052
- return;
2053
- }
2054
- clearRenewalTimer();
2055
- const ttlMs = tokenData.expiresIn * 1e3;
2056
- const renewInMs = Math.max(ttlMs * RENEWAL_RATIO, 5e3);
2057
- renewalTimer = setTimeout(async () => {
2058
- try {
2059
- await refresh();
2060
- scheduleRenewal();
2061
- } catch (err) {
2062
- console.warn(
2063
- `[spectrum-ts] Fusor token refresh failed; retrying in ${RETRY_DELAY_MS}ms.`,
2064
- err
2065
- );
2066
- scheduleRetry();
2067
- }
2068
- }, renewInMs);
2069
- renewalTimer?.unref?.();
2070
- };
2071
- scheduleRenewal();
2072
- return {
2073
- async getToken() {
2074
- if (Date.now() >= tokenExpiresAt - EXPIRY_BUFFER_MS) {
2075
- await refresh();
2076
- scheduleRenewal();
2077
- }
2078
- return tokenData.token;
2079
- },
2080
- invalidate() {
2081
- tokenExpiresAt = 0;
2082
- },
2083
- async dispose() {
2084
- disposed = true;
2085
- clearRenewalTimer();
2086
- }
2087
- };
2088
- })();
2089
- }
2090
-
2091
- // src/fusor/parse.ts
2092
- var CR = 13;
2093
- var LF = 10;
2094
- function findHeaderEnd(bytes) {
2095
- for (let i = 0; i + 3 < bytes.length; i++) {
2096
- if (bytes[i] === CR && bytes[i + 1] === LF && bytes[i + 2] === CR && bytes[i + 3] === LF) {
2097
- return i;
2098
- }
2099
- }
2100
- return -1;
2101
- }
2102
- function parseHttpRequest(bytes) {
2103
- const headerEnd = findHeaderEnd(bytes);
2104
- if (headerEnd < 0) {
2105
- throw new Error("fusor: raw_request missing CRLFCRLF header terminator");
2106
- }
2107
- const headerText = new TextDecoder("utf-8").decode(
2108
- bytes.subarray(0, headerEnd)
2109
- );
2110
- const rawBody = bytes.subarray(headerEnd + 4);
2111
- const lines = headerText.split("\r\n");
2112
- const requestLine = lines[0];
2113
- if (!requestLine) {
2114
- throw new Error("fusor: raw_request missing request line");
2115
- }
2116
- const firstSpace = requestLine.indexOf(" ");
2117
- const lastSpace = requestLine.lastIndexOf(" ");
2118
- if (firstSpace < 0 || lastSpace <= firstSpace) {
2119
- throw new Error(`fusor: malformed request line: ${requestLine}`);
2120
- }
2121
- const method = requestLine.slice(0, firstSpace);
2122
- const path = requestLine.slice(firstSpace + 1, lastSpace);
2123
- const headers = {};
2124
- for (let i = 1; i < lines.length; i++) {
2125
- const line = lines[i];
2126
- if (!line) {
2127
- continue;
2128
- }
2129
- const colon = line.indexOf(":");
2130
- if (colon < 0) {
2131
- continue;
2132
- }
2133
- const key = line.slice(0, colon).trim().toLowerCase();
2134
- const value = line.slice(colon + 1).trim();
2135
- if (!key) {
2136
- continue;
2137
- }
2138
- const existing = headers[key];
2139
- headers[key] = existing ? `${existing}, ${value}` : value;
2140
- }
2141
- return { method, path, headers, rawBody };
2142
- }
2143
-
2144
- // src/fusor/websocket.ts
2145
- import { createLogger } from "@photon-ai/otel";
2146
- var log = createLogger("spectrum.fusor.ws");
2147
- var FUSOR_WS_SUBPROTOCOL = "fusor.v1.json";
2148
- var DEFAULT_HEARTBEAT_INTERVAL_MS = 3e4;
2149
- var STALENESS_GRACE_MS = 5e3;
2150
- var FusorWsError = class extends Error {
2151
- closeCode;
2152
- errorCode;
2153
- constructor(message, closeCode, errorCode) {
2154
- super(message);
2155
- this.name = "FusorWsError";
2156
- this.closeCode = closeCode;
2157
- this.errorCode = errorCode;
2158
- }
2159
- };
2160
- function isWsAuthError(error) {
2161
- return error instanceof FusorWsError && (error.closeCode === 4401 || error.errorCode === "unauthenticated");
2162
- }
2163
- function decodeBase64(value) {
2164
- if (typeof Buffer !== "undefined") {
2165
- return new Uint8Array(Buffer.from(value, "base64"));
2166
- }
2167
- return Uint8Array.from(atob(value), (c) => c.charCodeAt(0));
2168
- }
2169
- function encodeBase64(bytes) {
2170
- if (typeof Buffer !== "undefined") {
2171
- return Buffer.from(bytes).toString("base64");
2172
- }
2173
- const chunkSize = 32768;
2174
- const parts = [];
2175
- for (let i = 0; i < bytes.length; i += chunkSize) {
2176
- parts.push(String.fromCharCode(...bytes.subarray(i, i + chunkSize)));
2177
- }
2178
- return btoa(parts.join(""));
2179
- }
2180
- function toRawInboundEvent(frame) {
2181
- const e = frame.event;
2182
- return {
2183
- eventId: e.eventId,
2184
- projectId: e.projectId,
2185
- platform: e.platform,
2186
- receivedAt: e.receivedAt ? new Date(e.receivedAt) : void 0,
2187
- sourceId: e.sourceId ?? "",
2188
- prevSubjectSeq: e.prevSubjectSeq ?? 0,
2189
- rawRequest: decodeBase64(e.rawRequest)
2190
- };
2191
- }
2192
- function runFusorWsSession(options) {
2193
- const WebSocketCtor = globalThis.WebSocket;
2194
- if (typeof WebSocketCtor !== "function") {
2195
- throw new FusorWsError(
2196
- "global WebSocket is not available in this runtime \u2014 the fusor websocket transport needs Bun, Node >= 22, or a browser/worker environment"
2197
- );
2198
- }
2199
- const wsOpen = WebSocketCtor.OPEN;
2200
- const ws = new WebSocketCtor(options.url, [FUSOR_WS_SUBPROTOCOL]);
2201
- let settled = false;
2202
- let closedByUs = false;
2203
- let pendingError = null;
2204
- let stalenessBudgetMs = 2 * DEFAULT_HEARTBEAT_INTERVAL_MS + STALENESS_GRACE_MS;
2205
- let watchdog;
2206
- let tail = Promise.resolve();
2207
- let resolveDone;
2208
- let rejectDone;
2209
- const done = new Promise((resolve, reject) => {
2210
- resolveDone = resolve;
2211
- rejectDone = reject;
2212
- });
2213
- const settle = (error) => {
2214
- if (settled) {
2215
- return;
2216
- }
2217
- settled = true;
2218
- if (watchdog) {
2219
- clearTimeout(watchdog);
2220
- watchdog = void 0;
2221
- }
2222
- if (error) {
2223
- rejectDone(error);
2224
- } else {
2225
- resolveDone();
2226
- }
2227
- };
2228
- const armWatchdog = () => {
2229
- if (settled) {
2230
- return;
2231
- }
2232
- if (watchdog) {
2233
- clearTimeout(watchdog);
2234
- }
2235
- watchdog = setTimeout(() => {
2236
- log.warn("fusor ws: no frame within staleness budget; closing", {
2237
- budgetMs: stalenessBudgetMs
2238
- });
2239
- settle(new FusorWsError("websocket heartbeat timeout"));
2240
- try {
2241
- ws.close();
2242
- } catch {
2243
- }
2244
- }, stalenessBudgetMs);
2245
- watchdog.unref?.();
2246
- };
2247
- const sendReplyFor = (eventId) => (reply2) => {
2248
- if (ws.readyState !== wsOpen) {
2249
- return;
2250
- }
2251
- ws.send(
2252
- JSON.stringify({
2253
- type: "reply",
2254
- eventId,
2255
- status: reply2.status,
2256
- headers: reply2.headers,
2257
- ...reply2.body.length > 0 && { body: encodeBase64(reply2.body) },
2258
- ...reply2.errorReason && { errorReason: reply2.errorReason }
2259
- })
2260
- );
2261
- };
2262
- const handleReadyFrame = (frame) => {
2263
- const interval = frame.heartbeatIntervalMs;
2264
- if (typeof interval === "number" && interval > 0) {
2265
- stalenessBudgetMs = 2 * interval + STALENESS_GRACE_MS;
2266
- }
2267
- log.info("fusor ws stream ready", {
2268
- projectId: typeof frame.projectId === "string" ? frame.projectId : "",
2269
- heartbeatIntervalMs: typeof interval === "number" ? interval : 0
2270
- });
2271
- };
2272
- const handleEventFrame = (frame) => {
2273
- const eventFrame = frame;
2274
- let event;
2275
- try {
2276
- event = toRawInboundEvent(eventFrame);
2277
- } catch (error) {
2278
- log.warn("fusor ws: undecodable event frame; skipping", {
2279
- error: error instanceof Error ? error.message : String(error)
2280
- });
2281
- return;
2282
- }
2283
- const sendReply = eventFrame.replyExpected ? sendReplyFor(event.eventId) : void 0;
2284
- tail = tail.then(() => options.onEvent(event, sendReply)).catch((error) => {
2285
- log.warn("fusor ws: event handler failed", {
2286
- eventId: event.eventId,
2287
- error: error instanceof Error ? error.message : String(error)
2288
- });
2289
- });
2290
- };
2291
- const handleErrorFrame = (frame) => {
2292
- const code = typeof frame.code === "string" ? frame.code : "unknown";
2293
- const message = typeof frame.message === "string" ? frame.message : "server error";
2294
- const reason = typeof frame.reason === "string" ? frame.reason : void 0;
2295
- if (frame.fatal === true) {
2296
- pendingError = { code, message, reason };
2297
- } else {
2298
- log.warn("fusor ws: server notice", { code, message, reason });
2299
- }
2300
- };
2301
- const handleFrame = (raw) => {
2302
- if (typeof raw !== "string") {
2303
- return;
2304
- }
2305
- let frame;
2306
- try {
2307
- frame = JSON.parse(raw);
2308
- } catch {
2309
- log.warn("fusor ws: unparseable server frame; ignoring");
2310
- return;
2311
- }
2312
- switch (frame.type) {
2313
- case "ready":
2314
- handleReadyFrame(frame);
2315
- return;
2316
- case "event":
2317
- handleEventFrame(frame);
2318
- return;
2319
- case "error":
2320
- handleErrorFrame(frame);
2321
- return;
2322
- default:
2323
- return;
2324
- }
2325
- };
2326
- ws.onopen = () => {
2327
- armWatchdog();
2328
- ws.send(
2329
- JSON.stringify({ type: "init", startSeq: 0, token: options.token })
2330
- );
2331
- };
2332
- ws.onmessage = (messageEvent) => {
2333
- armWatchdog();
2334
- handleFrame(messageEvent.data);
2335
- };
2336
- ws.onerror = () => {
2337
- log.debug("fusor ws: socket error event");
2338
- };
2339
- ws.onclose = (closeEvent) => {
2340
- if (closedByUs) {
2341
- settle();
2342
- return;
2343
- }
2344
- const detail = pendingError ? `${pendingError.code}${pendingError.reason ? `:${pendingError.reason}` : ""} \u2014 ${pendingError.message}` : closeEvent.reason || "connection closed";
2345
- settle(
2346
- new FusorWsError(
2347
- `fusor websocket closed (${closeEvent.code}): ${detail}`,
2348
- closeEvent.code,
2349
- pendingError?.code ?? (closeEvent.reason || void 0)
2350
- )
2351
- );
2352
- };
2353
- armWatchdog();
2354
- return {
2355
- done,
2356
- close() {
2357
- closedByUs = true;
2358
- try {
2359
- ws.close(1e3);
2360
- } catch {
2361
- }
2362
- const failsafe = setTimeout(() => settle(), 2e3);
2363
- failsafe.unref?.();
2364
- }
2365
- };
2366
- }
2367
-
2368
- // src/fusor/core.ts
2369
- var DEFAULT_FUSOR_WS_URL = "wss://fusor-ws.spectrum.photon.codes/v1/subscribe";
2370
- var RECONNECT_BASE_MS = 1e3;
2371
- var RECONNECT_MAX_MS = 3e4;
2372
- var log2 = createLogger2("spectrum.fusor");
2373
- var errorText = (error) => error instanceof Error ? error.message : String(error);
2374
- function toReplyBytes(body) {
2375
- if (body === void 0) {
2376
- return new Uint8Array(0);
2377
- }
2378
- if (typeof body === "string") {
2379
- return new TextEncoder().encode(body);
2380
- }
2381
- return body;
2382
- }
2383
- function combineReplies(outcomes) {
2384
- const successes = outcomes.filter((o) => o.ok);
2385
- if (successes.length === 0) {
2386
- const firstFailure = outcomes[0];
2387
- return {
2388
- eventId: "",
2389
- errorReason: firstFailure?.errorReason ?? "no handler succeeded",
2390
- status: 0,
2391
- headers: {},
2392
- body: new Uint8Array(0)
2393
- };
2394
- }
2395
- let status = 0;
2396
- const headers = {};
2397
- let body = new Uint8Array(0);
2398
- for (const outcome of successes) {
2399
- const reply2 = outcome.reply;
2400
- if (!reply2) {
2401
- continue;
2402
- }
2403
- if (reply2.status !== void 0 && reply2.status > status) {
2404
- status = reply2.status;
2405
- }
2406
- if (reply2.headers) {
2407
- for (const [k, v] of Object.entries(reply2.headers)) {
2408
- headers[k.toLowerCase()] = v;
2409
- }
2410
- }
2411
- const candidate = toReplyBytes(reply2.body);
2412
- if (candidate.length > 0) {
2413
- body = candidate;
2414
- }
2415
- }
2416
- return {
2417
- eventId: "",
2418
- errorReason: "",
2419
- status,
2420
- headers,
2421
- body
2422
- };
2423
- }
2424
- function routeHandlerResult(result, handler, deliver) {
2425
- if (result === void 0) {
2426
- return;
2427
- }
2428
- const items = Array.isArray(result) ? result : [result];
2429
- for (const item of items) {
2430
- if (!isFusorEvent(item)) {
2431
- deliver(item);
2432
- continue;
2433
- }
2434
- if (item.name === FUSOR_MESSAGES_CHANNEL) {
2435
- deliver(item.data);
2436
- } else {
2437
- handler.pushEvent(item.name, item.data);
2438
- }
2439
- }
2440
- }
2441
- function runHandlerOnce(handler, parsedRequest, deliver = handler.pushMessage) {
2442
- return (async () => {
2443
- try {
2444
- const payload = await handler.verify(parsedRequest);
2445
- let reply2;
2446
- let respondCalled = false;
2447
- let returned = false;
2448
- const respond = (next) => {
2449
- if (returned) {
2450
- log2.warn("fusor.respond called after handler returned; ignoring");
2451
- return;
2452
- }
2453
- if (respondCalled) {
2454
- log2.debug("fusor.respond called more than once; last call wins");
2455
- }
2456
- respondCalled = true;
2457
- reply2 = next;
2458
- };
2459
- const result = await handler.messages({ payload, respond });
2460
- returned = true;
2461
- routeHandlerResult(result, handler, deliver);
2462
- return { ok: true, reply: reply2 };
2463
- } catch (error) {
2464
- return { ok: false, errorReason: errorText(error) };
2465
- }
2466
- })();
2467
- }
2468
- var FusorCore = class {
2469
- options;
2470
- websocketEndpoint;
2471
- handlers = /* @__PURE__ */ new Map();
2472
- tokenProvider;
2473
- wsSession;
2474
- connectionLoop;
2475
- started = false;
2476
- stopped = false;
2477
- stopResolve;
2478
- stoppedPromise;
2479
- // The reconnect backoff sleep, made cancelable so close() can wake it.
2480
- reconnectTimer;
2481
- reconnectResolve;
2482
- constructor(options) {
2483
- this.options = options;
2484
- this.websocketEndpoint = options.websocketEndpoint ?? process.env.SPECTRUM_FUSOR_WS_URL ?? DEFAULT_FUSOR_WS_URL;
2485
- this.stoppedPromise = new Promise((resolve) => {
2486
- this.stopResolve = resolve;
2487
- });
2488
- }
2489
- register(platform, handler) {
2490
- const list = this.handlers.get(platform) ?? [];
2491
- list.push(handler);
2492
- this.handlers.set(platform, list);
2493
- }
2494
- async start() {
2495
- if (!(this.options.projectId && this.options.projectSecret)) {
2496
- throw new Error(
2497
- "fusor: streaming via spectrum.messages requires projectId and projectSecret"
2498
- );
2499
- }
2500
- if (this.started) {
2501
- return;
2502
- }
2503
- this.started = true;
2504
- this.tokenProvider = await createFusorTokenProvider(
2505
- this.options.projectId,
2506
- this.options.projectSecret
2507
- );
2508
- this.connectionLoop = this.runConnectionLoop().catch((error) => {
2509
- log2.error("fusor connection loop crashed", { error });
2510
- });
2511
- }
2512
- // Streaming transport: the fusor.v1.json WebSocket plane. A session that
2513
- // runs to a clean end reconnects immediately; an errored session backs
2514
- // off exponentially (reset on the next clean run).
2515
- async runConnectionLoop() {
2516
- let attempt = 0;
2517
- while (!this.stopped) {
2518
- const wsRan = await this.tryWebsocketOnce();
2519
- if (this.stopped) {
2520
- return;
2521
- }
2522
- if (wsRan) {
2523
- attempt = 0;
2524
- continue;
2525
- }
2526
- attempt += 1;
2527
- await this.backoffSleep(this.backoffMs(attempt));
2528
- }
2529
- }
2530
- // True when the stream ran to a clean end; false when it errored (the
2531
- // loop then backs off before reconnecting).
2532
- async tryWebsocketOnce() {
2533
- try {
2534
- await this.runWebsocketOnce();
2535
- return true;
2536
- } catch (error) {
2537
- if (isWsAuthError(error)) {
2538
- this.tokenProvider?.invalidate();
2539
- }
2540
- if (!this.stopped) {
2541
- log2.warn("fusor websocket stream errored; reconnecting", {
2542
- error: errorText(error)
2543
- });
2544
- }
2545
- return false;
2546
- }
2547
- }
2548
- backoffMs(attempt) {
2549
- return Math.min(RECONNECT_BASE_MS * 2 ** (attempt - 1), RECONNECT_MAX_MS);
2550
- }
2551
- // Cancelable sleep: close() clears the timer and resolves it so
2552
- // shutdown doesn't wait out the (up to 30s) backoff.
2553
- async backoffSleep(backoff) {
2554
- await new Promise((resolve) => {
2555
- this.reconnectResolve = resolve;
2556
- const timer = setTimeout(resolve, backoff);
2557
- timer.unref?.();
2558
- this.reconnectTimer = timer;
2559
- });
2560
- this.reconnectTimer = void 0;
2561
- this.reconnectResolve = void 0;
2562
- }
2563
- async runWebsocketOnce() {
2564
- if (!this.tokenProvider) {
2565
- throw new Error("fusor: token not initialized");
2566
- }
2567
- const token = await this.tokenProvider.getToken();
2568
- const session = runFusorWsSession({
2569
- url: this.websocketEndpoint,
2570
- token,
2571
- onEvent: async (event, sendReply) => {
2572
- if (this.stopped) {
2573
- return;
2574
- }
2575
- const reply2 = await this.processEvent(event);
2576
- sendReply?.(reply2);
2577
- }
2578
- });
2579
- this.wsSession = session;
2580
- try {
2581
- await session.done;
2582
- } finally {
2583
- this.wsSession = void 0;
2584
- }
2585
- }
2586
- // Transport-independent event processing: route by platform, parse the wire
2587
- // request, run every registered handler (verify → messages), and combine the
2588
- // results into a single InboundReply. Returns the reply instead of writing it
2589
- // anywhere, so both the streaming session (sendReply) and the synchronous
2590
- // webhook path can drive it. `deliver` controls where produced records go:
2591
- // the streaming path defaults to each handler's pushMessage (the per-platform
2592
- // queue feeding spectrum.messages); the webhook path collects them for the
2593
- // request instead.
2594
- async processEvent(event, deliver) {
2595
- const handlers = this.handlers.get(event.platform) ?? [];
2596
- if (handlers.length === 0) {
2597
- log2.warn("fusor: no handler for platform", { platform: event.platform });
2598
- return {
2599
- eventId: event.eventId,
2600
- errorReason: `no handler for platform ${event.platform}`,
2601
- status: 0,
2602
- headers: {},
2603
- body: new Uint8Array(0)
2604
- };
2605
- }
2606
- let parsedRequest;
2607
- try {
2608
- parsedRequest = parseHttpRequest(event.rawRequest);
2609
- } catch (error) {
2610
- const errorReason = errorText(error);
2611
- log2.warn("fusor: failed to parse raw_request", {
2612
- platform: event.platform,
2613
- error: errorReason
2614
- });
2615
- return {
2616
- eventId: event.eventId,
2617
- errorReason,
2618
- status: 0,
2619
- headers: {},
2620
- body: new Uint8Array(0)
2621
- };
2622
- }
2623
- const outcomes = await Promise.all(
2624
- handlers.map((handler) => runHandlerOnce(handler, parsedRequest, deliver))
2625
- );
2626
- const combined = combineReplies(outcomes);
2627
- combined.eventId = event.eventId;
2628
- return combined;
2629
- }
2630
- async close() {
2631
- if (this.stopped) {
2632
- return;
2633
- }
2634
- this.stopped = true;
2635
- this.wsSession?.close();
2636
- if (this.reconnectTimer) {
2637
- clearTimeout(this.reconnectTimer);
2638
- this.reconnectTimer = void 0;
2639
- }
2640
- this.reconnectResolve?.();
2641
- this.reconnectResolve = void 0;
2642
- if (this.tokenProvider) {
2643
- await this.tokenProvider.dispose();
2644
- }
2645
- if (this.connectionLoop) {
2646
- await this.connectionLoop;
2647
- }
2648
- this.stopResolve?.();
2649
- }
2650
- async waitStopped() {
2651
- return this.stoppedPromise;
2652
- }
2653
- };
2654
-
2655
- // src/utils/store.ts
2656
- var isRecordObject = (value) => {
2657
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
2658
- return false;
2659
- }
2660
- const prototype = Object.getPrototypeOf(value);
2661
- return prototype === Object.prototype || prototype === null;
2662
- };
2663
- function createStore() {
2664
- const data = /* @__PURE__ */ new Map();
2665
- return {
2666
- set(key, value) {
2667
- data.set(key, value);
2668
- },
2669
- get(key) {
2670
- return data.get(key);
2671
- },
2672
- has(key) {
2673
- return data.has(key);
2674
- },
2675
- delete(key) {
2676
- return data.delete(key);
2677
- },
2678
- clear() {
2679
- data.clear();
2680
- },
2681
- keys() {
2682
- return Array.from(data.keys());
2683
- },
2684
- string(key) {
2685
- const v = data.get(key);
2686
- return typeof v === "string" ? v : void 0;
2687
- },
2688
- number(key) {
2689
- const v = data.get(key);
2690
- return typeof v === "number" ? v : void 0;
2691
- },
2692
- bool(key) {
2693
- const v = data.get(key);
2694
- return typeof v === "boolean" ? v : void 0;
2695
- },
2696
- object(key) {
2697
- const v = data.get(key);
2698
- if (!isRecordObject(v)) {
2699
- return;
2700
- }
2701
- return v;
2702
- },
2703
- array(key) {
2704
- const v = data.get(key);
2705
- return Array.isArray(v) ? v : void 0;
2706
- }
2707
- };
2708
- }
2709
-
2710
- // src/spectrum.ts
2711
- var PHOTON_OTEL_ENDPOINT = "https://otlp.photon.codes";
2712
- var STREAM_CLOSE_TIMEOUT_MS = 5e3;
2713
- var lifecycleLog = createLogger3("spectrum.lifecycle");
2714
- var ignoreCleanupError = () => void 0;
2715
- var spectrumOptionsSchema = z.object({
2716
- flattenGroups: z.boolean().optional()
2717
- }).optional();
2718
- var spectrumConfigSchema = z.union([
2719
- z.object({
2720
- projectId: z.string().min(1),
2721
- projectSecret: z.string().min(1),
2722
- providers: z.array(z.custom()),
2723
- options: spectrumOptionsSchema,
2724
- telemetry: z.boolean().optional()
2725
- }),
2726
- z.object({
2727
- projectId: z.undefined().optional(),
2728
- projectSecret: z.undefined().optional(),
2729
- providers: z.array(z.custom()),
2730
- options: spectrumOptionsSchema,
2731
- telemetry: z.boolean().optional()
2732
- })
2733
- ]);
2734
- function bootstrapTelemetry(opts) {
2735
- const headers = {};
2736
- if (opts.projectId && opts.projectSecret) {
2737
- const credential = `${opts.projectId}:${opts.projectSecret}`;
2738
- headers.Authorization = `Basic ${btoa(credential)}`;
2739
- }
2740
- const resourceAttributes = {
2741
- "deployment.environment": process.env.DEPLOYMENT_ENV ?? SPECTRUM_BUILD_ENV
2742
- };
2743
- if (opts.projectId) {
2744
- resourceAttributes["spectrum.project_id"] = opts.projectId;
2745
- }
2746
- return setupOtel({
2747
- serviceName: "spectrum-ts",
2748
- serviceVersion: SPECTRUM_SDK_VERSION,
2749
- endpoint: PHOTON_OTEL_ENDPOINT,
2750
- headers,
2751
- resourceAttributes
2752
- });
2753
- }
2754
- async function Spectrum(options) {
2755
- spectrumConfigSchema.parse(options);
2756
- const {
2757
- projectId,
2758
- projectSecret,
2759
- providers,
2760
- options: runtimeOptions,
2761
- telemetry
2762
- } = options;
2763
- const flattenGroups = runtimeOptions?.flattenGroups ?? false;
2764
- const otelHandle = telemetry ? bootstrapTelemetry({ projectId, projectSecret }) : void 0;
2765
- const projectConfig = projectId !== void 0 && projectSecret !== void 0 ? await cloud.getProject(projectId, projectSecret) : void 0;
2766
- const platformStates = /* @__PURE__ */ new Map();
2767
- const fusorMessageSources = /* @__PURE__ */ new Map();
2768
- const messageBroadcasters = /* @__PURE__ */ new Map();
2769
- const fusorEventSources = /* @__PURE__ */ new Map();
2770
- const eventBroadcasters = /* @__PURE__ */ new Map();
2771
- const customEventStreams = /* @__PURE__ */ new Map();
2772
- let stopped = false;
2773
- const adaptIterable = (iterable, project) => stream((emit, end) => {
2774
- const iterator = iterable[Symbol.asyncIterator]();
2775
- const pump = (async () => {
2776
- try {
2777
- let result = await iterator.next();
2778
- while (!result.done) {
2779
- if (project) {
2780
- await project(result.value, emit);
2781
- } else {
2782
- await emit(result.value);
2783
- }
2784
- result = await iterator.next();
2785
- }
2786
- end();
2787
- } catch (error) {
2788
- end(error);
2789
- }
2790
- })();
2791
- return async () => {
2792
- await iterator.return?.();
2793
- await pump.catch(ignoreCleanupError);
2794
- };
2795
- });
2796
- const resolveRecordToMessages = async (record, rt) => {
2797
- const { client, config, definition, store } = rt;
2798
- const built = await withSpan(
2799
- "spectrum.message.receive",
2800
- {
2801
- "spectrum.provider": definition.name,
2802
- "spectrum.message.id": record.id,
2803
- "spectrum.space.id": record.space?.id,
2804
- ...contentAttrs(record.content),
2805
- ...senderAttrs(record.sender)
2806
- },
2807
- () => {
2808
- const spaceRef = {
2809
- ...record.space,
2810
- __platform: definition.name
2811
- };
2812
- const actionCtx = { space: spaceRef, client, config, store };
2813
- const space2 = buildSpace({
2814
- spaceRef,
2815
- extras: {},
2816
- actionCtx,
2817
- definition,
2818
- client,
2819
- config,
2820
- store
2821
- });
2822
- const normalizedMessage2 = wrapProviderMessage(
2823
- record,
2824
- {
2825
- client,
2826
- config,
2827
- definition,
2828
- space: space2,
2829
- spaceRef,
2830
- store
2831
- },
2832
- "inbound"
2833
- );
2834
- return { space: space2, normalizedMessage: normalizedMessage2 };
2835
- }
2836
- );
2837
- const { space, normalizedMessage } = built;
2838
- if (flattenGroups && normalizedMessage.content.type === "group") {
2839
- return normalizedMessage.content.items.map((item) => [
2840
- space,
2841
- item
2842
- ]);
2843
- }
2844
- return [[space, normalizedMessage]];
2845
- };
2846
- const createProviderMessagesStream = (state) => {
2847
- const { client, config, definition, store } = state;
2848
- const fusorSource = fusorMessageSources.get(definition.name);
2849
- const raw = fusorSource ? fusorSource.iterable : definition.messages({
2850
- client,
2851
- config,
2852
- projectConfig,
2853
- store
2854
- });
2855
- return adaptIterable(
2856
- raw,
2857
- async (record, emit) => {
2858
- const tuples = await resolveRecordToMessages(record, {
2859
- client,
2860
- config,
2861
- definition,
2862
- store
2863
- });
2864
- for (const tuple of tuples) {
2865
- await emit(tuple);
2866
- }
2867
- }
2868
- );
2869
- };
2870
- const getOrCreateMessageBroadcast = (state) => {
2871
- if (stopped) {
2872
- throw new Error(
2873
- `Spectrum instance has been stopped; cannot subscribe to "${state.definition.name}" messages`
2874
- );
2875
- }
2876
- const name = state.definition.name;
2877
- let broadcaster = messageBroadcasters.get(name);
2878
- if (!broadcaster) {
2879
- broadcaster = broadcast(createProviderMessagesStream(state));
2880
- messageBroadcasters.set(name, broadcaster);
2881
- }
2882
- return broadcaster;
2883
- };
2884
- const getOrCreateEventBroadcast = (platform, channel) => {
2885
- const queue = fusorEventSources.get(platform)?.get(channel);
2886
- if (!queue) {
2887
- return;
2888
- }
2889
- if (stopped) {
2890
- throw new Error(
2891
- `Spectrum instance has been stopped; cannot subscribe to "${platform}" event "${channel}"`
2892
- );
2893
- }
2894
- const key = `${platform}\0${channel}`;
2895
- let broadcaster = eventBroadcasters.get(key);
2896
- if (!broadcaster) {
2897
- broadcaster = broadcast(adaptIterable(queue.iterable));
2898
- eventBroadcasters.set(key, broadcaster);
2899
- }
2900
- return broadcaster;
2901
- };
2902
- await withSpan(
2903
- "spectrum.init",
2904
- {
2905
- "spectrum.provider_count": providers.length,
2906
- "spectrum.flatten_groups": flattenGroups
2907
- },
2908
- async () => {
2909
- for (const provider of providers) {
2910
- const providerConfig = provider;
2911
- const def = providerConfig.__definition;
2912
- const userConfig = def.config.parse(providerConfig.config);
2913
- const store = createStore();
2914
- const client = await withSpan(
2915
- "spectrum.provider.create_client",
2916
- {
2917
- "spectrum.provider": def.name
2918
- },
2919
- () => def.lifecycle.createClient({
2920
- config: userConfig,
2921
- projectId,
2922
- projectSecret,
2923
- projectConfig,
2924
- store
2925
- })
2926
- );
2927
- const state = {
2928
- client,
2929
- config: userConfig,
2930
- definition: def,
2931
- store
2932
- };
2933
- platformStates.set(def.name, {
2934
- ...state,
2935
- projectConfig,
2936
- subscribeMessages: () => getOrCreateMessageBroadcast(state).subscribe(),
2937
- // Fanout subscription to a fusor event channel. Returns undefined for
2938
- // regular platforms (no per-channel queue) — callers fall back to the
2939
- // producer path. Resolved lazily, after the fusor bootstrap below has
2940
- // created the per-(platform, channel) queues.
2941
- subscribeEvent: (channel) => getOrCreateEventBroadcast(def.name, channel)?.subscribe()
2942
- });
2943
- }
2944
- }
2945
- );
2946
- let fusorCore;
2947
- let fusorStartPromise;
2948
- const fusorPlatforms = [];
2949
- for (const [name, state] of platformStates) {
2950
- if (isFusorClient(state.client)) {
2951
- fusorPlatforms.push({ name, client: state.client });
2952
- }
2953
- }
2954
- if (fusorPlatforms.length > 0) {
2955
- fusorCore = new FusorCore({ projectId, projectSecret });
2956
- for (const { name, client } of fusorPlatforms) {
2957
- const queue = createAsyncQueue();
2958
- fusorMessageSources.set(name, queue);
2959
- const runtime = platformStates.get(name);
2960
- if (!runtime) {
2961
- continue;
2962
- }
2963
- const userMessages = runtime.definition.messages;
2964
- const declaredEvents = runtime.definition.events ?? {};
2965
- const eventQueues = /* @__PURE__ */ new Map();
2966
- for (const channel of Object.keys(declaredEvents)) {
2967
- eventQueues.set(channel, createAsyncQueue());
2968
- }
2969
- fusorEventSources.set(name, eventQueues);
2970
- const handler = {
2971
- verify: client.verify,
2972
- // Enrich the transport-level `{ payload, respond }` ctx with the same
2973
- // runtime context every other platform callback receives, so fusor
2974
- // handlers can read config/store/projectConfig directly instead of
2975
- // smuggling state through the payload.
2976
- messages: async (ctx) => userMessages({
2977
- ...ctx,
2978
- config: runtime.config,
2979
- store: runtime.store,
2980
- projectConfig: runtime.projectConfig
2981
- }),
2982
- pushMessage: (record) => queue.push(record),
2983
- pushEvent: (channel, data) => {
2984
- const eventQueue = eventQueues.get(channel);
2985
- if (!eventQueue) {
2986
- lifecycleLog.warn(
2987
- `spectrum: fusorEvent("${channel}", \u2026) names a channel not declared in "${name}".events; dropping`,
2988
- { platform: name, channel }
2989
- );
2990
- return;
2991
- }
2992
- eventQueue.push(data);
2993
- }
2994
- };
2995
- fusorCore.register(client.platform, handler);
2996
- }
2997
- }
2998
- const ensureFusorStarted = () => {
2999
- if (!fusorCore) {
3000
- return Promise.resolve();
3001
- }
3002
- if (!fusorStartPromise) {
3003
- fusorStartPromise = fusorCore.start();
3004
- }
3005
- return fusorStartPromise;
3006
- };
3007
- const providerNames = providers.map((p) => p.__definition.name).join(",");
3008
- lifecycleLog.info("Spectrum started", {
3009
- providerCount: providers.length,
3010
- providers: providerNames,
3011
- telemetry: telemetry === true
3012
- });
3013
- const createMessagesStream = () => stream((emit, end) => {
3014
- ensureFusorStarted().catch((error) => end(error));
3015
- const merged = mergeStreams(
3016
- Array.from(
3017
- platformStates.values(),
3018
- (runtime) => runtime.subscribeMessages()
3019
- )
3020
- );
3021
- const pump = (async () => {
3022
- try {
3023
- for await (const value of merged) {
3024
- await emit(value);
3025
- }
3026
- end();
3027
- } catch (error) {
3028
- end(error);
3029
- }
3030
- })();
3031
- return async () => {
3032
- await merged.close();
3033
- await pump.catch(ignoreCleanupError);
3034
- };
3035
- });
3036
- const createCustomEventStream = (eventName) => stream((emit, end) => {
3037
- const providerStreams = [];
3038
- for (const state of platformStates.values()) {
3039
- const { client, config, definition, store } = state;
3040
- let source = state.subscribeEvent?.(eventName);
3041
- if (!source) {
3042
- const producer = definition.events?.[eventName];
3043
- if (typeof producer !== "function") {
3044
- continue;
3045
- }
3046
- source = producer({ client, config, projectConfig, store });
3047
- }
3048
- const providerEvents = source;
3049
- providerStreams.push(
3050
- adaptIterable(
3051
- providerEvents,
3052
- async (value, emit2) => {
3053
- const annotated = await withSpan(
3054
- "spectrum.event",
3055
- {
3056
- "spectrum.provider": definition.name,
3057
- "spectrum.event.name": eventName
3058
- },
3059
- // Object payloads are flattened and tagged with `platform`. A
3060
- // primitive/null payload can't be spread (a string would mangle
3061
- // into indexed chars, a number/bool would vanish), so wrap it
3062
- // under `payload` instead.
3063
- () => typeof value === "object" && value !== null ? { ...value, platform: definition.name } : { platform: definition.name, payload: value }
3064
- );
3065
- await emit2(annotated);
3066
- }
3067
- )
3068
- );
3069
- }
3070
- const merged = mergeStreams(providerStreams);
3071
- const pump = (async () => {
3072
- try {
3073
- for await (const value of merged) {
3074
- await emit(value);
3075
- }
3076
- end();
3077
- } catch (error) {
3078
- end(error);
3079
- }
3080
- })();
3081
- return async () => {
3082
- await merged.close();
3083
- await pump.catch(ignoreCleanupError);
3084
- };
3085
- });
3086
- const messagesStream = createMessagesStream();
3087
- const closeFusorSources = () => {
3088
- for (const queue of fusorMessageSources.values()) {
3089
- queue.close();
3090
- }
3091
- fusorMessageSources.clear();
3092
- for (const queues of fusorEventSources.values()) {
3093
- for (const queue of queues.values()) {
3094
- queue.close();
3095
- }
3096
- }
3097
- fusorEventSources.clear();
3098
- };
3099
- const stopOnce = async () => {
3100
- if (stopped) {
3101
- return;
3102
- }
3103
- stopped = true;
3104
- const streamShutdowns = [
3105
- messagesStream.close(),
3106
- ...Array.from(
3107
- customEventStreams.values(),
3108
- (eventStream) => eventStream.close()
3109
- ),
3110
- ...Array.from(
3111
- messageBroadcasters.values(),
3112
- (broadcaster) => broadcaster.close()
3113
- ),
3114
- ...Array.from(
3115
- eventBroadcasters.values(),
3116
- (broadcaster) => broadcaster.close()
3117
- )
3118
- ];
3119
- process.off("SIGINT", handleSignal);
3120
- process.off("SIGTERM", handleSignal);
3121
- const streamCloseStart = performance.now();
3122
- const streamSettled = Promise.allSettled(streamShutdowns);
3123
- let streamTimedOut = false;
3124
- await Promise.race([
3125
- streamSettled,
3126
- new Promise((resolve) => {
3127
- setTimeout(() => {
3128
- streamTimedOut = true;
3129
- resolve();
3130
- }, STREAM_CLOSE_TIMEOUT_MS).unref();
3131
- })
3132
- ]);
3133
- if (streamTimedOut) {
3134
- lifecycleLog.warn("stream close timed out; proceeding to teardown", {
3135
- timeoutMs: STREAM_CLOSE_TIMEOUT_MS
3136
- });
3137
- }
3138
- let fusorCloseMs = 0;
3139
- if (fusorCore) {
3140
- const fusorCloseStart = performance.now();
3141
- if (fusorStartPromise) {
3142
- await fusorStartPromise.catch(ignoreCleanupError);
3143
- }
3144
- await fusorCore.close().catch((error) => {
3145
- lifecycleLog.warn("fusor core close failed", { error });
3146
- });
3147
- fusorCloseMs = Math.round(performance.now() - fusorCloseStart);
3148
- closeFusorSources();
3149
- }
3150
- const clientShutdowns = [];
3151
- for (const state of platformStates.values()) {
3152
- const destroy = state.definition.lifecycle.destroyClient;
3153
- if (!destroy) {
3154
- continue;
3155
- }
3156
- clientShutdowns.push(
3157
- withSpan(
3158
- "spectrum.provider.destroy_client",
3159
- {
3160
- "spectrum.provider": state.definition.name
3161
- },
3162
- () => destroy({
3163
- client: state.client,
3164
- store: state.store
3165
- })
3166
- )
3167
- );
3168
- }
3169
- const clientCloseStart = performance.now();
3170
- await Promise.allSettled(clientShutdowns);
3171
- const clientCloseMs = Math.round(performance.now() - clientCloseStart);
3172
- await streamSettled.catch(() => void 0);
3173
- const streamCloseMs = Math.round(performance.now() - streamCloseStart);
3174
- customEventStreams.clear();
3175
- messageBroadcasters.clear();
3176
- eventBroadcasters.clear();
3177
- platformStates.clear();
3178
- lifecycleLog.info("Spectrum stopped", {
3179
- providers: providerNames,
3180
- streamCloseMs,
3181
- fusorCloseMs,
3182
- clientCloseMs
3183
- });
3184
- if (otelHandle) {
3185
- await otelHandle.shutdown();
3186
- }
3187
- };
3188
- const handleSignal = () => {
3189
- setTimeout(() => process.exit(1), 3e3).unref();
3190
- stopOnce().then(() => process.exit(0)).catch(() => process.exit(1));
3191
- };
3192
- process.on("SIGINT", handleSignal);
3193
- process.on("SIGTERM", handleSignal);
3194
- const messages = messagesStream;
3195
- const customEventProxy = new Proxy(
3196
- {},
3197
- {
3198
- get(_target, prop) {
3199
- let eventStream = customEventStreams.get(prop);
3200
- if (!eventStream) {
3201
- eventStream = createCustomEventStream(prop);
3202
- customEventStreams.set(prop, eventStream);
3203
- }
3204
- return eventStream;
3205
- }
3206
- }
3207
- );
3208
- const encodeText = (s) => new TextEncoder().encode(s);
3209
- const buildWebhookResult = (asWeb, result) => {
3210
- if (asWeb) {
3211
- return new Response(result.body, {
3212
- status: result.status,
3213
- headers: result.headers
3214
- });
3215
- }
3216
- return result;
3217
- };
3218
- const readWebhookInput = async (request) => {
3219
- if (typeof Request !== "undefined" && request instanceof Request) {
3220
- return {
3221
- asWeb: true,
3222
- bodyBytes: new Uint8Array(await request.arrayBuffer())
3223
- };
3224
- }
3225
- const raw = request;
3226
- const bodyBytes = raw.body instanceof ArrayBuffer ? new Uint8Array(raw.body) : raw.body;
3227
- return { asWeb: false, bodyBytes };
3228
- };
3229
- const deliverWebhookMessages = async (collected, runtime, handler, event) => {
3230
- for (const record of collected) {
3231
- const tuples = await resolveRecordToMessages(record, runtime);
3232
- for (const [space, message] of tuples) {
3233
- try {
3234
- await handler(space, message);
3235
- } catch (error) {
3236
- lifecycleLog.error(
3237
- `spectrum.webhook: handler threw (async), ${error}`,
3238
- {
3239
- eventId: event.eventId,
3240
- platform: event.platform,
3241
- messageId: message.id,
3242
- error: error instanceof Error ? error.message : String(error)
3243
- }
3244
- );
3245
- }
3246
- }
3247
- }
3248
- };
3249
- const decodeWebhookEvent = (bodyBytes) => {
3250
- try {
3251
- return RawInboundEvent.decode(bodyBytes);
3252
- } catch (error) {
3253
- lifecycleLog.warn("spectrum.webhook: undecodable RawInboundEvent body", {
3254
- error: error instanceof Error ? error.message : String(error)
3255
- });
3256
- return null;
3257
- }
3258
- };
3259
- const processWebhookEvent = async (core, event, handler) => {
3260
- const collected = [];
3261
- const reply2 = await core.processEvent(event, (record) => {
3262
- collected.push(record);
3263
- });
3264
- if (reply2.errorReason) {
3265
- return {
3266
- status: 400,
3267
- headers: reply2.headers ?? {},
3268
- body: encodeText(reply2.errorReason)
3269
- };
3270
- }
3271
- const result = {
3272
- status: reply2.status === 0 ? 200 : reply2.status,
3273
- headers: reply2.headers ?? {},
3274
- body: reply2.body ?? new Uint8Array(0)
3275
- };
3276
- const runtime = platformStates.get(event.platform);
3277
- if (runtime && collected.length > 0) {
3278
- deliverWebhookMessages(collected, runtime, handler, event).catch(
3279
- (error) => {
3280
- lifecycleLog.error(
3281
- `spectrum.webhook: delivery failed (async), ${error}`,
3282
- {
3283
- eventId: event.eventId,
3284
- platform: event.platform,
3285
- error: error instanceof Error ? error.message : String(error)
3286
- }
3287
- );
3288
- }
3289
- );
3290
- }
3291
- return result;
3292
- };
3293
- const handleWebhook = async (request, handler) => {
3294
- if (!fusorCore) {
3295
- throw new Error(
3296
- "spectrum.webhook() requires at least one fusor provider; none are configured"
3297
- );
3298
- }
3299
- const { asWeb, bodyBytes } = await readWebhookInput(request);
3300
- const event = decodeWebhookEvent(bodyBytes);
3301
- if (!event) {
3302
- return buildWebhookResult(asWeb, {
3303
- status: 400,
3304
- headers: {},
3305
- body: new Uint8Array(0)
3306
- });
3307
- }
3308
- const result = await processWebhookEvent(fusorCore, event, handler);
3309
- return buildWebhookResult(asWeb, result);
3310
- };
3311
- const base = {
3312
- __providers: providers,
3313
- __internal: { platforms: platformStates },
3314
- config: projectConfig,
3315
- messages,
3316
- stop: stopOnce,
3317
- webhook: handleWebhook,
3318
- send: (async (space, ...content) => content.length === 1 ? await space.send(content[0]) : await space.send(
3319
- ...content
3320
- )),
3321
- edit: async (message, newContent) => {
3322
- await message.edit(newContent);
3323
- },
3324
- responding: async (space, fn) => space.responding(fn)
3325
- };
3326
- return new Proxy(base, {
3327
- get(target, prop, receiver) {
3328
- if (prop in target) {
3329
- return Reflect.get(target, prop, receiver);
3330
- }
3331
- if (typeof prop === "string") {
3332
- return customEventProxy[prop];
3333
- }
3334
- return;
3335
- }
3336
- });
3337
- }
3338
- export {
3339
- Emoji,
3340
- Spectrum,
3341
- SpectrumCloudError,
3342
- UnsupportedError,
3343
- attachment,
3344
- avatar,
3345
- broadcast,
3346
- cloud,
3347
- contact,
3348
- custom,
3349
- definePlatform,
3350
- edit,
3351
- fromVCard,
3352
- fusor,
3353
- fusorEvent,
3354
- group,
3355
- isFusorClient,
3356
- isFusorEvent,
3357
- markdown,
3358
- mergeStreams,
3359
- option,
3360
- poll,
3361
- reaction,
3362
- read,
3363
- rename,
3364
- reply,
3365
- resolveContents,
3366
- richlink,
3367
- stream,
3368
- text,
3369
- toVCard,
3370
- typing,
3371
- unsend,
3372
- voice
3373
- };
1
+ export * from "@spectrum-ts/core";
2
+ export {};