@vinaverse/tokens 0.1.0-alpha.7 → 0.1.0-alpha.9

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.
@@ -52,7 +52,12 @@ var en = {
52
52
  questionAddPhoto: "Add a photo",
53
53
  questionCharactersLeft: "{count} characters left",
54
54
  priceFrom: "From {price}",
55
+ /** A listing with no rating yet; empty draws nothing, a tenant's word ("New") draws in the rating's place. */
56
+ ratingNone: "",
55
57
  nextAvailable: "Next: {time}",
58
+ /** A time today and tomorrow, as `nextAvailable` says it (`{time}`: "10:00 AM"). */
59
+ today: "today, {time}",
60
+ tomorrow: "tomorrow, {time}",
56
61
  agentEnded: "This conversation ended",
57
62
  agentEndedBody: "Start a new one whenever you like.",
58
63
  agentStartOver: "Start a new conversation",
@@ -123,7 +128,10 @@ var es = {
123
128
  questionAddPhoto: "Agregar una foto",
124
129
  questionCharactersLeft: "Quedan {count} caracteres",
125
130
  priceFrom: "Desde {price}",
131
+ ratingNone: "",
126
132
  nextAvailable: "Pr\xF3ximo: {time}",
133
+ today: "hoy, {time}",
134
+ tomorrow: "ma\xF1ana, {time}",
127
135
  agentEnded: "Esta conversaci\xF3n termin\xF3",
128
136
  agentEndedBody: "Empieza una nueva cuando quieras.",
129
137
  agentStartOver: "Empezar una conversaci\xF3n nueva",
@@ -194,7 +202,10 @@ var ptBR = {
194
202
  questionAddPhoto: "Adicionar uma foto",
195
203
  questionCharactersLeft: "Restam {count} caracteres",
196
204
  priceFrom: "A partir de {price}",
205
+ ratingNone: "",
197
206
  nextAvailable: "Pr\xF3ximo hor\xE1rio: {time}",
207
+ today: "hoje, {time}",
208
+ tomorrow: "amanh\xE3, {time}",
198
209
  agentEnded: "Esta conversa terminou",
199
210
  agentEndedBody: "Comece uma nova quando quiser.",
200
211
  agentStartOver: "Come\xE7ar uma conversa nova",
@@ -324,6 +335,32 @@ function formatTimeRange(start, end, locale, timeZone) {
324
335
  return from.toISOString();
325
336
  }
326
337
  }
338
+ function dayOf(at, timeZone) {
339
+ const [y, m, d] = new Intl.DateTimeFormat("en-CA", {
340
+ year: "numeric",
341
+ month: "2-digit",
342
+ day: "2-digit",
343
+ ...timeZone ? { timeZone } : {}
344
+ }).format(at).split("-").map(Number);
345
+ return Date.UTC(y, m - 1, d) / 864e5;
346
+ }
347
+ function formatDayTime(start, words, locale, timeZone, now = Date.now()) {
348
+ const at = new Date(start);
349
+ if (Number.isNaN(at.getTime())) return start;
350
+ try {
351
+ const days = dayOf(at, timeZone) - dayOf(new Date(now), timeZone);
352
+ const word = days === 0 ? words.today : days === 1 ? words.tomorrow : "";
353
+ if (!word) return formatTimeRange(start, void 0, locale, timeZone);
354
+ const time = new Intl.DateTimeFormat(locale, {
355
+ hour: "numeric",
356
+ minute: "2-digit",
357
+ ...timeZone ? { timeZone } : {}
358
+ }).format(at);
359
+ return word.replace("{time}", time);
360
+ } catch {
361
+ return formatTimeRange(start, void 0, locale, timeZone);
362
+ }
363
+ }
327
364
  function formatDate(date, locale) {
328
365
  const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date);
329
366
  if (!m) return date;
@@ -346,6 +383,7 @@ exports.bannedWordsIn = bannedWordsIn;
346
383
  exports.builtInCopy = builtInCopy;
347
384
  exports.createTranslate = createTranslate;
348
385
  exports.formatDate = formatDate;
386
+ exports.formatDayTime = formatDayTime;
349
387
  exports.formatMoney = formatMoney;
350
388
  exports.formatTimeRange = formatTimeRange;
351
389
  exports.textDirection = textDirection;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/copy/copy.ts","../../src/copy/format.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// The words a Vinaverse UI says, in English, Spanish and Brazilian Portuguese, each overridable by the tenant except\n// the fallback disclosure. People first: \"agent\", never \"assistant\"; a person from the business is a person, by role.\n// `{name}` placeholders are filled from `vars`.\n\nconst en = {\n disclosureFallback: \"You're chatting with an AI agent. Powered by Vinaverse.\",\n agentLabel: 'AI agent',\n agentFallbackName: 'the agent',\n you: 'You',\n staffLabel: '{by} · person',\n staffFallbackRole: 'the team',\n composerPlaceholder: 'Message {agent}',\n composerPlaceholderTakeover: 'Message {by}',\n send: 'Send',\n stop: 'Stop',\n typeAnswerBelow: 'Type your answer below.',\n bannerConnecting: 'Connecting…',\n bannerReconnecting: 'Reconnecting…',\n bannerOffline: \"You're offline. Messages send when you're back.\",\n bannerContinuedElsewhere: 'This conversation continued on another device.',\n bannerUnavailable: \"Couldn't connect.\",\n continueHere: 'Continue here',\n tryAgain: 'Try again',\n talkToPerson: 'Talk to a person',\n messageSending: 'Sending',\n messageHeld: 'Sends when you continue',\n messageNotSent: 'Not sent',\n messageDelivered: 'Delivered',\n messageCutOff: 'This reply was cut off.',\n takeoverStarted: 'A person from {by} is replying now.',\n takeoverEnded: '{agent} is back.',\n handoffCreated: \"We've passed this to the team. They'll reply {expected}.\",\n handoffCreatedNoTime: \"We've passed this to the team. They'll reply soon.\",\n flowSent: 'Your answers were sent.',\n flowNotSent: \"Your answers couldn't be sent yet.\",\n turnFailed: 'Something went wrong.',\n working: '{agent} is working on it…',\n proposalConfirm: 'Confirm',\n proposalDecline: 'Decline',\n proposalChange: 'Change',\n proposalConfirmed: 'Confirmed',\n proposalDeclined: 'Declined',\n proposalFailed: \"Couldn't be confirmed\",\n proposalExpired: 'Expired',\n proposalSettled: 'No longer open',\n questionSubmit: 'Send',\n questionSkip: 'Skip',\n questionOther: 'Other',\n questionSearch: 'Search',\n questionAnswered: 'Answered',\n questionReplaced: 'Replaced by a newer question',\n questionStep: 'Question {step} of {total}',\n questionAddPhoto: 'Add a photo',\n questionCharactersLeft: '{count} characters left',\n priceFrom: 'From {price}',\n nextAvailable: 'Next: {time}',\n agentEnded: 'This conversation ended',\n agentEndedBody: 'Start a new one whenever you like.',\n agentStartOver: 'Start a new conversation',\n agentUnreachable: \"Couldn't reach {agent}\",\n agentUnreachableBody: 'Check your connection and try again.',\n agentOff: \"{agent} isn't available right now\",\n agentOffBody: 'Please try again later.',\n helpful: 'Was this helpful?',\n helpfulYes: 'Yes',\n helpfulNo: 'No',\n helpfulThanks: 'Thanks for telling us.',\n launcherOpen: 'Open {agent}',\n launcherGreeting: \"Hi, I'm {agent}. Ask me what you need.\",\n close: 'Close',\n welcomeFallback: \"Hi, I'm {agent}. How can I help?\",\n privacy: 'Privacy',\n cardsInRow: '{count} results, swipe for more',\n open: 'Open',\n} as const;\n\nexport type CopyKey = keyof typeof en;\nexport type Copy = Readonly<Record<CopyKey, string>>;\n/** A tenant's words, by key; a key left out (or undefined) keeps the built-in one. */\nexport type CopyOverrides = { readonly [K in CopyKey]?: string | undefined };\n\nconst es: Copy = {\n disclosureFallback:\n 'Estás hablando con un agente de IA. Con la tecnología de Vinaverse.',\n agentLabel: 'Agente de IA',\n agentFallbackName: 'el agente',\n you: 'Tú',\n staffLabel: '{by} · persona',\n staffFallbackRole: 'el equipo',\n composerPlaceholder: 'Escribe a {agent}',\n composerPlaceholderTakeover: 'Escribe a {by}',\n send: 'Enviar',\n stop: 'Detener',\n typeAnswerBelow: 'Escribe tu respuesta abajo.',\n bannerConnecting: 'Conectando…',\n bannerReconnecting: 'Reconectando…',\n bannerOffline: 'Sin conexión. Los mensajes se envían cuando vuelvas.',\n bannerContinuedElsewhere: 'Esta conversación continuó en otro dispositivo.',\n bannerUnavailable: 'No se pudo conectar.',\n continueHere: 'Continuar aquí',\n tryAgain: 'Intentar de nuevo',\n talkToPerson: 'Hablar con una persona',\n messageSending: 'Enviando',\n messageHeld: 'Se envía cuando continúes',\n messageNotSent: 'No enviado',\n messageDelivered: 'Entregado',\n messageCutOff: 'Esta respuesta quedó incompleta.',\n takeoverStarted: 'Una persona de {by} está respondiendo.',\n takeoverEnded: '{agent} volvió.',\n handoffCreated: 'Le pasamos esto al equipo. Responderán {expected}.',\n handoffCreatedNoTime: 'Le pasamos esto al equipo. Responderán pronto.',\n flowSent: 'Tus respuestas se enviaron.',\n flowNotSent: 'Tus respuestas aún no se pudieron enviar.',\n turnFailed: 'Algo salió mal.',\n working: '{agent} está en ello…',\n proposalConfirm: 'Confirmar',\n proposalDecline: 'Rechazar',\n proposalChange: 'Cambiar',\n proposalConfirmed: 'Confirmado',\n proposalDeclined: 'Rechazado',\n proposalFailed: 'No se pudo confirmar',\n proposalExpired: 'Vencido',\n proposalSettled: 'Ya no está abierto',\n questionSubmit: 'Enviar',\n questionSkip: 'Omitir',\n questionOther: 'Otro',\n questionSearch: 'Buscar',\n questionAnswered: 'Respondida',\n questionReplaced: 'Reemplazada por una pregunta más reciente',\n questionStep: 'Pregunta {step} de {total}',\n questionAddPhoto: 'Agregar una foto',\n questionCharactersLeft: 'Quedan {count} caracteres',\n priceFrom: 'Desde {price}',\n nextAvailable: 'Próximo: {time}',\n agentEnded: 'Esta conversación terminó',\n agentEndedBody: 'Empieza una nueva cuando quieras.',\n agentStartOver: 'Empezar una conversación nueva',\n agentUnreachable: 'No se pudo contactar a {agent}',\n agentUnreachableBody: 'Revisa tu conexión e inténtalo de nuevo.',\n agentOff: '{agent} no está disponible ahora',\n agentOffBody: 'Inténtalo de nuevo más tarde.',\n helpful: '¿Te sirvió?',\n helpfulYes: 'Sí',\n helpfulNo: 'No',\n helpfulThanks: 'Gracias por contarnos.',\n launcherOpen: 'Abrir {agent}',\n launcherGreeting: 'Hola, soy {agent}. Pregúntame lo que necesites.',\n close: 'Cerrar',\n welcomeFallback: 'Hola, soy {agent}. ¿En qué te ayudo?',\n privacy: 'Privacidad',\n cardsInRow: '{count} resultados, desliza para ver más',\n open: 'Abrir',\n};\n\nconst ptBR: Copy = {\n disclosureFallback:\n 'Você está conversando com um agente de IA. Com tecnologia Vinaverse.',\n agentLabel: 'Agente de IA',\n agentFallbackName: 'o agente',\n you: 'Você',\n staffLabel: '{by} · pessoa',\n staffFallbackRole: 'a equipe',\n composerPlaceholder: 'Mensagem para {agent}',\n composerPlaceholderTakeover: 'Mensagem para {by}',\n send: 'Enviar',\n stop: 'Parar',\n typeAnswerBelow: 'Digite sua resposta abaixo.',\n bannerConnecting: 'Conectando…',\n bannerReconnecting: 'Reconectando…',\n bannerOffline: 'Sem conexão. As mensagens são enviadas quando você voltar.',\n bannerContinuedElsewhere: 'Esta conversa continuou em outro aparelho.',\n bannerUnavailable: 'Não foi possível conectar.',\n continueHere: 'Continuar aqui',\n tryAgain: 'Tentar de novo',\n talkToPerson: 'Falar com uma pessoa',\n messageSending: 'Enviando',\n messageHeld: 'Será enviada quando você continuar',\n messageNotSent: 'Não enviada',\n messageDelivered: 'Entregue',\n messageCutOff: 'Esta resposta foi interrompida.',\n takeoverStarted: 'Uma pessoa de {by} está respondendo agora.',\n takeoverEnded: '{agent} voltou.',\n handoffCreated: 'Passamos isso para a equipe. Eles vão responder {expected}.',\n handoffCreatedNoTime:\n 'Passamos isso para a equipe. Eles vão responder em breve.',\n flowSent: 'Suas respostas foram enviadas.',\n flowNotSent: 'Ainda não foi possível enviar suas respostas.',\n turnFailed: 'Algo deu errado.',\n working: '{agent} está cuidando disso…',\n proposalConfirm: 'Confirmar',\n proposalDecline: 'Recusar',\n proposalChange: 'Alterar',\n proposalConfirmed: 'Confirmado',\n proposalDeclined: 'Recusado',\n proposalFailed: 'Não foi possível confirmar',\n proposalExpired: 'Expirado',\n proposalSettled: 'Não está mais aberto',\n questionSubmit: 'Enviar',\n questionSkip: 'Pular',\n questionOther: 'Outro',\n questionSearch: 'Buscar',\n questionAnswered: 'Respondida',\n questionReplaced: 'Substituída por uma pergunta mais recente',\n questionStep: 'Pergunta {step} de {total}',\n questionAddPhoto: 'Adicionar uma foto',\n questionCharactersLeft: 'Restam {count} caracteres',\n priceFrom: 'A partir de {price}',\n nextAvailable: 'Próximo horário: {time}',\n agentEnded: 'Esta conversa terminou',\n agentEndedBody: 'Comece uma nova quando quiser.',\n agentStartOver: 'Começar uma conversa nova',\n agentUnreachable: 'Não foi possível falar com {agent}',\n agentUnreachableBody: 'Verifique sua conexão e tente de novo.',\n agentOff: '{agent} não está disponível agora',\n agentOffBody: 'Tente de novo mais tarde.',\n helpful: 'Isso ajudou?',\n helpfulYes: 'Sim',\n helpfulNo: 'Não',\n helpfulThanks: 'Obrigado por avisar.',\n launcherOpen: 'Abrir {agent}',\n launcherGreeting: 'Oi, sou {agent}. Pergunte o que precisar.',\n close: 'Fechar',\n welcomeFallback: 'Oi, sou {agent}. Como posso ajudar?',\n privacy: 'Privacidade',\n cardsInRow: '{count} resultados, deslize para ver mais',\n open: 'Abrir',\n};\n\n/** The built-in languages; any other locale falls back to English, its own `copy` overrides aside. */\nexport const COPY: Readonly<Record<'en' | 'es' | 'pt-BR', Copy>> = {\n en,\n es,\n 'pt-BR': ptBR,\n};\n\n/**\n * Keys a tenant may not override in a built-in language: the AI disclosure is the platform's, never removed or reworded.\n * In a language without built-in copy the tenant supplies them, translated, so the disclosure reads in the person's\n * language, and only a translation that still discloses is taken (`discloses`): the label says AI, the disclosure says\n * AI and names Vinaverse.\n */\nconst FIXED: ReadonlySet<CopyKey> = new Set([\n 'disclosureFallback',\n 'agentLabel',\n]);\n\n/**\n * \"AI\" as languages write it: AI, IA (es, pt, fr, it, ro), KI (de, nl, da, no, sv), SI (pl), YZ (tr), ИИ (ru), ШІ\n * (uk), and the words for it in Arabic, Hebrew, Hindi, Chinese, Japanese and Korean.\n */\nexport const AI_MARK =\n /(?:^|[^\\p{L}])(?:AI|IA|KI|SI|YZ|ИИ|ШІ)(?:$|[^\\p{L}])|الذكاء الاصطناعي|بالذكاء|בינה מלאכותית|एआई|कृत्रिम बुद्धि|人工智能|人工知能|인공지능/u;\n\n/**\n * Whether a tenant's text for a fixed key still makes the AI disclosure: the label says AI; the disclosure says AI\n * and names Vinaverse. A tenant's translation that does not is ignored, and the English built-in shows instead.\n */\nfunction discloses(key: string, value: string): boolean {\n if (!AI_MARK.test(value)) return false;\n return key !== 'disclosureFallback' || value.includes('Vinaverse');\n}\n\nexport type Translate = (\n key: CopyKey,\n vars?: Readonly<Record<string, string | number>>,\n) => string;\n\n/** The built-in copy for a locale: its language (`es-US` → `es`, `pt-PT` → `pt-BR`), else null. */\nfunction builtIn(locale: string | undefined): Copy | null {\n const language = (locale ?? 'en').split(/[-_]/)[0]?.toLowerCase();\n if (language === 'en') return COPY.en;\n if (language === 'es') return COPY.es;\n if (language === 'pt') return COPY['pt-BR'];\n return null;\n}\n\n/** The built-in copy for a locale, English when the language has none. */\nexport function builtInCopy(locale: string | undefined): Copy {\n return builtIn(locale) ?? COPY.en;\n}\n\n/** A translator for a locale, with the tenant's overrides on top (fixed keys excepted). */\nexport function createTranslate(\n locale: string | undefined,\n overrides: CopyOverrides = {},\n): Translate {\n const own = builtIn(locale);\n const merged: Record<string, string> = { ...(own ?? COPY.en) };\n for (const [key, value] of Object.entries(overrides)) {\n if (value === undefined) continue;\n if (FIXED.has(key as CopyKey) && !(own === null && discloses(key, value)))\n continue;\n merged[key] = value;\n }\n return (key, vars) =>\n (merged[key] ?? en[key]).replace(/\\{(\\w+)\\}/g, (all, name: string) =>\n vars && name in vars ? String(vars[name]) : all,\n );\n}\n\n/**\n * Words a Vinaverse UI never says to people (a tenant override that uses them gets a development warning): the\n * runtime is an agent, never an assistant or a bot; and never \"crew\".\n */\nexport const BANNED_WORDS: readonly RegExp[] = [\n /\\bassistant/i,\n /\\basistente/i,\n /\\bassistent/i,\n /\\bbot\\b/i,\n /\\bcrew\\b/i,\n];\n\n/** The overrides that use a banned word, by key. */\nexport function bannedWordsIn(overrides: CopyOverrides): CopyKey[] {\n return (Object.entries(overrides) as [CopyKey, string | undefined][])\n .filter(([, v]) => v !== undefined && BANNED_WORDS.some((w) => w.test(v)))\n .map(([k]) => k);\n}\n","// Dates, times, money and text direction in the person's locale, through Intl (Hermes has it), with a plain fallback\n// where a runtime lacks it.\n\n/** Languages and scripts written right to left. */\nconst RTL_LANGUAGES = new Set([\n 'ar',\n 'he',\n 'iw',\n 'fa',\n 'ur',\n 'ps',\n 'yi',\n 'dv',\n 'ckb',\n 'sd',\n 'ug',\n 'syr',\n]);\nconst RTL_SCRIPTS = new Set([\n 'arab',\n 'hebr',\n 'thaa',\n 'syrc',\n 'nkoo',\n 'adlm',\n 'rohg',\n]);\n\n/** `rtl` for Arabic, Hebrew, Persian, Urdu and the other right-to-left languages and scripts; `ltr` otherwise. */\nexport function textDirection(locale: string | undefined): 'ltr' | 'rtl' {\n const parts = (locale ?? '').toLowerCase().split(/[-_]/);\n if (parts.some((p) => p.length === 4 && RTL_SCRIPTS.has(p))) return 'rtl';\n return RTL_LANGUAGES.has(parts[0] ?? '') ? 'rtl' : 'ltr';\n}\n\n/** An amount in minor units (`amount` cents) in its currency: `$85.00`. */\nexport function formatMoney(\n amountMinor: number,\n currency: string,\n locale?: string,\n): string {\n try {\n const format = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n });\n const digits = format.resolvedOptions().maximumFractionDigits ?? 2;\n return format.format(amountMinor / 10 ** digits);\n } catch {\n return `${currency} ${(amountMinor / 100).toFixed(2)}`;\n }\n}\n\n/** A start and an end: \"Wed, Oct 14, 10:00 – 11:30 AM\" in the locale and time zone. */\nexport function formatTimeRange(\n start: string,\n end: string | undefined,\n locale?: string,\n timeZone?: string,\n): string {\n const from = new Date(start);\n if (Number.isNaN(from.getTime())) return start;\n const options: Intl.DateTimeFormatOptions = {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n ...(timeZone ? { timeZone } : {}),\n };\n try {\n const format = new Intl.DateTimeFormat(locale, options);\n const to = end ? new Date(end) : null;\n if (!to || Number.isNaN(to.getTime())) return format.format(from);\n return typeof format.formatRange === 'function'\n ? format.formatRange(from, to)\n : `${format.format(from)} – ${format.format(to)}`;\n } catch {\n return from.toISOString();\n }\n}\n\n/** A calendar date (`YYYY-MM-DD`) in the locale: \"October 14, 2026\". */\nexport function formatDate(date: string, locale?: string): string {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(date);\n if (!m) return date;\n try {\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n timeZone: 'UTC',\n }).format(new Date(Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3]))));\n } catch {\n return date;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/copy/copy.ts","../../src/copy/format.ts"],"names":[],"mappings":";;;AAIA,IAAM,EAAA,GAAK;AAAA,EACT,kBAAA,EAAoB,yDAAA;AAAA,EACpB,UAAA,EAAY,UAAA;AAAA,EACZ,iBAAA,EAAmB,WAAA;AAAA,EACnB,GAAA,EAAK,KAAA;AAAA,EACL,UAAA,EAAY,kBAAA;AAAA,EACZ,iBAAA,EAAmB,UAAA;AAAA,EACnB,mBAAA,EAAqB,iBAAA;AAAA,EACrB,2BAAA,EAA6B,cAAA;AAAA,EAC7B,IAAA,EAAM,MAAA;AAAA,EACN,IAAA,EAAM,MAAA;AAAA,EACN,eAAA,EAAiB,yBAAA;AAAA,EACjB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,aAAA,EAAe,iDAAA;AAAA,EACf,wBAAA,EAA0B,gDAAA;AAAA,EAC1B,iBAAA,EAAmB,mBAAA;AAAA,EACnB,YAAA,EAAc,eAAA;AAAA,EACd,QAAA,EAAU,WAAA;AAAA,EACV,YAAA,EAAc,kBAAA;AAAA,EACd,cAAA,EAAgB,SAAA;AAAA,EAChB,WAAA,EAAa,yBAAA;AAAA,EACb,cAAA,EAAgB,UAAA;AAAA,EAChB,gBAAA,EAAkB,WAAA;AAAA,EAClB,aAAA,EAAe,yBAAA;AAAA,EACf,eAAA,EAAiB,qCAAA;AAAA,EACjB,aAAA,EAAe,kBAAA;AAAA,EACf,cAAA,EAAgB,0DAAA;AAAA,EAChB,oBAAA,EAAsB,oDAAA;AAAA,EACtB,QAAA,EAAU,yBAAA;AAAA,EACV,WAAA,EAAa,oCAAA;AAAA,EACb,UAAA,EAAY,uBAAA;AAAA,EACZ,OAAA,EAAS,gCAAA;AAAA,EACT,eAAA,EAAiB,SAAA;AAAA,EACjB,eAAA,EAAiB,SAAA;AAAA,EACjB,cAAA,EAAgB,QAAA;AAAA,EAChB,iBAAA,EAAmB,WAAA;AAAA,EACnB,gBAAA,EAAkB,UAAA;AAAA,EAClB,cAAA,EAAgB,uBAAA;AAAA,EAChB,eAAA,EAAiB,SAAA;AAAA,EACjB,eAAA,EAAiB,gBAAA;AAAA,EACjB,cAAA,EAAgB,MAAA;AAAA,EAChB,YAAA,EAAc,MAAA;AAAA,EACd,aAAA,EAAe,OAAA;AAAA,EACf,cAAA,EAAgB,QAAA;AAAA,EAChB,gBAAA,EAAkB,UAAA;AAAA,EAClB,gBAAA,EAAkB,8BAAA;AAAA,EAClB,YAAA,EAAc,4BAAA;AAAA,EACd,gBAAA,EAAkB,aAAA;AAAA,EAClB,sBAAA,EAAwB,yBAAA;AAAA,EACxB,SAAA,EAAW,cAAA;AAAA;AAAA,EAEX,UAAA,EAAY,EAAA;AAAA,EACZ,aAAA,EAAe,cAAA;AAAA;AAAA,EAEf,KAAA,EAAO,eAAA;AAAA,EACP,QAAA,EAAU,kBAAA;AAAA,EACV,UAAA,EAAY,yBAAA;AAAA,EACZ,cAAA,EAAgB,oCAAA;AAAA,EAChB,cAAA,EAAgB,0BAAA;AAAA,EAChB,gBAAA,EAAkB,wBAAA;AAAA,EAClB,oBAAA,EAAsB,sCAAA;AAAA,EACtB,QAAA,EAAU,mCAAA;AAAA,EACV,YAAA,EAAc,yBAAA;AAAA,EACd,OAAA,EAAS,mBAAA;AAAA,EACT,UAAA,EAAY,KAAA;AAAA,EACZ,SAAA,EAAW,IAAA;AAAA,EACX,aAAA,EAAe,wBAAA;AAAA,EACf,YAAA,EAAc,cAAA;AAAA,EACd,gBAAA,EAAkB,wCAAA;AAAA,EAClB,KAAA,EAAO,OAAA;AAAA,EACP,eAAA,EAAiB,kCAAA;AAAA,EACjB,OAAA,EAAS,SAAA;AAAA,EACT,UAAA,EAAY,iCAAA;AAAA,EACZ,IAAA,EAAM;AACR,CAAA;AAOA,IAAM,EAAA,GAAW;AAAA,EACf,kBAAA,EACE,2EAAA;AAAA,EACF,UAAA,EAAY,cAAA;AAAA,EACZ,iBAAA,EAAmB,WAAA;AAAA,EACnB,GAAA,EAAK,OAAA;AAAA,EACL,UAAA,EAAY,mBAAA;AAAA,EACZ,iBAAA,EAAmB,WAAA;AAAA,EACnB,mBAAA,EAAqB,mBAAA;AAAA,EACrB,2BAAA,EAA6B,gBAAA;AAAA,EAC7B,IAAA,EAAM,QAAA;AAAA,EACN,IAAA,EAAM,SAAA;AAAA,EACN,eAAA,EAAiB,6BAAA;AAAA,EACjB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,aAAA,EAAe,4DAAA;AAAA,EACf,wBAAA,EAA0B,uDAAA;AAAA,EAC1B,iBAAA,EAAmB,sBAAA;AAAA,EACnB,YAAA,EAAc,mBAAA;AAAA,EACd,QAAA,EAAU,mBAAA;AAAA,EACV,YAAA,EAAc,wBAAA;AAAA,EACd,cAAA,EAAgB,UAAA;AAAA,EAChB,WAAA,EAAa,iCAAA;AAAA,EACb,cAAA,EAAgB,YAAA;AAAA,EAChB,gBAAA,EAAkB,WAAA;AAAA,EAClB,aAAA,EAAe,qCAAA;AAAA,EACf,eAAA,EAAiB,2CAAA;AAAA,EACjB,aAAA,EAAe,oBAAA;AAAA,EACf,cAAA,EAAgB,uDAAA;AAAA,EAChB,oBAAA,EAAsB,mDAAA;AAAA,EACtB,QAAA,EAAU,6BAAA;AAAA,EACV,WAAA,EAAa,8CAAA;AAAA,EACb,UAAA,EAAY,oBAAA;AAAA,EACZ,OAAA,EAAS,+BAAA;AAAA,EACT,eAAA,EAAiB,WAAA;AAAA,EACjB,eAAA,EAAiB,UAAA;AAAA,EACjB,cAAA,EAAgB,SAAA;AAAA,EAChB,iBAAA,EAAmB,YAAA;AAAA,EACnB,gBAAA,EAAkB,WAAA;AAAA,EAClB,cAAA,EAAgB,sBAAA;AAAA,EAChB,eAAA,EAAiB,SAAA;AAAA,EACjB,eAAA,EAAiB,uBAAA;AAAA,EACjB,cAAA,EAAgB,QAAA;AAAA,EAChB,YAAA,EAAc,QAAA;AAAA,EACd,aAAA,EAAe,MAAA;AAAA,EACf,cAAA,EAAgB,QAAA;AAAA,EAChB,gBAAA,EAAkB,YAAA;AAAA,EAClB,gBAAA,EAAkB,8CAAA;AAAA,EAClB,YAAA,EAAc,4BAAA;AAAA,EACd,gBAAA,EAAkB,kBAAA;AAAA,EAClB,sBAAA,EAAwB,2BAAA;AAAA,EACxB,SAAA,EAAW,eAAA;AAAA,EACX,UAAA,EAAY,EAAA;AAAA,EACZ,aAAA,EAAe,oBAAA;AAAA,EACf,KAAA,EAAO,aAAA;AAAA,EACP,QAAA,EAAU,mBAAA;AAAA,EACV,UAAA,EAAY,iCAAA;AAAA,EACZ,cAAA,EAAgB,mCAAA;AAAA,EAChB,cAAA,EAAgB,mCAAA;AAAA,EAChB,gBAAA,EAAkB,gCAAA;AAAA,EAClB,oBAAA,EAAsB,gDAAA;AAAA,EACtB,QAAA,EAAU,qCAAA;AAAA,EACV,YAAA,EAAc,qCAAA;AAAA,EACd,OAAA,EAAS,mBAAA;AAAA,EACT,UAAA,EAAY,OAAA;AAAA,EACZ,SAAA,EAAW,IAAA;AAAA,EACX,aAAA,EAAe,wBAAA;AAAA,EACf,YAAA,EAAc,eAAA;AAAA,EACd,gBAAA,EAAkB,oDAAA;AAAA,EAClB,KAAA,EAAO,QAAA;AAAA,EACP,eAAA,EAAiB,4CAAA;AAAA,EACjB,OAAA,EAAS,YAAA;AAAA,EACT,UAAA,EAAY,6CAAA;AAAA,EACZ,IAAA,EAAM;AACR,CAAA;AAEA,IAAM,IAAA,GAAa;AAAA,EACjB,kBAAA,EACE,4EAAA;AAAA,EACF,UAAA,EAAY,cAAA;AAAA,EACZ,iBAAA,EAAmB,UAAA;AAAA,EACnB,GAAA,EAAK,SAAA;AAAA,EACL,UAAA,EAAY,kBAAA;AAAA,EACZ,iBAAA,EAAmB,UAAA;AAAA,EACnB,mBAAA,EAAqB,uBAAA;AAAA,EACrB,2BAAA,EAA6B,oBAAA;AAAA,EAC7B,IAAA,EAAM,QAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,eAAA,EAAiB,6BAAA;AAAA,EACjB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,aAAA,EAAe,qEAAA;AAAA,EACf,wBAAA,EAA0B,4CAAA;AAAA,EAC1B,iBAAA,EAAmB,kCAAA;AAAA,EACnB,YAAA,EAAc,gBAAA;AAAA,EACd,QAAA,EAAU,gBAAA;AAAA,EACV,YAAA,EAAc,sBAAA;AAAA,EACd,cAAA,EAAgB,UAAA;AAAA,EAChB,WAAA,EAAa,0CAAA;AAAA,EACb,cAAA,EAAgB,gBAAA;AAAA,EAChB,gBAAA,EAAkB,UAAA;AAAA,EAClB,aAAA,EAAe,iCAAA;AAAA,EACf,eAAA,EAAiB,+CAAA;AAAA,EACjB,aAAA,EAAe,iBAAA;AAAA,EACf,cAAA,EAAgB,gEAAA;AAAA,EAChB,oBAAA,EACE,8DAAA;AAAA,EACF,QAAA,EAAU,gCAAA;AAAA,EACV,WAAA,EAAa,qDAAA;AAAA,EACb,UAAA,EAAY,kBAAA;AAAA,EACZ,OAAA,EAAS,sCAAA;AAAA,EACT,eAAA,EAAiB,WAAA;AAAA,EACjB,eAAA,EAAiB,SAAA;AAAA,EACjB,cAAA,EAAgB,SAAA;AAAA,EAChB,iBAAA,EAAmB,YAAA;AAAA,EACnB,gBAAA,EAAkB,UAAA;AAAA,EAClB,cAAA,EAAgB,kCAAA;AAAA,EAChB,eAAA,EAAiB,UAAA;AAAA,EACjB,eAAA,EAAiB,4BAAA;AAAA,EACjB,cAAA,EAAgB,QAAA;AAAA,EAChB,YAAA,EAAc,OAAA;AAAA,EACd,aAAA,EAAe,OAAA;AAAA,EACf,cAAA,EAAgB,QAAA;AAAA,EAChB,gBAAA,EAAkB,YAAA;AAAA,EAClB,gBAAA,EAAkB,8CAAA;AAAA,EAClB,YAAA,EAAc,4BAAA;AAAA,EACd,gBAAA,EAAkB,oBAAA;AAAA,EAClB,sBAAA,EAAwB,2BAAA;AAAA,EACxB,SAAA,EAAW,qBAAA;AAAA,EACX,UAAA,EAAY,EAAA;AAAA,EACZ,aAAA,EAAe,+BAAA;AAAA,EACf,KAAA,EAAO,cAAA;AAAA,EACP,QAAA,EAAU,mBAAA;AAAA,EACV,UAAA,EAAY,wBAAA;AAAA,EACZ,cAAA,EAAgB,gCAAA;AAAA,EAChB,cAAA,EAAgB,8BAAA;AAAA,EAChB,gBAAA,EAAkB,0CAAA;AAAA,EAClB,oBAAA,EAAsB,2CAAA;AAAA,EACtB,QAAA,EAAU,4CAAA;AAAA,EACV,YAAA,EAAc,2BAAA;AAAA,EACd,OAAA,EAAS,cAAA;AAAA,EACT,UAAA,EAAY,KAAA;AAAA,EACZ,SAAA,EAAW,QAAA;AAAA,EACX,aAAA,EAAe,sBAAA;AAAA,EACf,YAAA,EAAc,eAAA;AAAA,EACd,gBAAA,EAAkB,2CAAA;AAAA,EAClB,KAAA,EAAO,QAAA;AAAA,EACP,eAAA,EAAiB,qCAAA;AAAA,EACjB,OAAA,EAAS,aAAA;AAAA,EACT,UAAA,EAAY,2CAAA;AAAA,EACZ,IAAA,EAAM;AACR,CAAA;AAGO,IAAM,IAAA,GAAsD;AAAA,EACjE,EAAA;AAAA,EACA,EAAA;AAAA,EACA,OAAA,EAAS;AACX;AAQA,IAAM,KAAA,uBAAkC,GAAA,CAAI;AAAA,EAC1C,oBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAMM,IAAM,OAAA,GACX;AAMF,SAAS,SAAA,CAAU,KAAa,KAAA,EAAwB;AACtD,EAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,CAAK,KAAK,GAAG,OAAO,KAAA;AACjC,EAAA,OAAO,GAAA,KAAQ,oBAAA,IAAwB,KAAA,CAAM,QAAA,CAAS,WAAW,CAAA;AACnE;AAQA,SAAS,QAAQ,MAAA,EAAyC;AACxD,EAAA,MAAM,QAAA,GAAA,CAAY,UAAU,IAAA,EAAM,KAAA,CAAM,MAAM,CAAA,CAAE,CAAC,GAAG,WAAA,EAAY;AAChE,EAAA,IAAI,QAAA,KAAa,IAAA,EAAM,OAAO,IAAA,CAAK,EAAA;AACnC,EAAA,IAAI,QAAA,KAAa,IAAA,EAAM,OAAO,IAAA,CAAK,EAAA;AACnC,EAAA,IAAI,QAAA,KAAa,IAAA,EAAM,OAAO,IAAA,CAAK,OAAO,CAAA;AAC1C,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,YAAY,MAAA,EAAkC;AAC5D,EAAA,OAAO,OAAA,CAAQ,MAAM,CAAA,IAAK,IAAA,CAAK,EAAA;AACjC;AAGO,SAAS,eAAA,CACd,MAAA,EACA,SAAA,GAA2B,EAAC,EACjB;AACX,EAAA,MAAM,GAAA,GAAM,QAAQ,MAAM,CAAA;AAC1B,EAAA,MAAM,MAAA,GAAiC,EAAE,GAAI,GAAA,IAAO,KAAK,EAAA,EAAI;AAC7D,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AACpD,IAAA,IAAI,UAAU,MAAA,EAAW;AACzB,IAAA,IAAI,KAAA,CAAM,IAAI,GAAc,CAAA,IAAK,EAAE,GAAA,KAAQ,IAAA,IAAQ,SAAA,CAAU,GAAA,EAAK,KAAK,CAAA,CAAA;AACrE,MAAA;AACF,IAAA,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AAAA,EAChB;AACA,EAAA,OAAO,CAAC,KAAK,IAAA,KAAA,CACV,MAAA,CAAO,GAAG,CAAA,IAAK,EAAA,CAAG,GAAG,CAAA,EAAG,OAAA;AAAA,IAAQ,YAAA;AAAA,IAAc,CAAC,GAAA,EAAK,IAAA,KACnD,IAAA,IAAQ,IAAA,IAAQ,OAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,GAAI;AAAA,GAC9C;AACJ;AAMO,IAAM,YAAA,GAAkC;AAAA,EAC7C,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF;AAGO,SAAS,cAAc,SAAA,EAAqC;AACjE,EAAA,OAAQ,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,CAC7B,MAAA,CAAO,CAAC,GAAG,CAAC,CAAA,KAAM,CAAA,KAAM,MAAA,IAAa,YAAA,CAAa,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA,CACxE,GAAA,CAAI,CAAC,CAAC,CAAC,CAAA,KAAM,CAAC,CAAA;AACnB;;;ACpUA,IAAM,aAAA,uBAAoB,GAAA,CAAI;AAAA,EAC5B,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAC,CAAA;AACD,IAAM,WAAA,uBAAkB,GAAA,CAAI;AAAA,EAC1B,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAC,CAAA;AAGM,SAAS,cAAc,MAAA,EAA2C;AACvE,EAAA,MAAM,SAAS,MAAA,IAAU,EAAA,EAAI,WAAA,EAAY,CAAE,MAAM,MAAM,CAAA;AACvD,EAAA,IAAI,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,CAAA,IAAK,WAAA,CAAY,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,OAAO,KAAA;AACpE,EAAA,OAAO,cAAc,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA,IAAK,EAAE,IAAI,KAAA,GAAQ,KAAA;AACrD;AAGO,SAAS,WAAA,CACd,WAAA,EACA,QAAA,EACA,MAAA,EACQ;AACR,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ;AAAA,MAC3C,KAAA,EAAO,UAAA;AAAA,MACP;AAAA,KACD,CAAA;AACD,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,eAAA,EAAgB,CAAE,qBAAA,IAAyB,CAAA;AACjE,IAAA,OAAO,MAAA,CAAO,MAAA,CAAO,WAAA,GAAc,EAAA,IAAM,MAAM,CAAA;AAAA,EACjD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,GAAG,QAAQ,CAAA,CAAA,EAAA,CAAK,cAAc,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA;AAAA,EACtD;AACF;AAGO,SAAS,eAAA,CACd,KAAA,EACA,GAAA,EACA,MAAA,EACA,QAAA,EACQ;AACR,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,KAAK,CAAA;AAC3B,EAAA,IAAI,OAAO,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,GAAG,OAAO,KAAA;AACzC,EAAA,MAAM,OAAA,GAAsC;AAAA,IAC1C,OAAA,EAAS,OAAA;AAAA,IACT,KAAA,EAAO,OAAA;AAAA,IACP,GAAA,EAAK,SAAA;AAAA,IACL,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,GAAI,QAAA,GAAW,EAAE,QAAA,KAAa;AAAC,GACjC;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,cAAA,CAAe,QAAQ,OAAO,CAAA;AACtD,IAAA,MAAM,EAAA,GAAK,GAAA,GAAM,IAAI,IAAA,CAAK,GAAG,CAAA,GAAI,IAAA;AACjC,IAAA,IAAI,CAAC,EAAA,IAAM,MAAA,CAAO,KAAA,CAAM,EAAA,CAAG,OAAA,EAAS,CAAA,EAAG,OAAO,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA;AAChE,IAAA,OAAO,OAAO,MAAA,CAAO,WAAA,KAAgB,aACjC,MAAA,CAAO,WAAA,CAAY,MAAM,EAAE,CAAA,GAC3B,CAAA,EAAG,MAAA,CAAO,OAAO,IAAI,CAAC,WAAM,MAAA,CAAO,MAAA,CAAO,EAAE,CAAC,CAAA,CAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAK,WAAA,EAAY;AAAA,EAC1B;AACF;AAGA,SAAS,KAAA,CAAM,IAAU,QAAA,EAAsC;AAC7D,EAAA,MAAM,CAAC,GAAG,CAAA,EAAG,CAAC,IAAI,IAAI,IAAA,CAAK,eAAe,OAAA,EAAS;AAAA,IACjD,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,GAAA,EAAK,SAAA;AAAA,IACL,GAAI,QAAA,GAAW,EAAE,QAAA,KAAa;AAAC,GAChC,EACE,MAAA,CAAO,EAAE,EACT,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,MAAM,CAAA;AACb,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAc,CAAA,GAAe,CAAA,EAAG,CAAW,CAAA,GAAI,KAAA;AACjE;AAOO,SAAS,aAAA,CACd,OACA,KAAA,EACA,MAAA,EACA,UACA,GAAA,GAAc,IAAA,CAAK,KAAI,EACf;AACR,EAAA,MAAM,EAAA,GAAK,IAAI,IAAA,CAAK,KAAK,CAAA;AACzB,EAAA,IAAI,OAAO,KAAA,CAAM,EAAA,CAAG,OAAA,EAAS,GAAG,OAAO,KAAA;AACvC,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,EAAA,EAAI,QAAQ,CAAA,GAAI,MAAM,IAAI,IAAA,CAAK,GAAG,CAAA,EAAG,QAAQ,CAAA;AAChE,IAAA,MAAM,IAAA,GAAO,SAAS,CAAA,GAAI,KAAA,CAAM,QAAQ,IAAA,KAAS,CAAA,GAAI,MAAM,QAAA,GAAW,EAAA;AACtE,IAAA,IAAI,CAAC,IAAA,EAAM,OAAO,gBAAgB,KAAA,EAAO,KAAA,CAAA,EAAW,QAAQ,QAAQ,CAAA;AACpE,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,cAAA,CAAe,MAAA,EAAQ;AAAA,MAC3C,IAAA,EAAM,SAAA;AAAA,MACN,MAAA,EAAQ,SAAA;AAAA,MACR,GAAI,QAAA,GAAW,EAAE,QAAA,KAAa;AAAC,KAChC,CAAA,CAAE,MAAA,CAAO,EAAE,CAAA;AACZ,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,IAAI,CAAA;AAAA,EACpC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,eAAA,CAAgB,KAAA,EAAO,MAAA,EAAW,MAAA,EAAQ,QAAQ,CAAA;AAAA,EAC3D;AACF;AAGO,SAAS,UAAA,CAAW,MAAc,MAAA,EAAyB;AAChE,EAAA,MAAM,CAAA,GAAI,2BAAA,CAA4B,IAAA,CAAK,IAAI,CAAA;AAC/C,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,IAAA,CAAK,cAAA,CAAe,MAAA,EAAQ;AAAA,MACrC,IAAA,EAAM,SAAA;AAAA,MACN,KAAA,EAAO,MAAA;AAAA,MACP,GAAA,EAAK,SAAA;AAAA,MACL,QAAA,EAAU;AAAA,KACX,CAAA,CAAE,MAAA,CAAO,IAAI,IAAA,CAAK,KAAK,GAAA,CAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG,OAAO,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,CAAA,EAAG,MAAA,CAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAAA,EAC5E,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"index.cjs","sourcesContent":["// The words a Vinaverse UI says, in English, Spanish and Brazilian Portuguese, each overridable by the tenant except\n// the fallback disclosure. People first: \"agent\", never \"assistant\"; a person from the business is a person, by role.\n// `{name}` placeholders are filled from `vars`.\n\nconst en = {\n disclosureFallback: \"You're chatting with an AI agent. Powered by Vinaverse.\",\n agentLabel: 'AI agent',\n agentFallbackName: 'the agent',\n you: 'You',\n staffLabel: '{by} · person',\n staffFallbackRole: 'the team',\n composerPlaceholder: 'Message {agent}',\n composerPlaceholderTakeover: 'Message {by}',\n send: 'Send',\n stop: 'Stop',\n typeAnswerBelow: 'Type your answer below.',\n bannerConnecting: 'Connecting…',\n bannerReconnecting: 'Reconnecting…',\n bannerOffline: \"You're offline. Messages send when you're back.\",\n bannerContinuedElsewhere: 'This conversation continued on another device.',\n bannerUnavailable: \"Couldn't connect.\",\n continueHere: 'Continue here',\n tryAgain: 'Try again',\n talkToPerson: 'Talk to a person',\n messageSending: 'Sending',\n messageHeld: 'Sends when you continue',\n messageNotSent: 'Not sent',\n messageDelivered: 'Delivered',\n messageCutOff: 'This reply was cut off.',\n takeoverStarted: 'A person from {by} is replying now.',\n takeoverEnded: '{agent} is back.',\n handoffCreated: \"We've passed this to the team. They'll reply {expected}.\",\n handoffCreatedNoTime: \"We've passed this to the team. They'll reply soon.\",\n flowSent: 'Your answers were sent.',\n flowNotSent: \"Your answers couldn't be sent yet.\",\n turnFailed: 'Something went wrong.',\n working: '{agent} is working on it…',\n proposalConfirm: 'Confirm',\n proposalDecline: 'Decline',\n proposalChange: 'Change',\n proposalConfirmed: 'Confirmed',\n proposalDeclined: 'Declined',\n proposalFailed: \"Couldn't be confirmed\",\n proposalExpired: 'Expired',\n proposalSettled: 'No longer open',\n questionSubmit: 'Send',\n questionSkip: 'Skip',\n questionOther: 'Other',\n questionSearch: 'Search',\n questionAnswered: 'Answered',\n questionReplaced: 'Replaced by a newer question',\n questionStep: 'Question {step} of {total}',\n questionAddPhoto: 'Add a photo',\n questionCharactersLeft: '{count} characters left',\n priceFrom: 'From {price}',\n /** A listing with no rating yet; empty draws nothing, a tenant's word (\"New\") draws in the rating's place. */\n ratingNone: '',\n nextAvailable: 'Next: {time}',\n /** A time today and tomorrow, as `nextAvailable` says it (`{time}`: \"10:00 AM\"). */\n today: 'today, {time}',\n tomorrow: 'tomorrow, {time}',\n agentEnded: 'This conversation ended',\n agentEndedBody: 'Start a new one whenever you like.',\n agentStartOver: 'Start a new conversation',\n agentUnreachable: \"Couldn't reach {agent}\",\n agentUnreachableBody: 'Check your connection and try again.',\n agentOff: \"{agent} isn't available right now\",\n agentOffBody: 'Please try again later.',\n helpful: 'Was this helpful?',\n helpfulYes: 'Yes',\n helpfulNo: 'No',\n helpfulThanks: 'Thanks for telling us.',\n launcherOpen: 'Open {agent}',\n launcherGreeting: \"Hi, I'm {agent}. Ask me what you need.\",\n close: 'Close',\n welcomeFallback: \"Hi, I'm {agent}. How can I help?\",\n privacy: 'Privacy',\n cardsInRow: '{count} results, swipe for more',\n open: 'Open',\n} as const;\n\nexport type CopyKey = keyof typeof en;\nexport type Copy = Readonly<Record<CopyKey, string>>;\n/** A tenant's words, by key; a key left out (or undefined) keeps the built-in one. */\nexport type CopyOverrides = { readonly [K in CopyKey]?: string | undefined };\n\nconst es: Copy = {\n disclosureFallback:\n 'Estás hablando con un agente de IA. Con la tecnología de Vinaverse.',\n agentLabel: 'Agente de IA',\n agentFallbackName: 'el agente',\n you: 'Tú',\n staffLabel: '{by} · persona',\n staffFallbackRole: 'el equipo',\n composerPlaceholder: 'Escribe a {agent}',\n composerPlaceholderTakeover: 'Escribe a {by}',\n send: 'Enviar',\n stop: 'Detener',\n typeAnswerBelow: 'Escribe tu respuesta abajo.',\n bannerConnecting: 'Conectando…',\n bannerReconnecting: 'Reconectando…',\n bannerOffline: 'Sin conexión. Los mensajes se envían cuando vuelvas.',\n bannerContinuedElsewhere: 'Esta conversación continuó en otro dispositivo.',\n bannerUnavailable: 'No se pudo conectar.',\n continueHere: 'Continuar aquí',\n tryAgain: 'Intentar de nuevo',\n talkToPerson: 'Hablar con una persona',\n messageSending: 'Enviando',\n messageHeld: 'Se envía cuando continúes',\n messageNotSent: 'No enviado',\n messageDelivered: 'Entregado',\n messageCutOff: 'Esta respuesta quedó incompleta.',\n takeoverStarted: 'Una persona de {by} está respondiendo.',\n takeoverEnded: '{agent} volvió.',\n handoffCreated: 'Le pasamos esto al equipo. Responderán {expected}.',\n handoffCreatedNoTime: 'Le pasamos esto al equipo. Responderán pronto.',\n flowSent: 'Tus respuestas se enviaron.',\n flowNotSent: 'Tus respuestas aún no se pudieron enviar.',\n turnFailed: 'Algo salió mal.',\n working: '{agent} está en ello…',\n proposalConfirm: 'Confirmar',\n proposalDecline: 'Rechazar',\n proposalChange: 'Cambiar',\n proposalConfirmed: 'Confirmado',\n proposalDeclined: 'Rechazado',\n proposalFailed: 'No se pudo confirmar',\n proposalExpired: 'Vencido',\n proposalSettled: 'Ya no está abierto',\n questionSubmit: 'Enviar',\n questionSkip: 'Omitir',\n questionOther: 'Otro',\n questionSearch: 'Buscar',\n questionAnswered: 'Respondida',\n questionReplaced: 'Reemplazada por una pregunta más reciente',\n questionStep: 'Pregunta {step} de {total}',\n questionAddPhoto: 'Agregar una foto',\n questionCharactersLeft: 'Quedan {count} caracteres',\n priceFrom: 'Desde {price}',\n ratingNone: '',\n nextAvailable: 'Próximo: {time}',\n today: 'hoy, {time}',\n tomorrow: 'mañana, {time}',\n agentEnded: 'Esta conversación terminó',\n agentEndedBody: 'Empieza una nueva cuando quieras.',\n agentStartOver: 'Empezar una conversación nueva',\n agentUnreachable: 'No se pudo contactar a {agent}',\n agentUnreachableBody: 'Revisa tu conexión e inténtalo de nuevo.',\n agentOff: '{agent} no está disponible ahora',\n agentOffBody: 'Inténtalo de nuevo más tarde.',\n helpful: '¿Te sirvió?',\n helpfulYes: 'Sí',\n helpfulNo: 'No',\n helpfulThanks: 'Gracias por contarnos.',\n launcherOpen: 'Abrir {agent}',\n launcherGreeting: 'Hola, soy {agent}. Pregúntame lo que necesites.',\n close: 'Cerrar',\n welcomeFallback: 'Hola, soy {agent}. ¿En qué te ayudo?',\n privacy: 'Privacidad',\n cardsInRow: '{count} resultados, desliza para ver más',\n open: 'Abrir',\n};\n\nconst ptBR: Copy = {\n disclosureFallback:\n 'Você está conversando com um agente de IA. Com tecnologia Vinaverse.',\n agentLabel: 'Agente de IA',\n agentFallbackName: 'o agente',\n you: 'Você',\n staffLabel: '{by} · pessoa',\n staffFallbackRole: 'a equipe',\n composerPlaceholder: 'Mensagem para {agent}',\n composerPlaceholderTakeover: 'Mensagem para {by}',\n send: 'Enviar',\n stop: 'Parar',\n typeAnswerBelow: 'Digite sua resposta abaixo.',\n bannerConnecting: 'Conectando…',\n bannerReconnecting: 'Reconectando…',\n bannerOffline: 'Sem conexão. As mensagens são enviadas quando você voltar.',\n bannerContinuedElsewhere: 'Esta conversa continuou em outro aparelho.',\n bannerUnavailable: 'Não foi possível conectar.',\n continueHere: 'Continuar aqui',\n tryAgain: 'Tentar de novo',\n talkToPerson: 'Falar com uma pessoa',\n messageSending: 'Enviando',\n messageHeld: 'Será enviada quando você continuar',\n messageNotSent: 'Não enviada',\n messageDelivered: 'Entregue',\n messageCutOff: 'Esta resposta foi interrompida.',\n takeoverStarted: 'Uma pessoa de {by} está respondendo agora.',\n takeoverEnded: '{agent} voltou.',\n handoffCreated: 'Passamos isso para a equipe. Eles vão responder {expected}.',\n handoffCreatedNoTime:\n 'Passamos isso para a equipe. Eles vão responder em breve.',\n flowSent: 'Suas respostas foram enviadas.',\n flowNotSent: 'Ainda não foi possível enviar suas respostas.',\n turnFailed: 'Algo deu errado.',\n working: '{agent} está cuidando disso…',\n proposalConfirm: 'Confirmar',\n proposalDecline: 'Recusar',\n proposalChange: 'Alterar',\n proposalConfirmed: 'Confirmado',\n proposalDeclined: 'Recusado',\n proposalFailed: 'Não foi possível confirmar',\n proposalExpired: 'Expirado',\n proposalSettled: 'Não está mais aberto',\n questionSubmit: 'Enviar',\n questionSkip: 'Pular',\n questionOther: 'Outro',\n questionSearch: 'Buscar',\n questionAnswered: 'Respondida',\n questionReplaced: 'Substituída por uma pergunta mais recente',\n questionStep: 'Pergunta {step} de {total}',\n questionAddPhoto: 'Adicionar uma foto',\n questionCharactersLeft: 'Restam {count} caracteres',\n priceFrom: 'A partir de {price}',\n ratingNone: '',\n nextAvailable: 'Próximo horário: {time}',\n today: 'hoje, {time}',\n tomorrow: 'amanhã, {time}',\n agentEnded: 'Esta conversa terminou',\n agentEndedBody: 'Comece uma nova quando quiser.',\n agentStartOver: 'Começar uma conversa nova',\n agentUnreachable: 'Não foi possível falar com {agent}',\n agentUnreachableBody: 'Verifique sua conexão e tente de novo.',\n agentOff: '{agent} não está disponível agora',\n agentOffBody: 'Tente de novo mais tarde.',\n helpful: 'Isso ajudou?',\n helpfulYes: 'Sim',\n helpfulNo: 'Não',\n helpfulThanks: 'Obrigado por avisar.',\n launcherOpen: 'Abrir {agent}',\n launcherGreeting: 'Oi, sou {agent}. Pergunte o que precisar.',\n close: 'Fechar',\n welcomeFallback: 'Oi, sou {agent}. Como posso ajudar?',\n privacy: 'Privacidade',\n cardsInRow: '{count} resultados, deslize para ver mais',\n open: 'Abrir',\n};\n\n/** The built-in languages; any other locale falls back to English, its own `copy` overrides aside. */\nexport const COPY: Readonly<Record<'en' | 'es' | 'pt-BR', Copy>> = {\n en,\n es,\n 'pt-BR': ptBR,\n};\n\n/**\n * Keys a tenant may not override in a built-in language: the AI disclosure is the platform's, never removed or reworded.\n * In a language without built-in copy the tenant supplies them, translated, so the disclosure reads in the person's\n * language, and only a translation that still discloses is taken (`discloses`): the label says AI, the disclosure says\n * AI and names Vinaverse.\n */\nconst FIXED: ReadonlySet<CopyKey> = new Set([\n 'disclosureFallback',\n 'agentLabel',\n]);\n\n/**\n * \"AI\" as languages write it: AI, IA (es, pt, fr, it, ro), KI (de, nl, da, no, sv), SI (pl), YZ (tr), ИИ (ru), ШІ\n * (uk), and the words for it in Arabic, Hebrew, Hindi, Chinese, Japanese and Korean.\n */\nexport const AI_MARK =\n /(?:^|[^\\p{L}])(?:AI|IA|KI|SI|YZ|ИИ|ШІ)(?:$|[^\\p{L}])|الذكاء الاصطناعي|بالذكاء|בינה מלאכותית|एआई|कृत्रिम बुद्धि|人工智能|人工知能|인공지능/u;\n\n/**\n * Whether a tenant's text for a fixed key still makes the AI disclosure: the label says AI; the disclosure says AI\n * and names Vinaverse. A tenant's translation that does not is ignored, and the English built-in shows instead.\n */\nfunction discloses(key: string, value: string): boolean {\n if (!AI_MARK.test(value)) return false;\n return key !== 'disclosureFallback' || value.includes('Vinaverse');\n}\n\nexport type Translate = (\n key: CopyKey,\n vars?: Readonly<Record<string, string | number>>,\n) => string;\n\n/** The built-in copy for a locale: its language (`es-US` → `es`, `pt-PT` → `pt-BR`), else null. */\nfunction builtIn(locale: string | undefined): Copy | null {\n const language = (locale ?? 'en').split(/[-_]/)[0]?.toLowerCase();\n if (language === 'en') return COPY.en;\n if (language === 'es') return COPY.es;\n if (language === 'pt') return COPY['pt-BR'];\n return null;\n}\n\n/** The built-in copy for a locale, English when the language has none. */\nexport function builtInCopy(locale: string | undefined): Copy {\n return builtIn(locale) ?? COPY.en;\n}\n\n/** A translator for a locale, with the tenant's overrides on top (fixed keys excepted). */\nexport function createTranslate(\n locale: string | undefined,\n overrides: CopyOverrides = {},\n): Translate {\n const own = builtIn(locale);\n const merged: Record<string, string> = { ...(own ?? COPY.en) };\n for (const [key, value] of Object.entries(overrides)) {\n if (value === undefined) continue;\n if (FIXED.has(key as CopyKey) && !(own === null && discloses(key, value)))\n continue;\n merged[key] = value;\n }\n return (key, vars) =>\n (merged[key] ?? en[key]).replace(/\\{(\\w+)\\}/g, (all, name: string) =>\n vars && name in vars ? String(vars[name]) : all,\n );\n}\n\n/**\n * Words a Vinaverse UI never says to people (a tenant override that uses them gets a development warning): the\n * runtime is an agent, never an assistant or a bot; and never \"crew\".\n */\nexport const BANNED_WORDS: readonly RegExp[] = [\n /\\bassistant/i,\n /\\basistente/i,\n /\\bassistent/i,\n /\\bbot\\b/i,\n /\\bcrew\\b/i,\n];\n\n/** The overrides that use a banned word, by key. */\nexport function bannedWordsIn(overrides: CopyOverrides): CopyKey[] {\n return (Object.entries(overrides) as [CopyKey, string | undefined][])\n .filter(([, v]) => v !== undefined && BANNED_WORDS.some((w) => w.test(v)))\n .map(([k]) => k);\n}\n","// Dates, times, money and text direction in the person's locale, through Intl (Hermes has it), with a plain fallback\n// where a runtime lacks it.\n\n/** Languages and scripts written right to left. */\nconst RTL_LANGUAGES = new Set([\n 'ar',\n 'he',\n 'iw',\n 'fa',\n 'ur',\n 'ps',\n 'yi',\n 'dv',\n 'ckb',\n 'sd',\n 'ug',\n 'syr',\n]);\nconst RTL_SCRIPTS = new Set([\n 'arab',\n 'hebr',\n 'thaa',\n 'syrc',\n 'nkoo',\n 'adlm',\n 'rohg',\n]);\n\n/** `rtl` for Arabic, Hebrew, Persian, Urdu and the other right-to-left languages and scripts; `ltr` otherwise. */\nexport function textDirection(locale: string | undefined): 'ltr' | 'rtl' {\n const parts = (locale ?? '').toLowerCase().split(/[-_]/);\n if (parts.some((p) => p.length === 4 && RTL_SCRIPTS.has(p))) return 'rtl';\n return RTL_LANGUAGES.has(parts[0] ?? '') ? 'rtl' : 'ltr';\n}\n\n/** An amount in minor units (`amount` cents) in its currency: `$85.00`. */\nexport function formatMoney(\n amountMinor: number,\n currency: string,\n locale?: string,\n): string {\n try {\n const format = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n });\n const digits = format.resolvedOptions().maximumFractionDigits ?? 2;\n return format.format(amountMinor / 10 ** digits);\n } catch {\n return `${currency} ${(amountMinor / 100).toFixed(2)}`;\n }\n}\n\n/** A start and an end: \"Wed, Oct 14, 10:00 – 11:30 AM\" in the locale and time zone. */\nexport function formatTimeRange(\n start: string,\n end: string | undefined,\n locale?: string,\n timeZone?: string,\n): string {\n const from = new Date(start);\n if (Number.isNaN(from.getTime())) return start;\n const options: Intl.DateTimeFormatOptions = {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n ...(timeZone ? { timeZone } : {}),\n };\n try {\n const format = new Intl.DateTimeFormat(locale, options);\n const to = end ? new Date(end) : null;\n if (!to || Number.isNaN(to.getTime())) return format.format(from);\n return typeof format.formatRange === 'function'\n ? format.formatRange(from, to)\n : `${format.format(from)} – ${format.format(to)}`;\n } catch {\n return from.toISOString();\n }\n}\n\n/** The day a moment falls on in a time zone, as a day count, so two days compare across DST. */\nfunction dayOf(at: Date, timeZone: string | undefined): number {\n const [y, m, d] = new Intl.DateTimeFormat('en-CA', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n ...(timeZone ? { timeZone } : {}),\n })\n .format(at)\n .split('-')\n .map(Number);\n return Date.UTC(y as number, (m as number) - 1, d as number) / 86_400_000;\n}\n\n/**\n * A moment as a person says it: \"today, 10:00 AM\" and \"tomorrow, 10:00 AM\" (`today` and `tomorrow` are the copy's\n * words, with `{time}`), else the date and time (\"Fri, Oct 17, 10:00 AM\"), in the locale and time zone. `now` is the\n * clock it is judged by.\n */\nexport function formatDayTime(\n start: string,\n words: { readonly today: string; readonly tomorrow: string },\n locale?: string,\n timeZone?: string,\n now: number = Date.now(),\n): string {\n const at = new Date(start);\n if (Number.isNaN(at.getTime())) return start;\n try {\n const days = dayOf(at, timeZone) - dayOf(new Date(now), timeZone);\n const word = days === 0 ? words.today : days === 1 ? words.tomorrow : '';\n if (!word) return formatTimeRange(start, undefined, locale, timeZone);\n const time = new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n minute: '2-digit',\n ...(timeZone ? { timeZone } : {}),\n }).format(at);\n return word.replace('{time}', time);\n } catch {\n return formatTimeRange(start, undefined, locale, timeZone);\n }\n}\n\n/** A calendar date (`YYYY-MM-DD`) in the locale: \"October 14, 2026\". */\nexport function formatDate(date: string, locale?: string): string {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(date);\n if (!m) return date;\n try {\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n timeZone: 'UTC',\n }).format(new Date(Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3]))));\n } catch {\n return date;\n }\n}\n"]}
@@ -49,7 +49,12 @@ declare const en: {
49
49
  readonly questionAddPhoto: "Add a photo";
50
50
  readonly questionCharactersLeft: "{count} characters left";
51
51
  readonly priceFrom: "From {price}";
52
+ /** A listing with no rating yet; empty draws nothing, a tenant's word ("New") draws in the rating's place. */
53
+ readonly ratingNone: "";
52
54
  readonly nextAvailable: "Next: {time}";
55
+ /** A time today and tomorrow, as `nextAvailable` says it (`{time}`: "10:00 AM"). */
56
+ readonly today: "today, {time}";
57
+ readonly tomorrow: "tomorrow, {time}";
53
58
  readonly agentEnded: "This conversation ended";
54
59
  readonly agentEndedBody: "Start a new one whenever you like.";
55
60
  readonly agentStartOver: "Start a new conversation";
@@ -101,7 +106,16 @@ declare function textDirection(locale: string | undefined): 'ltr' | 'rtl';
101
106
  declare function formatMoney(amountMinor: number, currency: string, locale?: string): string;
102
107
  /** A start and an end: "Wed, Oct 14, 10:00 – 11:30 AM" in the locale and time zone. */
103
108
  declare function formatTimeRange(start: string, end: string | undefined, locale?: string, timeZone?: string): string;
109
+ /**
110
+ * A moment as a person says it: "today, 10:00 AM" and "tomorrow, 10:00 AM" (`today` and `tomorrow` are the copy's
111
+ * words, with `{time}`), else the date and time ("Fri, Oct 17, 10:00 AM"), in the locale and time zone. `now` is the
112
+ * clock it is judged by.
113
+ */
114
+ declare function formatDayTime(start: string, words: {
115
+ readonly today: string;
116
+ readonly tomorrow: string;
117
+ }, locale?: string, timeZone?: string, now?: number): string;
104
118
  /** A calendar date (`YYYY-MM-DD`) in the locale: "October 14, 2026". */
105
119
  declare function formatDate(date: string, locale?: string): string;
106
120
 
107
- export { AI_MARK, BANNED_WORDS, COPY, type Copy, type CopyKey, type CopyOverrides, type Translate, bannedWordsIn, builtInCopy, createTranslate, formatDate, formatMoney, formatTimeRange, textDirection };
121
+ export { AI_MARK, BANNED_WORDS, COPY, type Copy, type CopyKey, type CopyOverrides, type Translate, bannedWordsIn, builtInCopy, createTranslate, formatDate, formatDayTime, formatMoney, formatTimeRange, textDirection };
@@ -49,7 +49,12 @@ declare const en: {
49
49
  readonly questionAddPhoto: "Add a photo";
50
50
  readonly questionCharactersLeft: "{count} characters left";
51
51
  readonly priceFrom: "From {price}";
52
+ /** A listing with no rating yet; empty draws nothing, a tenant's word ("New") draws in the rating's place. */
53
+ readonly ratingNone: "";
52
54
  readonly nextAvailable: "Next: {time}";
55
+ /** A time today and tomorrow, as `nextAvailable` says it (`{time}`: "10:00 AM"). */
56
+ readonly today: "today, {time}";
57
+ readonly tomorrow: "tomorrow, {time}";
53
58
  readonly agentEnded: "This conversation ended";
54
59
  readonly agentEndedBody: "Start a new one whenever you like.";
55
60
  readonly agentStartOver: "Start a new conversation";
@@ -101,7 +106,16 @@ declare function textDirection(locale: string | undefined): 'ltr' | 'rtl';
101
106
  declare function formatMoney(amountMinor: number, currency: string, locale?: string): string;
102
107
  /** A start and an end: "Wed, Oct 14, 10:00 – 11:30 AM" in the locale and time zone. */
103
108
  declare function formatTimeRange(start: string, end: string | undefined, locale?: string, timeZone?: string): string;
109
+ /**
110
+ * A moment as a person says it: "today, 10:00 AM" and "tomorrow, 10:00 AM" (`today` and `tomorrow` are the copy's
111
+ * words, with `{time}`), else the date and time ("Fri, Oct 17, 10:00 AM"), in the locale and time zone. `now` is the
112
+ * clock it is judged by.
113
+ */
114
+ declare function formatDayTime(start: string, words: {
115
+ readonly today: string;
116
+ readonly tomorrow: string;
117
+ }, locale?: string, timeZone?: string, now?: number): string;
104
118
  /** A calendar date (`YYYY-MM-DD`) in the locale: "October 14, 2026". */
105
119
  declare function formatDate(date: string, locale?: string): string;
106
120
 
107
- export { AI_MARK, BANNED_WORDS, COPY, type Copy, type CopyKey, type CopyOverrides, type Translate, bannedWordsIn, builtInCopy, createTranslate, formatDate, formatMoney, formatTimeRange, textDirection };
121
+ export { AI_MARK, BANNED_WORDS, COPY, type Copy, type CopyKey, type CopyOverrides, type Translate, bannedWordsIn, builtInCopy, createTranslate, formatDate, formatDayTime, formatMoney, formatTimeRange, textDirection };
@@ -50,7 +50,12 @@ var en = {
50
50
  questionAddPhoto: "Add a photo",
51
51
  questionCharactersLeft: "{count} characters left",
52
52
  priceFrom: "From {price}",
53
+ /** A listing with no rating yet; empty draws nothing, a tenant's word ("New") draws in the rating's place. */
54
+ ratingNone: "",
53
55
  nextAvailable: "Next: {time}",
56
+ /** A time today and tomorrow, as `nextAvailable` says it (`{time}`: "10:00 AM"). */
57
+ today: "today, {time}",
58
+ tomorrow: "tomorrow, {time}",
54
59
  agentEnded: "This conversation ended",
55
60
  agentEndedBody: "Start a new one whenever you like.",
56
61
  agentStartOver: "Start a new conversation",
@@ -121,7 +126,10 @@ var es = {
121
126
  questionAddPhoto: "Agregar una foto",
122
127
  questionCharactersLeft: "Quedan {count} caracteres",
123
128
  priceFrom: "Desde {price}",
129
+ ratingNone: "",
124
130
  nextAvailable: "Pr\xF3ximo: {time}",
131
+ today: "hoy, {time}",
132
+ tomorrow: "ma\xF1ana, {time}",
125
133
  agentEnded: "Esta conversaci\xF3n termin\xF3",
126
134
  agentEndedBody: "Empieza una nueva cuando quieras.",
127
135
  agentStartOver: "Empezar una conversaci\xF3n nueva",
@@ -192,7 +200,10 @@ var ptBR = {
192
200
  questionAddPhoto: "Adicionar uma foto",
193
201
  questionCharactersLeft: "Restam {count} caracteres",
194
202
  priceFrom: "A partir de {price}",
203
+ ratingNone: "",
195
204
  nextAvailable: "Pr\xF3ximo hor\xE1rio: {time}",
205
+ today: "hoje, {time}",
206
+ tomorrow: "amanh\xE3, {time}",
196
207
  agentEnded: "Esta conversa terminou",
197
208
  agentEndedBody: "Comece uma nova quando quiser.",
198
209
  agentStartOver: "Come\xE7ar uma conversa nova",
@@ -322,6 +333,32 @@ function formatTimeRange(start, end, locale, timeZone) {
322
333
  return from.toISOString();
323
334
  }
324
335
  }
336
+ function dayOf(at, timeZone) {
337
+ const [y, m, d] = new Intl.DateTimeFormat("en-CA", {
338
+ year: "numeric",
339
+ month: "2-digit",
340
+ day: "2-digit",
341
+ ...timeZone ? { timeZone } : {}
342
+ }).format(at).split("-").map(Number);
343
+ return Date.UTC(y, m - 1, d) / 864e5;
344
+ }
345
+ function formatDayTime(start, words, locale, timeZone, now = Date.now()) {
346
+ const at = new Date(start);
347
+ if (Number.isNaN(at.getTime())) return start;
348
+ try {
349
+ const days = dayOf(at, timeZone) - dayOf(new Date(now), timeZone);
350
+ const word = days === 0 ? words.today : days === 1 ? words.tomorrow : "";
351
+ if (!word) return formatTimeRange(start, void 0, locale, timeZone);
352
+ const time = new Intl.DateTimeFormat(locale, {
353
+ hour: "numeric",
354
+ minute: "2-digit",
355
+ ...timeZone ? { timeZone } : {}
356
+ }).format(at);
357
+ return word.replace("{time}", time);
358
+ } catch {
359
+ return formatTimeRange(start, void 0, locale, timeZone);
360
+ }
361
+ }
325
362
  function formatDate(date, locale) {
326
363
  const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date);
327
364
  if (!m) return date;
@@ -337,6 +374,6 @@ function formatDate(date, locale) {
337
374
  }
338
375
  }
339
376
 
340
- export { AI_MARK, BANNED_WORDS, COPY, bannedWordsIn, builtInCopy, createTranslate, formatDate, formatMoney, formatTimeRange, textDirection };
377
+ export { AI_MARK, BANNED_WORDS, COPY, bannedWordsIn, builtInCopy, createTranslate, formatDate, formatDayTime, formatMoney, formatTimeRange, textDirection };
341
378
  //# sourceMappingURL=index.js.map
342
379
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/copy/copy.ts","../../src/copy/format.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// The words a Vinaverse UI says, in English, Spanish and Brazilian Portuguese, each overridable by the tenant except\n// the fallback disclosure. People first: \"agent\", never \"assistant\"; a person from the business is a person, by role.\n// `{name}` placeholders are filled from `vars`.\n\nconst en = {\n disclosureFallback: \"You're chatting with an AI agent. Powered by Vinaverse.\",\n agentLabel: 'AI agent',\n agentFallbackName: 'the agent',\n you: 'You',\n staffLabel: '{by} · person',\n staffFallbackRole: 'the team',\n composerPlaceholder: 'Message {agent}',\n composerPlaceholderTakeover: 'Message {by}',\n send: 'Send',\n stop: 'Stop',\n typeAnswerBelow: 'Type your answer below.',\n bannerConnecting: 'Connecting…',\n bannerReconnecting: 'Reconnecting…',\n bannerOffline: \"You're offline. Messages send when you're back.\",\n bannerContinuedElsewhere: 'This conversation continued on another device.',\n bannerUnavailable: \"Couldn't connect.\",\n continueHere: 'Continue here',\n tryAgain: 'Try again',\n talkToPerson: 'Talk to a person',\n messageSending: 'Sending',\n messageHeld: 'Sends when you continue',\n messageNotSent: 'Not sent',\n messageDelivered: 'Delivered',\n messageCutOff: 'This reply was cut off.',\n takeoverStarted: 'A person from {by} is replying now.',\n takeoverEnded: '{agent} is back.',\n handoffCreated: \"We've passed this to the team. They'll reply {expected}.\",\n handoffCreatedNoTime: \"We've passed this to the team. They'll reply soon.\",\n flowSent: 'Your answers were sent.',\n flowNotSent: \"Your answers couldn't be sent yet.\",\n turnFailed: 'Something went wrong.',\n working: '{agent} is working on it…',\n proposalConfirm: 'Confirm',\n proposalDecline: 'Decline',\n proposalChange: 'Change',\n proposalConfirmed: 'Confirmed',\n proposalDeclined: 'Declined',\n proposalFailed: \"Couldn't be confirmed\",\n proposalExpired: 'Expired',\n proposalSettled: 'No longer open',\n questionSubmit: 'Send',\n questionSkip: 'Skip',\n questionOther: 'Other',\n questionSearch: 'Search',\n questionAnswered: 'Answered',\n questionReplaced: 'Replaced by a newer question',\n questionStep: 'Question {step} of {total}',\n questionAddPhoto: 'Add a photo',\n questionCharactersLeft: '{count} characters left',\n priceFrom: 'From {price}',\n nextAvailable: 'Next: {time}',\n agentEnded: 'This conversation ended',\n agentEndedBody: 'Start a new one whenever you like.',\n agentStartOver: 'Start a new conversation',\n agentUnreachable: \"Couldn't reach {agent}\",\n agentUnreachableBody: 'Check your connection and try again.',\n agentOff: \"{agent} isn't available right now\",\n agentOffBody: 'Please try again later.',\n helpful: 'Was this helpful?',\n helpfulYes: 'Yes',\n helpfulNo: 'No',\n helpfulThanks: 'Thanks for telling us.',\n launcherOpen: 'Open {agent}',\n launcherGreeting: \"Hi, I'm {agent}. Ask me what you need.\",\n close: 'Close',\n welcomeFallback: \"Hi, I'm {agent}. How can I help?\",\n privacy: 'Privacy',\n cardsInRow: '{count} results, swipe for more',\n open: 'Open',\n} as const;\n\nexport type CopyKey = keyof typeof en;\nexport type Copy = Readonly<Record<CopyKey, string>>;\n/** A tenant's words, by key; a key left out (or undefined) keeps the built-in one. */\nexport type CopyOverrides = { readonly [K in CopyKey]?: string | undefined };\n\nconst es: Copy = {\n disclosureFallback:\n 'Estás hablando con un agente de IA. Con la tecnología de Vinaverse.',\n agentLabel: 'Agente de IA',\n agentFallbackName: 'el agente',\n you: 'Tú',\n staffLabel: '{by} · persona',\n staffFallbackRole: 'el equipo',\n composerPlaceholder: 'Escribe a {agent}',\n composerPlaceholderTakeover: 'Escribe a {by}',\n send: 'Enviar',\n stop: 'Detener',\n typeAnswerBelow: 'Escribe tu respuesta abajo.',\n bannerConnecting: 'Conectando…',\n bannerReconnecting: 'Reconectando…',\n bannerOffline: 'Sin conexión. Los mensajes se envían cuando vuelvas.',\n bannerContinuedElsewhere: 'Esta conversación continuó en otro dispositivo.',\n bannerUnavailable: 'No se pudo conectar.',\n continueHere: 'Continuar aquí',\n tryAgain: 'Intentar de nuevo',\n talkToPerson: 'Hablar con una persona',\n messageSending: 'Enviando',\n messageHeld: 'Se envía cuando continúes',\n messageNotSent: 'No enviado',\n messageDelivered: 'Entregado',\n messageCutOff: 'Esta respuesta quedó incompleta.',\n takeoverStarted: 'Una persona de {by} está respondiendo.',\n takeoverEnded: '{agent} volvió.',\n handoffCreated: 'Le pasamos esto al equipo. Responderán {expected}.',\n handoffCreatedNoTime: 'Le pasamos esto al equipo. Responderán pronto.',\n flowSent: 'Tus respuestas se enviaron.',\n flowNotSent: 'Tus respuestas aún no se pudieron enviar.',\n turnFailed: 'Algo salió mal.',\n working: '{agent} está en ello…',\n proposalConfirm: 'Confirmar',\n proposalDecline: 'Rechazar',\n proposalChange: 'Cambiar',\n proposalConfirmed: 'Confirmado',\n proposalDeclined: 'Rechazado',\n proposalFailed: 'No se pudo confirmar',\n proposalExpired: 'Vencido',\n proposalSettled: 'Ya no está abierto',\n questionSubmit: 'Enviar',\n questionSkip: 'Omitir',\n questionOther: 'Otro',\n questionSearch: 'Buscar',\n questionAnswered: 'Respondida',\n questionReplaced: 'Reemplazada por una pregunta más reciente',\n questionStep: 'Pregunta {step} de {total}',\n questionAddPhoto: 'Agregar una foto',\n questionCharactersLeft: 'Quedan {count} caracteres',\n priceFrom: 'Desde {price}',\n nextAvailable: 'Próximo: {time}',\n agentEnded: 'Esta conversación terminó',\n agentEndedBody: 'Empieza una nueva cuando quieras.',\n agentStartOver: 'Empezar una conversación nueva',\n agentUnreachable: 'No se pudo contactar a {agent}',\n agentUnreachableBody: 'Revisa tu conexión e inténtalo de nuevo.',\n agentOff: '{agent} no está disponible ahora',\n agentOffBody: 'Inténtalo de nuevo más tarde.',\n helpful: '¿Te sirvió?',\n helpfulYes: 'Sí',\n helpfulNo: 'No',\n helpfulThanks: 'Gracias por contarnos.',\n launcherOpen: 'Abrir {agent}',\n launcherGreeting: 'Hola, soy {agent}. Pregúntame lo que necesites.',\n close: 'Cerrar',\n welcomeFallback: 'Hola, soy {agent}. ¿En qué te ayudo?',\n privacy: 'Privacidad',\n cardsInRow: '{count} resultados, desliza para ver más',\n open: 'Abrir',\n};\n\nconst ptBR: Copy = {\n disclosureFallback:\n 'Você está conversando com um agente de IA. Com tecnologia Vinaverse.',\n agentLabel: 'Agente de IA',\n agentFallbackName: 'o agente',\n you: 'Você',\n staffLabel: '{by} · pessoa',\n staffFallbackRole: 'a equipe',\n composerPlaceholder: 'Mensagem para {agent}',\n composerPlaceholderTakeover: 'Mensagem para {by}',\n send: 'Enviar',\n stop: 'Parar',\n typeAnswerBelow: 'Digite sua resposta abaixo.',\n bannerConnecting: 'Conectando…',\n bannerReconnecting: 'Reconectando…',\n bannerOffline: 'Sem conexão. As mensagens são enviadas quando você voltar.',\n bannerContinuedElsewhere: 'Esta conversa continuou em outro aparelho.',\n bannerUnavailable: 'Não foi possível conectar.',\n continueHere: 'Continuar aqui',\n tryAgain: 'Tentar de novo',\n talkToPerson: 'Falar com uma pessoa',\n messageSending: 'Enviando',\n messageHeld: 'Será enviada quando você continuar',\n messageNotSent: 'Não enviada',\n messageDelivered: 'Entregue',\n messageCutOff: 'Esta resposta foi interrompida.',\n takeoverStarted: 'Uma pessoa de {by} está respondendo agora.',\n takeoverEnded: '{agent} voltou.',\n handoffCreated: 'Passamos isso para a equipe. Eles vão responder {expected}.',\n handoffCreatedNoTime:\n 'Passamos isso para a equipe. Eles vão responder em breve.',\n flowSent: 'Suas respostas foram enviadas.',\n flowNotSent: 'Ainda não foi possível enviar suas respostas.',\n turnFailed: 'Algo deu errado.',\n working: '{agent} está cuidando disso…',\n proposalConfirm: 'Confirmar',\n proposalDecline: 'Recusar',\n proposalChange: 'Alterar',\n proposalConfirmed: 'Confirmado',\n proposalDeclined: 'Recusado',\n proposalFailed: 'Não foi possível confirmar',\n proposalExpired: 'Expirado',\n proposalSettled: 'Não está mais aberto',\n questionSubmit: 'Enviar',\n questionSkip: 'Pular',\n questionOther: 'Outro',\n questionSearch: 'Buscar',\n questionAnswered: 'Respondida',\n questionReplaced: 'Substituída por uma pergunta mais recente',\n questionStep: 'Pergunta {step} de {total}',\n questionAddPhoto: 'Adicionar uma foto',\n questionCharactersLeft: 'Restam {count} caracteres',\n priceFrom: 'A partir de {price}',\n nextAvailable: 'Próximo horário: {time}',\n agentEnded: 'Esta conversa terminou',\n agentEndedBody: 'Comece uma nova quando quiser.',\n agentStartOver: 'Começar uma conversa nova',\n agentUnreachable: 'Não foi possível falar com {agent}',\n agentUnreachableBody: 'Verifique sua conexão e tente de novo.',\n agentOff: '{agent} não está disponível agora',\n agentOffBody: 'Tente de novo mais tarde.',\n helpful: 'Isso ajudou?',\n helpfulYes: 'Sim',\n helpfulNo: 'Não',\n helpfulThanks: 'Obrigado por avisar.',\n launcherOpen: 'Abrir {agent}',\n launcherGreeting: 'Oi, sou {agent}. Pergunte o que precisar.',\n close: 'Fechar',\n welcomeFallback: 'Oi, sou {agent}. Como posso ajudar?',\n privacy: 'Privacidade',\n cardsInRow: '{count} resultados, deslize para ver mais',\n open: 'Abrir',\n};\n\n/** The built-in languages; any other locale falls back to English, its own `copy` overrides aside. */\nexport const COPY: Readonly<Record<'en' | 'es' | 'pt-BR', Copy>> = {\n en,\n es,\n 'pt-BR': ptBR,\n};\n\n/**\n * Keys a tenant may not override in a built-in language: the AI disclosure is the platform's, never removed or reworded.\n * In a language without built-in copy the tenant supplies them, translated, so the disclosure reads in the person's\n * language, and only a translation that still discloses is taken (`discloses`): the label says AI, the disclosure says\n * AI and names Vinaverse.\n */\nconst FIXED: ReadonlySet<CopyKey> = new Set([\n 'disclosureFallback',\n 'agentLabel',\n]);\n\n/**\n * \"AI\" as languages write it: AI, IA (es, pt, fr, it, ro), KI (de, nl, da, no, sv), SI (pl), YZ (tr), ИИ (ru), ШІ\n * (uk), and the words for it in Arabic, Hebrew, Hindi, Chinese, Japanese and Korean.\n */\nexport const AI_MARK =\n /(?:^|[^\\p{L}])(?:AI|IA|KI|SI|YZ|ИИ|ШІ)(?:$|[^\\p{L}])|الذكاء الاصطناعي|بالذكاء|בינה מלאכותית|एआई|कृत्रिम बुद्धि|人工智能|人工知能|인공지능/u;\n\n/**\n * Whether a tenant's text for a fixed key still makes the AI disclosure: the label says AI; the disclosure says AI\n * and names Vinaverse. A tenant's translation that does not is ignored, and the English built-in shows instead.\n */\nfunction discloses(key: string, value: string): boolean {\n if (!AI_MARK.test(value)) return false;\n return key !== 'disclosureFallback' || value.includes('Vinaverse');\n}\n\nexport type Translate = (\n key: CopyKey,\n vars?: Readonly<Record<string, string | number>>,\n) => string;\n\n/** The built-in copy for a locale: its language (`es-US` → `es`, `pt-PT` → `pt-BR`), else null. */\nfunction builtIn(locale: string | undefined): Copy | null {\n const language = (locale ?? 'en').split(/[-_]/)[0]?.toLowerCase();\n if (language === 'en') return COPY.en;\n if (language === 'es') return COPY.es;\n if (language === 'pt') return COPY['pt-BR'];\n return null;\n}\n\n/** The built-in copy for a locale, English when the language has none. */\nexport function builtInCopy(locale: string | undefined): Copy {\n return builtIn(locale) ?? COPY.en;\n}\n\n/** A translator for a locale, with the tenant's overrides on top (fixed keys excepted). */\nexport function createTranslate(\n locale: string | undefined,\n overrides: CopyOverrides = {},\n): Translate {\n const own = builtIn(locale);\n const merged: Record<string, string> = { ...(own ?? COPY.en) };\n for (const [key, value] of Object.entries(overrides)) {\n if (value === undefined) continue;\n if (FIXED.has(key as CopyKey) && !(own === null && discloses(key, value)))\n continue;\n merged[key] = value;\n }\n return (key, vars) =>\n (merged[key] ?? en[key]).replace(/\\{(\\w+)\\}/g, (all, name: string) =>\n vars && name in vars ? String(vars[name]) : all,\n );\n}\n\n/**\n * Words a Vinaverse UI never says to people (a tenant override that uses them gets a development warning): the\n * runtime is an agent, never an assistant or a bot; and never \"crew\".\n */\nexport const BANNED_WORDS: readonly RegExp[] = [\n /\\bassistant/i,\n /\\basistente/i,\n /\\bassistent/i,\n /\\bbot\\b/i,\n /\\bcrew\\b/i,\n];\n\n/** The overrides that use a banned word, by key. */\nexport function bannedWordsIn(overrides: CopyOverrides): CopyKey[] {\n return (Object.entries(overrides) as [CopyKey, string | undefined][])\n .filter(([, v]) => v !== undefined && BANNED_WORDS.some((w) => w.test(v)))\n .map(([k]) => k);\n}\n","// Dates, times, money and text direction in the person's locale, through Intl (Hermes has it), with a plain fallback\n// where a runtime lacks it.\n\n/** Languages and scripts written right to left. */\nconst RTL_LANGUAGES = new Set([\n 'ar',\n 'he',\n 'iw',\n 'fa',\n 'ur',\n 'ps',\n 'yi',\n 'dv',\n 'ckb',\n 'sd',\n 'ug',\n 'syr',\n]);\nconst RTL_SCRIPTS = new Set([\n 'arab',\n 'hebr',\n 'thaa',\n 'syrc',\n 'nkoo',\n 'adlm',\n 'rohg',\n]);\n\n/** `rtl` for Arabic, Hebrew, Persian, Urdu and the other right-to-left languages and scripts; `ltr` otherwise. */\nexport function textDirection(locale: string | undefined): 'ltr' | 'rtl' {\n const parts = (locale ?? '').toLowerCase().split(/[-_]/);\n if (parts.some((p) => p.length === 4 && RTL_SCRIPTS.has(p))) return 'rtl';\n return RTL_LANGUAGES.has(parts[0] ?? '') ? 'rtl' : 'ltr';\n}\n\n/** An amount in minor units (`amount` cents) in its currency: `$85.00`. */\nexport function formatMoney(\n amountMinor: number,\n currency: string,\n locale?: string,\n): string {\n try {\n const format = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n });\n const digits = format.resolvedOptions().maximumFractionDigits ?? 2;\n return format.format(amountMinor / 10 ** digits);\n } catch {\n return `${currency} ${(amountMinor / 100).toFixed(2)}`;\n }\n}\n\n/** A start and an end: \"Wed, Oct 14, 10:00 – 11:30 AM\" in the locale and time zone. */\nexport function formatTimeRange(\n start: string,\n end: string | undefined,\n locale?: string,\n timeZone?: string,\n): string {\n const from = new Date(start);\n if (Number.isNaN(from.getTime())) return start;\n const options: Intl.DateTimeFormatOptions = {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n ...(timeZone ? { timeZone } : {}),\n };\n try {\n const format = new Intl.DateTimeFormat(locale, options);\n const to = end ? new Date(end) : null;\n if (!to || Number.isNaN(to.getTime())) return format.format(from);\n return typeof format.formatRange === 'function'\n ? format.formatRange(from, to)\n : `${format.format(from)} – ${format.format(to)}`;\n } catch {\n return from.toISOString();\n }\n}\n\n/** A calendar date (`YYYY-MM-DD`) in the locale: \"October 14, 2026\". */\nexport function formatDate(date: string, locale?: string): string {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(date);\n if (!m) return date;\n try {\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n timeZone: 'UTC',\n }).format(new Date(Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3]))));\n } catch {\n return date;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/copy/copy.ts","../../src/copy/format.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// The words a Vinaverse UI says, in English, Spanish and Brazilian Portuguese, each overridable by the tenant except\n// the fallback disclosure. People first: \"agent\", never \"assistant\"; a person from the business is a person, by role.\n// `{name}` placeholders are filled from `vars`.\n\nconst en = {\n disclosureFallback: \"You're chatting with an AI agent. Powered by Vinaverse.\",\n agentLabel: 'AI agent',\n agentFallbackName: 'the agent',\n you: 'You',\n staffLabel: '{by} · person',\n staffFallbackRole: 'the team',\n composerPlaceholder: 'Message {agent}',\n composerPlaceholderTakeover: 'Message {by}',\n send: 'Send',\n stop: 'Stop',\n typeAnswerBelow: 'Type your answer below.',\n bannerConnecting: 'Connecting…',\n bannerReconnecting: 'Reconnecting…',\n bannerOffline: \"You're offline. Messages send when you're back.\",\n bannerContinuedElsewhere: 'This conversation continued on another device.',\n bannerUnavailable: \"Couldn't connect.\",\n continueHere: 'Continue here',\n tryAgain: 'Try again',\n talkToPerson: 'Talk to a person',\n messageSending: 'Sending',\n messageHeld: 'Sends when you continue',\n messageNotSent: 'Not sent',\n messageDelivered: 'Delivered',\n messageCutOff: 'This reply was cut off.',\n takeoverStarted: 'A person from {by} is replying now.',\n takeoverEnded: '{agent} is back.',\n handoffCreated: \"We've passed this to the team. They'll reply {expected}.\",\n handoffCreatedNoTime: \"We've passed this to the team. They'll reply soon.\",\n flowSent: 'Your answers were sent.',\n flowNotSent: \"Your answers couldn't be sent yet.\",\n turnFailed: 'Something went wrong.',\n working: '{agent} is working on it…',\n proposalConfirm: 'Confirm',\n proposalDecline: 'Decline',\n proposalChange: 'Change',\n proposalConfirmed: 'Confirmed',\n proposalDeclined: 'Declined',\n proposalFailed: \"Couldn't be confirmed\",\n proposalExpired: 'Expired',\n proposalSettled: 'No longer open',\n questionSubmit: 'Send',\n questionSkip: 'Skip',\n questionOther: 'Other',\n questionSearch: 'Search',\n questionAnswered: 'Answered',\n questionReplaced: 'Replaced by a newer question',\n questionStep: 'Question {step} of {total}',\n questionAddPhoto: 'Add a photo',\n questionCharactersLeft: '{count} characters left',\n priceFrom: 'From {price}',\n /** A listing with no rating yet; empty draws nothing, a tenant's word (\"New\") draws in the rating's place. */\n ratingNone: '',\n nextAvailable: 'Next: {time}',\n /** A time today and tomorrow, as `nextAvailable` says it (`{time}`: \"10:00 AM\"). */\n today: 'today, {time}',\n tomorrow: 'tomorrow, {time}',\n agentEnded: 'This conversation ended',\n agentEndedBody: 'Start a new one whenever you like.',\n agentStartOver: 'Start a new conversation',\n agentUnreachable: \"Couldn't reach {agent}\",\n agentUnreachableBody: 'Check your connection and try again.',\n agentOff: \"{agent} isn't available right now\",\n agentOffBody: 'Please try again later.',\n helpful: 'Was this helpful?',\n helpfulYes: 'Yes',\n helpfulNo: 'No',\n helpfulThanks: 'Thanks for telling us.',\n launcherOpen: 'Open {agent}',\n launcherGreeting: \"Hi, I'm {agent}. Ask me what you need.\",\n close: 'Close',\n welcomeFallback: \"Hi, I'm {agent}. How can I help?\",\n privacy: 'Privacy',\n cardsInRow: '{count} results, swipe for more',\n open: 'Open',\n} as const;\n\nexport type CopyKey = keyof typeof en;\nexport type Copy = Readonly<Record<CopyKey, string>>;\n/** A tenant's words, by key; a key left out (or undefined) keeps the built-in one. */\nexport type CopyOverrides = { readonly [K in CopyKey]?: string | undefined };\n\nconst es: Copy = {\n disclosureFallback:\n 'Estás hablando con un agente de IA. Con la tecnología de Vinaverse.',\n agentLabel: 'Agente de IA',\n agentFallbackName: 'el agente',\n you: 'Tú',\n staffLabel: '{by} · persona',\n staffFallbackRole: 'el equipo',\n composerPlaceholder: 'Escribe a {agent}',\n composerPlaceholderTakeover: 'Escribe a {by}',\n send: 'Enviar',\n stop: 'Detener',\n typeAnswerBelow: 'Escribe tu respuesta abajo.',\n bannerConnecting: 'Conectando…',\n bannerReconnecting: 'Reconectando…',\n bannerOffline: 'Sin conexión. Los mensajes se envían cuando vuelvas.',\n bannerContinuedElsewhere: 'Esta conversación continuó en otro dispositivo.',\n bannerUnavailable: 'No se pudo conectar.',\n continueHere: 'Continuar aquí',\n tryAgain: 'Intentar de nuevo',\n talkToPerson: 'Hablar con una persona',\n messageSending: 'Enviando',\n messageHeld: 'Se envía cuando continúes',\n messageNotSent: 'No enviado',\n messageDelivered: 'Entregado',\n messageCutOff: 'Esta respuesta quedó incompleta.',\n takeoverStarted: 'Una persona de {by} está respondiendo.',\n takeoverEnded: '{agent} volvió.',\n handoffCreated: 'Le pasamos esto al equipo. Responderán {expected}.',\n handoffCreatedNoTime: 'Le pasamos esto al equipo. Responderán pronto.',\n flowSent: 'Tus respuestas se enviaron.',\n flowNotSent: 'Tus respuestas aún no se pudieron enviar.',\n turnFailed: 'Algo salió mal.',\n working: '{agent} está en ello…',\n proposalConfirm: 'Confirmar',\n proposalDecline: 'Rechazar',\n proposalChange: 'Cambiar',\n proposalConfirmed: 'Confirmado',\n proposalDeclined: 'Rechazado',\n proposalFailed: 'No se pudo confirmar',\n proposalExpired: 'Vencido',\n proposalSettled: 'Ya no está abierto',\n questionSubmit: 'Enviar',\n questionSkip: 'Omitir',\n questionOther: 'Otro',\n questionSearch: 'Buscar',\n questionAnswered: 'Respondida',\n questionReplaced: 'Reemplazada por una pregunta más reciente',\n questionStep: 'Pregunta {step} de {total}',\n questionAddPhoto: 'Agregar una foto',\n questionCharactersLeft: 'Quedan {count} caracteres',\n priceFrom: 'Desde {price}',\n ratingNone: '',\n nextAvailable: 'Próximo: {time}',\n today: 'hoy, {time}',\n tomorrow: 'mañana, {time}',\n agentEnded: 'Esta conversación terminó',\n agentEndedBody: 'Empieza una nueva cuando quieras.',\n agentStartOver: 'Empezar una conversación nueva',\n agentUnreachable: 'No se pudo contactar a {agent}',\n agentUnreachableBody: 'Revisa tu conexión e inténtalo de nuevo.',\n agentOff: '{agent} no está disponible ahora',\n agentOffBody: 'Inténtalo de nuevo más tarde.',\n helpful: '¿Te sirvió?',\n helpfulYes: 'Sí',\n helpfulNo: 'No',\n helpfulThanks: 'Gracias por contarnos.',\n launcherOpen: 'Abrir {agent}',\n launcherGreeting: 'Hola, soy {agent}. Pregúntame lo que necesites.',\n close: 'Cerrar',\n welcomeFallback: 'Hola, soy {agent}. ¿En qué te ayudo?',\n privacy: 'Privacidad',\n cardsInRow: '{count} resultados, desliza para ver más',\n open: 'Abrir',\n};\n\nconst ptBR: Copy = {\n disclosureFallback:\n 'Você está conversando com um agente de IA. Com tecnologia Vinaverse.',\n agentLabel: 'Agente de IA',\n agentFallbackName: 'o agente',\n you: 'Você',\n staffLabel: '{by} · pessoa',\n staffFallbackRole: 'a equipe',\n composerPlaceholder: 'Mensagem para {agent}',\n composerPlaceholderTakeover: 'Mensagem para {by}',\n send: 'Enviar',\n stop: 'Parar',\n typeAnswerBelow: 'Digite sua resposta abaixo.',\n bannerConnecting: 'Conectando…',\n bannerReconnecting: 'Reconectando…',\n bannerOffline: 'Sem conexão. As mensagens são enviadas quando você voltar.',\n bannerContinuedElsewhere: 'Esta conversa continuou em outro aparelho.',\n bannerUnavailable: 'Não foi possível conectar.',\n continueHere: 'Continuar aqui',\n tryAgain: 'Tentar de novo',\n talkToPerson: 'Falar com uma pessoa',\n messageSending: 'Enviando',\n messageHeld: 'Será enviada quando você continuar',\n messageNotSent: 'Não enviada',\n messageDelivered: 'Entregue',\n messageCutOff: 'Esta resposta foi interrompida.',\n takeoverStarted: 'Uma pessoa de {by} está respondendo agora.',\n takeoverEnded: '{agent} voltou.',\n handoffCreated: 'Passamos isso para a equipe. Eles vão responder {expected}.',\n handoffCreatedNoTime:\n 'Passamos isso para a equipe. Eles vão responder em breve.',\n flowSent: 'Suas respostas foram enviadas.',\n flowNotSent: 'Ainda não foi possível enviar suas respostas.',\n turnFailed: 'Algo deu errado.',\n working: '{agent} está cuidando disso…',\n proposalConfirm: 'Confirmar',\n proposalDecline: 'Recusar',\n proposalChange: 'Alterar',\n proposalConfirmed: 'Confirmado',\n proposalDeclined: 'Recusado',\n proposalFailed: 'Não foi possível confirmar',\n proposalExpired: 'Expirado',\n proposalSettled: 'Não está mais aberto',\n questionSubmit: 'Enviar',\n questionSkip: 'Pular',\n questionOther: 'Outro',\n questionSearch: 'Buscar',\n questionAnswered: 'Respondida',\n questionReplaced: 'Substituída por uma pergunta mais recente',\n questionStep: 'Pergunta {step} de {total}',\n questionAddPhoto: 'Adicionar uma foto',\n questionCharactersLeft: 'Restam {count} caracteres',\n priceFrom: 'A partir de {price}',\n ratingNone: '',\n nextAvailable: 'Próximo horário: {time}',\n today: 'hoje, {time}',\n tomorrow: 'amanhã, {time}',\n agentEnded: 'Esta conversa terminou',\n agentEndedBody: 'Comece uma nova quando quiser.',\n agentStartOver: 'Começar uma conversa nova',\n agentUnreachable: 'Não foi possível falar com {agent}',\n agentUnreachableBody: 'Verifique sua conexão e tente de novo.',\n agentOff: '{agent} não está disponível agora',\n agentOffBody: 'Tente de novo mais tarde.',\n helpful: 'Isso ajudou?',\n helpfulYes: 'Sim',\n helpfulNo: 'Não',\n helpfulThanks: 'Obrigado por avisar.',\n launcherOpen: 'Abrir {agent}',\n launcherGreeting: 'Oi, sou {agent}. Pergunte o que precisar.',\n close: 'Fechar',\n welcomeFallback: 'Oi, sou {agent}. Como posso ajudar?',\n privacy: 'Privacidade',\n cardsInRow: '{count} resultados, deslize para ver mais',\n open: 'Abrir',\n};\n\n/** The built-in languages; any other locale falls back to English, its own `copy` overrides aside. */\nexport const COPY: Readonly<Record<'en' | 'es' | 'pt-BR', Copy>> = {\n en,\n es,\n 'pt-BR': ptBR,\n};\n\n/**\n * Keys a tenant may not override in a built-in language: the AI disclosure is the platform's, never removed or reworded.\n * In a language without built-in copy the tenant supplies them, translated, so the disclosure reads in the person's\n * language, and only a translation that still discloses is taken (`discloses`): the label says AI, the disclosure says\n * AI and names Vinaverse.\n */\nconst FIXED: ReadonlySet<CopyKey> = new Set([\n 'disclosureFallback',\n 'agentLabel',\n]);\n\n/**\n * \"AI\" as languages write it: AI, IA (es, pt, fr, it, ro), KI (de, nl, da, no, sv), SI (pl), YZ (tr), ИИ (ru), ШІ\n * (uk), and the words for it in Arabic, Hebrew, Hindi, Chinese, Japanese and Korean.\n */\nexport const AI_MARK =\n /(?:^|[^\\p{L}])(?:AI|IA|KI|SI|YZ|ИИ|ШІ)(?:$|[^\\p{L}])|الذكاء الاصطناعي|بالذكاء|בינה מלאכותית|एआई|कृत्रिम बुद्धि|人工智能|人工知能|인공지능/u;\n\n/**\n * Whether a tenant's text for a fixed key still makes the AI disclosure: the label says AI; the disclosure says AI\n * and names Vinaverse. A tenant's translation that does not is ignored, and the English built-in shows instead.\n */\nfunction discloses(key: string, value: string): boolean {\n if (!AI_MARK.test(value)) return false;\n return key !== 'disclosureFallback' || value.includes('Vinaverse');\n}\n\nexport type Translate = (\n key: CopyKey,\n vars?: Readonly<Record<string, string | number>>,\n) => string;\n\n/** The built-in copy for a locale: its language (`es-US` → `es`, `pt-PT` → `pt-BR`), else null. */\nfunction builtIn(locale: string | undefined): Copy | null {\n const language = (locale ?? 'en').split(/[-_]/)[0]?.toLowerCase();\n if (language === 'en') return COPY.en;\n if (language === 'es') return COPY.es;\n if (language === 'pt') return COPY['pt-BR'];\n return null;\n}\n\n/** The built-in copy for a locale, English when the language has none. */\nexport function builtInCopy(locale: string | undefined): Copy {\n return builtIn(locale) ?? COPY.en;\n}\n\n/** A translator for a locale, with the tenant's overrides on top (fixed keys excepted). */\nexport function createTranslate(\n locale: string | undefined,\n overrides: CopyOverrides = {},\n): Translate {\n const own = builtIn(locale);\n const merged: Record<string, string> = { ...(own ?? COPY.en) };\n for (const [key, value] of Object.entries(overrides)) {\n if (value === undefined) continue;\n if (FIXED.has(key as CopyKey) && !(own === null && discloses(key, value)))\n continue;\n merged[key] = value;\n }\n return (key, vars) =>\n (merged[key] ?? en[key]).replace(/\\{(\\w+)\\}/g, (all, name: string) =>\n vars && name in vars ? String(vars[name]) : all,\n );\n}\n\n/**\n * Words a Vinaverse UI never says to people (a tenant override that uses them gets a development warning): the\n * runtime is an agent, never an assistant or a bot; and never \"crew\".\n */\nexport const BANNED_WORDS: readonly RegExp[] = [\n /\\bassistant/i,\n /\\basistente/i,\n /\\bassistent/i,\n /\\bbot\\b/i,\n /\\bcrew\\b/i,\n];\n\n/** The overrides that use a banned word, by key. */\nexport function bannedWordsIn(overrides: CopyOverrides): CopyKey[] {\n return (Object.entries(overrides) as [CopyKey, string | undefined][])\n .filter(([, v]) => v !== undefined && BANNED_WORDS.some((w) => w.test(v)))\n .map(([k]) => k);\n}\n","// Dates, times, money and text direction in the person's locale, through Intl (Hermes has it), with a plain fallback\n// where a runtime lacks it.\n\n/** Languages and scripts written right to left. */\nconst RTL_LANGUAGES = new Set([\n 'ar',\n 'he',\n 'iw',\n 'fa',\n 'ur',\n 'ps',\n 'yi',\n 'dv',\n 'ckb',\n 'sd',\n 'ug',\n 'syr',\n]);\nconst RTL_SCRIPTS = new Set([\n 'arab',\n 'hebr',\n 'thaa',\n 'syrc',\n 'nkoo',\n 'adlm',\n 'rohg',\n]);\n\n/** `rtl` for Arabic, Hebrew, Persian, Urdu and the other right-to-left languages and scripts; `ltr` otherwise. */\nexport function textDirection(locale: string | undefined): 'ltr' | 'rtl' {\n const parts = (locale ?? '').toLowerCase().split(/[-_]/);\n if (parts.some((p) => p.length === 4 && RTL_SCRIPTS.has(p))) return 'rtl';\n return RTL_LANGUAGES.has(parts[0] ?? '') ? 'rtl' : 'ltr';\n}\n\n/** An amount in minor units (`amount` cents) in its currency: `$85.00`. */\nexport function formatMoney(\n amountMinor: number,\n currency: string,\n locale?: string,\n): string {\n try {\n const format = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n });\n const digits = format.resolvedOptions().maximumFractionDigits ?? 2;\n return format.format(amountMinor / 10 ** digits);\n } catch {\n return `${currency} ${(amountMinor / 100).toFixed(2)}`;\n }\n}\n\n/** A start and an end: \"Wed, Oct 14, 10:00 – 11:30 AM\" in the locale and time zone. */\nexport function formatTimeRange(\n start: string,\n end: string | undefined,\n locale?: string,\n timeZone?: string,\n): string {\n const from = new Date(start);\n if (Number.isNaN(from.getTime())) return start;\n const options: Intl.DateTimeFormatOptions = {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n ...(timeZone ? { timeZone } : {}),\n };\n try {\n const format = new Intl.DateTimeFormat(locale, options);\n const to = end ? new Date(end) : null;\n if (!to || Number.isNaN(to.getTime())) return format.format(from);\n return typeof format.formatRange === 'function'\n ? format.formatRange(from, to)\n : `${format.format(from)} – ${format.format(to)}`;\n } catch {\n return from.toISOString();\n }\n}\n\n/** The day a moment falls on in a time zone, as a day count, so two days compare across DST. */\nfunction dayOf(at: Date, timeZone: string | undefined): number {\n const [y, m, d] = new Intl.DateTimeFormat('en-CA', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n ...(timeZone ? { timeZone } : {}),\n })\n .format(at)\n .split('-')\n .map(Number);\n return Date.UTC(y as number, (m as number) - 1, d as number) / 86_400_000;\n}\n\n/**\n * A moment as a person says it: \"today, 10:00 AM\" and \"tomorrow, 10:00 AM\" (`today` and `tomorrow` are the copy's\n * words, with `{time}`), else the date and time (\"Fri, Oct 17, 10:00 AM\"), in the locale and time zone. `now` is the\n * clock it is judged by.\n */\nexport function formatDayTime(\n start: string,\n words: { readonly today: string; readonly tomorrow: string },\n locale?: string,\n timeZone?: string,\n now: number = Date.now(),\n): string {\n const at = new Date(start);\n if (Number.isNaN(at.getTime())) return start;\n try {\n const days = dayOf(at, timeZone) - dayOf(new Date(now), timeZone);\n const word = days === 0 ? words.today : days === 1 ? words.tomorrow : '';\n if (!word) return formatTimeRange(start, undefined, locale, timeZone);\n const time = new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n minute: '2-digit',\n ...(timeZone ? { timeZone } : {}),\n }).format(at);\n return word.replace('{time}', time);\n } catch {\n return formatTimeRange(start, undefined, locale, timeZone);\n }\n}\n\n/** A calendar date (`YYYY-MM-DD`) in the locale: \"October 14, 2026\". */\nexport function formatDate(date: string, locale?: string): string {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(date);\n if (!m) return date;\n try {\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n timeZone: 'UTC',\n }).format(new Date(Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3]))));\n } catch {\n return date;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vinaverse/tokens",
3
- "version": "0.1.0-alpha.7",
3
+ "version": "0.1.0-alpha.9",
4
4
  "description": "Vinaverse design tokens and copy shared by every UI kit: colors for light and dark, type, spacing, radii, motion, a contrast check; and the words the kits say, with the rules on them.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Vinaverse, Inc.",
@@ -19,6 +19,10 @@
19
19
  "sideEffects": false,
20
20
  "exports": {
21
21
  ".": {
22
+ "react-native": {
23
+ "types": "./dist/index.d.cts",
24
+ "default": "./dist/index.cjs"
25
+ },
22
26
  "import": {
23
27
  "types": "./dist/index.d.ts",
24
28
  "default": "./dist/index.js"
@@ -29,6 +33,10 @@
29
33
  }
30
34
  },
31
35
  "./copy": {
36
+ "react-native": {
37
+ "types": "./dist/copy/index.d.cts",
38
+ "default": "./dist/copy/index.cjs"
39
+ },
32
40
  "import": {
33
41
  "types": "./dist/copy/index.d.ts",
34
42
  "default": "./dist/copy/index.js"