@curless/hotel-storefront 0.53.0 → 0.55.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 (99) hide show
  1. package/dist/about.d.ts +24 -0
  2. package/dist/about.d.ts.map +1 -0
  3. package/dist/about.js +28 -0
  4. package/dist/about.js.map +1 -0
  5. package/dist/aggregate/make.js +2 -2
  6. package/dist/aggregate/make.js.map +1 -1
  7. package/dist/backend.d.ts +15 -0
  8. package/dist/backend.d.ts.map +1 -1
  9. package/dist/backend.js.map +1 -1
  10. package/dist/card.generated.d.ts +1 -1
  11. package/dist/card.generated.js +2 -2
  12. package/dist/card.generated.js.map +1 -1
  13. package/dist/config.d.ts +33 -2
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js.map +1 -1
  16. package/dist/coupon-words.d.ts +12 -0
  17. package/dist/coupon-words.d.ts.map +1 -0
  18. package/dist/coupon-words.js +19 -0
  19. package/dist/coupon-words.js.map +1 -0
  20. package/dist/dates.js +1 -1
  21. package/dist/dates.js.map +1 -1
  22. package/dist/demo-hotels.d.ts +6 -0
  23. package/dist/demo-hotels.d.ts.map +1 -1
  24. package/dist/demo-hotels.js +57 -17
  25. package/dist/demo-hotels.js.map +1 -1
  26. package/dist/fence.d.ts.map +1 -1
  27. package/dist/fence.js +4 -3
  28. package/dist/fence.js.map +1 -1
  29. package/dist/huazhu/backend.d.ts +6 -0
  30. package/dist/huazhu/backend.d.ts.map +1 -1
  31. package/dist/huazhu/backend.js +25 -22
  32. package/dist/huazhu/backend.js.map +1 -1
  33. package/dist/huazhu/catalog.d.ts +6 -6
  34. package/dist/huazhu/catalog.d.ts.map +1 -1
  35. package/dist/huazhu/catalog.js +33 -15
  36. package/dist/huazhu/catalog.js.map +1 -1
  37. package/dist/huazhu/client.js +1 -1
  38. package/dist/huazhu/client.js.map +1 -1
  39. package/dist/huazhu/make.d.ts.map +1 -1
  40. package/dist/huazhu/make.js +1 -0
  41. package/dist/huazhu/make.js.map +1 -1
  42. package/dist/huazhu/sandbox.d.ts.map +1 -1
  43. package/dist/huazhu/sandbox.js +5 -3
  44. package/dist/huazhu/sandbox.js.map +1 -1
  45. package/dist/legal.d.ts.map +1 -1
  46. package/dist/legal.js +104 -80
  47. package/dist/legal.js.map +1 -1
  48. package/dist/lib.d.ts +1 -1
  49. package/dist/lib.d.ts.map +1 -1
  50. package/dist/lib.js +1 -1
  51. package/dist/lib.js.map +1 -1
  52. package/dist/otaless/backend.d.ts +31 -0
  53. package/dist/otaless/backend.d.ts.map +1 -0
  54. package/dist/otaless/backend.js +502 -0
  55. package/dist/otaless/backend.js.map +1 -0
  56. package/dist/otaless/client.d.ts +103 -0
  57. package/dist/otaless/client.d.ts.map +1 -0
  58. package/dist/otaless/client.js +110 -0
  59. package/dist/otaless/client.js.map +1 -0
  60. package/dist/otaless/fake.d.ts +27 -0
  61. package/dist/otaless/fake.d.ts.map +1 -0
  62. package/dist/otaless/fake.js +239 -0
  63. package/dist/otaless/fake.js.map +1 -0
  64. package/dist/otaless/make.d.ts +4 -0
  65. package/dist/otaless/make.d.ts.map +1 -0
  66. package/dist/otaless/make.js +71 -0
  67. package/dist/otaless/make.js.map +1 -0
  68. package/dist/paid.d.ts.map +1 -1
  69. package/dist/paid.js +9 -9
  70. package/dist/paid.js.map +1 -1
  71. package/dist/present.d.ts +6 -1
  72. package/dist/present.d.ts.map +1 -1
  73. package/dist/present.js +20 -5
  74. package/dist/present.js.map +1 -1
  75. package/dist/reference.d.ts.map +1 -1
  76. package/dist/reference.js +10 -3
  77. package/dist/reference.js.map +1 -1
  78. package/dist/server.d.ts +2 -2
  79. package/dist/server.d.ts.map +1 -1
  80. package/dist/server.js +8 -6
  81. package/dist/server.js.map +1 -1
  82. package/dist/supplier.d.ts +6 -0
  83. package/dist/supplier.d.ts.map +1 -1
  84. package/dist/supplier.js +4 -0
  85. package/dist/supplier.js.map +1 -1
  86. package/dist/surface.d.ts.map +1 -1
  87. package/dist/surface.js +100 -71
  88. package/dist/surface.js.map +1 -1
  89. package/dist/tools.d.ts +19 -0
  90. package/dist/tools.d.ts.map +1 -1
  91. package/dist/tools.js +204 -102
  92. package/dist/tools.js.map +1 -1
  93. package/dist/types.d.ts +58 -0
  94. package/dist/types.d.ts.map +1 -1
  95. package/dist/vocab.d.ts +0 -14
  96. package/dist/vocab.d.ts.map +1 -1
  97. package/dist/vocab.js +19 -22
  98. package/dist/vocab.js.map +1 -1
  99. package/package.json +1 -1
@@ -0,0 +1,502 @@
1
+ import { DEFAULT_PAGE, MAX_PAGE, notPricedForNoAnswer, partyNeedsOf, } from '../backend.js';
2
+ import { nights as nightsOf } from '../dates.js';
3
+ import { FACILITIES, hasFacility } from '../facilities.js';
4
+ import { money, toMinor } from '../money.js';
5
+ import { nameKey } from '../names.js';
6
+ import { OtalessError } from './client.js';
7
+ // The Otaless hotel market on the Otaless hotel backend (robin, 2026-11-03:
8
+ // 「Otaless 切到 curless 的 dev 环境吧,包括 ui,如果没数据就不显示」).
9
+ //
10
+ // ⚠️ WHAT THE BACKEND SENDS, AND NOTHING ELSE. No picture, introduction,
11
+ // rating, check-in time or rooms-left count is filled in where it sends none:
12
+ // the card and the words leave that part out (`summary` is empty, `imageUrl`
13
+ // absent, `Room.uncounted`). Its words are shown as they came - a name, a
14
+ // brand, a cancellation sentence - with no "demo" or "test" said over them
15
+ // (robin, 2026-11-03: 「他们传什么直接用就行」).
16
+ //
17
+ // ⚠️ READ-ONLY (`capabilities.readOnly`): see client.ts.
18
+ /** Every group here, whatever the backend says of it: browse, look, compare, plan - book nothing. */
19
+ export const OTALESS_CAPABILITIES = {
20
+ members: false,
21
+ extras: false,
22
+ changes: false,
23
+ booking: 'pay-at-hotel',
24
+ policies: false,
25
+ readOnly: true,
26
+ };
27
+ /**
28
+ * `roomsLeft` for a rate the backend sends with no count (`Room.uncounted`):
29
+ * enough for any one line here, and never said or drawn.
30
+ */
31
+ export const UNCOUNTED_ROOMS = 99;
32
+ /** What a trip with nothing in it is priced in: there is no hotel to take it from. */
33
+ const EMPTY_CURRENCY = 'CNY';
34
+ /** How many hotels are remembered between searches, so one can be opened by its id after a restart. */
35
+ const KEPT_HOTELS = 5_000;
36
+ const refusal = (code, message) => Object.assign(new Error(message), { code });
37
+ /** An amount the backend sends as a number or as a decimal string (`BigDecimal`). */
38
+ const num = (v) => {
39
+ const n = typeof v === 'string' ? Number(v) : v;
40
+ return typeof n === 'number' && Number.isFinite(n) ? n : undefined;
41
+ };
42
+ const text = (v) => typeof v === 'string' && v.trim() ? v.trim() : undefined;
43
+ const regionNames = (() => {
44
+ try {
45
+ return new Intl.DisplayNames(['en'], { type: 'region' });
46
+ }
47
+ catch {
48
+ return undefined;
49
+ }
50
+ })();
51
+ /** "CN" → "China": the country the backend's code names, never a guess at one it did not send. */
52
+ const countryOf = (code) => {
53
+ try {
54
+ const n = regionNames?.of(code);
55
+ return n && n !== code ? n : undefined;
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ };
61
+ /** `{providerCode}:{roomId}` → the `roomId` the quote asks for (the document's ID rule, §1). */
62
+ export const originalPart = (unified) => {
63
+ const i = unified.indexOf(':');
64
+ return i < 0 ? unified : unified.slice(i + 1);
65
+ };
66
+ export const createOtalessHotels = (opts) => {
67
+ const { client } = opts;
68
+ const named = new Map((opts.groups ?? []).map((g) => [g.code, g]));
69
+ /** Every group the backend has named in an answer, beyond the configured ones. */
70
+ const seen = new Set();
71
+ const hotels = new Map();
72
+ const kept = opts.state?.read();
73
+ for (const h of kept?.hotels ?? [])
74
+ if (h && typeof h.id === 'string')
75
+ hotels.set(h.id, h);
76
+ for (const g of kept?.groups ?? [])
77
+ if (typeof g === 'string')
78
+ seen.add(g);
79
+ opts.state?.bind(() => ({ hotels: [...hotels.values()], groups: [...seen] }));
80
+ const remember = (h) => {
81
+ hotels.delete(h.id);
82
+ hotels.set(h.id, h);
83
+ while (hotels.size > KEPT_HOTELS) {
84
+ const first = hotels.keys().next().value;
85
+ if (first === undefined)
86
+ break;
87
+ hotels.delete(first);
88
+ }
89
+ opts.state?.changed();
90
+ };
91
+ const noteGroups = (codes) => {
92
+ let more = false;
93
+ for (const c of codes) {
94
+ if (c && !named.has(c) && !seen.has(c)) {
95
+ seen.add(c);
96
+ more = true;
97
+ }
98
+ }
99
+ if (more)
100
+ opts.state?.changed();
101
+ };
102
+ /** A group by its code: the configured name, or the code as the backend sends it. */
103
+ const groupOf = (code) => {
104
+ const g = named.get(code);
105
+ return { supplier: code, name: g?.name ?? code, ...(g?.names ? { names: g.names } : {}) };
106
+ };
107
+ const toHotel = (w) => {
108
+ const id = text(w.unifiedId);
109
+ const name = text(w.name);
110
+ if (!id || !name)
111
+ return undefined;
112
+ const code = text(w.providerCode) ?? (id.includes(':') ? id.slice(0, id.indexOf(':')) : '');
113
+ const country = text(w.country);
114
+ const cc = country && /^[A-Za-z]{2}$/.test(country) ? country.toUpperCase() : undefined;
115
+ const countryName = cc ? countryOf(cc) : country;
116
+ const city = text(w.city) ?? '';
117
+ const currency = text(w.minPrice?.originalCurrency)?.toUpperCase();
118
+ const from = num(w.minPrice?.originalAmount);
119
+ const lat = num(w.latitude);
120
+ const lng = num(w.longitude);
121
+ return {
122
+ id,
123
+ name,
124
+ brand: text(w.brand) ?? '',
125
+ ...(code ? { supplier: code } : {}),
126
+ city,
127
+ cityId: city.toLowerCase().replace(/\s+/g, '-'),
128
+ ...(cc ? { countryCode: cc } : {}),
129
+ ...(countryName ? { country: countryName } : {}),
130
+ ...(text(w.address) ? { address: text(w.address) } : {}),
131
+ ...(lat !== undefined && lng !== undefined && (lat !== 0 || lng !== 0)
132
+ ? { geo: { lat, lng } }
133
+ : {}),
134
+ // ⚠️ NONE SENT, NONE WRITTEN: the hotel's page has no "about" without it.
135
+ summary: '',
136
+ amenities: (w.amenities ?? []).filter((a) => typeof a === 'string' && !!a.trim()),
137
+ currency: currency ?? '',
138
+ ...(currency && from !== undefined && from > 0
139
+ ? { fromNightly: money(toMinor(from, currency), currency) }
140
+ : {}),
141
+ };
142
+ };
143
+ const toRoom = (r, stay) => {
144
+ const id = text(r.unifiedRoomId);
145
+ const name = text(r.name);
146
+ const currency = text(r.price?.originalCurrency)?.toUpperCase();
147
+ const amount = num(r.price?.originalAmount);
148
+ if (!id || !name || !currency || amount === undefined || amount <= 0)
149
+ return undefined;
150
+ const n = nightsOf(stay.checkIn, stay.checkOut);
151
+ const nightly = money(toMinor(amount, currency), currency);
152
+ return {
153
+ id,
154
+ name,
155
+ // The document's every room has it; one that came without is the
156
+ // backend's answer for this party.
157
+ sleeps: num(r.maxOccupancy) ?? stay.guests,
158
+ ...(text(r.bedType) ? { beds: text(r.bedType) } : {}),
159
+ breakfast: r.breakfastIncluded === true,
160
+ // ⚠️ A NIGHT'S PRICE, TAXES IN: the document's room is ¥1,380 "含税费及服务
161
+ // 费" and the same room quoted for two nights is ¥2,760. The trip is priced
162
+ // by the backend's own quote (`quote`), never by this product.
163
+ nightly,
164
+ stayTotal: money(nightly.minor * n, currency),
165
+ taxesAndFees: money(0, currency),
166
+ nights: n,
167
+ // ⚠️ NOT PARSED: the sentence is shown as it is (`Room.terms`).
168
+ refundable: false,
169
+ terms: text(r.cancellationPolicy) ?? '',
170
+ roomsLeft: UNCOUNTED_ROOMS,
171
+ uncounted: true,
172
+ };
173
+ };
174
+ /** A hotel by its id - or by a name that fits one and only one of the hotels seen. */
175
+ const find = (ref) => {
176
+ const exact = hotels.get(ref.trim());
177
+ if (exact)
178
+ return exact;
179
+ const key = nameKey(ref);
180
+ if (!key)
181
+ return undefined;
182
+ const all = [...hotels.values()];
183
+ const same = all.filter((h) => nameKey(h.name) === key);
184
+ if (same.length === 1)
185
+ return same[0];
186
+ const like = all.filter((h) => nameKey(h.name).includes(key));
187
+ return like.length === 1 ? like[0] : undefined;
188
+ };
189
+ const roomsFor = async (h, stay) => {
190
+ const wire = await client.rooms({
191
+ unifiedHotelId: h.id,
192
+ checkIn: stay.checkIn,
193
+ checkOut: stay.checkOut,
194
+ });
195
+ return wire.flatMap((r) => toRoom(r, stay) ?? []);
196
+ };
197
+ const suppliers = () => [...(opts.groups ?? []).map((g) => g.code), ...[...seen].filter((c) => !named.has(c))].map((code) => {
198
+ const g = named.get(code);
199
+ return {
200
+ id: code,
201
+ name: g?.name ?? code,
202
+ ...(g?.names ? { names: g.names } : {}),
203
+ ...(g?.logoUrl ? { logoUrl: g.logoUrl } : {}),
204
+ // ⚠️ NO "DEMO" OR "TEST" OVER IT (robin, 2026-11-03): what the backend
205
+ // sends is shown as the backend's.
206
+ mode: 'live',
207
+ capabilities: OTALESS_CAPABILITIES,
208
+ };
209
+ });
210
+ return {
211
+ brand: opts.brand,
212
+ capabilities: OTALESS_CAPABILITIES,
213
+ suppliers,
214
+ supplierOf: (hotelId) => hotels.get(hotelId)?.supplier ??
215
+ (hotelId.includes(':') ? hotelId.slice(0, hotelId.indexOf(':')) : undefined),
216
+ async searchHotels(q) {
217
+ const place = text(q.city) ?? text(q.query);
218
+ const answer = await client.search({
219
+ ...(place ? { destination: place } : {}),
220
+ ...(q.stay
221
+ ? { checkIn: q.stay.checkIn, checkOut: q.stay.checkOut, adultCount: q.stay.guests }
222
+ : {}),
223
+ ...(q.filters?.supplier ? { channelCodes: [q.filters.supplier] } : {}),
224
+ });
225
+ noteGroups([...(answer.queriedProviders ?? []), ...(answer.degradedProviders ?? [])]);
226
+ const all = (answer.hotels ?? []).flatMap((w) => toHotel(w) ?? []);
227
+ for (const h of all)
228
+ remember(h);
229
+ noteGroups(all.map((h) => h.supplier));
230
+ const degraded = [...new Set(answer.degradedProviders ?? [])]
231
+ .filter((c) => typeof c === 'string' && c)
232
+ .map(groupOf);
233
+ const unapplied = [];
234
+ const ignored = {};
235
+ const f = q.filters ?? {};
236
+ const placed = f.supplier ? all.filter((h) => h.supplier === f.supplier) : all;
237
+ let passed = placed;
238
+ if (f.brand) {
239
+ const b = nameKey(f.brand);
240
+ passed = passed.filter((h) => nameKey(h.brand) === b);
241
+ }
242
+ for (const k of f.facilities ?? [])
243
+ passed = passed.filter((h) => hasFacility(h.amenities, k));
244
+ // Rooms by the hour: none is sold here, so none passes (`HotelFilters.hourly`).
245
+ if (f.hourly)
246
+ passed = [];
247
+ if (f.freeCancellation || f.breakfast || f.bed) {
248
+ ignored.roomTerms = true;
249
+ unapplied.push('Whether a room can be cancelled free, includes breakfast or has a given bed is only known room by room here, on each hotel for the nights asked about - this list is not narrowed by it.');
250
+ }
251
+ const currencies = [...new Set(placed.map((h) => h.currency).filter(Boolean))];
252
+ const oneCurrency = currencies.length <= 1;
253
+ let overBudget;
254
+ const beforeCeiling = passed.length;
255
+ if (q.maxNightly !== undefined) {
256
+ if (oneCurrency) {
257
+ const cap = currencies[0] ? toMinor(q.maxNightly, currencies[0]) : undefined;
258
+ const under = passed.filter((h) => !h.fromNightly || cap === undefined || h.fromNightly.minor <= cap);
259
+ overBudget = passed.length - under.length;
260
+ passed = under;
261
+ }
262
+ else {
263
+ ignored.ceiling = true;
264
+ unapplied.push(`These hotels charge in ${currencies.join(', ')}; a price ceiling is only applied across one currency, so it was not applied.`);
265
+ }
266
+ }
267
+ if (q.sort === 'price-low' || q.sort === 'price-high') {
268
+ if (oneCurrency) {
269
+ const dir = q.sort === 'price-low' ? 1 : -1;
270
+ passed = [...passed].sort((a, b) => (a.fromNightly ? 0 : 1) - (b.fromNightly ? 0 : 1) ||
271
+ dir * ((a.fromNightly?.minor ?? 0) - (b.fromNightly?.minor ?? 0)));
272
+ }
273
+ else {
274
+ ignored.sort = true;
275
+ unapplied.push(`These hotels charge in ${currencies.join(', ')}; nothing here converts one into another, so they are not put in price order.`);
276
+ }
277
+ }
278
+ if (q.sort === 'rating') {
279
+ ignored.sort = true;
280
+ unapplied.push('No ratings are published here, so the list is not in rating order.');
281
+ }
282
+ const count = (xs) => {
283
+ const m = new Map();
284
+ for (const x of xs)
285
+ if (x)
286
+ m.set(x, (m.get(x) ?? 0) + 1);
287
+ return [...m.entries()].sort((a, b) => b[1] - a[1]);
288
+ };
289
+ const offset = Math.max(0, Math.floor(q.offset ?? 0));
290
+ const limit = Math.max(1, Math.min(MAX_PAGE, Math.floor(q.limit ?? DEFAULT_PAGE)));
291
+ const codeOf = new Map(passed.map((h) => [h.country ?? '', h.countryCode]));
292
+ return {
293
+ hotels: passed.slice(offset, offset + limit),
294
+ total: passed.length,
295
+ currencies,
296
+ ...(overBudget ? { overBudget } : {}),
297
+ ...(placed.length !== passed.length ? { beforeFilters: placed.length } : {}),
298
+ ...(q.maxNightly !== undefined && oneCurrency ? { beforeCeiling } : {}),
299
+ facets: {
300
+ countries: count(passed.map((h) => h.country ?? '')).map(([name, n]) => ({
301
+ name,
302
+ count: n,
303
+ ...(codeOf.get(name) ? { code: codeOf.get(name) } : {}),
304
+ })),
305
+ cities: count(passed.map((h) => h.city)).map(([name, n]) => {
306
+ const country = passed.find((h) => h.city === name)?.country;
307
+ return { name, count: n, ...(country ? { country } : {}) };
308
+ }),
309
+ },
310
+ refine: {
311
+ brands: count(placed.map((h) => h.brand)).map(([name, n]) => ({ name, count: n })),
312
+ suppliers: count(all.map((h) => h.supplier ?? '')).map(([id, n]) => ({ id, count: n })),
313
+ facilities: FACILITIES.map((x) => ({
314
+ key: x.key,
315
+ label: x.label,
316
+ count: placed.filter((h) => hasFacility(h.amenities, x.key)).length,
317
+ })).filter((x) => x.count > 0),
318
+ freeCancellation: 0,
319
+ breakfast: 0,
320
+ },
321
+ ...(unapplied.length ? { unapplied, ignored } : {}),
322
+ ...(degraded.length ? { degraded } : {}),
323
+ };
324
+ },
325
+ namesLike(ref) {
326
+ const key = nameKey(ref);
327
+ if (!key)
328
+ return [];
329
+ const like = [...hotels.values()].filter((h) => nameKey(h.name).includes(key));
330
+ return like.length > 1
331
+ ? like
332
+ .slice(0, 6)
333
+ .map((h) => ({ id: h.id, name: h.name, ...(h.city ? { city: h.city } : {}) }))
334
+ : [];
335
+ },
336
+ async getHotel(ref, stay) {
337
+ const h = find(ref);
338
+ if (!h)
339
+ return null;
340
+ if (!stay)
341
+ return { hotel: h };
342
+ let rooms;
343
+ try {
344
+ rooms = await roomsFor(h, stay);
345
+ }
346
+ catch (err) {
347
+ if (!(err instanceof OtalessError))
348
+ throw err;
349
+ return {
350
+ hotel: h,
351
+ stay,
352
+ noRooms: `${h.name}'s rooms could not be read just now (${err.message}) - asking again in a moment may work.`,
353
+ noRoomsCode: 'unreachable',
354
+ };
355
+ }
356
+ const hotel = !h.currency && rooms[0] ? { ...h, currency: rooms[0].nightly.currency } : h;
357
+ if (rooms.length === 0) {
358
+ return {
359
+ hotel,
360
+ stay,
361
+ noRooms: `${h.name} has no room for ${stay.checkIn} to ${stay.checkOut} here.`,
362
+ noRoomsCode: 'unavailable',
363
+ };
364
+ }
365
+ const fitting = rooms.filter((r) => r.sleeps >= stay.guests);
366
+ if (fitting.length === 0) {
367
+ const largest = Math.max(...rooms.map((r) => r.sleeps));
368
+ const p = partyNeedsOf(stay.guests, largest);
369
+ return { hotel, stay, noRooms: p.why, noRoomsCode: p.code, noRoomsArgs: p.args };
370
+ }
371
+ return { hotel, stay, rooms: fitting };
372
+ },
373
+ // No rate calendar: the backend has none (§8.2), and one rooms request per
374
+ // date would be seven of them for one hotel opened.
375
+ datesAround: async () => [],
376
+ signInMember: async () => null,
377
+ rememberPreferences: async () => [],
378
+ extrasFor: async () => [],
379
+ policies: async () => [],
380
+ async quote(trip) {
381
+ const lines = [];
382
+ const dropped = [];
383
+ const silent = new Map();
384
+ for (const line of trip.lines) {
385
+ if (line.kind !== 'room') {
386
+ dropped.push({
387
+ title: line.extraId,
388
+ why: 'No add-ons are sold here.',
389
+ code: 'unavailable',
390
+ });
391
+ continue;
392
+ }
393
+ const h = find(line.hotelId);
394
+ if (!h) {
395
+ dropped.push({
396
+ title: line.hotelId,
397
+ why: 'That hotel is not known here any more - search for it again.',
398
+ code: 'unavailable',
399
+ });
400
+ continue;
401
+ }
402
+ const wanted = Math.max(1, Math.floor(line.rooms ?? 1));
403
+ try {
404
+ const room = (await roomsFor(h, line.stay)).find((r) => r.id === line.roomId);
405
+ if (!room) {
406
+ dropped.push({
407
+ title: h.name,
408
+ why: `${h.name} has no such room for ${line.stay.checkIn} to ${line.stay.checkOut} here.`,
409
+ code: 'unavailable',
410
+ });
411
+ continue;
412
+ }
413
+ const q = await client.quote({
414
+ unifiedHotelId: h.id,
415
+ roomId: originalPart(room.id),
416
+ checkIn: line.stay.checkIn,
417
+ checkOut: line.stay.checkOut,
418
+ roomCount: wanted,
419
+ adultCount: line.stay.guests,
420
+ });
421
+ const currency = text(q.originalCurrency)?.toUpperCase();
422
+ const amount = num(q.originalAmount);
423
+ if (!currency || amount === undefined || amount <= 0) {
424
+ dropped.push({
425
+ title: h.name,
426
+ why: `${h.name}'s price for ${room.name} could not be had just now - asking again in a moment may work.`,
427
+ code: 'unreachable',
428
+ });
429
+ continue;
430
+ }
431
+ const total = money(toMinor(amount, currency), currency);
432
+ lines.push({
433
+ kind: 'room',
434
+ hotelId: h.id,
435
+ hotelName: h.name,
436
+ roomRef: room.id,
437
+ title: room.name,
438
+ // The bed in the group's words; breakfast as a code, which a card says
439
+ // in the guest's language (an English word here showed on a Chinese card).
440
+ ...(room.beds ? { detail: room.beds } : {}),
441
+ ...(room.breakfast ? { meal: { plan: 'breakfast' } } : {}),
442
+ stay: line.stay,
443
+ nights: room.nights,
444
+ quantity: wanted,
445
+ unit: room.nightly,
446
+ total,
447
+ terms: room.terms ?? '',
448
+ day: line.stay.checkIn,
449
+ });
450
+ }
451
+ catch (err) {
452
+ if (!(err instanceof OtalessError))
453
+ throw err;
454
+ // ⚠️ "DID NOT ANSWER" IS NOT "CANNOT BE HAD" (2026-11-03 review, C5).
455
+ const g = groupOf(h.supplier ?? '');
456
+ if (err.backendCode === undefined) {
457
+ silent.set(g.supplier, g);
458
+ }
459
+ else {
460
+ dropped.push({
461
+ title: h.name,
462
+ why: `${g.name} could not price ${h.name} for those nights: ${err.message}.`,
463
+ code: 'unavailable',
464
+ });
465
+ }
466
+ }
467
+ }
468
+ dropped.push(...[...silent.values()].map(notPricedForNoAnswer));
469
+ const currency = lines[0]?.total.currency ?? EMPTY_CURRENCY;
470
+ if (lines.some((l) => l.total.currency !== currency)) {
471
+ throw refusal('mixed-currency', `These hotels charge in ${[...new Set(lines.map((l) => l.total.currency))].join(' and ')}; a trip is priced one currency at a time.`);
472
+ }
473
+ const sum = lines.reduce((a, l) => a + l.total.minor, 0);
474
+ const stays = lines.map((l) => l.stay);
475
+ const sameStay = stays.length > 0 &&
476
+ new Set(stays.map((s) => `${s?.checkIn}|${s?.checkOut}|${s?.guests}`)).size === 1;
477
+ return {
478
+ lines,
479
+ subtotal: money(sum, currency),
480
+ taxesAndFees: money(0, currency),
481
+ // ⚠️ THE BACKEND'S OWN WORD: its quote is "包含增值税与服务费的精确总价"
482
+ // - the total with its taxes and service charge in.
483
+ taxesIncluded: true,
484
+ total: money(sum, currency),
485
+ ...(sameStay && stays[0] ? { stay: stays[0] } : {}),
486
+ ...(dropped.length ? { dropped } : {}),
487
+ };
488
+ },
489
+ // ⚠️ NEVER CALLED: the tools that would are not offered (`readOnly`). Each
490
+ // refuses all the same, should anything reach it.
491
+ async requestBooking() {
492
+ throw refusal('read-only', 'Nothing can be booked here yet.');
493
+ },
494
+ listBookings: async () => [],
495
+ findBooking: async () => null,
496
+ previewChange: async () => null,
497
+ changeBooking: async () => null,
498
+ previewCancellation: async () => null,
499
+ cancelBooking: async () => null,
500
+ };
501
+ };
502
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/otaless/backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EAEZ,QAAQ,EAER,oBAAoB,EACpB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AActC,OAAO,EAAsB,YAAY,EAAiC,MAAM,aAAa,CAAC;AAE9F,4EAA4E;AAC5E,mDAAmD;AACnD,EAAE;AACF,yEAAyE;AACzE,8EAA8E;AAC9E,6EAA6E;AAC7E,0EAA0E;AAC1E,2EAA2E;AAC3E,qCAAqC;AACrC,EAAE;AACF,yDAAyD;AAEzD,qGAAqG;AACrG,MAAM,CAAC,MAAM,oBAAoB,GAAwB;IACvD,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,cAAc;IACvB,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE,IAAI;CACf,CAAC;AAKF;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAElC,sFAAsF;AACtF,MAAM,cAAc,GAAG,KAAK,CAAC;AAE7B,uGAAuG;AACvG,MAAM,WAAW,GAAG,KAAK,CAAC;AAE1B,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,OAAe,EAAS,EAAE,CACvD,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AAE9C,qFAAqF;AACrF,MAAM,GAAG,GAAG,CAAC,CAAU,EAAsB,EAAE;IAC7C,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACrE,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,CAAC,CAAU,EAAsB,EAAE,CAC9C,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAE3D,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE;IACxB,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,EAAE,CAAC;AAEL,kGAAkG;AAClG,MAAM,SAAS,GAAG,CAAC,IAAY,EAAsB,EAAE;IACrD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,WAAW,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC,CAAC;AAEF,gGAAgG;AAChG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAU,EAAE;IACtD,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC;AAYF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAA0B,EAAgB,EAAE;IAC9E,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,kFAAkF;IAClF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAC;IAExC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAA2C,CAAC;IACzE,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,MAAM,IAAI,EAAE;QAAE,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3F,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,MAAM,IAAI,EAAE;QAAE,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAE9E,MAAM,QAAQ,GAAG,CAAC,CAAQ,EAAE,EAAE;QAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACpB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACpB,OAAO,MAAM,CAAC,IAAI,GAAG,WAAW,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YACzC,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM;YAC/B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;IACxB,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,CAAC,KAA6B,EAAE,EAAE;QACnD,IAAI,IAAI,GAAG,KAAK,CAAC;QACjB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACZ,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,IAAI,IAAI;YAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;IAClC,CAAC,CAAC;IAEF,qFAAqF;IACrF,MAAM,OAAO,GAAG,CAAC,IAAY,EAAc,EAAE;QAC3C,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5F,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,CAAY,EAAqB,EAAE;QAClD,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAChC,MAAM,EAAE,GAAG,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACxF,MAAM,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,WAAW,EAAE,CAAC;QACnE,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC5B,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7B,OAAO;YACL,EAAE;YACF,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE;YAC1B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;YAC/C,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;gBACpE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;gBACvB,CAAC,CAAC,EAAE,CAAC;YACP,0EAA0E;YAC1E,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CACnC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CACxD;YACD,QAAQ,EAAE,QAAQ,IAAI,EAAE;YACxB,GAAG,CAAC,QAAQ,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,GAAG,CAAC;gBAC5C,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,EAAE;gBAC3D,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,CAAW,EAAE,IAAU,EAAoB,EAAE;QAC3D,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,gBAAgB,CAAC,EAAE,WAAW,EAAE,CAAC;QAChE,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QACvF,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC3D,OAAO;YACL,EAAE;YACF,IAAI;YACJ,iEAAiE;YACjE,mCAAmC;YACnC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,MAAM;YAC1C,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,SAAS,EAAE,CAAC,CAAC,iBAAiB,KAAK,IAAI;YACvC,sEAAsE;YACtE,2EAA2E;YAC3E,+DAA+D;YAC/D,OAAO;YACP,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC;YAC7C,YAAY,EAAE,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;YAChC,MAAM,EAAE,CAAC;YACT,gEAAgE;YAChE,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,EAAE;YACvC,SAAS,EAAE,eAAe;YAC1B,SAAS,EAAE,IAAI;SAChB,CAAC;IACJ,CAAC,CAAC;IAEF,sFAAsF;IACtF,MAAM,IAAI,GAAG,CAAC,GAAW,EAAqB,EAAE;QAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACrC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACxD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAQ,EAAE,IAAU,EAAmB,EAAE;QAC/D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAC9B,cAAc,EAAE,CAAC,CAAC,EAAE;YACpB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,GAAmB,EAAE,CACrC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CACxF,CAAC,IAAI,EAAE,EAAE;QACP,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO;YACL,EAAE,EAAE,IAAI;YACR,IAAI,EAAE,CAAC,EAAE,IAAI,IAAI,IAAI;YACrB,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,uEAAuE;YACvE,mCAAmC;YACnC,IAAI,EAAE,MAAM;YACZ,YAAY,EAAE,oBAAoB;SACnC,CAAC;IACJ,CAAC,CACF,CAAC;IAEJ,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,YAAY,EAAE,oBAAoB;QAClC,SAAS;QACT,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CACtB,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,QAAQ;YAC7B,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE9E,KAAK,CAAC,YAAY,CAAC,CAAc;YAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;gBACjC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxC,GAAG,CAAC,CAAC,CAAC,IAAI;oBACR,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE;oBACnF,CAAC,CAAC,EAAE,CAAC;gBACP,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvE,CAAC,CAAC;YACH,UAAU,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACtF,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACnE,KAAK,MAAM,CAAC,IAAI,GAAG;gBAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;iBAC1D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC;iBACzC,GAAG,CAAC,OAAO,CAAC,CAAC;YAEhB,MAAM,SAAS,GAAa,EAAE,CAAC;YAC/B,MAAM,OAAO,GAA8C,EAAE,CAAC;YAC9D,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/E,IAAI,MAAM,GAAG,MAAM,CAAC;YACpB,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;gBACZ,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBAC3B,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YACxD,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,EAAE;gBAChC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7D,gFAAgF;YAChF,IAAI,CAAC,CAAC,MAAM;gBAAE,MAAM,GAAG,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;gBAC/C,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;gBACzB,SAAS,CAAC,IAAI,CACZ,0LAA0L,CAC3L,CAAC;YACJ,CAAC;YACD,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC/E,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC;YAC3C,IAAI,UAA8B,CAAC;YACnC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;YACpC,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC/B,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CACzB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI,GAAG,CACzE,CAAC;oBACF,UAAU,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;oBAC1C,MAAM,GAAG,KAAK,CAAC;gBACjB,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;oBACvB,SAAS,CAAC,IAAI,CACZ,0BAA0B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,+EAA+E,CAC/H,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACtD,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC5C,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CACvB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACjD,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CACpE,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;oBACpB,SAAS,CAAC,IAAI,CACZ,0BAA0B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,+EAA+E,CAC/H,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;gBACpB,SAAS,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;YACvF,CAAC;YAED,MAAM,KAAK,GAAG,CAAmB,EAAO,EAAE,EAAE;gBAC1C,MAAM,CAAC,GAAG,IAAI,GAAG,EAAa,CAAC;gBAC/B,KAAK,MAAM,CAAC,IAAI,EAAE;oBAAE,IAAI,CAAC;wBAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACzD,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,CAAC,CAAC;YACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;YACnF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC5E,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;gBAC5C,KAAK,EAAE,MAAM,CAAC,MAAM;gBACpB,UAAU;gBACV,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrC,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5E,GAAG,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvE,MAAM,EAAE;oBACN,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACvE,IAAI;wBACJ,KAAK,EAAE,CAAC;wBACR,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACxD,CAAC,CAAC;oBACH,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;wBACzD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,OAAO,CAAC;wBAC7D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC7D,CAAC,CAAC;iBACH;gBACD,MAAM,EAAE;oBACN,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;oBAClF,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;oBACvF,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACjC,GAAG,EAAE,CAAC,CAAC,GAAG;wBACV,KAAK,EAAE,CAAC,CAAC,KAAK;wBACd,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM;qBACpE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;oBAC9B,gBAAgB,EAAE,CAAC;oBACnB,SAAS,EAAE,CAAC;iBACb;gBACD,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnD,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACzC,CAAC;QACJ,CAAC;QAED,SAAS,CAAC,GAAW;YACnB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YACzB,IAAI,CAAC,GAAG;gBAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/E,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC;gBACpB,CAAC,CAAC,IAAI;qBACD,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;qBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBAClF,CAAC,CAAC,EAAE,CAAC;QACT,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,GAAW,EAAE,IAAW;YACrC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,IAAI,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpB,IAAI,CAAC,IAAI;gBAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAC/B,IAAI,KAAa,CAAC;YAClB,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,CAAC,GAAG,YAAY,YAAY,CAAC;oBAAE,MAAM,GAAG,CAAC;gBAC9C,OAAO;oBACL,KAAK,EAAE,CAAC;oBACR,IAAI;oBACJ,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,wCAAwC,GAAG,CAAC,OAAO,wCAAwC;oBAC7G,WAAW,EAAE,aAAa;iBAC3B,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO;oBACL,KAAK;oBACL,IAAI;oBACJ,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,oBAAoB,IAAI,CAAC,OAAO,OAAO,IAAI,CAAC,QAAQ,QAAQ;oBAC9E,WAAW,EAAE,aAAa;iBAC3B,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACxD,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC7C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACnF,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QACzC,CAAC;QAED,2EAA2E;QAC3E,oDAAoD;QACpD,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QAE3B,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QAC9B,mBAAmB,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QACnC,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QACzB,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QAExB,KAAK,CAAC,KAAK,CAAC,IAAI;YACd,MAAM,KAAK,GAAgB,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAkC,EAAE,CAAC;YAClD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBACzB,OAAO,CAAC,IAAI,CAAC;wBACX,KAAK,EAAE,IAAI,CAAC,OAAO;wBACnB,GAAG,EAAE,2BAA2B;wBAChC,IAAI,EAAE,aAAa;qBACpB,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC7B,IAAI,CAAC,CAAC,EAAE,CAAC;oBACP,OAAO,CAAC,IAAI,CAAC;wBACX,KAAK,EAAE,IAAI,CAAC,OAAO;wBACnB,GAAG,EAAE,8DAA8D;wBACnE,IAAI,EAAE,aAAa;qBACpB,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;gBACxD,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC9E,IAAI,CAAC,IAAI,EAAE,CAAC;wBACV,OAAO,CAAC,IAAI,CAAC;4BACX,KAAK,EAAE,CAAC,CAAC,IAAI;4BACb,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,yBAAyB,IAAI,CAAC,IAAI,CAAC,OAAO,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,QAAQ;4BACzF,IAAI,EAAE,aAAa;yBACpB,CAAC,CAAC;wBACH,SAAS;oBACX,CAAC;oBACD,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;wBAC3B,cAAc,EAAE,CAAC,CAAC,EAAE;wBACpB,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC7B,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO;wBAC1B,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ;wBAC5B,SAAS,EAAE,MAAM;wBACjB,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;qBAC7B,CAAC,CAAC;oBACH,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,WAAW,EAAE,CAAC;oBACzD,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;oBACrC,IAAI,CAAC,QAAQ,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;wBACrD,OAAO,CAAC,IAAI,CAAC;4BACX,KAAK,EAAE,CAAC,CAAC,IAAI;4BACb,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,gBAAgB,IAAI,CAAC,IAAI,iEAAiE;4BACxG,IAAI,EAAE,aAAa;yBACpB,CAAC,CAAC;wBACH,SAAS;oBACX,CAAC;oBACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;oBACzD,KAAK,CAAC,IAAI,CAAC;wBACT,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,CAAC,CAAC,EAAE;wBACb,SAAS,EAAE,CAAC,CAAC,IAAI;wBACjB,OAAO,EAAE,IAAI,CAAC,EAAE;wBAChB,KAAK,EAAE,IAAI,CAAC,IAAI;wBAChB,uEAAuE;wBACvE,2EAA2E;wBAC3E,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC3C,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,WAAoB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACnE,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,MAAM,EAAE,IAAI,CAAC,MAAM;wBACnB,QAAQ,EAAE,MAAM;wBAChB,IAAI,EAAE,IAAI,CAAC,OAAO;wBAClB,KAAK;wBACL,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;wBACvB,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO;qBACvB,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,CAAC,GAAG,YAAY,YAAY,CAAC;wBAAE,MAAM,GAAG,CAAC;oBAC9C,sEAAsE;oBACtE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;oBACpC,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;wBAClC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;oBAC5B,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,IAAI,CAAC;4BACX,KAAK,EAAE,CAAC,CAAC,IAAI;4BACb,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,oBAAoB,CAAC,CAAC,IAAI,sBAAsB,GAAG,CAAC,OAAO,GAAG;4BAC5E,IAAI,EAAE,aAAa;yBACpB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAChE,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,IAAI,cAAc,CAAC;YAC5D,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC;gBACrD,MAAM,OAAO,CACX,gBAAgB,EAChB,0BAA0B,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,4CAA4C,CACrI,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACzD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,QAAQ,GACZ,KAAK,CAAC,MAAM,GAAG,CAAC;gBAChB,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,QAAQ,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC;YACpF,OAAO;gBACL,KAAK;gBACL,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC;gBAC9B,YAAY,EAAE,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;gBAChC,2DAA2D;gBAC3D,oDAAoD;gBACpD,aAAa,EAAE,IAAI;gBACnB,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC;gBAC3B,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvC,CAAC;QACJ,CAAC;QAED,2EAA2E;QAC3E,kDAAkD;QAClD,KAAK,CAAC,cAAc;YAClB,MAAM,OAAO,CAAC,WAAW,EAAE,iCAAiC,CAAC,CAAC;QAChE,CAAC;QACD,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QAC5B,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QAC7B,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QAC/B,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QAC/B,mBAAmB,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QACrC,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;KAChC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,103 @@
1
+ /** Every answer: `code` 200 is success; anything else is the backend's refusal, `msg` its words. */
2
+ export type R<T> = {
3
+ code?: number;
4
+ msg?: string;
5
+ data?: T;
6
+ };
7
+ /** An amount in the hotel's own currency - and a USD figure we never show or sort by (robin, 2026-10-21). */
8
+ export type WirePrice = {
9
+ originalCurrency?: string;
10
+ originalAmount?: number | string;
11
+ settlementCurrency?: string;
12
+ settlementAmount?: number | string;
13
+ feeNotice?: string;
14
+ };
15
+ export type WireHotel = {
16
+ unifiedId?: string;
17
+ providerCode?: string;
18
+ brand?: string;
19
+ originalId?: string;
20
+ name?: string;
21
+ city?: string;
22
+ country?: string;
23
+ address?: string;
24
+ latitude?: number;
25
+ longitude?: number;
26
+ distanceKm?: number;
27
+ score?: number;
28
+ minPrice?: WirePrice;
29
+ amenities?: string[];
30
+ extensions?: Record<string, unknown>;
31
+ };
32
+ export type WireSearch = {
33
+ totalCount?: number;
34
+ queriedProviders?: string[];
35
+ successProviders?: string[];
36
+ degradedProviders?: string[];
37
+ executionTimes?: Record<string, number>;
38
+ hotels?: WireHotel[];
39
+ };
40
+ export type WireRoom = {
41
+ unifiedRoomId?: string;
42
+ originalRoomId?: string;
43
+ providerCode?: string;
44
+ name?: string;
45
+ bedType?: string;
46
+ maxOccupancy?: number;
47
+ price?: WirePrice;
48
+ breakfastIncluded?: boolean;
49
+ cancellationPolicy?: string;
50
+ amenities?: string[];
51
+ };
52
+ export type SearchBody = {
53
+ destination?: string;
54
+ checkIn?: string;
55
+ checkOut?: string;
56
+ adultCount?: number;
57
+ channelCodes?: string[];
58
+ sortBy?: 'price_asc' | 'price_desc' | 'score_desc';
59
+ lang?: string;
60
+ };
61
+ export type QuoteBody = {
62
+ unifiedHotelId: string;
63
+ roomId: string;
64
+ checkIn: string;
65
+ checkOut: string;
66
+ roomCount: number;
67
+ adultCount: number;
68
+ };
69
+ /** The backend refused, in its own code and words - or did not answer. */
70
+ export declare class OtalessError extends Error {
71
+ readonly status?: number | undefined;
72
+ readonly backendCode?: number | undefined;
73
+ constructor(message: string, status?: number | undefined, backendCode?: number | undefined);
74
+ }
75
+ /**
76
+ * The backend's `@RepeatSubmit`: the same request again within its window is
77
+ * refused with this code - reads too (总线程, 2026-11-03). Every read is kept
78
+ * for `CACHE_MS`, so a card redrawing or a model asking twice is answered from
79
+ * here and never sends the same request twice in a row.
80
+ */
81
+ export declare const REPEAT_SUBMIT = 10014;
82
+ export type OtalessClientOptions = {
83
+ baseUrl: string;
84
+ tenant: string;
85
+ fetch?: typeof fetch;
86
+ now?: () => number;
87
+ /** How long one request is waited for. */
88
+ timeoutMs?: number;
89
+ /** For tests: how long to wait before asking again after a repeat-submit refusal. */
90
+ repeatPauseMs?: number;
91
+ };
92
+ export type OtalessClient = {
93
+ search(body: SearchBody): Promise<WireSearch>;
94
+ rooms(q: {
95
+ unifiedHotelId: string;
96
+ checkIn?: string;
97
+ checkOut?: string;
98
+ lang?: string;
99
+ }): Promise<WireRoom[]>;
100
+ quote(body: QuoteBody): Promise<WirePrice>;
101
+ };
102
+ export declare const createOtalessClient: (opts: OtalessClientOptions) => OtalessClient;
103
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/otaless/client.ts"],"names":[],"mappings":"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"}