@wasto/sdk 1.0.3

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 (55) hide show
  1. package/dist/index.d.mts +2562 -0
  2. package/dist/index.d.ts +2562 -0
  3. package/dist/index.js +2566 -0
  4. package/dist/index.mjs +2405 -0
  5. package/package.json +30 -0
  6. package/src/client.ts +692 -0
  7. package/src/dashboard-apps.ts +350 -0
  8. package/src/dto/cms-app-settings.ts +91 -0
  9. package/src/enums.ts +298 -0
  10. package/src/free-tier.ts +56 -0
  11. package/src/index.ts +35 -0
  12. package/src/opening-hours/constants.ts +48 -0
  13. package/src/opening-hours/convert.ts +276 -0
  14. package/src/opening-hours/format.ts +99 -0
  15. package/src/opening-hours/index.ts +9 -0
  16. package/src/opening-hours/is-open-now.ts +38 -0
  17. package/src/opening-hours/resolve.ts +71 -0
  18. package/src/opening-hours/time.ts +74 -0
  19. package/src/opening-hours/timezone.ts +34 -0
  20. package/src/opening-hours/types.ts +53 -0
  21. package/src/opening-hours/validate.ts +182 -0
  22. package/src/roi/calculations.ts +732 -0
  23. package/src/roi/index.ts +1 -0
  24. package/src/types/asset-bookings.types.ts +19 -0
  25. package/src/types/asset-interventions.types.ts +24 -0
  26. package/src/types/assets.types.ts +68 -0
  27. package/src/types/auth.types.ts +37 -0
  28. package/src/types/blog-posts.types.ts +19 -0
  29. package/src/types/calendar-pdf.types.ts +24 -0
  30. package/src/types/calendo-events.types.ts +64 -0
  31. package/src/types/challenges.types.ts +30 -0
  32. package/src/types/chatbot.types.ts +82 -0
  33. package/src/types/cities.types.ts +27 -0
  34. package/src/types/city-groups.types.ts +46 -0
  35. package/src/types/cms.types.ts +87 -0
  36. package/src/types/field-reports.types.ts +66 -0
  37. package/src/types/free-tier.types.ts +54 -0
  38. package/src/types/index.ts +32 -0
  39. package/src/types/iot.types.ts +31 -0
  40. package/src/types/maintenance.types.ts +44 -0
  41. package/src/types/mapso.types.ts +146 -0
  42. package/src/types/notifications.types.ts +68 -0
  43. package/src/types/onboarding.types.ts +117 -0
  44. package/src/types/operational-zones.types.ts +70 -0
  45. package/src/types/pagination.types.ts +33 -0
  46. package/src/types/providers.types.ts +29 -0
  47. package/src/types/quiz-questions.types.ts +59 -0
  48. package/src/types/recycling-points.types.ts +47 -0
  49. package/src/types/roi.types.ts +60 -0
  50. package/src/types/surveys.types.ts +103 -0
  51. package/src/types/tickets.types.ts +65 -0
  52. package/src/types/users.types.ts +30 -0
  53. package/src/types/waste-collection-places-query.types.ts +4 -0
  54. package/src/types/waste-collection-places.types.ts +33 -0
  55. package/src/types/waste-types.types.ts +21 -0
package/dist/index.js ADDED
@@ -0,0 +1,2566 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AssetEventType: () => AssetEventType,
24
+ AssetStatus: () => AssetStatus,
25
+ AssetType: () => AssetType,
26
+ BookingStatus: () => BookingStatus,
27
+ CITEO_DOM_MULTIPLIERS: () => CITEO_DOM_MULTIPLIERS,
28
+ CalendoEventStatus: () => CalendoEventStatus,
29
+ CalendoEventType: () => CalendoEventType,
30
+ CalendoTicketSaleStatus: () => CalendoTicketSaleStatus,
31
+ ChatMessageRole: () => ChatMessageRole,
32
+ ChatStatus: () => ChatStatus,
33
+ CityGroupType: () => CityGroupType,
34
+ CityStatus: () => CityStatus,
35
+ CmsMenuLinkType: () => CmsMenuLinkType,
36
+ CmsSiteType: () => CmsSiteType,
37
+ DASHBOARD_APPS: () => DASHBOARD_APPS,
38
+ DASHBOARD_APP_BY_KEY: () => DASHBOARD_APP_BY_KEY,
39
+ DASHBOARD_APP_BY_SLUG: () => DASHBOARD_APP_BY_SLUG,
40
+ DEFAULT_ENABLED_DASHBOARD_APP_SLUGS: () => DEFAULT_ENABLED_DASHBOARD_APP_SLUGS,
41
+ DEFAULT_PAGE: () => DEFAULT_PAGE,
42
+ DEFAULT_PAGE_SIZE: () => DEFAULT_PAGE_SIZE,
43
+ DOM_INSEE_PREFIXES: () => DOM_INSEE_PREFIXES,
44
+ DashboardAppSlug: () => DashboardAppSlug,
45
+ FREE_SELF_SERVE_DASHBOARD_APP_SLUGS: () => FREE_SELF_SERVE_DASHBOARD_APP_SLUGS,
46
+ FREE_TIER_FEATURES: () => FREE_TIER_FEATURES,
47
+ FREE_TIER_FEATURE_KEYS: () => FREE_TIER_FEATURE_KEYS,
48
+ FREE_TIER_LIMITS: () => FREE_TIER_LIMITS,
49
+ FREE_TIER_RESOURCES: () => FREE_TIER_RESOURCES,
50
+ FieldReportFormStatus: () => FieldReportFormStatus,
51
+ FieldReportStatus: () => FieldReportStatus,
52
+ InterventionStatus: () => InterventionStatus,
53
+ InterventionType: () => InterventionType,
54
+ MAX_PAGE_SIZE: () => MAX_PAGE_SIZE,
55
+ MapEventStatus: () => MapEventStatus,
56
+ MapEventType: () => MapEventType,
57
+ MapPoiCategory: () => MapPoiCategory,
58
+ MapPoiStatus: () => MapPoiStatus,
59
+ MapZoneType: () => MapZoneType,
60
+ NotificationDeliveryStatus: () => NotificationDeliveryStatus,
61
+ NotificationStatus: () => NotificationStatus,
62
+ ONBOARDING_RESTRICTED_APP_SLUGS: () => ONBOARDING_RESTRICTED_APP_SLUGS,
63
+ OperationalZoneStatus: () => OperationalZoneStatus,
64
+ OperationalZoneType: () => OperationalZoneType,
65
+ PRESET_SLOTS: () => PRESET_SLOTS,
66
+ PermissionAction: () => PermissionAction,
67
+ PermissionResource: () => PermissionResource,
68
+ ProviderType: () => ProviderType,
69
+ QuestionType: () => QuestionType,
70
+ ROI_DEFAULTS: () => ROI_DEFAULTS,
71
+ ROI_DISCLAIMER: () => ROI_DISCLAIMER,
72
+ ROI_SCENARIO_DEFS: () => ROI_SCENARIO_DEFS,
73
+ RecipientGroupType: () => RecipientGroupType,
74
+ ResponseStatus: () => ResponseStatus,
75
+ SurveyMode: () => SurveyMode,
76
+ SurveyStatus: () => SurveyStatus,
77
+ TGAP_LANDFILL_EUR_PER_TONNE: () => TGAP_LANDFILL_EUR_PER_TONNE,
78
+ TerritoryActionStatus: () => TerritoryActionStatus,
79
+ TerritoryActionType: () => TerritoryActionType,
80
+ TicketFormStatus: () => TicketFormStatus,
81
+ TicketStatus: () => TicketStatus,
82
+ UserRole: () => UserRole,
83
+ WASTO_LANDINGS_DOMAIN: () => WASTO_LANDINGS_DOMAIN,
84
+ WASTO_LANDINGS_INDEX_HOST: () => WASTO_LANDINGS_INDEX_HOST,
85
+ WASTO_RESERVED_SUBDOMAINS: () => WASTO_RESERVED_SUBDOMAINS,
86
+ WASTO_SECTIONS: () => WASTO_SECTIONS,
87
+ WASTO_SECTION_BY_KEY: () => WASTO_SECTION_BY_KEY,
88
+ WEEKDAYS: () => WEEKDAYS,
89
+ WEEKDAY_INDEX: () => WEEKDAY_INDEX,
90
+ WEEKDAY_LABELS_FR: () => WEEKDAY_LABELS_FR,
91
+ WEEKDAY_LABELS_FR_SHORT: () => WEEKDAY_LABELS_FR_SHORT,
92
+ WEEKDAY_REF_DATES: () => WEEKDAY_REF_DATES,
93
+ WastoApiError: () => WastoApiError,
94
+ addDaysToIsoDate: () => addDaysToIsoDate,
95
+ adjustCostPerBadTonneForTgap: () => adjustCostPerBadTonneForTgap,
96
+ allocateSavingsByAction: () => allocateSavingsByAction,
97
+ applyCiteoDomMultiplier: () => applyCiteoDomMultiplier,
98
+ applyStackedErrorReductions: () => applyStackedErrorReductions,
99
+ buildBauVsRealSeries: () => buildBauVsRealSeries,
100
+ buildPaginationMeta: () => buildPaginationMeta,
101
+ computeActionImpactConfidence: () => computeActionImpactConfidence,
102
+ computeGec: () => computeGec,
103
+ computeOverallConfidence: () => computeOverallConfidence,
104
+ computePenetrationRate: () => computePenetrationRate,
105
+ computeRoiIndicators: () => computeRoiIndicators,
106
+ convertLocalToUtc: () => convertLocalToUtc,
107
+ convertUtcToLocal: () => convertUtcToLocal,
108
+ createEmptyLocalRules: () => createEmptyLocalRules,
109
+ createEmptyOpeningHours: () => createEmptyOpeningHours,
110
+ createWastoClient: () => createWastoClient,
111
+ currentFiscalYear: () => currentFiscalYear,
112
+ dashboardAppKeyFromLandingHost: () => dashboardAppKeyFromLandingHost,
113
+ dashboardAppKeyToSlug: () => dashboardAppKeyToSlug,
114
+ dashboardAppSlugToKey: () => dashboardAppSlugToKey,
115
+ detectDomTerritory: () => detectDomTerritory,
116
+ estimateHouseholds: () => estimateHouseholds,
117
+ formatOpeningHoursSummary: () => formatOpeningHoursSummary,
118
+ formatOpeningHoursWeekly: () => formatOpeningHoursWeekly,
119
+ formatTimeDisplay: () => formatTimeDisplay,
120
+ formatTimeMinutes: () => formatTimeMinutes,
121
+ formatWeeklyRow: () => formatWeeklyRow,
122
+ getBrowserTimeZone: () => getBrowserTimeZone,
123
+ getFreeTierLimit: () => getFreeTierLimit,
124
+ getFreeTierMediaBytesLimit: () => getFreeTierMediaBytesLimit,
125
+ getTgapEurPerTonne: () => getTgapEurPerTonne,
126
+ getTimezoneOffsetMinutes: () => getTimezoneOffsetMinutes,
127
+ isActionCountedInRoi: () => isActionCountedInRoi,
128
+ isDashboardAppLandingHost: () => isDashboardAppLandingHost,
129
+ isDomInseeCode: () => isDomInseeCode,
130
+ isFreeSelfServeAppAccess: () => isFreeSelfServeAppAccess,
131
+ isFreeTierFeatureEnabled: () => isFreeTierFeatureEnabled,
132
+ isOpenNow: () => isOpenNow,
133
+ localDateTimeToUtc: () => localDateTimeToUtc,
134
+ localRulesFromRange: () => localRulesFromRange,
135
+ nextWeekday: () => nextWeekday,
136
+ normalizeDashboardAppSlug: () => normalizeDashboardAppSlug,
137
+ openNowLabel: () => openNowLabel,
138
+ parseTimeMinutes: () => parseTimeMinutes,
139
+ refDateForWeekday: () => refDateForWeekday,
140
+ resolveDashboardAppLandingUrl: () => resolveDashboardAppLandingUrl,
141
+ resolveEnabledDashboardAppSlugs: () => resolveEnabledDashboardAppSlugs,
142
+ resolveHoursDisplay: () => resolveHoursDisplay,
143
+ resolveHoursMode: () => resolveHoursMode,
144
+ resolveHoursModeFromPoint: () => resolveHoursModeFromPoint,
145
+ resolveHoursText: () => resolveHoursText,
146
+ resolveOpeningHoursLocal: () => resolveOpeningHoursLocal,
147
+ resolveOpeningHoursUtc: () => resolveOpeningHoursUtc,
148
+ resolveWastoLandingsIndexUrl: () => resolveWastoLandingsIndexUrl,
149
+ roundEuro: () => roundEuro,
150
+ simulateTerritory100kExample: () => simulateTerritory100kExample,
151
+ slotsOverlap: () => slotsOverlap,
152
+ sortSlots: () => sortSlots,
153
+ utcDateIso: () => utcDateIso,
154
+ utcHhmmFromDate: () => utcHhmmFromDate,
155
+ validateLocalOpeningHours: () => validateLocalOpeningHours,
156
+ validateOpeningHours: () => validateOpeningHours,
157
+ weekdayFromUtcDate: () => weekdayFromUtcDate
158
+ });
159
+ module.exports = __toCommonJS(index_exports);
160
+
161
+ // src/enums.ts
162
+ var UserRole = /* @__PURE__ */ ((UserRole2) => {
163
+ UserRole2["ADMIN"] = "ADMIN";
164
+ UserRole2["GESTIONNAIRE_COLLECTIVITE"] = "GESTIONNAIRE_COLLECTIVITE";
165
+ UserRole2["USER"] = "USER";
166
+ return UserRole2;
167
+ })(UserRole || {});
168
+ var CityGroupType = /* @__PURE__ */ ((CityGroupType2) => {
169
+ CityGroupType2["AGGLOMERATION"] = "AGGLOMERATION";
170
+ CityGroupType2["COMMUNAUTE"] = "COMMUNAUTE";
171
+ CityGroupType2["METROPOLE"] = "METROPOLE";
172
+ CityGroupType2["SYNDICAT"] = "SYNDICAT";
173
+ CityGroupType2["AUTRE"] = "AUTRE";
174
+ return CityGroupType2;
175
+ })(CityGroupType || {});
176
+ var CityStatus = /* @__PURE__ */ ((CityStatus2) => {
177
+ CityStatus2["NON_ACTIF"] = "NON_ACTIF";
178
+ CityStatus2["INCOMPLET"] = "INCOMPLET";
179
+ CityStatus2["ACTIF"] = "ACTIF";
180
+ CityStatus2["MAINTENANCE"] = "MAINTENANCE";
181
+ return CityStatus2;
182
+ })(CityStatus || {});
183
+ var RecipientGroupType = /* @__PURE__ */ ((RecipientGroupType2) => {
184
+ RecipientGroupType2["CITY"] = "CITY";
185
+ RecipientGroupType2["CITY_GROUP"] = "CITY_GROUP";
186
+ RecipientGroupType2["ZONE"] = "ZONE";
187
+ return RecipientGroupType2;
188
+ })(RecipientGroupType || {});
189
+ var NotificationStatus = /* @__PURE__ */ ((NotificationStatus2) => {
190
+ NotificationStatus2["DRAFT"] = "DRAFT";
191
+ NotificationStatus2["SCHEDULED"] = "SCHEDULED";
192
+ NotificationStatus2["SENT"] = "SENT";
193
+ NotificationStatus2["ARCHIVED"] = "ARCHIVED";
194
+ return NotificationStatus2;
195
+ })(NotificationStatus || {});
196
+ var NotificationDeliveryStatus = /* @__PURE__ */ ((NotificationDeliveryStatus2) => {
197
+ NotificationDeliveryStatus2["PENDING"] = "PENDING";
198
+ NotificationDeliveryStatus2["SENT"] = "SENT";
199
+ NotificationDeliveryStatus2["FAILED"] = "FAILED";
200
+ return NotificationDeliveryStatus2;
201
+ })(NotificationDeliveryStatus || {});
202
+ var CmsSiteType = /* @__PURE__ */ ((CmsSiteType2) => {
203
+ CmsSiteType2["SITE"] = "SITE";
204
+ CmsSiteType2["APP"] = "APP";
205
+ return CmsSiteType2;
206
+ })(CmsSiteType || {});
207
+ var CmsMenuLinkType = /* @__PURE__ */ ((CmsMenuLinkType2) => {
208
+ CmsMenuLinkType2["PAGE"] = "PAGE";
209
+ CmsMenuLinkType2["EXTERNAL"] = "EXTERNAL";
210
+ CmsMenuLinkType2["COMPONENT"] = "COMPONENT";
211
+ return CmsMenuLinkType2;
212
+ })(CmsMenuLinkType || {});
213
+ var ChatMessageRole = /* @__PURE__ */ ((ChatMessageRole2) => {
214
+ ChatMessageRole2["USER"] = "USER";
215
+ ChatMessageRole2["ASSISTANT"] = "ASSISTANT";
216
+ ChatMessageRole2["AGENT"] = "AGENT";
217
+ return ChatMessageRole2;
218
+ })(ChatMessageRole || {});
219
+ var ChatStatus = /* @__PURE__ */ ((ChatStatus2) => {
220
+ ChatStatus2["OPEN"] = "OPEN";
221
+ ChatStatus2["WAITING_AGENT"] = "WAITING_AGENT";
222
+ ChatStatus2["RESOLVED"] = "RESOLVED";
223
+ ChatStatus2["CLOSED"] = "CLOSED";
224
+ return ChatStatus2;
225
+ })(ChatStatus || {});
226
+ var PermissionAction = /* @__PURE__ */ ((PermissionAction2) => {
227
+ PermissionAction2["READ"] = "READ";
228
+ PermissionAction2["WRITE"] = "WRITE";
229
+ return PermissionAction2;
230
+ })(PermissionAction || {});
231
+ var PermissionResource = /* @__PURE__ */ ((PermissionResource2) => {
232
+ PermissionResource2["USERS"] = "USERS";
233
+ PermissionResource2["CITIES"] = "CITIES";
234
+ PermissionResource2["CITY_GROUPS"] = "CITY_GROUPS";
235
+ PermissionResource2["BLOG_POSTS"] = "BLOG_POSTS";
236
+ PermissionResource2["CHALLENGES"] = "CHALLENGES";
237
+ PermissionResource2["SERIES"] = "SERIES";
238
+ PermissionResource2["BADGES"] = "BADGES";
239
+ PermissionResource2["NOTIFICATIONS"] = "NOTIFICATIONS";
240
+ PermissionResource2["RECIPIENT_GROUPS"] = "RECIPIENT_GROUPS";
241
+ PermissionResource2["WASTE_TYPES"] = "WASTE_TYPES";
242
+ PermissionResource2["WASTE_COLLECTION_PLACES"] = "WASTE_COLLECTION_PLACES";
243
+ PermissionResource2["RECYCLING_POINTS"] = "RECYCLING_POINTS";
244
+ PermissionResource2["QUIZ_QUESTIONS"] = "QUIZ_QUESTIONS";
245
+ PermissionResource2["CHAT_CONVERSATIONS"] = "CHAT_CONVERSATIONS";
246
+ PermissionResource2["ANALYTICS"] = "ANALYTICS";
247
+ PermissionResource2["ASSETS"] = "ASSETS";
248
+ PermissionResource2["IOT_DEVICES"] = "IOT_DEVICES";
249
+ PermissionResource2["SURVEYS"] = "SURVEYS";
250
+ PermissionResource2["TICKETS"] = "TICKETS";
251
+ PermissionResource2["TICKET_FORMS"] = "TICKET_FORMS";
252
+ PermissionResource2["PROVIDERS"] = "PROVIDERS";
253
+ PermissionResource2["CMS_SITES"] = "CMS_SITES";
254
+ PermissionResource2["CMS_PAGES"] = "CMS_PAGES";
255
+ PermissionResource2["CMS_MEDIA"] = "CMS_MEDIA";
256
+ PermissionResource2["CALENDO_EVENTS"] = "CALENDO_EVENTS";
257
+ PermissionResource2["MAPSO_EVENTS"] = "MAPSO_EVENTS";
258
+ PermissionResource2["FIELD_REPORTS"] = "FIELD_REPORTS";
259
+ return PermissionResource2;
260
+ })(PermissionResource || {});
261
+ var TerritoryActionType = /* @__PURE__ */ ((TerritoryActionType2) => {
262
+ TerritoryActionType2["AWARENESS"] = "AWARENESS";
263
+ TerritoryActionType2["CONTROLS"] = "CONTROLS";
264
+ TerritoryActionType2["EQUIPMENT"] = "EQUIPMENT";
265
+ TerritoryActionType2["WASTO_APP"] = "WASTO_APP";
266
+ TerritoryActionType2["TRAINING"] = "TRAINING";
267
+ TerritoryActionType2["OTHER"] = "OTHER";
268
+ return TerritoryActionType2;
269
+ })(TerritoryActionType || {});
270
+ var TerritoryActionStatus = /* @__PURE__ */ ((TerritoryActionStatus2) => {
271
+ TerritoryActionStatus2["PLANNED"] = "PLANNED";
272
+ TerritoryActionStatus2["IN_PROGRESS"] = "IN_PROGRESS";
273
+ TerritoryActionStatus2["COMPLETED"] = "COMPLETED";
274
+ TerritoryActionStatus2["CANCELLED"] = "CANCELLED";
275
+ return TerritoryActionStatus2;
276
+ })(TerritoryActionStatus || {});
277
+ var AssetType = /* @__PURE__ */ ((AssetType2) => {
278
+ AssetType2["BENNE"] = "BENNE";
279
+ AssetType2["BORNE_VERRE"] = "BORNE_VERRE";
280
+ AssetType2["BORNE_TEMPORAIRE"] = "BORNE_TEMPORAIRE";
281
+ AssetType2["EPHEMERE"] = "EPHEMERE";
282
+ AssetType2["LOCATION"] = "LOCATION";
283
+ AssetType2["VEHICULE"] = "VEHICULE";
284
+ AssetType2["CAMION"] = "CAMION";
285
+ return AssetType2;
286
+ })(AssetType || {});
287
+ var AssetStatus = /* @__PURE__ */ ((AssetStatus2) => {
288
+ AssetStatus2["DISPONIBLE"] = "DISPONIBLE";
289
+ AssetStatus2["EN_LOCATION"] = "EN_LOCATION";
290
+ AssetStatus2["EN_MAINTENANCE"] = "EN_MAINTENANCE";
291
+ AssetStatus2["HORS_SERVICE"] = "HORS_SERVICE";
292
+ return AssetStatus2;
293
+ })(AssetStatus || {});
294
+ var BookingStatus = /* @__PURE__ */ ((BookingStatus2) => {
295
+ BookingStatus2["PENDING"] = "PENDING";
296
+ BookingStatus2["CONFIRMED"] = "CONFIRMED";
297
+ BookingStatus2["CANCELLED"] = "CANCELLED";
298
+ return BookingStatus2;
299
+ })(BookingStatus || {});
300
+ var SurveyStatus = /* @__PURE__ */ ((SurveyStatus2) => {
301
+ SurveyStatus2["DRAFT"] = "DRAFT";
302
+ SurveyStatus2["ACTIVE"] = "ACTIVE";
303
+ SurveyStatus2["ARCHIVED"] = "ARCHIVED";
304
+ return SurveyStatus2;
305
+ })(SurveyStatus || {});
306
+ var SurveyMode = /* @__PURE__ */ ((SurveyMode2) => {
307
+ SurveyMode2["FIELD"] = "FIELD";
308
+ SurveyMode2["ONLINE"] = "ONLINE";
309
+ SurveyMode2["PHONE"] = "PHONE";
310
+ return SurveyMode2;
311
+ })(SurveyMode || {});
312
+ var QuestionType = /* @__PURE__ */ ((QuestionType2) => {
313
+ QuestionType2["TEXT"] = "TEXT";
314
+ QuestionType2["NUMBER"] = "NUMBER";
315
+ QuestionType2["CHOICE"] = "CHOICE";
316
+ QuestionType2["MULTIPLE_CHOICE"] = "MULTIPLE_CHOICE";
317
+ QuestionType2["RATING"] = "RATING";
318
+ QuestionType2["DATE"] = "DATE";
319
+ QuestionType2["LOCATION"] = "LOCATION";
320
+ QuestionType2["PHOTO"] = "PHOTO";
321
+ QuestionType2["YES_NO"] = "YES_NO";
322
+ return QuestionType2;
323
+ })(QuestionType || {});
324
+ var ResponseStatus = /* @__PURE__ */ ((ResponseStatus2) => {
325
+ ResponseStatus2["DRAFT"] = "DRAFT";
326
+ ResponseStatus2["SUBMITTED"] = "SUBMITTED";
327
+ ResponseStatus2["SYNCED"] = "SYNCED";
328
+ return ResponseStatus2;
329
+ })(ResponseStatus || {});
330
+ var TicketFormStatus = /* @__PURE__ */ ((TicketFormStatus2) => {
331
+ TicketFormStatus2["DRAFT"] = "DRAFT";
332
+ TicketFormStatus2["ACTIVE"] = "ACTIVE";
333
+ TicketFormStatus2["ARCHIVED"] = "ARCHIVED";
334
+ return TicketFormStatus2;
335
+ })(TicketFormStatus || {});
336
+ var TicketStatus = /* @__PURE__ */ ((TicketStatus2) => {
337
+ TicketStatus2["OUVERT"] = "OUVERT";
338
+ TicketStatus2["EN_COURS"] = "EN_COURS";
339
+ TicketStatus2["RESOLU"] = "RESOLU";
340
+ TicketStatus2["FERME"] = "FERME";
341
+ return TicketStatus2;
342
+ })(TicketStatus || {});
343
+ var FieldReportFormStatus = /* @__PURE__ */ ((FieldReportFormStatus2) => {
344
+ FieldReportFormStatus2["DRAFT"] = "DRAFT";
345
+ FieldReportFormStatus2["ACTIVE"] = "ACTIVE";
346
+ FieldReportFormStatus2["ARCHIVED"] = "ARCHIVED";
347
+ return FieldReportFormStatus2;
348
+ })(FieldReportFormStatus || {});
349
+ var FieldReportStatus = /* @__PURE__ */ ((FieldReportStatus2) => {
350
+ FieldReportStatus2["OUVERT"] = "OUVERT";
351
+ FieldReportStatus2["EN_COURS"] = "EN_COURS";
352
+ FieldReportStatus2["RESOLU"] = "RESOLU";
353
+ FieldReportStatus2["FERME"] = "FERME";
354
+ return FieldReportStatus2;
355
+ })(FieldReportStatus || {});
356
+ var ProviderType = /* @__PURE__ */ ((ProviderType2) => {
357
+ ProviderType2["LOCATION_ASSETS"] = "LOCATION_ASSETS";
358
+ ProviderType2["ANIMATION_CHALLENGE"] = "ANIMATION_CHALLENGE";
359
+ ProviderType2["MAINTENANCE"] = "MAINTENANCE";
360
+ ProviderType2["AUTRE"] = "AUTRE";
361
+ return ProviderType2;
362
+ })(ProviderType || {});
363
+ var InterventionType = /* @__PURE__ */ ((InterventionType2) => {
364
+ InterventionType2["MAINTENANCE"] = "MAINTENANCE";
365
+ InterventionType2["INDISPO"] = "INDISPO";
366
+ InterventionType2["CONTROLE"] = "CONTROLE";
367
+ InterventionType2["OTHER"] = "OTHER";
368
+ return InterventionType2;
369
+ })(InterventionType || {});
370
+ var InterventionStatus = /* @__PURE__ */ ((InterventionStatus2) => {
371
+ InterventionStatus2["PLANNED"] = "PLANNED";
372
+ InterventionStatus2["IN_PROGRESS"] = "IN_PROGRESS";
373
+ InterventionStatus2["DONE"] = "DONE";
374
+ InterventionStatus2["CANCELLED"] = "CANCELLED";
375
+ return InterventionStatus2;
376
+ })(InterventionStatus || {});
377
+ var AssetEventType = /* @__PURE__ */ ((AssetEventType2) => {
378
+ AssetEventType2["LOCATION_CHANGE"] = "LOCATION_CHANGE";
379
+ AssetEventType2["STATUS_CHANGE"] = "STATUS_CHANGE";
380
+ AssetEventType2["MAINTENANCE"] = "MAINTENANCE";
381
+ AssetEventType2["INSPECTION"] = "INSPECTION";
382
+ AssetEventType2["OTHER"] = "OTHER";
383
+ return AssetEventType2;
384
+ })(AssetEventType || {});
385
+ var CalendoEventType = /* @__PURE__ */ ((CalendoEventType2) => {
386
+ CalendoEventType2["CONCERT"] = "CONCERT";
387
+ CalendoEventType2["ANIMATION"] = "ANIMATION";
388
+ CalendoEventType2["EXPOSITION"] = "EXPOSITION";
389
+ CalendoEventType2["OTHER"] = "OTHER";
390
+ return CalendoEventType2;
391
+ })(CalendoEventType || {});
392
+ var CalendoEventStatus = /* @__PURE__ */ ((CalendoEventStatus2) => {
393
+ CalendoEventStatus2["DRAFT"] = "DRAFT";
394
+ CalendoEventStatus2["PUBLISHED"] = "PUBLISHED";
395
+ CalendoEventStatus2["CANCELLED"] = "CANCELLED";
396
+ CalendoEventStatus2["SOLD_OUT"] = "SOLD_OUT";
397
+ return CalendoEventStatus2;
398
+ })(CalendoEventStatus || {});
399
+ var CalendoTicketSaleStatus = /* @__PURE__ */ ((CalendoTicketSaleStatus2) => {
400
+ CalendoTicketSaleStatus2["CONFIRMED"] = "CONFIRMED";
401
+ CalendoTicketSaleStatus2["CANCELLED"] = "CANCELLED";
402
+ CalendoTicketSaleStatus2["REFUNDED"] = "REFUNDED";
403
+ return CalendoTicketSaleStatus2;
404
+ })(CalendoTicketSaleStatus || {});
405
+ var MapEventType = /* @__PURE__ */ ((MapEventType2) => {
406
+ MapEventType2["FAIR"] = "FAIR";
407
+ MapEventType2["MARKET"] = "MARKET";
408
+ MapEventType2["FESTIVAL"] = "FESTIVAL";
409
+ MapEventType2["PERMANENT"] = "PERMANENT";
410
+ MapEventType2["OTHER"] = "OTHER";
411
+ return MapEventType2;
412
+ })(MapEventType || {});
413
+ var MapEventStatus = /* @__PURE__ */ ((MapEventStatus2) => {
414
+ MapEventStatus2["DRAFT"] = "DRAFT";
415
+ MapEventStatus2["PUBLISHED"] = "PUBLISHED";
416
+ MapEventStatus2["ARCHIVED"] = "ARCHIVED";
417
+ return MapEventStatus2;
418
+ })(MapEventStatus || {});
419
+ var MapPoiCategory = /* @__PURE__ */ ((MapPoiCategory2) => {
420
+ MapPoiCategory2["ATTRACTION_STAND"] = "ATTRACTION_STAND";
421
+ MapPoiCategory2["TOILET"] = "TOILET";
422
+ MapPoiCategory2["SECURITY"] = "SECURITY";
423
+ MapPoiCategory2["FOOD"] = "FOOD";
424
+ MapPoiCategory2["WATER_FOUNTAIN"] = "WATER_FOUNTAIN";
425
+ MapPoiCategory2["WASTO_RECYCLING"] = "WASTO_RECYCLING";
426
+ MapPoiCategory2["WASTO_BIOWASTE"] = "WASTO_BIOWASTE";
427
+ MapPoiCategory2["WASTO_RETURN"] = "WASTO_RETURN";
428
+ MapPoiCategory2["TRAVAUX"] = "TRAVAUX";
429
+ return MapPoiCategory2;
430
+ })(MapPoiCategory || {});
431
+ var MapZoneType = /* @__PURE__ */ ((MapZoneType2) => {
432
+ MapZoneType2["PARKING_PROVISOIRE"] = "PARKING_PROVISOIRE";
433
+ MapZoneType2["ZONE_INTERDITE"] = "ZONE_INTERDITE";
434
+ MapZoneType2["AUTRE"] = "AUTRE";
435
+ return MapZoneType2;
436
+ })(MapZoneType || {});
437
+ var MapPoiStatus = /* @__PURE__ */ ((MapPoiStatus2) => {
438
+ MapPoiStatus2["ACTIVE"] = "ACTIVE";
439
+ MapPoiStatus2["MAINTENANCE"] = "MAINTENANCE";
440
+ MapPoiStatus2["CLOSED"] = "CLOSED";
441
+ return MapPoiStatus2;
442
+ })(MapPoiStatus || {});
443
+ var OperationalZoneType = /* @__PURE__ */ ((OperationalZoneType2) => {
444
+ OperationalZoneType2["TRAVAUX"] = "TRAVAUX";
445
+ OperationalZoneType2["PARKING_PROVISOIRE"] = "PARKING_PROVISOIRE";
446
+ OperationalZoneType2["ZONE_INTERDITE"] = "ZONE_INTERDITE";
447
+ OperationalZoneType2["AUTRE"] = "AUTRE";
448
+ return OperationalZoneType2;
449
+ })(OperationalZoneType || {});
450
+ var OperationalZoneStatus = /* @__PURE__ */ ((OperationalZoneStatus2) => {
451
+ OperationalZoneStatus2["DRAFT"] = "DRAFT";
452
+ OperationalZoneStatus2["ACTIVE"] = "ACTIVE";
453
+ OperationalZoneStatus2["ARCHIVED"] = "ARCHIVED";
454
+ return OperationalZoneStatus2;
455
+ })(OperationalZoneStatus || {});
456
+
457
+ // src/dashboard-apps.ts
458
+ var DashboardAppSlug = /* @__PURE__ */ ((DashboardAppSlug2) => {
459
+ DashboardAppSlug2["WORKSPACE"] = "WORKSPACE";
460
+ DashboardAppSlug2["WASTO"] = "WASTO";
461
+ DashboardAppSlug2["APPSO"] = "APPSO";
462
+ DashboardAppSlug2["CALENDO"] = "CALENDO";
463
+ DashboardAppSlug2["ACTO"] = "ACTO";
464
+ DashboardAppSlug2["ASSISTO"] = "ASSISTO";
465
+ DashboardAppSlug2["PLAYO"] = "PLAYO";
466
+ DashboardAppSlug2["MAPSO"] = "MAPSO";
467
+ DashboardAppSlug2["IAGO"] = "IAGO";
468
+ DashboardAppSlug2["PEDAGO"] = "PEDAGO";
469
+ DashboardAppSlug2["MARKETO"] = "MARKETO";
470
+ return DashboardAppSlug2;
471
+ })(DashboardAppSlug || {});
472
+ var WASTO_SECTIONS = [
473
+ {
474
+ slug: "WORKSPACE" /* WORKSPACE */,
475
+ key: "workspace",
476
+ label: "WORKSPACE",
477
+ sectionLabel: "Tableau de bord",
478
+ dashboardPath: "/dashboard"
479
+ },
480
+ {
481
+ slug: "WASTO" /* WASTO */,
482
+ key: "wasto",
483
+ label: "WAST'O",
484
+ sectionLabel: "R\xE9f\xE9rentiel & collecte",
485
+ dashboardPath: "/referentiel"
486
+ },
487
+ {
488
+ slug: "PLAYO" /* PLAYO */,
489
+ key: "playo",
490
+ label: "PLAY'O",
491
+ sectionLabel: "Engagement",
492
+ dashboardPath: "/engagement"
493
+ },
494
+ {
495
+ slug: "ACTO" /* ACTO */,
496
+ key: "acto",
497
+ label: "ACT'O",
498
+ sectionLabel: "Animation terrain",
499
+ dashboardPath: "/terrain/enquetes"
500
+ },
501
+ {
502
+ slug: "IAGO" /* IAGO */,
503
+ key: "iago",
504
+ label: "AGENT'O",
505
+ sectionLabel: "Scan & IA",
506
+ dashboardPath: "/scan",
507
+ isDevOnly: true
508
+ },
509
+ {
510
+ slug: "MAPSO" /* MAPSO */,
511
+ key: "mapso",
512
+ label: "MAPS'O",
513
+ sectionLabel: "Cartographie",
514
+ dashboardPath: "/cartographie/infrastructures"
515
+ },
516
+ {
517
+ slug: "CALENDO" /* CALENDO */,
518
+ key: "calendo",
519
+ label: "CALEND'O",
520
+ sectionLabel: "\xC9v\xE9nements",
521
+ dashboardPath: "/evenements"
522
+ },
523
+ {
524
+ slug: "APPSO" /* APPSO */,
525
+ key: "appso",
526
+ label: "APP'O",
527
+ sectionLabel: "Studio app",
528
+ dashboardPath: "/studio-app/apps"
529
+ },
530
+ {
531
+ slug: "PEDAGO" /* PEDAGO */,
532
+ key: "pedago",
533
+ label: "PEDAG'O",
534
+ sectionLabel: "Analyses & ROI",
535
+ dashboardPath: "/analyses",
536
+ isDevOnly: true
537
+ },
538
+ {
539
+ slug: "ASSISTO" /* ASSISTO */,
540
+ key: "assisto",
541
+ label: "ASSIST'O",
542
+ sectionLabel: "Support",
543
+ dashboardPath: "/support"
544
+ }
545
+ ];
546
+ var DASHBOARD_APPS = [
547
+ {
548
+ slug: "WORKSPACE" /* WORKSPACE */,
549
+ key: "workspace",
550
+ label: "WORKSPACE",
551
+ dashboardPath: "/dashboard"
552
+ },
553
+ {
554
+ slug: "WASTO" /* WASTO */,
555
+ key: "wasto",
556
+ label: "WAST'O",
557
+ dashboardPath: "/referentiel"
558
+ },
559
+ {
560
+ slug: "APPSO" /* APPSO */,
561
+ key: "appso",
562
+ label: "APP'O",
563
+ dashboardPath: "/studio-app/apps"
564
+ },
565
+ {
566
+ slug: "CALENDO" /* CALENDO */,
567
+ key: "calendo",
568
+ label: "CALEND'O",
569
+ dashboardPath: "/evenements"
570
+ },
571
+ {
572
+ slug: "ACTO" /* ACTO */,
573
+ key: "acto",
574
+ label: "ACT'O",
575
+ dashboardPath: "/terrain/enquetes"
576
+ },
577
+ {
578
+ slug: "ASSISTO" /* ASSISTO */,
579
+ key: "assisto",
580
+ label: "ASSIST'O",
581
+ dashboardPath: "/support"
582
+ },
583
+ {
584
+ slug: "PLAYO" /* PLAYO */,
585
+ key: "playo",
586
+ label: "PLAY'O",
587
+ dashboardPath: "/engagement"
588
+ },
589
+ {
590
+ slug: "MAPSO" /* MAPSO */,
591
+ key: "mapso",
592
+ label: "MAPS'O",
593
+ dashboardPath: "/cartographie/infrastructures"
594
+ },
595
+ {
596
+ slug: "IAGO" /* IAGO */,
597
+ key: "iago",
598
+ label: "AGENT'O",
599
+ dashboardPath: "/scan",
600
+ isDevOnly: true
601
+ },
602
+ {
603
+ slug: "PEDAGO" /* PEDAGO */,
604
+ key: "pedago",
605
+ label: "PEDAG'O",
606
+ dashboardPath: "/analyses",
607
+ isDevOnly: true
608
+ },
609
+ {
610
+ slug: "MARKETO" /* MARKETO */,
611
+ key: "marketo",
612
+ label: "MARKET'O",
613
+ dashboardPath: "/analyses",
614
+ isDevOnly: true
615
+ }
616
+ ];
617
+ var WASTO_SECTION_BY_KEY = Object.fromEntries(
618
+ WASTO_SECTIONS.map((s) => [s.key, s])
619
+ );
620
+ var DASHBOARD_APP_BY_SLUG = Object.fromEntries(
621
+ DASHBOARD_APPS.map((a) => [a.slug, a])
622
+ );
623
+ var DASHBOARD_APP_BY_KEY = Object.fromEntries(
624
+ DASHBOARD_APPS.map((a) => [a.key, a])
625
+ );
626
+ var DEFAULT_ENABLED_DASHBOARD_APP_SLUGS = DASHBOARD_APPS.filter(
627
+ (a) => !a.isDevOnly
628
+ ).map((a) => a.slug);
629
+ var FREE_SELF_SERVE_DASHBOARD_APP_SLUGS = [
630
+ "WORKSPACE" /* WORKSPACE */,
631
+ "WASTO" /* WASTO */,
632
+ "APPSO" /* APPSO */
633
+ ];
634
+ var FREE_SELF_SERVE_LEGACY_EXTRA_SLUGS = [
635
+ "PLAYO" /* PLAYO */
636
+ ];
637
+ function normalizeDashboardAppSlug(value) {
638
+ const upper = value.toUpperCase();
639
+ if (DASHBOARD_APP_BY_SLUG[upper]) {
640
+ return upper;
641
+ }
642
+ return dashboardAppKeyToSlug(value.toLowerCase());
643
+ }
644
+ function isFreeSelfServeAppAccess(enabledSlugs) {
645
+ if (enabledSlugs.length === 0) return false;
646
+ const free = /* @__PURE__ */ new Set([
647
+ ...FREE_SELF_SERVE_DASHBOARD_APP_SLUGS,
648
+ ...FREE_SELF_SERVE_LEGACY_EXTRA_SLUGS
649
+ ]);
650
+ return enabledSlugs.every((slug) => {
651
+ const normalized = normalizeDashboardAppSlug(slug);
652
+ return normalized != null && free.has(normalized);
653
+ });
654
+ }
655
+ function resolveEnabledDashboardAppSlugs(rows) {
656
+ if (rows.length === 0) {
657
+ return [...DEFAULT_ENABLED_DASHBOARD_APP_SLUGS];
658
+ }
659
+ const enabled = rows.filter((r) => r.enabled).map((r) => r.appSlug).filter((slug) => DASHBOARD_APPS.some((a) => a.slug === slug));
660
+ return [...new Set(enabled)];
661
+ }
662
+ function dashboardAppSlugToKey(slug) {
663
+ return DASHBOARD_APP_BY_SLUG[slug]?.key ?? slug.toLowerCase();
664
+ }
665
+ function dashboardAppKeyToSlug(key) {
666
+ return DASHBOARD_APP_BY_KEY[key]?.slug ?? null;
667
+ }
668
+ var WASTO_LANDINGS_DOMAIN = "wasto.localhost";
669
+ var WASTO_LANDINGS_INDEX_HOST = `apps.${WASTO_LANDINGS_DOMAIN}`;
670
+ var WASTO_RESERVED_SUBDOMAINS = /* @__PURE__ */ new Set([
671
+ "api",
672
+ "admin",
673
+ "dashboard",
674
+ "docs",
675
+ "field-survey",
676
+ "apps"
677
+ ]);
678
+ function isDashboardAppLandingHost(host) {
679
+ const normalized = host.split(":")[0]?.toLowerCase() ?? "";
680
+ if (normalized === WASTO_LANDINGS_INDEX_HOST) {
681
+ return true;
682
+ }
683
+ const match = normalized.match(/^([a-z]+)\.wasto\.localhost$/);
684
+ if (!match) {
685
+ return false;
686
+ }
687
+ const subdomain = match[1];
688
+ if (WASTO_RESERVED_SUBDOMAINS.has(subdomain)) {
689
+ return false;
690
+ }
691
+ return Boolean(DASHBOARD_APP_BY_KEY[subdomain]);
692
+ }
693
+ function dashboardAppKeyFromLandingHost(host) {
694
+ const normalized = host.split(":")[0]?.toLowerCase() ?? "";
695
+ if (normalized === WASTO_LANDINGS_INDEX_HOST) {
696
+ return null;
697
+ }
698
+ const match = normalized.match(/^([a-z]+)\.wasto\.localhost$/);
699
+ if (!match) {
700
+ return null;
701
+ }
702
+ const key = match[1];
703
+ if (WASTO_RESERVED_SUBDOMAINS.has(key) || !DASHBOARD_APP_BY_KEY[key]) {
704
+ return null;
705
+ }
706
+ return key;
707
+ }
708
+ function resolveDashboardAppLandingUrl(key, options) {
709
+ if (!DASHBOARD_APP_BY_KEY[key]) {
710
+ return null;
711
+ }
712
+ const domain = options?.domain ?? WASTO_LANDINGS_DOMAIN;
713
+ const protocol = options?.protocol ?? "http";
714
+ return `${protocol}://${key}.${domain}`;
715
+ }
716
+ function resolveWastoLandingsIndexUrl(options) {
717
+ const domain = options?.domain ?? WASTO_LANDINGS_DOMAIN;
718
+ const protocol = options?.protocol ?? "http";
719
+ return `${protocol}://apps.${domain}`;
720
+ }
721
+
722
+ // src/free-tier.ts
723
+ var FREE_TIER_LIMITS = {
724
+ cmsApps: 1,
725
+ cmsPages: 5,
726
+ blogPosts: 10,
727
+ cmsMedia: 50,
728
+ cmsMediaBytesMb: 50,
729
+ wasteTypes: 15,
730
+ collectionPlaces: 10,
731
+ printCalendarTemplates: 3
732
+ };
733
+ var FREE_TIER_FEATURES = {
734
+ challenges: false,
735
+ roi: false,
736
+ notifications: false,
737
+ recyclingPoints: false,
738
+ assets: false,
739
+ nativeStorePublication: false,
740
+ inviteMembers: false
741
+ };
742
+ var FREE_TIER_RESOURCES = [
743
+ "cmsApps",
744
+ "cmsPages",
745
+ "blogPosts",
746
+ "cmsMedia",
747
+ "wasteTypes",
748
+ "collectionPlaces",
749
+ "printCalendarTemplates"
750
+ ];
751
+ var FREE_TIER_FEATURE_KEYS = [
752
+ "challenges",
753
+ "roi",
754
+ "notifications",
755
+ "recyclingPoints",
756
+ "assets",
757
+ "nativeStorePublication",
758
+ "inviteMembers"
759
+ ];
760
+ function getFreeTierLimit(resource) {
761
+ return FREE_TIER_LIMITS[resource];
762
+ }
763
+ function getFreeTierMediaBytesLimit() {
764
+ return FREE_TIER_LIMITS.cmsMediaBytesMb * 1024 * 1024;
765
+ }
766
+ function isFreeTierFeatureEnabled(feature) {
767
+ return FREE_TIER_FEATURES[feature] === true;
768
+ }
769
+
770
+ // src/types/pagination.types.ts
771
+ var DEFAULT_PAGE = 1;
772
+ var DEFAULT_PAGE_SIZE = 20;
773
+ var MAX_PAGE_SIZE = 100;
774
+ function buildPaginationMeta(page, pageSize, total) {
775
+ return {
776
+ page,
777
+ pageSize,
778
+ total,
779
+ totalPages: Math.ceil(total / pageSize) || 1
780
+ };
781
+ }
782
+
783
+ // src/types/onboarding.types.ts
784
+ var ONBOARDING_RESTRICTED_APP_SLUGS = FREE_SELF_SERVE_DASHBOARD_APP_SLUGS;
785
+
786
+ // src/roi/calculations.ts
787
+ var ROI_DEFAULTS = {
788
+ annualTonnage: 12e3,
789
+ errorRatePercent: 25,
790
+ costPerBadTonne: 300,
791
+ /** Habitants par foyer (proxy si householdCount absent). */
792
+ peoplePerHousehold: 2.2
793
+ };
794
+ var CITEO_DOM_MULTIPLIERS = {
795
+ lightPackaging: 2.3,
796
+ glass: 1.9,
797
+ paper: 4.3,
798
+ communication: 1.25,
799
+ ambassadors: 1.25,
800
+ /** Facteur composite simplifié pour majorer un soutien Citeo agrégé saisi. */
801
+ compositeSupport: 2.3
802
+ };
803
+ var DOM_INSEE_PREFIXES = [
804
+ "971",
805
+ // Guadeloupe
806
+ "972",
807
+ // Martinique
808
+ "973",
809
+ // Guyane
810
+ "974",
811
+ // La Réunion
812
+ "976"
813
+ // Mayotte
814
+ ];
815
+ var TGAP_LANDFILL_EUR_PER_TONNE = {
816
+ 2024: 61,
817
+ 2025: 65,
818
+ 2026: 69,
819
+ 2027: 73,
820
+ 2028: 77,
821
+ 2029: 81,
822
+ 2030: 85
823
+ };
824
+ function currentFiscalYear(now = /* @__PURE__ */ new Date()) {
825
+ return now.getFullYear();
826
+ }
827
+ function getTgapEurPerTonne(fiscalYear) {
828
+ if (TGAP_LANDFILL_EUR_PER_TONNE[fiscalYear] != null) {
829
+ return TGAP_LANDFILL_EUR_PER_TONNE[fiscalYear];
830
+ }
831
+ if (fiscalYear < 2024) return 61;
832
+ if (fiscalYear > 2030) return 85;
833
+ const base = 65;
834
+ return base + (fiscalYear - 2025) * 4;
835
+ }
836
+ function adjustCostPerBadTonneForTgap(opts) {
837
+ const nonTgap = Math.max(
838
+ 0,
839
+ opts.previousCostPerBadTonne - opts.previousTgapEurPerTonne
840
+ );
841
+ return roundEuro(nonTgap + opts.nextTgapEurPerTonne);
842
+ }
843
+ function buildBauVsRealSeries(opts) {
844
+ const byYear = new Map(opts.years.map((y) => [y.fiscalYear, y]));
845
+ const points = [];
846
+ for (let y = opts.fromYear; y <= opts.toYear; y++) {
847
+ const tgap = getTgapEurPerTonne(y);
848
+ const bauCost = adjustCostPerBadTonneForTgap({
849
+ previousCostPerBadTonne: opts.reference.costPerBadTonne,
850
+ previousTgapEurPerTonne: opts.reference.tgapEurPerTonne,
851
+ nextTgapEurPerTonne: tgap
852
+ });
853
+ const bau = computeGec(
854
+ opts.reference.tonnageOmr,
855
+ opts.reference.errorRatePercent,
856
+ bauCost
857
+ );
858
+ const snap = byYear.get(y);
859
+ if (snap) {
860
+ points.push({
861
+ fiscalYear: y,
862
+ tonnageOmr: snap.tonnageOmr,
863
+ errorRatePercent: snap.errorRatePercent,
864
+ costPerBadTonne: snap.costPerBadTonne,
865
+ tgapEurPerTonne: snap.tgapEurPerTonne,
866
+ realGecEur: snap.gecEur,
867
+ bauGecEur: bau.gecEur,
868
+ cenEur: snap.cenEur,
869
+ hasSnapshot: true,
870
+ annualBilanConfirmed: snap.annualBilanConfirmed === true
871
+ });
872
+ } else {
873
+ points.push({
874
+ fiscalYear: y,
875
+ tonnageOmr: opts.reference.tonnageOmr,
876
+ errorRatePercent: opts.reference.errorRatePercent,
877
+ costPerBadTonne: bauCost,
878
+ tgapEurPerTonne: tgap,
879
+ realGecEur: bau.gecEur,
880
+ bauGecEur: bau.gecEur,
881
+ cenEur: null,
882
+ hasSnapshot: false,
883
+ annualBilanConfirmed: false
884
+ });
885
+ }
886
+ }
887
+ return points;
888
+ }
889
+ var ROI_SCENARIO_DEFS = [
890
+ {
891
+ id: "awareness",
892
+ label: "Sensibilisation seule",
893
+ errorReductionFactor: 0.12,
894
+ costBase: 8e3,
895
+ costPerTonne: 0.35
896
+ },
897
+ {
898
+ id: "controls",
899
+ label: "Formation + contr\xF4les",
900
+ errorReductionFactor: 0.28,
901
+ costBase: 45e3,
902
+ costPerTonne: 1.8
903
+ },
904
+ {
905
+ id: "wasto",
906
+ label: "Wast-O (app + IA + pilotage)",
907
+ errorReductionFactor: 0.45,
908
+ costBase: 18e3,
909
+ costPerTonne: 0.9
910
+ }
911
+ ];
912
+ var ROI_DISCLAIMER = "Ordres de grandeur p\xE9dagogiques fond\xE9s sur des hypoth\xE8ses d\xE9claratives (tonnages, taux d\u2019erreur, budgets). Non contractuels \u2014 \xE0 affiner avec les donn\xE9es exploitant / SITOM / TGAP.";
913
+ function clamp(n, min, max) {
914
+ return Math.min(max, Math.max(min, n));
915
+ }
916
+ function roundEuro(n) {
917
+ return Math.round(n);
918
+ }
919
+ function isDomInseeCode(codeInsee) {
920
+ if (!codeInsee) return false;
921
+ const normalized = codeInsee.trim();
922
+ return DOM_INSEE_PREFIXES.some((p) => normalized.startsWith(p));
923
+ }
924
+ function detectDomTerritory(opts) {
925
+ if (opts.cityInseeCodes?.some((c) => isDomInseeCode(c))) return true;
926
+ const code = (opts.cityGroupCode ?? "").toUpperCase();
927
+ const name = (opts.cityGroupName ?? "").toUpperCase();
928
+ if (name.includes("CINOR") || name.includes("REUNION") || name.includes("R\xC9UNION")) {
929
+ return true;
930
+ }
931
+ if (code.includes("974") || code.includes("CINOR")) return true;
932
+ return false;
933
+ }
934
+ function applyCiteoDomMultiplier(baseCiteoEur, isDom) {
935
+ const baseEur = roundEuro(baseCiteoEur);
936
+ const multiplier = isDom ? CITEO_DOM_MULTIPLIERS.compositeSupport : 1;
937
+ return {
938
+ baseEur,
939
+ multiplier,
940
+ effectiveEur: roundEuro(baseEur * multiplier)
941
+ };
942
+ }
943
+ function computeGec(annualTonnage, errorRatePercent, costPerBadTonne) {
944
+ const badTonnes = annualTonnage * (errorRatePercent / 100);
945
+ return {
946
+ badTonnes: Math.round(badTonnes * 10) / 10,
947
+ gecEur: roundEuro(badTonnes * costPerBadTonne)
948
+ };
949
+ }
950
+ function applyStackedErrorReductions(baselineErrorRatePercent, reductionsPercent) {
951
+ let rate = baselineErrorRatePercent;
952
+ for (const r of reductionsPercent) {
953
+ const factor = clamp(r, 0, 95) / 100;
954
+ rate = rate * (1 - factor);
955
+ }
956
+ return clamp(Math.round(rate * 10) / 10, 1, 99);
957
+ }
958
+ function isActionCountedInRoi(status) {
959
+ if (!status) return true;
960
+ return status !== "CANCELLED" && status !== "PLANNED";
961
+ }
962
+ function computeActionImpactConfidence(action, live) {
963
+ const type = (action.type ?? "OTHER").toUpperCase();
964
+ const isApp = type === "WASTO_APP";
965
+ const hasLiveDigital = live.penetrationRatePercent > 0 || live.activeDevices30d > 0 || live.validatedVisionScans > 0 || live.challengeCompletions > 0;
966
+ if (isApp && !hasLiveDigital) {
967
+ return {
968
+ level: 1,
969
+ label: "Confiance faible",
970
+ tone: "low",
971
+ message: "Impact th\xE9orique (0 utilisateur actif)",
972
+ impactFactor: 0.25
973
+ };
974
+ }
975
+ if (isApp && live.penetrationRatePercent < 2) {
976
+ return {
977
+ level: 1,
978
+ label: "Confiance faible",
979
+ tone: "low",
980
+ message: `P\xE9n\xE9tration faible (${live.penetrationRatePercent} %) \u2014 impact brid\xE9`,
981
+ impactFactor: 0.5
982
+ };
983
+ }
984
+ if (isApp && live.penetrationRatePercent >= 5) {
985
+ return {
986
+ level: 2,
987
+ label: "Confiance moyenne",
988
+ tone: "medium",
989
+ message: "Proxy live app disponible",
990
+ impactFactor: 1
991
+ };
992
+ }
993
+ if (type === "AWARENESS" || type === "TRAINING" || type === "CONTROLS") {
994
+ if (live.terrainResponses > 0) {
995
+ return {
996
+ level: 2,
997
+ label: "Confiance moyenne",
998
+ tone: "medium",
999
+ message: "Appuy\xE9 par des donn\xE9es terrain",
1000
+ impactFactor: 1
1001
+ };
1002
+ }
1003
+ return {
1004
+ level: 1,
1005
+ label: "Confiance faible",
1006
+ tone: "low",
1007
+ message: "Impact d\xE9claratif (pas encore de preuve mesur\xE9e)",
1008
+ impactFactor: 0.85
1009
+ };
1010
+ }
1011
+ return {
1012
+ level: 1,
1013
+ label: "Confiance faible",
1014
+ tone: "low",
1015
+ message: "Impact d\xE9claratif",
1016
+ impactFactor: 0.85
1017
+ };
1018
+ }
1019
+ function computeOverallConfidence(actionConfidences, opts) {
1020
+ if (opts?.annualBilanConfirmed) {
1021
+ return {
1022
+ level: 3,
1023
+ label: "Confiance \xE9lev\xE9e",
1024
+ tone: "high",
1025
+ message: "Bilan annuel consolid\xE9 (TGAP / exploitant / co\xFBt du service) \u2014 niveau d\xE9cideurs",
1026
+ impactFactor: 1
1027
+ };
1028
+ }
1029
+ if (actionConfidences.length === 0) {
1030
+ return {
1031
+ level: 1,
1032
+ label: "Confiance faible",
1033
+ tone: "low",
1034
+ message: "Aucune action active",
1035
+ impactFactor: 1
1036
+ };
1037
+ }
1038
+ const minLevel = Math.min(
1039
+ ...actionConfidences.map((c) => c.level)
1040
+ );
1041
+ if (minLevel === 1) {
1042
+ return {
1043
+ level: 1,
1044
+ label: "Confiance faible",
1045
+ tone: "low",
1046
+ message: "ROI en partie th\xE9orique \u2014 au moins une action sans preuve live",
1047
+ impactFactor: 1
1048
+ };
1049
+ }
1050
+ if (minLevel === 2) {
1051
+ return {
1052
+ level: 2,
1053
+ label: "Confiance moyenne",
1054
+ tone: "medium",
1055
+ message: "ROI appuy\xE9 par des proxies live",
1056
+ impactFactor: 1
1057
+ };
1058
+ }
1059
+ return {
1060
+ level: 3,
1061
+ label: "Confiance \xE9lev\xE9e",
1062
+ tone: "high",
1063
+ message: "ROI adoss\xE9 \xE0 des preuves repr\xE9sentatives",
1064
+ impactFactor: 1
1065
+ };
1066
+ }
1067
+ function computeRoiIndicators(economics, actions, live) {
1068
+ const baselineRate = economics.baselineErrorRatePercent ?? economics.errorRatePercent;
1069
+ const baselineTonnage = economics.baselineAnnualTonnageOmr ?? economics.annualTonnageOmr;
1070
+ const cost = economics.costPerBadTonne;
1071
+ const liveSignals = live ?? {
1072
+ penetrationRatePercent: 0,
1073
+ activeDevices30d: 0,
1074
+ validatedVisionScans: 0,
1075
+ challengeCompletions: 0,
1076
+ terrainResponses: 0
1077
+ };
1078
+ const before = computeGec(baselineTonnage, baselineRate, cost);
1079
+ const counted = actions.filter((a) => isActionCountedInRoi(a.status));
1080
+ const confidences = counted.map(
1081
+ (a) => computeActionImpactConfidence(a, liveSignals)
1082
+ );
1083
+ const reductions = counted.map((a, i) => {
1084
+ const factor = confidences[i]?.impactFactor ?? 1;
1085
+ return Math.max(0, a.errorReductionPercent) * factor;
1086
+ });
1087
+ const afterRate = reductions.length > 0 ? applyStackedErrorReductions(baselineRate, reductions) : economics.errorRatePercent;
1088
+ const combinedErrorReductionPoints = Math.round((baselineRate - afterRate) * 10) / 10;
1089
+ const combinedErrorReductionPercent = baselineRate > 0 ? Math.round((1 - afterRate / baselineRate) * 1e3) / 10 : 0;
1090
+ const after = computeGec(economics.annualTonnageOmr, afterRate, cost);
1091
+ const grossSavingsEur = roundEuro(before.gecEur - after.gecEur);
1092
+ const actionsBudgetEur = roundEuro(
1093
+ counted.reduce(
1094
+ (sum, a) => sum + (a.budgetCapexEur || 0) + (a.budgetOpexEur || 0),
1095
+ 0
1096
+ )
1097
+ );
1098
+ const wastoAnnualCostEur = roundEuro(economics.wastoAnnualCostEur ?? 0);
1099
+ const totalActionBudgetsEur = roundEuro(actionsBudgetEur + wastoAnnualCostEur);
1100
+ const isDomTerritory = economics.isDomTerritory === true;
1101
+ const citeo = applyCiteoDomMultiplier(
1102
+ economics.citeoSupportGainEur ?? 0,
1103
+ isDomTerritory
1104
+ );
1105
+ const cenEur = roundEuro(
1106
+ grossSavingsEur + citeo.effectiveEur - totalActionBudgetsEur
1107
+ );
1108
+ const roiMultiple = totalActionBudgetsEur > 0 ? Math.round(
1109
+ (grossSavingsEur + citeo.effectiveEur) / totalActionBudgetsEur * 10
1110
+ ) / 10 : null;
1111
+ const overallConfidence = computeOverallConfidence(confidences, {
1112
+ annualBilanConfirmed: economics.annualBilanConfirmed === true || liveSignals.annualBilanConfirmed === true
1113
+ });
1114
+ const stackingParts = reductions.map((r) => `(1 \u2212 ${Math.round(r * 10) / 10}/100)`).join(" \xD7 ");
1115
+ return {
1116
+ gecEur: before.gecEur,
1117
+ baselineBadTonnes: before.badTonnes,
1118
+ baselineErrorRatePercent: baselineRate,
1119
+ afterErrorRatePercent: afterRate,
1120
+ combinedErrorReductionPoints,
1121
+ combinedErrorReductionPercent,
1122
+ stackingFormula: reductions.length > 0 ? `taux_apr\xE8s = ${baselineRate} % \xD7 ${stackingParts}` : "Aucune r\xE9duction active",
1123
+ afterAnnualLossEur: after.gecEur,
1124
+ afterBadTonnes: after.badTonnes,
1125
+ grossSavingsEur,
1126
+ actionsBudgetEur,
1127
+ wastoAnnualCostEur,
1128
+ totalActionBudgetsEur,
1129
+ citeoSupportGainEur: citeo.effectiveEur,
1130
+ citeoSupportBaseEur: citeo.baseEur,
1131
+ citeoDomMultiplier: citeo.multiplier,
1132
+ isDomTerritory,
1133
+ cenEur,
1134
+ roiMultiple,
1135
+ overallConfidence,
1136
+ disclaimer: ROI_DISCLAIMER
1137
+ };
1138
+ }
1139
+ function allocateSavingsByAction(grossSavingsEur, actions, live) {
1140
+ const liveSignals = live ?? {
1141
+ penetrationRatePercent: 0,
1142
+ activeDevices30d: 0,
1143
+ validatedVisionScans: 0,
1144
+ challengeCompletions: 0,
1145
+ terrainResponses: 0
1146
+ };
1147
+ const counted = actions.filter((a) => isActionCountedInRoi(a.status));
1148
+ const enriched = counted.map((a) => {
1149
+ const confidence = computeActionImpactConfidence(a, liveSignals);
1150
+ return {
1151
+ action: a,
1152
+ confidence,
1153
+ effectiveReductionPercent: Math.max(0, a.errorReductionPercent) * confidence.impactFactor
1154
+ };
1155
+ });
1156
+ const totalReduction = enriched.reduce(
1157
+ (s, e) => s + e.effectiveReductionPercent,
1158
+ 0
1159
+ );
1160
+ if (totalReduction <= 0 || enriched.length === 0) {
1161
+ return enriched.map((e) => ({
1162
+ id: e.action.id,
1163
+ name: e.action.name,
1164
+ type: e.action.type,
1165
+ shareEur: 0,
1166
+ budgetEur: roundEuro(
1167
+ (e.action.budgetCapexEur || 0) + (e.action.budgetOpexEur || 0)
1168
+ ),
1169
+ confidence: e.confidence,
1170
+ effectiveReductionPercent: e.effectiveReductionPercent
1171
+ }));
1172
+ }
1173
+ return enriched.map((e) => {
1174
+ const weight = e.effectiveReductionPercent / totalReduction;
1175
+ return {
1176
+ id: e.action.id,
1177
+ name: e.action.name,
1178
+ type: e.action.type,
1179
+ shareEur: roundEuro(grossSavingsEur * weight),
1180
+ budgetEur: roundEuro(
1181
+ (e.action.budgetCapexEur || 0) + (e.action.budgetOpexEur || 0)
1182
+ ),
1183
+ confidence: e.confidence,
1184
+ effectiveReductionPercent: Math.round(e.effectiveReductionPercent * 10) / 10
1185
+ };
1186
+ });
1187
+ }
1188
+ function estimateHouseholds(householdCount, population) {
1189
+ if (householdCount && householdCount > 0) return householdCount;
1190
+ if (population && population > 0) {
1191
+ return Math.round(population / ROI_DEFAULTS.peoplePerHousehold);
1192
+ }
1193
+ return 0;
1194
+ }
1195
+ function computePenetrationRate(activeHouseholdsProxy, householdCount) {
1196
+ if (householdCount <= 0) return 0;
1197
+ return Math.round(activeHouseholdsProxy / householdCount * 1e3) / 10;
1198
+ }
1199
+ function simulateTerritory100kExample() {
1200
+ const economics = {
1201
+ annualTonnageOmr: 24e3,
1202
+ errorRatePercent: 25,
1203
+ costPerBadTonne: 300,
1204
+ wastoAnnualCostEur: 18e3,
1205
+ citeoSupportGainEur: 4e4,
1206
+ baselineErrorRatePercent: 25,
1207
+ baselineAnnualTonnageOmr: 24e3
1208
+ };
1209
+ const actions = [
1210
+ {
1211
+ id: "1",
1212
+ name: "Campagne sensibilisation",
1213
+ type: "AWARENESS",
1214
+ status: "IN_PROGRESS",
1215
+ budgetCapexEur: 0,
1216
+ budgetOpexEur: 12e3,
1217
+ errorReductionPercent: 12
1218
+ },
1219
+ {
1220
+ id: "2",
1221
+ name: "Contr\xF4les de bac",
1222
+ type: "CONTROLS",
1223
+ status: "IN_PROGRESS",
1224
+ budgetCapexEur: 5e3,
1225
+ budgetOpexEur: 35e3,
1226
+ errorReductionPercent: 18
1227
+ },
1228
+ {
1229
+ id: "3",
1230
+ name: "Wast-O app",
1231
+ type: "WASTO_APP",
1232
+ status: "IN_PROGRESS",
1233
+ budgetCapexEur: 0,
1234
+ budgetOpexEur: 0,
1235
+ errorReductionPercent: 20
1236
+ }
1237
+ ];
1238
+ const live = {
1239
+ penetrationRatePercent: 3,
1240
+ activeDevices30d: 1200,
1241
+ validatedVisionScans: 400,
1242
+ challengeCompletions: 80,
1243
+ terrainResponses: 50
1244
+ };
1245
+ const indicators = computeRoiIndicators(economics, actions, live);
1246
+ const households = estimateHouseholds(null, 1e5);
1247
+ return {
1248
+ population: 1e5,
1249
+ households,
1250
+ economics,
1251
+ actions,
1252
+ indicators,
1253
+ contributions: allocateSavingsByAction(
1254
+ indicators.grossSavingsEur,
1255
+ actions,
1256
+ live
1257
+ )
1258
+ };
1259
+ }
1260
+
1261
+ // src/opening-hours/types.ts
1262
+ var WEEKDAYS = [
1263
+ "monday",
1264
+ "tuesday",
1265
+ "wednesday",
1266
+ "thursday",
1267
+ "friday",
1268
+ "saturday",
1269
+ "sunday"
1270
+ ];
1271
+
1272
+ // src/opening-hours/constants.ts
1273
+ var WEEKDAY_REF_DATES = {
1274
+ monday: "2024-01-01",
1275
+ tuesday: "2024-01-02",
1276
+ wednesday: "2024-01-03",
1277
+ thursday: "2024-01-04",
1278
+ friday: "2024-01-05",
1279
+ saturday: "2024-01-06",
1280
+ sunday: "2024-01-07"
1281
+ };
1282
+ var WEEKDAY_LABELS_FR = {
1283
+ monday: "Lundi",
1284
+ tuesday: "Mardi",
1285
+ wednesday: "Mercredi",
1286
+ thursday: "Jeudi",
1287
+ friday: "Vendredi",
1288
+ saturday: "Samedi",
1289
+ sunday: "Dimanche"
1290
+ };
1291
+ var WEEKDAY_LABELS_FR_SHORT = {
1292
+ monday: "Lun",
1293
+ tuesday: "Mar",
1294
+ wednesday: "Mer",
1295
+ thursday: "Jeu",
1296
+ friday: "Ven",
1297
+ saturday: "Sam",
1298
+ sunday: "Dim"
1299
+ };
1300
+ var WEEKDAY_INDEX = {
1301
+ monday: 0,
1302
+ tuesday: 1,
1303
+ wednesday: 2,
1304
+ thursday: 3,
1305
+ friday: 4,
1306
+ saturday: 5,
1307
+ sunday: 6
1308
+ };
1309
+ var PRESET_SLOTS = {
1310
+ morning: { open: "08:00", close: "12:00" },
1311
+ afternoon: { open: "14:00", close: "18:00" },
1312
+ fullDay: { open: "08:00", close: "18:00" }
1313
+ };
1314
+
1315
+ // src/opening-hours/time.ts
1316
+ var TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)$/;
1317
+ function parseTimeMinutes(value) {
1318
+ const m = TIME_RE.exec(value.trim());
1319
+ if (!m) return null;
1320
+ return Number(m[1]) * 60 + Number(m[2]);
1321
+ }
1322
+ function formatTimeMinutes(totalMinutes) {
1323
+ const normalized = (totalMinutes % (24 * 60) + 24 * 60) % (24 * 60);
1324
+ const h = Math.floor(normalized / 60);
1325
+ const min = normalized % 60;
1326
+ return `${String(h).padStart(2, "0")}:${String(min).padStart(2, "0")}`;
1327
+ }
1328
+ function formatTimeDisplay(value) {
1329
+ const minutes = parseTimeMinutes(value);
1330
+ if (minutes == null) return value;
1331
+ const h = Math.floor(minutes / 60);
1332
+ const min = minutes % 60;
1333
+ return min === 0 ? `${h}h` : `${h}h${String(min).padStart(2, "0")}`;
1334
+ }
1335
+ function slotsOverlap(a, b) {
1336
+ const aOpen = parseTimeMinutes(a.open);
1337
+ const aClose = parseTimeMinutes(a.close);
1338
+ const bOpen = parseTimeMinutes(b.open);
1339
+ const bClose = parseTimeMinutes(b.close);
1340
+ if (aOpen == null || aClose == null || bOpen == null || bClose == null) return false;
1341
+ if (aClose <= aOpen || bClose <= bOpen) return false;
1342
+ return aOpen < bClose && bOpen < aClose;
1343
+ }
1344
+ function sortSlots(slots) {
1345
+ return [...slots].sort(
1346
+ (a, b) => (parseTimeMinutes(a.open) ?? 0) - (parseTimeMinutes(b.open) ?? 0)
1347
+ );
1348
+ }
1349
+ function nextWeekday(day) {
1350
+ const idx = (WEEKDAY_INDEX[day] + 1) % 7;
1351
+ return WEEKDAYS[idx];
1352
+ }
1353
+ function addDaysToIsoDate(isoDate, days) {
1354
+ const [y, mo, d] = isoDate.split("-").map(Number);
1355
+ const dt = new Date(Date.UTC(y, mo - 1, d + days));
1356
+ return dt.toISOString().slice(0, 10);
1357
+ }
1358
+ function weekdayFromUtcDate(date) {
1359
+ const jsDay = date.getUTCDay();
1360
+ const map = [
1361
+ "sunday",
1362
+ "monday",
1363
+ "tuesday",
1364
+ "wednesday",
1365
+ "thursday",
1366
+ "friday",
1367
+ "saturday"
1368
+ ];
1369
+ return map[jsDay];
1370
+ }
1371
+ function utcHhmmFromDate(date) {
1372
+ return formatTimeMinutes(date.getUTCHours() * 60 + date.getUTCMinutes());
1373
+ }
1374
+ function refDateForWeekday(day) {
1375
+ return WEEKDAY_REF_DATES[day];
1376
+ }
1377
+
1378
+ // src/opening-hours/timezone.ts
1379
+ function getTimezoneOffsetMinutes(timeZone, at) {
1380
+ const utc = new Date(at.toLocaleString("en-US", { timeZone: "UTC" }));
1381
+ const zoned = new Date(at.toLocaleString("en-US", { timeZone }));
1382
+ return (zoned.getTime() - utc.getTime()) / 6e4;
1383
+ }
1384
+ function localDateTimeToUtc(dateIso, time, timeZone) {
1385
+ const [y, mo, d] = dateIso.split("-").map(Number);
1386
+ const [h, mi] = time.split(":").map(Number);
1387
+ let utcMs = Date.UTC(y, mo - 1, d, h, mi, 0);
1388
+ for (let i = 0; i < 2; i++) {
1389
+ const offset = getTimezoneOffsetMinutes(timeZone, new Date(utcMs));
1390
+ utcMs = Date.UTC(y, mo - 1, d, h, mi, 0) - offset * 6e4;
1391
+ }
1392
+ return new Date(utcMs);
1393
+ }
1394
+ function getBrowserTimeZone() {
1395
+ try {
1396
+ return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
1397
+ } catch {
1398
+ return "UTC";
1399
+ }
1400
+ }
1401
+ function utcDateIso(at) {
1402
+ return at.toISOString().slice(0, 10);
1403
+ }
1404
+
1405
+ // src/opening-hours/validate.ts
1406
+ var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
1407
+ function isPlainObject(v) {
1408
+ return v != null && typeof v === "object" && !Array.isArray(v);
1409
+ }
1410
+ function validateTimeSlot(slot, path, errors) {
1411
+ if (!isPlainObject(slot)) {
1412
+ errors.push(`${path} : cr\xE9neau invalide`);
1413
+ return false;
1414
+ }
1415
+ const open = slot.open;
1416
+ const close = slot.close;
1417
+ if (typeof open !== "string" || parseTimeMinutes(open) == null) {
1418
+ errors.push(`${path}.open : heure invalide (HH:mm)`);
1419
+ return false;
1420
+ }
1421
+ if (typeof close !== "string" || parseTimeMinutes(close) == null) {
1422
+ errors.push(`${path}.close : heure invalide (HH:mm)`);
1423
+ return false;
1424
+ }
1425
+ const openMin = parseTimeMinutes(open);
1426
+ const closeMin = parseTimeMinutes(close);
1427
+ if (closeMin <= openMin) {
1428
+ errors.push(`${path} : l'heure de fermeture doit \xEAtre apr\xE8s l'ouverture (UTC)`);
1429
+ return false;
1430
+ }
1431
+ return true;
1432
+ }
1433
+ function validateRule(rule, index, errors) {
1434
+ if (!isPlainObject(rule)) {
1435
+ errors.push(`rules[${index}] : r\xE8gle invalide`);
1436
+ return false;
1437
+ }
1438
+ if (!Array.isArray(rule.days) || rule.days.length === 0) {
1439
+ errors.push(`rules[${index}].days : au moins un jour requis`);
1440
+ return false;
1441
+ }
1442
+ for (const day of rule.days) {
1443
+ if (typeof day !== "string" || !WEEKDAYS.includes(day)) {
1444
+ errors.push(`rules[${index}].days : jour invalide (${String(day)})`);
1445
+ }
1446
+ }
1447
+ if (!Array.isArray(rule.slots) || rule.slots.length === 0) {
1448
+ errors.push(`rules[${index}].slots : au moins un cr\xE9neau requis`);
1449
+ return false;
1450
+ }
1451
+ const slots = [];
1452
+ rule.slots.forEach((slot, slotIndex) => {
1453
+ if (validateTimeSlot(slot, `rules[${index}].slots[${slotIndex}]`, errors)) {
1454
+ slots.push(slot);
1455
+ }
1456
+ });
1457
+ const sorted = sortSlots(slots);
1458
+ for (let i = 0; i < sorted.length - 1; i++) {
1459
+ if (slotsOverlap(sorted[i], sorted[i + 1])) {
1460
+ errors.push(`rules[${index}].slots : cr\xE9neaux qui se chevauchent`);
1461
+ break;
1462
+ }
1463
+ }
1464
+ return errors.length === 0;
1465
+ }
1466
+ function validateException(exc, index, errors) {
1467
+ if (!isPlainObject(exc)) {
1468
+ errors.push(`exceptions[${index}] : exception invalide`);
1469
+ return false;
1470
+ }
1471
+ if (typeof exc.date !== "string" || !DATE_RE.test(exc.date)) {
1472
+ errors.push(`exceptions[${index}].date : date invalide (YYYY-MM-DD)`);
1473
+ return false;
1474
+ }
1475
+ if (exc.closed === true) return true;
1476
+ if (exc.closed === false) {
1477
+ if (!Array.isArray(exc.slots) || exc.slots.length === 0) {
1478
+ errors.push(`exceptions[${index}].slots : requis si non ferm\xE9`);
1479
+ return false;
1480
+ }
1481
+ exc.slots.forEach((slot, slotIndex) => {
1482
+ validateTimeSlot(slot, `exceptions[${index}].slots[${slotIndex}]`, errors);
1483
+ });
1484
+ return true;
1485
+ }
1486
+ errors.push(`exceptions[${index}].closed : bool\xE9en requis`);
1487
+ return false;
1488
+ }
1489
+ function validateOpeningHours(input) {
1490
+ const errors = [];
1491
+ if (!isPlainObject(input)) {
1492
+ return { ok: false, errors: ["Horaires : objet attendu"] };
1493
+ }
1494
+ if (input.version !== 1) {
1495
+ errors.push("version : doit \xEAtre 1");
1496
+ }
1497
+ if (input.storage !== "utc") {
1498
+ errors.push('storage : doit \xEAtre "utc"');
1499
+ }
1500
+ if (!Array.isArray(input.rules)) {
1501
+ errors.push("rules : tableau attendu");
1502
+ return { ok: false, errors };
1503
+ }
1504
+ input.rules.forEach((rule, index) => validateRule(rule, index, errors));
1505
+ const daySet = /* @__PURE__ */ new Set();
1506
+ if (Array.isArray(input.rules)) {
1507
+ for (const rule of input.rules) {
1508
+ if (!isPlainObject(rule) || !Array.isArray(rule.days)) continue;
1509
+ for (const day of rule.days) {
1510
+ if (typeof day === "string" && WEEKDAYS.includes(day)) {
1511
+ const wd = day;
1512
+ if (daySet.has(wd)) {
1513
+ errors.push(`rules : le jour ${wd} appara\xEEt dans plusieurs r\xE8gles`);
1514
+ }
1515
+ daySet.add(wd);
1516
+ }
1517
+ }
1518
+ }
1519
+ }
1520
+ if (input.exceptions != null) {
1521
+ if (!Array.isArray(input.exceptions)) {
1522
+ errors.push("exceptions : tableau attendu");
1523
+ } else {
1524
+ input.exceptions.forEach((exc, index) => validateException(exc, index, errors));
1525
+ }
1526
+ }
1527
+ if (errors.length > 0) {
1528
+ return { ok: false, errors };
1529
+ }
1530
+ return {
1531
+ ok: true,
1532
+ value: {
1533
+ version: 1,
1534
+ storage: "utc",
1535
+ rules: input.rules.map((r) => ({
1536
+ days: [...r.days],
1537
+ slots: sortSlots([...r.slots])
1538
+ })),
1539
+ exceptions: input.exceptions
1540
+ }
1541
+ };
1542
+ }
1543
+ function validateLocalOpeningHours(input) {
1544
+ return validateOpeningHours({
1545
+ version: 1,
1546
+ storage: "utc",
1547
+ rules: input.rules,
1548
+ exceptions: input.exceptions
1549
+ });
1550
+ }
1551
+ function createEmptyOpeningHours() {
1552
+ return { version: 1, storage: "utc", rules: [] };
1553
+ }
1554
+ function createEmptyLocalRules() {
1555
+ return [];
1556
+ }
1557
+
1558
+ // src/opening-hours/convert.ts
1559
+ function addSlotToMap(map, day, slot) {
1560
+ const existing = map.get(day) ?? [];
1561
+ existing.push(slot);
1562
+ map.set(day, existing);
1563
+ }
1564
+ function mergeSlots(slots) {
1565
+ const sorted = sortSlots(slots);
1566
+ const merged = [];
1567
+ for (const slot of sorted) {
1568
+ const last = merged[merged.length - 1];
1569
+ if (last && last.close === slot.open) {
1570
+ merged[merged.length - 1] = { open: last.open, close: slot.close };
1571
+ } else {
1572
+ merged.push({ ...slot });
1573
+ }
1574
+ }
1575
+ return merged.filter((s) => {
1576
+ const o = parseTimeMinutes(s.open);
1577
+ const c = parseTimeMinutes(s.close);
1578
+ return o != null && c != null && c > o;
1579
+ });
1580
+ }
1581
+ function mapToRules(map) {
1582
+ const rules = [];
1583
+ for (const day of WEEKDAYS) {
1584
+ const slots = map.get(day);
1585
+ if (!slots?.length) continue;
1586
+ rules.push({ days: [day], slots: mergeSlots(slots) });
1587
+ }
1588
+ return coalesceDayRules(rules);
1589
+ }
1590
+ function coalesceDayRules(rules) {
1591
+ const bySignature = /* @__PURE__ */ new Map();
1592
+ for (const rule of rules) {
1593
+ const sig = JSON.stringify(rule.slots);
1594
+ const days = bySignature.get(sig) ?? [];
1595
+ days.push(...rule.days);
1596
+ bySignature.set(sig, days);
1597
+ }
1598
+ const out = [];
1599
+ for (const [sig, days] of bySignature) {
1600
+ out.push({
1601
+ days: sortWeekdays([...new Set(days)]),
1602
+ slots: JSON.parse(sig)
1603
+ });
1604
+ }
1605
+ return out;
1606
+ }
1607
+ function sortWeekdays(days) {
1608
+ const order = new Map(WEEKDAYS.map((d, i) => [d, i]));
1609
+ return [...days].sort((a, b) => (order.get(a) ?? 0) - (order.get(b) ?? 0));
1610
+ }
1611
+ function convertLocalSlotToUtcFixed(map, localDay, slot, timeZone) {
1612
+ const openMin = parseTimeMinutes(slot.open);
1613
+ const closeMin = parseTimeMinutes(slot.close);
1614
+ if (openMin == null || closeMin == null) return;
1615
+ const openDate = refDateForWeekday(localDay);
1616
+ let closeDate = openDate;
1617
+ const closeTime = slot.close;
1618
+ if (closeMin <= openMin) {
1619
+ closeDate = addDaysToIsoDate(openDate, 1);
1620
+ }
1621
+ const openUtc = localDateTimeToUtc(openDate, slot.open, timeZone);
1622
+ const closeUtc = localDateTimeToUtc(closeDate, closeTime, timeZone);
1623
+ const openDay = weekdayFromUtcDate(openUtc);
1624
+ const closeDay = weekdayFromUtcDate(closeUtc);
1625
+ const openStr = utcHhmmFromDate(openUtc);
1626
+ const closeStr = utcHhmmFromDate(closeUtc);
1627
+ if (openDay === closeDay) {
1628
+ if (openStr !== closeStr) {
1629
+ addSlotToMap(map, openDay, { open: openStr, close: closeStr });
1630
+ }
1631
+ return;
1632
+ }
1633
+ addSlotToMap(map, openDay, { open: openStr, close: "23:59" });
1634
+ if (closeStr !== "00:00") {
1635
+ addSlotToMap(map, closeDay, { open: "00:00", close: closeStr });
1636
+ }
1637
+ }
1638
+ function convertUtcSlotToLocal(map, utcDay, slot, timeZone) {
1639
+ const openMin = parseTimeMinutes(slot.open);
1640
+ const closeMin = parseTimeMinutes(slot.close);
1641
+ if (openMin == null || closeMin == null) return;
1642
+ const openDate = refDateForWeekday(utcDay);
1643
+ let closeDate = openDate;
1644
+ const closeTime = slot.close;
1645
+ if (closeMin <= openMin) {
1646
+ closeDate = addDaysToIsoDate(openDate, 1);
1647
+ }
1648
+ const openUtc = /* @__PURE__ */ new Date(`${openDate}T${slot.open}:00.000Z`);
1649
+ const closeUtc = /* @__PURE__ */ new Date(`${closeDate}T${closeTime}:00.000Z`);
1650
+ const openLocal = formatZoned(openUtc, timeZone);
1651
+ const closeLocal = formatZoned(closeUtc, timeZone);
1652
+ if (openLocal.day === closeLocal.day) {
1653
+ if (openLocal.time !== closeLocal.time) {
1654
+ addSlotToMap(map, openLocal.day, { open: openLocal.time, close: closeLocal.time });
1655
+ }
1656
+ return;
1657
+ }
1658
+ addSlotToMap(map, openLocal.day, { open: openLocal.time, close: "23:59" });
1659
+ if (closeLocal.time !== "00:00") {
1660
+ addSlotToMap(map, closeLocal.day, { open: "00:00", close: closeLocal.time });
1661
+ }
1662
+ }
1663
+ function formatZoned(utc, timeZone) {
1664
+ const parts = new Intl.DateTimeFormat("en-US", {
1665
+ timeZone,
1666
+ weekday: "long",
1667
+ hour: "2-digit",
1668
+ minute: "2-digit",
1669
+ hour12: false
1670
+ }).formatToParts(utc);
1671
+ const weekdayRaw = parts.find((p) => p.type === "weekday")?.value?.toLowerCase();
1672
+ const hour = parts.find((p) => p.type === "hour")?.value ?? "00";
1673
+ const minute = parts.find((p) => p.type === "minute")?.value ?? "00";
1674
+ const dayMap = {
1675
+ monday: "monday",
1676
+ tuesday: "tuesday",
1677
+ wednesday: "wednesday",
1678
+ thursday: "thursday",
1679
+ friday: "friday",
1680
+ saturday: "saturday",
1681
+ sunday: "sunday"
1682
+ };
1683
+ const day = dayMap[weekdayRaw ?? "monday"] ?? "monday";
1684
+ return { day, time: `${hour.padStart(2, "0")}:${minute.padStart(2, "0")}` };
1685
+ }
1686
+ function convertLocalToUtc(local, timeZone) {
1687
+ const map = /* @__PURE__ */ new Map();
1688
+ for (const rule of local.rules) {
1689
+ for (const day of rule.days) {
1690
+ for (const slot of rule.slots) {
1691
+ convertLocalSlotToUtcFixed(map, day, slot, timeZone);
1692
+ }
1693
+ }
1694
+ }
1695
+ const exceptions = local.exceptions?.map((exc) => {
1696
+ if (exc.closed) return exc;
1697
+ const excMap = /* @__PURE__ */ new Map();
1698
+ for (const slot of exc.slots) {
1699
+ convertLocalSlotToUtcFixed(excMap, "monday", slot, timeZone);
1700
+ }
1701
+ const merged = [...excMap.values()].flat();
1702
+ return { ...exc, slots: merged.length ? mergeSlots(merged) : exc.slots };
1703
+ });
1704
+ return {
1705
+ version: 1,
1706
+ storage: "utc",
1707
+ rules: mapToRules(map),
1708
+ exceptions
1709
+ };
1710
+ }
1711
+ function convertUtcToLocal(utc, timeZone) {
1712
+ const map = /* @__PURE__ */ new Map();
1713
+ for (const rule of utc.rules) {
1714
+ for (const day of rule.days) {
1715
+ for (const slot of rule.slots) {
1716
+ convertUtcSlotToLocal(map, day, slot, timeZone);
1717
+ }
1718
+ }
1719
+ }
1720
+ const exceptions = utc.exceptions?.map((exc) => {
1721
+ if (exc.closed) return exc;
1722
+ const excMap = /* @__PURE__ */ new Map();
1723
+ for (const slot of exc.slots) {
1724
+ convertUtcSlotToLocal(excMap, "monday", slot, timeZone);
1725
+ }
1726
+ const merged = [...excMap.values()].flat();
1727
+ return { ...exc, slots: merged.length ? mergeSlots(merged) : exc.slots };
1728
+ });
1729
+ return {
1730
+ rules: mapToRules(map),
1731
+ exceptions
1732
+ };
1733
+ }
1734
+ function localRulesFromRange(fromDay, toDay, slots, exceptDays = []) {
1735
+ const fromIdx = WEEKDAYS.indexOf(fromDay);
1736
+ const toIdx = WEEKDAYS.indexOf(toDay);
1737
+ const except = new Set(exceptDays);
1738
+ const days = [];
1739
+ if (fromIdx <= toIdx) {
1740
+ for (let i = fromIdx; i <= toIdx; i++) {
1741
+ const d = WEEKDAYS[i];
1742
+ if (!except.has(d)) days.push(d);
1743
+ }
1744
+ } else {
1745
+ for (let i = fromIdx; i < 7; i++) {
1746
+ const d = WEEKDAYS[i];
1747
+ if (!except.has(d)) days.push(d);
1748
+ }
1749
+ for (let i = 0; i <= toIdx; i++) {
1750
+ const d = WEEKDAYS[i];
1751
+ if (!except.has(d)) days.push(d);
1752
+ }
1753
+ }
1754
+ return { days, slots: [...slots] };
1755
+ }
1756
+
1757
+ // src/opening-hours/format.ts
1758
+ function formatSlots(slots) {
1759
+ return slots.map((s) => `${formatTimeDisplay(s.open)}\u2013${formatTimeDisplay(s.close)}`).join(", ");
1760
+ }
1761
+ function compressDayRanges(days) {
1762
+ if (days.length === 0) return [];
1763
+ const order = new Map(WEEKDAYS.map((d, i) => [d, i]));
1764
+ const sorted = [...days].sort((a, b) => (order.get(a) ?? 0) - (order.get(b) ?? 0));
1765
+ const ranges = [];
1766
+ let start = sorted[0];
1767
+ let prev = sorted[0];
1768
+ let prevIdx = order.get(prev) ?? 0;
1769
+ const flush = (from, to) => {
1770
+ if (from === to) {
1771
+ ranges.push(WEEKDAY_LABELS_FR_SHORT[from]);
1772
+ } else {
1773
+ ranges.push(`${WEEKDAY_LABELS_FR_SHORT[from]}\u2013${WEEKDAY_LABELS_FR_SHORT[to]}`);
1774
+ }
1775
+ };
1776
+ for (let i = 1; i < sorted.length; i++) {
1777
+ const day = sorted[i];
1778
+ const idx = order.get(day) ?? 0;
1779
+ if (idx === prevIdx + 1) {
1780
+ prev = day;
1781
+ prevIdx = idx;
1782
+ } else {
1783
+ flush(start, prev);
1784
+ start = day;
1785
+ prev = day;
1786
+ prevIdx = idx;
1787
+ }
1788
+ }
1789
+ flush(start, prev);
1790
+ return ranges;
1791
+ }
1792
+ function formatRulesSummary(rules) {
1793
+ const parts = [];
1794
+ for (const rule of rules) {
1795
+ if (!rule.days.length || !rule.slots.length) continue;
1796
+ const dayPart = compressDayRanges(rule.days).join(", ");
1797
+ const slotPart = formatSlots(rule.slots);
1798
+ parts.push(`${dayPart} ${slotPart}`);
1799
+ }
1800
+ return parts.join(" \xB7 ");
1801
+ }
1802
+ function formatOpeningHoursSummary(hours, timeZone) {
1803
+ const rules = "storage" in hours && hours.storage === "utc" && timeZone ? convertUtcToLocal(hours, timeZone).rules : hours.rules;
1804
+ return formatRulesSummary(rules);
1805
+ }
1806
+ function formatOpeningHoursWeekly(hours, timeZone) {
1807
+ const rules = timeZone != null ? convertUtcToLocal(hours, timeZone).rules : hours.rules;
1808
+ const byDay = /* @__PURE__ */ new Map();
1809
+ for (const rule of rules) {
1810
+ for (const day of rule.days) {
1811
+ const existing = byDay.get(day) ?? [];
1812
+ byDay.set(day, [...existing, ...rule.slots]);
1813
+ }
1814
+ }
1815
+ return WEEKDAYS.map((day) => {
1816
+ const slots = byDay.get(day) ?? [];
1817
+ return {
1818
+ day,
1819
+ label: WEEKDAY_LABELS_FR[day],
1820
+ closed: slots.length === 0,
1821
+ slots
1822
+ };
1823
+ });
1824
+ }
1825
+ function formatWeeklyRow(row) {
1826
+ if (row.closed) return "Ferm\xE9";
1827
+ return formatSlots(row.slots);
1828
+ }
1829
+
1830
+ // src/opening-hours/resolve.ts
1831
+ function resolveHoursMode(details) {
1832
+ if (!details) return "text";
1833
+ const mode = details.hoursMode;
1834
+ if (mode === "structured" || mode === "text") return mode;
1835
+ if (details.openingHours != null) return "structured";
1836
+ return "text";
1837
+ }
1838
+ function resolveOpeningHoursUtc(point) {
1839
+ const details = point.details;
1840
+ if (!details || resolveHoursMode(details) !== "structured") return null;
1841
+ const raw = details.openingHours;
1842
+ if (!raw || typeof raw !== "object") return null;
1843
+ return raw;
1844
+ }
1845
+ function resolveOpeningHoursLocal(point, timeZone) {
1846
+ const utc = resolveOpeningHoursUtc(point);
1847
+ if (!utc) return null;
1848
+ const tz = timeZone ?? getBrowserTimeZone();
1849
+ return convertUtcToLocal(utc, tz);
1850
+ }
1851
+ function resolveHoursText(point) {
1852
+ const details = point.details;
1853
+ if (resolveHoursMode(details) === "text") {
1854
+ const fromDetails = details?.hours;
1855
+ if (typeof fromDetails === "string" && fromDetails.trim()) return fromDetails.trim();
1856
+ if (typeof point.hours === "string" && point.hours.trim()) return point.hours.trim();
1857
+ return null;
1858
+ }
1859
+ return null;
1860
+ }
1861
+ function resolveHoursDisplay(point, timeZone) {
1862
+ const text = resolveHoursText(point);
1863
+ if (text) return text;
1864
+ const utc = resolveOpeningHoursUtc(point);
1865
+ if (!utc) {
1866
+ if (typeof point.hours === "string" && point.hours.trim()) return point.hours.trim();
1867
+ return null;
1868
+ }
1869
+ const tz = timeZone ?? getBrowserTimeZone();
1870
+ const summary = formatOpeningHoursSummary(utc, tz);
1871
+ return summary || null;
1872
+ }
1873
+ function resolveHoursModeFromPoint(point) {
1874
+ return resolveHoursMode(point.details ?? void 0);
1875
+ }
1876
+
1877
+ // src/opening-hours/is-open-now.ts
1878
+ function isOpenNow(hours, at = /* @__PURE__ */ new Date()) {
1879
+ const dateIso = utcDateIso(at);
1880
+ const exceptions = hours.exceptions ?? [];
1881
+ for (const exc of exceptions) {
1882
+ if (exc.date !== dateIso) continue;
1883
+ if (exc.closed) return false;
1884
+ return isWithinSlots(exc.slots, at);
1885
+ }
1886
+ const weekday = weekdayFromUtcDate(at);
1887
+ const rules = hours.rules.filter((r) => r.days.includes(weekday));
1888
+ for (const rule of rules) {
1889
+ if (isWithinSlots(rule.slots, at)) return true;
1890
+ }
1891
+ return false;
1892
+ }
1893
+ function isWithinSlots(slots, at) {
1894
+ const nowMin = at.getUTCHours() * 60 + at.getUTCMinutes();
1895
+ for (const slot of slots) {
1896
+ const open = parseTimeMinutes(slot.open);
1897
+ const close = parseTimeMinutes(slot.close);
1898
+ if (open == null || close == null) continue;
1899
+ if (nowMin >= open && nowMin < close) return true;
1900
+ }
1901
+ return false;
1902
+ }
1903
+ function openNowLabel(hours, at) {
1904
+ return isOpenNow(hours, at) ? "Ouvert" : "Ferm\xE9";
1905
+ }
1906
+
1907
+ // src/client.ts
1908
+ var WastoApiError = class extends Error {
1909
+ constructor(message, status, body) {
1910
+ super(message);
1911
+ this.status = status;
1912
+ this.body = body;
1913
+ this.name = "WastoApiError";
1914
+ }
1915
+ };
1916
+ function getHeaders(config, init) {
1917
+ const token = config.getToken?.();
1918
+ const headers = {
1919
+ ...config.defaultHeaders ?? {},
1920
+ ...init
1921
+ };
1922
+ if (token) {
1923
+ headers["Authorization"] = `Bearer ${token}`;
1924
+ }
1925
+ const body = init?.body;
1926
+ if (!headers["Content-Type"] && !(typeof FormData !== "undefined" && body instanceof FormData)) {
1927
+ headers["Content-Type"] = "application/json";
1928
+ }
1929
+ return headers;
1930
+ }
1931
+ async function handleResponse(res) {
1932
+ if (!res.ok) {
1933
+ let message = `HTTP ${res.status}`;
1934
+ try {
1935
+ const text = await res.text();
1936
+ if (text) {
1937
+ try {
1938
+ const json = JSON.parse(text);
1939
+ message = json.message ?? json.error ?? text;
1940
+ } catch {
1941
+ message = text;
1942
+ }
1943
+ }
1944
+ } catch {
1945
+ }
1946
+ throw new WastoApiError(message, res.status, void 0);
1947
+ }
1948
+ const contentType = res.headers.get("content-type");
1949
+ if (contentType?.includes("application/json")) {
1950
+ return res.json();
1951
+ }
1952
+ return res.text();
1953
+ }
1954
+ function createWastoClient(config) {
1955
+ const base = config.baseUrl.replace(/\/$/, "");
1956
+ const notifyRequestError = (err, context) => {
1957
+ if (!config.onRequestError) return;
1958
+ const error = err instanceof Error ? err : new Error(String(err));
1959
+ const status = context.status ?? (error instanceof WastoApiError ? error.status : void 0);
1960
+ try {
1961
+ config.onRequestError(error, {
1962
+ method: context.method,
1963
+ url: context.url,
1964
+ path: context.path,
1965
+ status
1966
+ });
1967
+ } catch {
1968
+ }
1969
+ };
1970
+ const request = async (path, options = {}) => {
1971
+ const url = path.startsWith("http") ? path : `${base}${path.startsWith("/") ? path : `/${path}`}`;
1972
+ const method = (options.method ?? "GET").toUpperCase();
1973
+ try {
1974
+ const res = await fetch(url, {
1975
+ ...options,
1976
+ headers: getHeaders(config, options.headers)
1977
+ });
1978
+ return await handleResponse(res);
1979
+ } catch (err) {
1980
+ notifyRequestError(err, { method, url, path });
1981
+ throw err;
1982
+ }
1983
+ };
1984
+ const requestPublic = async (path, options = {}) => {
1985
+ const url = path.startsWith("http") ? path : `${base}${path.startsWith("/") ? path : `/${path}`}`;
1986
+ const method = (options.method ?? "GET").toUpperCase();
1987
+ const headers = {
1988
+ ...options.headers
1989
+ };
1990
+ const body = options?.body;
1991
+ if (!headers["Content-Type"] && !(typeof FormData !== "undefined" && body instanceof FormData)) {
1992
+ headers["Content-Type"] = "application/json";
1993
+ }
1994
+ try {
1995
+ const res = await fetch(url, { ...options, headers });
1996
+ return await handleResponse(res);
1997
+ } catch (err) {
1998
+ notifyRequestError(err, { method, url, path });
1999
+ throw err;
2000
+ }
2001
+ };
2002
+ return {
2003
+ request,
2004
+ auth: {
2005
+ login: (email, password) => request("/auth/login", {
2006
+ method: "POST",
2007
+ body: JSON.stringify({ email, password })
2008
+ }),
2009
+ register: (data) => request("/auth/register", {
2010
+ method: "POST",
2011
+ body: JSON.stringify(data)
2012
+ }),
2013
+ forgotPassword: (email) => request("/auth/forgot-password", {
2014
+ method: "POST",
2015
+ body: JSON.stringify({ email })
2016
+ }),
2017
+ resetPassword: (token, password) => request("/auth/reset-password", {
2018
+ method: "POST",
2019
+ body: JSON.stringify({ token, password })
2020
+ }),
2021
+ acceptInvite: (data) => request("/auth/accept-invite", {
2022
+ method: "POST",
2023
+ body: JSON.stringify(data)
2024
+ }),
2025
+ verify2fa: (pendingToken, code) => request("/auth/verify-2fa", {
2026
+ method: "POST",
2027
+ body: JSON.stringify({ pendingToken, code })
2028
+ })
2029
+ },
2030
+ users: {
2031
+ findAll: (params) => {
2032
+ const q = new URLSearchParams();
2033
+ if (params?.page != null) q.set("page", String(params.page));
2034
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2035
+ const query = q.toString();
2036
+ return request(`/users${query ? `?${query}` : ""}`);
2037
+ },
2038
+ getById: (id) => request(`/users/${id}`),
2039
+ getMe: () => request("/users/me"),
2040
+ create: (data) => request("/users", { method: "POST", body: JSON.stringify(data) }),
2041
+ invite: (data) => request("/users/invite", { method: "POST", body: JSON.stringify(data) }),
2042
+ update: (id, data) => request(`/users/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
2043
+ updateMe: (data) => request("/users/me", { method: "PATCH", body: JSON.stringify(data) }),
2044
+ remove: (id) => request(`/users/${id}`, { method: "DELETE" })
2045
+ },
2046
+ assets: {
2047
+ findAll: (params) => {
2048
+ const q = new URLSearchParams();
2049
+ if (params?.page != null) q.set("page", String(params.page));
2050
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2051
+ if (params?.cityId) q.set("cityId", params.cityId);
2052
+ if (params?.cityGroupId) q.set("cityGroupId", params.cityGroupId);
2053
+ if (params?.type) q.set("type", params.type);
2054
+ if (params?.status) q.set("status", params.status);
2055
+ const query = q.toString();
2056
+ return request(`/assets${query ? `?${query}` : ""}`);
2057
+ },
2058
+ getMapLocations: (params) => {
2059
+ const q = new URLSearchParams();
2060
+ if (params?.page != null) q.set("page", String(params.page));
2061
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2062
+ if (params?.cityId) q.set("cityId", params.cityId);
2063
+ if (params?.cityGroupId) q.set("cityGroupId", params.cityGroupId);
2064
+ if (params?.type) q.set("type", params.type);
2065
+ if (params?.status) q.set("status", params.status);
2066
+ const query = q.toString();
2067
+ return request(`/assets/map/locations${query ? `?${query}` : ""}`);
2068
+ },
2069
+ getById: (id) => request(`/assets/${id}`),
2070
+ create: (data) => request("/assets", { method: "POST", body: JSON.stringify(data) }),
2071
+ update: (id, data) => request(`/assets/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
2072
+ remove: (id) => request(`/assets/${id}`, { method: "DELETE" })
2073
+ },
2074
+ cities: {
2075
+ findAll: (params) => {
2076
+ const q = new URLSearchParams();
2077
+ if (params?.page != null) q.set("page", String(params.page));
2078
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2079
+ const query = q.toString();
2080
+ return request(`/cities${query ? `?${query}` : ""}`);
2081
+ },
2082
+ getById: (id) => request(`/cities/${id}`),
2083
+ create: (data) => request("/cities", { method: "POST", body: JSON.stringify(data) }),
2084
+ update: (id, data) => request(`/cities/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
2085
+ remove: (id) => request(`/cities/${id}`, { method: "DELETE" }),
2086
+ wasteTypes: (cityId) => ({
2087
+ /** @deprecated Préférez cityGroups.wasteTypes pour la gestion du catalogue. */
2088
+ list: (params) => {
2089
+ const q = new URLSearchParams();
2090
+ if (params?.page != null) q.set("page", String(params.page));
2091
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2092
+ const query = q.toString();
2093
+ return request(`/cities/${cityId}/waste-types${query ? `?${query}` : ""}`);
2094
+ },
2095
+ /** @deprecated Préférez cityGroups.wasteTypes.create */
2096
+ create: (data) => request(`/cities/${cityId}/waste-types`, {
2097
+ method: "POST",
2098
+ body: JSON.stringify(data)
2099
+ }),
2100
+ getById: (id) => request(`/cities/${cityId}/waste-types/${id}`),
2101
+ /** @deprecated Préférez cityGroups.wasteTypes.update */
2102
+ update: (id, data) => request(`/cities/${cityId}/waste-types/${id}`, {
2103
+ method: "PATCH",
2104
+ body: JSON.stringify(data)
2105
+ }),
2106
+ /** @deprecated Délie la ville ; préférez cityGroups.wasteTypes.unlinkCity ou remove */
2107
+ remove: (id) => request(`/cities/${cityId}/waste-types/${id}`, {
2108
+ method: "DELETE"
2109
+ })
2110
+ }),
2111
+ wasteCollectionPlaces: (cityId) => ({
2112
+ list: (params) => {
2113
+ const q = new URLSearchParams();
2114
+ if (params?.page != null) q.set("page", String(params.page));
2115
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2116
+ const query = q.toString();
2117
+ return request(`/cities/${cityId}/waste-collection-places${query ? `?${query}` : ""}`);
2118
+ },
2119
+ create: (data) => request(`/cities/${cityId}/waste-collection-places`, {
2120
+ method: "POST",
2121
+ body: JSON.stringify(data)
2122
+ }),
2123
+ getById: (id) => request(`/cities/${cityId}/waste-collection-places/${id}`),
2124
+ update: (id, data) => request(`/cities/${cityId}/waste-collection-places/${id}`, {
2125
+ method: "PATCH",
2126
+ body: JSON.stringify(data)
2127
+ }),
2128
+ remove: (id) => request(`/cities/${cityId}/waste-collection-places/${id}`, {
2129
+ method: "DELETE"
2130
+ })
2131
+ }),
2132
+ quizQuestions: (cityId) => ({
2133
+ list: (params) => {
2134
+ const q = new URLSearchParams();
2135
+ if (params?.page != null) q.set("page", String(params.page));
2136
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2137
+ const query = q.toString();
2138
+ return request(`/cities/${cityId}/quiz-questions${query ? `?${query}` : ""}`);
2139
+ },
2140
+ create: (data) => request(`/cities/${cityId}/quiz-questions`, {
2141
+ method: "POST",
2142
+ body: JSON.stringify(data)
2143
+ }),
2144
+ getById: (id) => request(`/cities/${cityId}/quiz-questions/${id}`),
2145
+ update: (id, data) => request(`/cities/${cityId}/quiz-questions/${id}`, {
2146
+ method: "PATCH",
2147
+ body: JSON.stringify(data)
2148
+ }),
2149
+ remove: (id) => request(`/cities/${cityId}/quiz-questions/${id}`, {
2150
+ method: "DELETE"
2151
+ })
2152
+ }),
2153
+ recyclingPoints: (cityId) => ({
2154
+ list: (params) => {
2155
+ const q = new URLSearchParams();
2156
+ if (params?.page != null) q.set("page", String(params.page));
2157
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2158
+ const query = q.toString();
2159
+ return request(`/cities/${cityId}/recycling-points${query ? `?${query}` : ""}`);
2160
+ },
2161
+ create: (data) => request(`/cities/${cityId}/recycling-points`, {
2162
+ method: "POST",
2163
+ body: JSON.stringify(data)
2164
+ }),
2165
+ getById: (id) => request(`/cities/${cityId}/recycling-points/${id}`),
2166
+ update: (id, data) => request(`/cities/${cityId}/recycling-points/${id}`, {
2167
+ method: "PATCH",
2168
+ body: JSON.stringify(data)
2169
+ }),
2170
+ remove: (id) => request(`/cities/${cityId}/recycling-points/${id}`, {
2171
+ method: "DELETE"
2172
+ })
2173
+ })
2174
+ },
2175
+ wasteTypeDetails: (wasteTypeId) => ({
2176
+ list: (params) => {
2177
+ const q = new URLSearchParams();
2178
+ if (params?.page != null) q.set("page", String(params.page));
2179
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2180
+ const query = q.toString();
2181
+ return request(`/waste-types/${wasteTypeId}/details${query ? `?${query}` : ""}`);
2182
+ },
2183
+ create: (data) => request(`/waste-types/${wasteTypeId}/details`, {
2184
+ method: "POST",
2185
+ body: JSON.stringify(data)
2186
+ }),
2187
+ update: (id, data) => request(`/waste-types/${wasteTypeId}/details/${id}`, {
2188
+ method: "PATCH",
2189
+ body: JSON.stringify(data)
2190
+ }),
2191
+ remove: (id) => request(`/waste-types/${wasteTypeId}/details/${id}`, {
2192
+ method: "DELETE"
2193
+ })
2194
+ }),
2195
+ cityGroups: {
2196
+ findAll: (params) => {
2197
+ const q = new URLSearchParams();
2198
+ if (params?.page != null) q.set("page", String(params.page));
2199
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2200
+ const query = q.toString();
2201
+ return request(`/city-groups${query ? `?${query}` : ""}`);
2202
+ },
2203
+ getById: (id) => request(`/city-groups/${id}`),
2204
+ create: (data) => request("/city-groups", { method: "POST", body: JSON.stringify(data) }),
2205
+ update: (id, data) => request(`/city-groups/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
2206
+ remove: (id) => request(`/city-groups/${id}`, { method: "DELETE" }),
2207
+ wasteTypes: (cityGroupId) => ({
2208
+ list: (params) => {
2209
+ const q = new URLSearchParams();
2210
+ if (params?.page != null) q.set("page", String(params.page));
2211
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2212
+ const query = q.toString();
2213
+ return request(
2214
+ `/city-groups/${cityGroupId}/waste-types${query ? `?${query}` : ""}`
2215
+ );
2216
+ },
2217
+ getById: (id) => request(`/city-groups/${cityGroupId}/waste-types/${id}`),
2218
+ create: (data) => request(`/city-groups/${cityGroupId}/waste-types`, {
2219
+ method: "POST",
2220
+ body: JSON.stringify(data)
2221
+ }),
2222
+ update: (id, data) => request(`/city-groups/${cityGroupId}/waste-types/${id}`, {
2223
+ method: "PATCH",
2224
+ body: JSON.stringify(data)
2225
+ }),
2226
+ remove: (id) => request(`/city-groups/${cityGroupId}/waste-types/${id}`, {
2227
+ method: "DELETE"
2228
+ }),
2229
+ linkCity: (wasteTypeId, cityId) => request(
2230
+ `/city-groups/${cityGroupId}/waste-types/${wasteTypeId}/cities/${cityId}`,
2231
+ { method: "POST" }
2232
+ ),
2233
+ unlinkCity: (wasteTypeId, cityId) => request(
2234
+ `/city-groups/${cityGroupId}/waste-types/${wasteTypeId}/cities/${cityId}`,
2235
+ { method: "DELETE" }
2236
+ )
2237
+ })
2238
+ },
2239
+ public: {
2240
+ cities: {
2241
+ findAll: (params) => {
2242
+ const q = new URLSearchParams();
2243
+ if (params?.page != null) q.set("page", String(params.page));
2244
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2245
+ const query = q.toString();
2246
+ return requestPublic(`/public/cities${query ? `?${query}` : ""}`);
2247
+ },
2248
+ getById: (id) => requestPublic(`/public/cities/${id}`),
2249
+ getWasteTypes: (cityId, params) => {
2250
+ const q = new URLSearchParams();
2251
+ if (params?.page != null) q.set("page", String(params.page));
2252
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2253
+ const query = q.toString();
2254
+ return requestPublic(`/public/cities/${encodeURIComponent(cityId)}/waste-types${query ? `?${query}` : ""}`);
2255
+ },
2256
+ getWasteCollectionPlaces: (cityId, params) => {
2257
+ const q = new URLSearchParams();
2258
+ if (params?.page != null) q.set("page", String(params.page));
2259
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2260
+ const query = q.toString();
2261
+ return requestPublic(`/public/cities/${encodeURIComponent(cityId)}/waste-collection-places${query ? `?${query}` : ""}`);
2262
+ },
2263
+ getRecyclingPoints: (cityId, params) => {
2264
+ const q = new URLSearchParams();
2265
+ if (params?.page != null) q.set("page", String(params.page));
2266
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2267
+ const query = q.toString();
2268
+ return requestPublic(`/public/cities/${encodeURIComponent(cityId)}/recycling-points${query ? `?${query}` : ""}`);
2269
+ },
2270
+ getChallenges: (cityId, params) => {
2271
+ const q = new URLSearchParams();
2272
+ if (params?.page != null) q.set("page", String(params.page));
2273
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2274
+ const query = q.toString();
2275
+ return requestPublic(`/public/cities/${encodeURIComponent(cityId)}/challenges${query ? `?${query}` : ""}`);
2276
+ },
2277
+ getBadges: (cityId, params) => {
2278
+ const q = new URLSearchParams();
2279
+ if (params?.page != null) q.set("page", String(params.page));
2280
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2281
+ const query = q.toString();
2282
+ return requestPublic(`/public/cities/${encodeURIComponent(cityId)}/badges${query ? `?${query}` : ""}`);
2283
+ },
2284
+ getOperationalZones: (cityId, params) => {
2285
+ const q = new URLSearchParams();
2286
+ if (params?.page != null) q.set("page", String(params.page));
2287
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2288
+ const query = q.toString();
2289
+ return requestPublic(`/public/cities/${encodeURIComponent(cityId)}/operational-zones${query ? `?${query}` : ""}`);
2290
+ },
2291
+ searchStreetSectors: (cityId, params) => {
2292
+ const q = new URLSearchParams();
2293
+ q.set("q", params.q);
2294
+ if (params.cityGroupId) q.set("cityGroupId", params.cityGroupId);
2295
+ return requestPublic(
2296
+ `/public/cities/${encodeURIComponent(cityId)}/street-sectors?${q.toString()}`
2297
+ );
2298
+ },
2299
+ getCalendarPdfUrl: (cityId, placeId, year) => {
2300
+ const q = new URLSearchParams();
2301
+ if (year != null) q.set("year", String(year));
2302
+ const query = q.toString();
2303
+ return `${base}/public/cities/${encodeURIComponent(cityId)}/places/${encodeURIComponent(placeId)}/calendar-pdf${query ? `?${query}` : ""}`;
2304
+ },
2305
+ getCalendarPrintUrl: (cityId, placeId, year, preview = false) => {
2306
+ const q = new URLSearchParams();
2307
+ if (year != null) q.set("year", String(year));
2308
+ if (preview) q.set("preview", "1");
2309
+ const query = q.toString();
2310
+ return `${base}/public/cities/${encodeURIComponent(cityId)}/places/${encodeURIComponent(placeId)}/calendar-print${query ? `?${query}` : ""}`;
2311
+ }
2312
+ },
2313
+ challenges: {
2314
+ list: (cityId, params) => {
2315
+ const q = new URLSearchParams();
2316
+ if (cityId != null) q.set("cityId", cityId);
2317
+ if (params?.page != null) q.set("page", String(params.page));
2318
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2319
+ const query = q.toString();
2320
+ return requestPublic(`/public/challenges${query ? `?${query}` : ""}`);
2321
+ },
2322
+ getById: (id) => requestPublic(`/public/challenges/${id}`),
2323
+ getSeries: (id) => requestPublic(`/public/challenges/${id}/series`),
2324
+ complete: (id, body) => requestPublic(`/public/challenges/${id}/complete`, {
2325
+ method: "POST",
2326
+ body: JSON.stringify(body)
2327
+ }),
2328
+ getProgress: (deviceId) => requestPublic(`/public/challenges/progress/${encodeURIComponent(deviceId)}`)
2329
+ },
2330
+ blogPosts: {
2331
+ list: (cityGroupId, params) => {
2332
+ const q = new URLSearchParams();
2333
+ if (cityGroupId != null) q.set("cityGroupId", cityGroupId);
2334
+ if (params?.page != null) q.set("page", String(params.page));
2335
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2336
+ const query = q.toString();
2337
+ return requestPublic(`/public/blog-posts${query ? `?${query}` : ""}`);
2338
+ },
2339
+ getById: (id) => requestPublic(`/public/blog-posts/${id}`)
2340
+ },
2341
+ announcements: {
2342
+ listForCity: (cityId) => requestPublic(`/public/announcements?cityId=${encodeURIComponent(cityId)}`)
2343
+ },
2344
+ cityGroups: {
2345
+ searchStreetSectors: (cityGroupId, params) => {
2346
+ const q = new URLSearchParams();
2347
+ q.set("q", params.q);
2348
+ return requestPublic(
2349
+ `/public/city-groups/${encodeURIComponent(cityGroupId)}/street-sectors?${q.toString()}`
2350
+ );
2351
+ }
2352
+ },
2353
+ tickets: {
2354
+ getForms: (params) => {
2355
+ const q = new URLSearchParams();
2356
+ if (params?.page != null) q.set("page", String(params.page));
2357
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2358
+ const query = q.toString();
2359
+ return requestPublic(`/public/tickets/forms${query ? `?${query}` : ""}`);
2360
+ },
2361
+ getForm: (id) => requestPublic(`/public/tickets/forms/${id}`),
2362
+ create: (data) => requestPublic("/public/tickets", {
2363
+ method: "POST",
2364
+ body: JSON.stringify(data)
2365
+ }),
2366
+ getByAccessKey: (accessKey) => requestPublic(`/public/tickets/${encodeURIComponent(accessKey)}`)
2367
+ },
2368
+ chat: {
2369
+ getAvailability: (params) => {
2370
+ const q = new URLSearchParams();
2371
+ if (typeof params === "string") {
2372
+ q.set("cityId", params);
2373
+ } else {
2374
+ if (params.cityGroupId) q.set("cityGroupId", params.cityGroupId);
2375
+ if (params.cityId) q.set("cityId", params.cityId);
2376
+ }
2377
+ return requestPublic(`/public/chat/availability?${q.toString()}`);
2378
+ },
2379
+ createConversation: (body) => requestPublic("/public/chat/conversations", {
2380
+ method: "POST",
2381
+ body: JSON.stringify(body)
2382
+ }),
2383
+ setConversationLocation: (conversationId, body) => requestPublic(
2384
+ `/public/chat/conversations/${encodeURIComponent(conversationId)}/location`,
2385
+ {
2386
+ method: "PATCH",
2387
+ body: JSON.stringify(body)
2388
+ }
2389
+ ),
2390
+ getConversations: (deviceId, params) => {
2391
+ const q = new URLSearchParams();
2392
+ if (params?.page != null) q.set("page", String(params.page));
2393
+ if (params?.pageSize != null) q.set("pageSize", String(params.pageSize));
2394
+ const query = q.toString();
2395
+ return requestPublic(`/public/chat/conversations/${encodeURIComponent(deviceId)}${query ? `?${query}` : ""}`);
2396
+ },
2397
+ getMessages: (conversationId) => requestPublic(`/public/chat/conversations/${conversationId}/messages`),
2398
+ sendMessage: (conversationId, body) => requestPublic(`/public/chat/conversations/${conversationId}/messages`, {
2399
+ method: "POST",
2400
+ body: JSON.stringify(body)
2401
+ })
2402
+ },
2403
+ devices: {
2404
+ registerPushToken: (deviceId, body) => requestPublic(`/public/devices/${encodeURIComponent(deviceId)}/push-token`, {
2405
+ method: "POST",
2406
+ body: JSON.stringify(body)
2407
+ })
2408
+ },
2409
+ analytics: {
2410
+ track: (payload) => requestPublic("/public/analytics/track", {
2411
+ method: "POST",
2412
+ body: JSON.stringify(payload)
2413
+ }),
2414
+ delete: (deviceId) => requestPublic(`/public/analytics/delete/${encodeURIComponent(deviceId)}`, {
2415
+ method: "DELETE"
2416
+ })
2417
+ },
2418
+ cms: {
2419
+ getPageById: (id) => requestPublic(`/public/cms/pages/${encodeURIComponent(id)}`),
2420
+ getSiteBySlug: (slug) => requestPublic(`/public/cms/sites/${encodeURIComponent(slug)}`),
2421
+ getAppBySlug: (slug) => requestPublic(`/public/cms/apps/${encodeURIComponent(slug)}`),
2422
+ getAppMenuById: (appSlug, menuId) => requestPublic(
2423
+ `/public/cms/apps/${encodeURIComponent(appSlug)}/menus/by-id/${encodeURIComponent(menuId)}`
2424
+ )
2425
+ }
2426
+ }
2427
+ };
2428
+ }
2429
+ // Annotate the CommonJS export names for ESM import in node:
2430
+ 0 && (module.exports = {
2431
+ AssetEventType,
2432
+ AssetStatus,
2433
+ AssetType,
2434
+ BookingStatus,
2435
+ CITEO_DOM_MULTIPLIERS,
2436
+ CalendoEventStatus,
2437
+ CalendoEventType,
2438
+ CalendoTicketSaleStatus,
2439
+ ChatMessageRole,
2440
+ ChatStatus,
2441
+ CityGroupType,
2442
+ CityStatus,
2443
+ CmsMenuLinkType,
2444
+ CmsSiteType,
2445
+ DASHBOARD_APPS,
2446
+ DASHBOARD_APP_BY_KEY,
2447
+ DASHBOARD_APP_BY_SLUG,
2448
+ DEFAULT_ENABLED_DASHBOARD_APP_SLUGS,
2449
+ DEFAULT_PAGE,
2450
+ DEFAULT_PAGE_SIZE,
2451
+ DOM_INSEE_PREFIXES,
2452
+ DashboardAppSlug,
2453
+ FREE_SELF_SERVE_DASHBOARD_APP_SLUGS,
2454
+ FREE_TIER_FEATURES,
2455
+ FREE_TIER_FEATURE_KEYS,
2456
+ FREE_TIER_LIMITS,
2457
+ FREE_TIER_RESOURCES,
2458
+ FieldReportFormStatus,
2459
+ FieldReportStatus,
2460
+ InterventionStatus,
2461
+ InterventionType,
2462
+ MAX_PAGE_SIZE,
2463
+ MapEventStatus,
2464
+ MapEventType,
2465
+ MapPoiCategory,
2466
+ MapPoiStatus,
2467
+ MapZoneType,
2468
+ NotificationDeliveryStatus,
2469
+ NotificationStatus,
2470
+ ONBOARDING_RESTRICTED_APP_SLUGS,
2471
+ OperationalZoneStatus,
2472
+ OperationalZoneType,
2473
+ PRESET_SLOTS,
2474
+ PermissionAction,
2475
+ PermissionResource,
2476
+ ProviderType,
2477
+ QuestionType,
2478
+ ROI_DEFAULTS,
2479
+ ROI_DISCLAIMER,
2480
+ ROI_SCENARIO_DEFS,
2481
+ RecipientGroupType,
2482
+ ResponseStatus,
2483
+ SurveyMode,
2484
+ SurveyStatus,
2485
+ TGAP_LANDFILL_EUR_PER_TONNE,
2486
+ TerritoryActionStatus,
2487
+ TerritoryActionType,
2488
+ TicketFormStatus,
2489
+ TicketStatus,
2490
+ UserRole,
2491
+ WASTO_LANDINGS_DOMAIN,
2492
+ WASTO_LANDINGS_INDEX_HOST,
2493
+ WASTO_RESERVED_SUBDOMAINS,
2494
+ WASTO_SECTIONS,
2495
+ WASTO_SECTION_BY_KEY,
2496
+ WEEKDAYS,
2497
+ WEEKDAY_INDEX,
2498
+ WEEKDAY_LABELS_FR,
2499
+ WEEKDAY_LABELS_FR_SHORT,
2500
+ WEEKDAY_REF_DATES,
2501
+ WastoApiError,
2502
+ addDaysToIsoDate,
2503
+ adjustCostPerBadTonneForTgap,
2504
+ allocateSavingsByAction,
2505
+ applyCiteoDomMultiplier,
2506
+ applyStackedErrorReductions,
2507
+ buildBauVsRealSeries,
2508
+ buildPaginationMeta,
2509
+ computeActionImpactConfidence,
2510
+ computeGec,
2511
+ computeOverallConfidence,
2512
+ computePenetrationRate,
2513
+ computeRoiIndicators,
2514
+ convertLocalToUtc,
2515
+ convertUtcToLocal,
2516
+ createEmptyLocalRules,
2517
+ createEmptyOpeningHours,
2518
+ createWastoClient,
2519
+ currentFiscalYear,
2520
+ dashboardAppKeyFromLandingHost,
2521
+ dashboardAppKeyToSlug,
2522
+ dashboardAppSlugToKey,
2523
+ detectDomTerritory,
2524
+ estimateHouseholds,
2525
+ formatOpeningHoursSummary,
2526
+ formatOpeningHoursWeekly,
2527
+ formatTimeDisplay,
2528
+ formatTimeMinutes,
2529
+ formatWeeklyRow,
2530
+ getBrowserTimeZone,
2531
+ getFreeTierLimit,
2532
+ getFreeTierMediaBytesLimit,
2533
+ getTgapEurPerTonne,
2534
+ getTimezoneOffsetMinutes,
2535
+ isActionCountedInRoi,
2536
+ isDashboardAppLandingHost,
2537
+ isDomInseeCode,
2538
+ isFreeSelfServeAppAccess,
2539
+ isFreeTierFeatureEnabled,
2540
+ isOpenNow,
2541
+ localDateTimeToUtc,
2542
+ localRulesFromRange,
2543
+ nextWeekday,
2544
+ normalizeDashboardAppSlug,
2545
+ openNowLabel,
2546
+ parseTimeMinutes,
2547
+ refDateForWeekday,
2548
+ resolveDashboardAppLandingUrl,
2549
+ resolveEnabledDashboardAppSlugs,
2550
+ resolveHoursDisplay,
2551
+ resolveHoursMode,
2552
+ resolveHoursModeFromPoint,
2553
+ resolveHoursText,
2554
+ resolveOpeningHoursLocal,
2555
+ resolveOpeningHoursUtc,
2556
+ resolveWastoLandingsIndexUrl,
2557
+ roundEuro,
2558
+ simulateTerritory100kExample,
2559
+ slotsOverlap,
2560
+ sortSlots,
2561
+ utcDateIso,
2562
+ utcHhmmFromDate,
2563
+ validateLocalOpeningHours,
2564
+ validateOpeningHours,
2565
+ weekdayFromUtcDate
2566
+ });