@seatlayer/core 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -73,9 +73,11 @@ var de = {
73
73
  "picker.restrictedView": "Eingeschr\xE4nkte Sicht",
74
74
  "picker.obstructedView": "Sichtbehinderung",
75
75
  "picker.premiumSeat": "Premium-Platz",
76
- "picker.hideLimitedView": "Pl\xE4tze mit eingeschr\xE4nkter Sicht ausblenden"
76
+ "picker.hideLimitedView": "Pl\xE4tze mit eingeschr\xE4nkter Sicht ausblenden",
77
+ "picker.bestSeatsPremium": "Beste Pl\xE4tze",
78
+ "picker.premiumFallbackNote": "Kein Premium-Block mit {count} Pl\xE4tzen \u2014 beste verf\xFCgbare werden angezeigt"
77
79
  };
78
80
  export {
79
81
  de
80
82
  };
81
- //# sourceMappingURL=de-KPTY7UOT.js.map
83
+ //# sourceMappingURL=de-DRWMZ2FV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/i18n/locales/de.ts"],"sourcesContent":["/**\n * German bundle — native-quality translations of the English reference dictionary.\n * Keys are identical to en.ts; values are translated to German (de).\n *\n * Conventions:\n * - flat dot-namespaced keys: \"<surface>.<element>\" (picker.holdSeats)\n * - {name} interpolation, {count} reserved for tCount plural keys\n * - plural keys end in \".one\" / \".other\" (Intl.PluralRules categories)\n */\n\nimport type { Dict } from '../index';\n\nexport const de: Dict = {\n // shared\n 'common.cancel': 'Abbrechen',\n 'common.close': 'Schließen',\n 'common.done': 'Fertig',\n 'common.copied': '✓ Kopiert',\n\n // buyer picker (extraction in progress — P4 of the port plan)\n 'picker.holdSeats': 'Plätze reservieren & Kasse',\n 'picker.completeBooking': 'Buchung abschließen',\n 'picker.seatsHeld': 'Plätze reserviert — {time}',\n 'picker.holdExpired': 'Ihre Reservierung ist abgelaufen — die Plätze wurden freigegeben. Bitte erneut auswählen.',\n 'picker.seatTaken': 'Platz {label} wurde gerade von einem anderen Käufer gebucht.',\n 'picker.poweredBy': 'Bereitgestellt von SeatLayer',\n 'picker.testMode': 'TESTMODUS',\n 'picker.colorblind': 'Farbenblind-freundliche Farben',\n 'picker.orphanHint': 'Dadurch bleibt ein einzelner Platz übrig — rücken Sie ggf. einen Platz weiter.',\n 'picker.seats.one': '{count} Platz',\n 'picker.seats.other': '{count} Plätze',\n\n // renderer (drawn on the Konva map — shared by the embed SDK)\n 'map.aria': 'Sitzplan. Mit Pfeiltasten zwischen Plätzen navigieren, Eingabe zum Auswählen.',\n 'map.seatsLeft': '{count} FREI',\n 'map.statusHeld': 'Reserviert',\n 'map.statusTaken': 'Vergeben',\n 'map.fromPrice': 'AB {price}',\n\n // buyer picker page (src/pages/PickerPage.tsx)\n 'picker.language': 'Sprache',\n 'picker.zoomToFit': 'Auf Größe anpassen',\n 'picker.seatCountLabel': 'Plätze',\n 'picker.capacity': 'Kapazität',\n 'picker.viewMode': 'Ansichtsmodus',\n 'picker.floor': 'Etage',\n 'picker.zoomLevel': 'Zoomstufe',\n 'picker.rungTip.zones': 'Übersicht — Bereichsgruppen wie Nordtribüne oder VIP',\n 'picker.rungTip.sections': 'Bereichs-Blöcke — Kategoriesortierung + Verfügbarkeitstönung',\n 'picker.rungTip.seats': 'Einzelne Plätze — Blöcke lösen sich zu Punkten auf',\n 'picker.rungLabel.zones': 'ZONEN',\n 'picker.rungLabel.sections': 'BEREICHE',\n 'picker.rungLabel.seats': 'PLÄTZE',\n 'picker.sectionSummaryAria': 'Bereichszusammenfassung {label}',\n 'picker.closeSectionSummary': 'Bereichszusammenfassung schließen',\n 'picker.seatsLeftInSection.one': '{count} Platz verfügbar',\n 'picker.seatsLeftInSection.other': '{count} Plätze verfügbar',\n 'picker.overview': 'Übersicht',\n 'picker.tapSeatHint': 'Tippen Sie auf einen Platz, um die Ansicht zu prüfen',\n 'picker.chartSize': 'Kartengröße',\n 'picker.custom': 'Benutzerdefiniert',\n 'picker.categories': 'Kategorien',\n 'picker.accessibility': 'Barrierefreiheit',\n 'picker.showAnyAccessible': 'Jeden barrierefreien Platz anzeigen',\n 'picker.any': 'Beliebig',\n 'picker.yourSeats': 'Ihre Plätze',\n 'picker.emptySeats': 'Tippen Sie auf die Plätze auf der Karte',\n 'picker.emptySeatsWithGa': 'Tippen Sie auf die Plätze auf der Karte · tippen Sie auf einen Stehbereich für Stehplatztickets',\n 'picker.oneFewer': 'Einen weniger',\n 'picker.oneMore': 'Einen mehr',\n 'picker.remove': '{label} entfernen',\n 'picker.ticketTierFor': 'Ticketklasse für {label}',\n 'picker.total': 'Gesamt: {amount}',\n 'picker.viewFromSeat': 'Ansicht von Platz {label}',\n 'picker.real360': 'REAL 360°',\n 'picker.preview': 'VORSCHAU',\n 'picker.open360': 'Öffnen Sie die 360°-Ansicht',\n 'picker.sightline': '≈ {m} m zur Bühne · freie Sicht',\n 'picker.bookedDemo': 'Gebucht! (Demo)',\n 'picker.bookButton.one': '{count} Ticket buchen — {amount}',\n 'picker.bookButton.other': '{count} Tickets buchen — {amount}',\n 'picker.simulateCrowd': 'Menschenmenge simulieren: {state}',\n 'picker.on': 'AN',\n 'picker.off': 'AUS',\n 'picker.panorama360': '360°-Veranstaltungsfotos',\n 'picker.illustrationCaption': 'Illustration · ≈ {m} m von der Bühne',\n 'picker.restrictedView': 'Eingeschränkte Sicht',\n 'picker.obstructedView': 'Sichtbehinderung',\n 'picker.premiumSeat': 'Premium-Platz',\n 'picker.hideLimitedView': 'Plätze mit eingeschränkter Sicht ausblenden',\n};\n"],"mappings":";AAYO,IAAM,KAAW;AAAA;AAAA,EAEtB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA;AAAA,EAGjB,oBAAoB;AAAA,EACpB,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA;AAAA,EAGtB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA;AAAA,EAGjB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,iCAAiC;AAAA,EACjC,mCAAmC;AAAA,EACnC,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,0BAA0B;AAC5B;","names":[]}
1
+ {"version":3,"sources":["../src/i18n/locales/de.ts"],"sourcesContent":["/**\n * German bundle — native-quality translations of the English reference dictionary.\n * Keys are identical to en.ts; values are translated to German (de).\n *\n * Conventions:\n * - flat dot-namespaced keys: \"<surface>.<element>\" (picker.holdSeats)\n * - {name} interpolation, {count} reserved for tCount plural keys\n * - plural keys end in \".one\" / \".other\" (Intl.PluralRules categories)\n */\n\nimport type { Dict } from '../index';\n\nexport const de: Dict = {\n // shared\n 'common.cancel': 'Abbrechen',\n 'common.close': 'Schließen',\n 'common.done': 'Fertig',\n 'common.copied': '✓ Kopiert',\n\n // buyer picker (extraction in progress — P4 of the port plan)\n 'picker.holdSeats': 'Plätze reservieren & Kasse',\n 'picker.completeBooking': 'Buchung abschließen',\n 'picker.seatsHeld': 'Plätze reserviert — {time}',\n 'picker.holdExpired': 'Ihre Reservierung ist abgelaufen — die Plätze wurden freigegeben. Bitte erneut auswählen.',\n 'picker.seatTaken': 'Platz {label} wurde gerade von einem anderen Käufer gebucht.',\n 'picker.poweredBy': 'Bereitgestellt von SeatLayer',\n 'picker.testMode': 'TESTMODUS',\n 'picker.colorblind': 'Farbenblind-freundliche Farben',\n 'picker.orphanHint': 'Dadurch bleibt ein einzelner Platz übrig — rücken Sie ggf. einen Platz weiter.',\n 'picker.seats.one': '{count} Platz',\n 'picker.seats.other': '{count} Plätze',\n\n // renderer (drawn on the Konva map — shared by the embed SDK)\n 'map.aria': 'Sitzplan. Mit Pfeiltasten zwischen Plätzen navigieren, Eingabe zum Auswählen.',\n 'map.seatsLeft': '{count} FREI',\n 'map.statusHeld': 'Reserviert',\n 'map.statusTaken': 'Vergeben',\n 'map.fromPrice': 'AB {price}',\n\n // buyer picker page (src/pages/PickerPage.tsx)\n 'picker.language': 'Sprache',\n 'picker.zoomToFit': 'Auf Größe anpassen',\n 'picker.seatCountLabel': 'Plätze',\n 'picker.capacity': 'Kapazität',\n 'picker.viewMode': 'Ansichtsmodus',\n 'picker.floor': 'Etage',\n 'picker.zoomLevel': 'Zoomstufe',\n 'picker.rungTip.zones': 'Übersicht — Bereichsgruppen wie Nordtribüne oder VIP',\n 'picker.rungTip.sections': 'Bereichs-Blöcke — Kategoriesortierung + Verfügbarkeitstönung',\n 'picker.rungTip.seats': 'Einzelne Plätze — Blöcke lösen sich zu Punkten auf',\n 'picker.rungLabel.zones': 'ZONEN',\n 'picker.rungLabel.sections': 'BEREICHE',\n 'picker.rungLabel.seats': 'PLÄTZE',\n 'picker.sectionSummaryAria': 'Bereichszusammenfassung {label}',\n 'picker.closeSectionSummary': 'Bereichszusammenfassung schließen',\n 'picker.seatsLeftInSection.one': '{count} Platz verfügbar',\n 'picker.seatsLeftInSection.other': '{count} Plätze verfügbar',\n 'picker.overview': 'Übersicht',\n 'picker.tapSeatHint': 'Tippen Sie auf einen Platz, um die Ansicht zu prüfen',\n 'picker.chartSize': 'Kartengröße',\n 'picker.custom': 'Benutzerdefiniert',\n 'picker.categories': 'Kategorien',\n 'picker.accessibility': 'Barrierefreiheit',\n 'picker.showAnyAccessible': 'Jeden barrierefreien Platz anzeigen',\n 'picker.any': 'Beliebig',\n 'picker.yourSeats': 'Ihre Plätze',\n 'picker.emptySeats': 'Tippen Sie auf die Plätze auf der Karte',\n 'picker.emptySeatsWithGa': 'Tippen Sie auf die Plätze auf der Karte · tippen Sie auf einen Stehbereich für Stehplatztickets',\n 'picker.oneFewer': 'Einen weniger',\n 'picker.oneMore': 'Einen mehr',\n 'picker.remove': '{label} entfernen',\n 'picker.ticketTierFor': 'Ticketklasse für {label}',\n 'picker.total': 'Gesamt: {amount}',\n 'picker.viewFromSeat': 'Ansicht von Platz {label}',\n 'picker.real360': 'REAL 360°',\n 'picker.preview': 'VORSCHAU',\n 'picker.open360': 'Öffnen Sie die 360°-Ansicht',\n 'picker.sightline': '≈ {m} m zur Bühne · freie Sicht',\n 'picker.bookedDemo': 'Gebucht! (Demo)',\n 'picker.bookButton.one': '{count} Ticket buchen — {amount}',\n 'picker.bookButton.other': '{count} Tickets buchen — {amount}',\n 'picker.simulateCrowd': 'Menschenmenge simulieren: {state}',\n 'picker.on': 'AN',\n 'picker.off': 'AUS',\n 'picker.panorama360': '360°-Veranstaltungsfotos',\n 'picker.illustrationCaption': 'Illustration · ≈ {m} m von der Bühne',\n 'picker.restrictedView': 'Eingeschränkte Sicht',\n 'picker.obstructedView': 'Sichtbehinderung',\n 'picker.premiumSeat': 'Premium-Platz',\n 'picker.hideLimitedView': 'Plätze mit eingeschränkter Sicht ausblenden',\n 'picker.bestSeatsPremium': 'Beste Plätze',\n 'picker.premiumFallbackNote': 'Kein Premium-Block mit {count} Plätzen — beste verfügbare werden angezeigt',\n};\n"],"mappings":";AAYO,IAAM,KAAW;AAAA;AAAA,EAEtB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA;AAAA,EAGjB,oBAAoB;AAAA,EACpB,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA;AAAA,EAGtB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA;AAAA,EAGjB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,iCAAiC;AAAA,EACjC,mCAAmC;AAAA,EACnC,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,8BAA8B;AAChC;","names":[]}
@@ -73,9 +73,11 @@ var es = {
73
73
  "picker.restrictedView": "Visibilidad restringida",
74
74
  "picker.obstructedView": "Visibilidad obstruida",
75
75
  "picker.premiumSeat": "Asiento premium",
76
- "picker.hideLimitedView": "Ocultar asientos con visibilidad limitada"
76
+ "picker.hideLimitedView": "Ocultar asientos con visibilidad limitada",
77
+ "picker.bestSeatsPremium": "Mejores asientos",
78
+ "picker.premiumFallbackNote": "No hay un bloque premium de {count}: mostrando los mejores disponibles"
77
79
  };
78
80
  export {
79
81
  es
80
82
  };
81
- //# sourceMappingURL=es-ALPR5FBB.js.map
83
+ //# sourceMappingURL=es-N73CIVTC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/i18n/locales/es.ts"],"sourcesContent":["/**\n * Spanish (es) bundle — neutral/international Spanish translation.\n * Follows the same key structure as en.ts; all placeholders and brand\n * names preserved.\n */\n\nimport type { Dict } from '../index';\n\nexport const es: Dict = {\n // shared\n 'common.cancel': 'Cancelar',\n 'common.close': 'Cerrar',\n 'common.done': 'Listo',\n 'common.copied': '✓ Copiado',\n\n // buyer picker (extraction in progress — P4 of the port plan)\n 'picker.holdSeats': 'Retener asientos y comprar',\n 'picker.completeBooking': 'Completar reserva',\n 'picker.seatsHeld': 'Asientos retenidos — {time}',\n 'picker.holdExpired': 'Tu retención expiró — los asientos fueron liberados. Elige de nuevo.',\n 'picker.seatTaken': 'El asiento {label} fue tomado por otro comprador.',\n 'picker.poweredBy': 'Con la tecnología de SeatLayer',\n 'picker.testMode': 'MODO DE PRUEBA',\n 'picker.colorblind': 'Colores aptos para daltonismo',\n 'picker.orphanHint': 'Esto deja un asiento aislado — considera desplazarte un asiento.',\n 'picker.seats.one': '{count} asiento',\n 'picker.seats.other': '{count} asientos',\n\n // renderer (drawn on the Konva map — shared by the embed SDK)\n 'map.aria': 'Mapa de asientos. Usa las flechas para moverte entre asientos, Intro para seleccionar.',\n 'map.seatsLeft': '{count} LIBRES',\n 'map.statusHeld': 'En espera',\n 'map.statusTaken': 'Ocupado',\n 'map.fromPrice': 'DESDE {price}',\n\n // buyer picker page (src/pages/PickerPage.tsx)\n 'picker.language': 'Idioma',\n 'picker.zoomToFit': 'Ajustar zoom',\n 'picker.seatCountLabel': 'asientos',\n 'picker.capacity': 'capacidad',\n 'picker.viewMode': 'Modo de vista',\n 'picker.floor': 'Piso',\n 'picker.zoomLevel': 'Nivel de zoom',\n 'picker.rungTip.zones': 'Vista general — grupos de secciones como Grada norte o VIP',\n 'picker.rungTip.sections': 'Bloques de sección — mezcla de categorías + matiz de disponibilidad',\n 'picker.rungTip.seats': 'Asientos individuales — los bloques se convierten en puntos',\n 'picker.rungLabel.zones': 'ZONAS',\n 'picker.rungLabel.sections': 'SECCIONES',\n 'picker.rungLabel.seats': 'ASIENTOS',\n 'picker.sectionSummaryAria': 'Resumen de sección {label}',\n 'picker.closeSectionSummary': 'Cerrar resumen de sección',\n 'picker.seatsLeftInSection.one': '{count} asiento disponible',\n 'picker.seatsLeftInSection.other': '{count} asientos disponibles',\n 'picker.overview': 'Descripción general',\n 'picker.tapSeatHint': 'Toca cualquier asiento para ver su vista',\n 'picker.chartSize': 'Tamaño del gráfico',\n 'picker.custom': 'Personalizado',\n 'picker.categories': 'Categorías',\n 'picker.accessibility': 'Accesibilidad',\n 'picker.showAnyAccessible': 'Mostrar cualquier asiento accesible',\n 'picker.any': 'Cualquiera',\n 'picker.yourSeats': 'Tus asientos',\n 'picker.emptySeats': 'Toca asientos en el mapa',\n 'picker.emptySeatsWithGa': 'Toca asientos en el mapa · toca un área de pie para entradas de entrada general',\n 'picker.oneFewer': 'Uno menos',\n 'picker.oneMore': 'Uno más',\n 'picker.remove': 'Eliminar {label}',\n 'picker.ticketTierFor': 'Categoría de entrada para {label}',\n 'picker.total': 'Total: {amount}',\n 'picker.viewFromSeat': 'Vista desde el asiento {label}',\n 'picker.real360': 'REAL 360°',\n 'picker.preview': 'VISTA PREVIA',\n 'picker.open360': 'Abrir vista de 360°',\n 'picker.sightline': '≈ {m} m al escenario · visión despejada',\n 'picker.bookedDemo': '¡Reservado! (demostración)',\n 'picker.bookButton.one': 'Reservar {count} entrada — {amount}',\n 'picker.bookButton.other': 'Reservar {count} entradas — {amount}',\n 'picker.simulateCrowd': 'Simular multitud: {state}',\n 'picker.on': 'ACTIVADO',\n 'picker.off': 'DESACTIVADO',\n 'picker.panorama360': 'Foto de 360° del lugar',\n 'picker.illustrationCaption': 'ilustración · ≈ {m} m del escenario',\n 'picker.restrictedView': 'Visibilidad restringida',\n 'picker.obstructedView': 'Visibilidad obstruida',\n 'picker.premiumSeat': 'Asiento premium',\n 'picker.hideLimitedView': 'Ocultar asientos con visibilidad limitada',\n};\n"],"mappings":";AAQO,IAAM,KAAW;AAAA;AAAA,EAEtB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA;AAAA,EAGjB,oBAAoB;AAAA,EACpB,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA;AAAA,EAGtB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA;AAAA,EAGjB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,iCAAiC;AAAA,EACjC,mCAAmC;AAAA,EACnC,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,0BAA0B;AAC5B;","names":[]}
1
+ {"version":3,"sources":["../src/i18n/locales/es.ts"],"sourcesContent":["/**\n * Spanish (es) bundle — neutral/international Spanish translation.\n * Follows the same key structure as en.ts; all placeholders and brand\n * names preserved.\n */\n\nimport type { Dict } from '../index';\n\nexport const es: Dict = {\n // shared\n 'common.cancel': 'Cancelar',\n 'common.close': 'Cerrar',\n 'common.done': 'Listo',\n 'common.copied': '✓ Copiado',\n\n // buyer picker (extraction in progress — P4 of the port plan)\n 'picker.holdSeats': 'Retener asientos y comprar',\n 'picker.completeBooking': 'Completar reserva',\n 'picker.seatsHeld': 'Asientos retenidos — {time}',\n 'picker.holdExpired': 'Tu retención expiró — los asientos fueron liberados. Elige de nuevo.',\n 'picker.seatTaken': 'El asiento {label} fue tomado por otro comprador.',\n 'picker.poweredBy': 'Con la tecnología de SeatLayer',\n 'picker.testMode': 'MODO DE PRUEBA',\n 'picker.colorblind': 'Colores aptos para daltonismo',\n 'picker.orphanHint': 'Esto deja un asiento aislado — considera desplazarte un asiento.',\n 'picker.seats.one': '{count} asiento',\n 'picker.seats.other': '{count} asientos',\n\n // renderer (drawn on the Konva map — shared by the embed SDK)\n 'map.aria': 'Mapa de asientos. Usa las flechas para moverte entre asientos, Intro para seleccionar.',\n 'map.seatsLeft': '{count} LIBRES',\n 'map.statusHeld': 'En espera',\n 'map.statusTaken': 'Ocupado',\n 'map.fromPrice': 'DESDE {price}',\n\n // buyer picker page (src/pages/PickerPage.tsx)\n 'picker.language': 'Idioma',\n 'picker.zoomToFit': 'Ajustar zoom',\n 'picker.seatCountLabel': 'asientos',\n 'picker.capacity': 'capacidad',\n 'picker.viewMode': 'Modo de vista',\n 'picker.floor': 'Piso',\n 'picker.zoomLevel': 'Nivel de zoom',\n 'picker.rungTip.zones': 'Vista general — grupos de secciones como Grada norte o VIP',\n 'picker.rungTip.sections': 'Bloques de sección — mezcla de categorías + matiz de disponibilidad',\n 'picker.rungTip.seats': 'Asientos individuales — los bloques se convierten en puntos',\n 'picker.rungLabel.zones': 'ZONAS',\n 'picker.rungLabel.sections': 'SECCIONES',\n 'picker.rungLabel.seats': 'ASIENTOS',\n 'picker.sectionSummaryAria': 'Resumen de sección {label}',\n 'picker.closeSectionSummary': 'Cerrar resumen de sección',\n 'picker.seatsLeftInSection.one': '{count} asiento disponible',\n 'picker.seatsLeftInSection.other': '{count} asientos disponibles',\n 'picker.overview': 'Descripción general',\n 'picker.tapSeatHint': 'Toca cualquier asiento para ver su vista',\n 'picker.chartSize': 'Tamaño del gráfico',\n 'picker.custom': 'Personalizado',\n 'picker.categories': 'Categorías',\n 'picker.accessibility': 'Accesibilidad',\n 'picker.showAnyAccessible': 'Mostrar cualquier asiento accesible',\n 'picker.any': 'Cualquiera',\n 'picker.yourSeats': 'Tus asientos',\n 'picker.emptySeats': 'Toca asientos en el mapa',\n 'picker.emptySeatsWithGa': 'Toca asientos en el mapa · toca un área de pie para entradas de entrada general',\n 'picker.oneFewer': 'Uno menos',\n 'picker.oneMore': 'Uno más',\n 'picker.remove': 'Eliminar {label}',\n 'picker.ticketTierFor': 'Categoría de entrada para {label}',\n 'picker.total': 'Total: {amount}',\n 'picker.viewFromSeat': 'Vista desde el asiento {label}',\n 'picker.real360': 'REAL 360°',\n 'picker.preview': 'VISTA PREVIA',\n 'picker.open360': 'Abrir vista de 360°',\n 'picker.sightline': '≈ {m} m al escenario · visión despejada',\n 'picker.bookedDemo': '¡Reservado! (demostración)',\n 'picker.bookButton.one': 'Reservar {count} entrada — {amount}',\n 'picker.bookButton.other': 'Reservar {count} entradas — {amount}',\n 'picker.simulateCrowd': 'Simular multitud: {state}',\n 'picker.on': 'ACTIVADO',\n 'picker.off': 'DESACTIVADO',\n 'picker.panorama360': 'Foto de 360° del lugar',\n 'picker.illustrationCaption': 'ilustración · ≈ {m} m del escenario',\n 'picker.restrictedView': 'Visibilidad restringida',\n 'picker.obstructedView': 'Visibilidad obstruida',\n 'picker.premiumSeat': 'Asiento premium',\n 'picker.hideLimitedView': 'Ocultar asientos con visibilidad limitada',\n 'picker.bestSeatsPremium': 'Mejores asientos',\n 'picker.premiumFallbackNote': 'No hay un bloque premium de {count}: mostrando los mejores disponibles',\n};\n"],"mappings":";AAQO,IAAM,KAAW;AAAA;AAAA,EAEtB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA;AAAA,EAGjB,oBAAoB;AAAA,EACpB,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA;AAAA,EAGtB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA;AAAA,EAGjB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,iCAAiC;AAAA,EACjC,mCAAmC;AAAA,EACnC,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,8BAA8B;AAChC;","names":[]}
@@ -73,9 +73,11 @@ var fr = {
73
73
  "picker.restrictedView": "Visibilit\xE9 r\xE9duite",
74
74
  "picker.obstructedView": "Vue obstru\xE9e",
75
75
  "picker.premiumSeat": "Place premium",
76
- "picker.hideLimitedView": "Masquer les places \xE0 visibilit\xE9 r\xE9duite"
76
+ "picker.hideLimitedView": "Masquer les places \xE0 visibilit\xE9 r\xE9duite",
77
+ "picker.bestSeatsPremium": "Meilleures places",
78
+ "picker.premiumFallbackNote": "Aucun bloc premium de {count} \u2014 affichage des meilleures places disponibles"
77
79
  };
78
80
  export {
79
81
  fr
80
82
  };
81
- //# sourceMappingURL=fr-HVQLQD2N.js.map
83
+ //# sourceMappingURL=fr-SOY2OB4P.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/i18n/locales/fr.ts"],"sourcesContent":["/**\n * French (fr) bundle — native French translation.\n * Follows the same key structure as en.ts; all placeholders and brand\n * names preserved.\n */\n\nimport type { Dict } from '../index';\n\nexport const fr: Dict = {\n // shared\n 'common.cancel': 'Annuler',\n 'common.close': 'Fermer',\n 'common.done': 'Terminé',\n 'common.copied': '✓ Copié',\n\n // buyer picker (extraction in progress — P4 of the port plan)\n 'picker.holdSeats': 'Réserver les sièges et valider',\n 'picker.completeBooking': 'Terminer la réservation',\n 'picker.seatsHeld': 'Sièges réservés — {time}',\n 'picker.holdExpired': 'Votre réservation a expiré — les sièges ont été libérés. Sélectionnez à nouveau.',\n 'picker.seatTaken': 'Le siège {label} vient d\\'être réservé par un autre acheteur.',\n 'picker.poweredBy': 'Propulsé par SeatLayer',\n 'picker.testMode': 'MODE TEST',\n 'picker.colorblind': 'Couleurs adaptées au daltonisme',\n 'picker.orphanHint': \"Cela laisse un siège isolé — pensez à vous décaler d'un siège.\",\n 'picker.seats.one': '{count} siège',\n 'picker.seats.other': '{count} sièges',\n\n // renderer (drawn on the Konva map — shared by the embed SDK)\n 'map.aria': 'Plan de salle. Utilisez les flèches pour naviguer entre les sièges, Entrée pour sélectionner.',\n 'map.seatsLeft': '{count} LIBRES',\n 'map.statusHeld': 'En attente',\n 'map.statusTaken': 'Pris',\n 'map.fromPrice': 'DÈS {price}',\n\n // buyer picker page (src/pages/PickerPage.tsx)\n 'picker.language': 'Langue',\n 'picker.zoomToFit': 'Ajuster le zoom',\n 'picker.seatCountLabel': 'sièges',\n 'picker.capacity': 'capacité',\n 'picker.viewMode': 'Mode d\\'affichage',\n 'picker.floor': 'Étage',\n 'picker.zoomLevel': 'Niveau de zoom',\n 'picker.rungTip.zones': 'Vue générale — groupes de sections comme Tribune nord ou VIP',\n 'picker.rungTip.sections': 'Blocs de sections — mélange de catégories + teinte de disponibilité',\n 'picker.rungTip.seats': 'Sièges individuels — les blocs se transforment en points',\n 'picker.rungLabel.zones': 'ZONES',\n 'picker.rungLabel.sections': 'SECTIONS',\n 'picker.rungLabel.seats': 'SIÈGES',\n 'picker.sectionSummaryAria': 'Résumé de la section {label}',\n 'picker.closeSectionSummary': 'Fermer le résumé de la section',\n 'picker.seatsLeftInSection.one': '{count} siège restant',\n 'picker.seatsLeftInSection.other': '{count} sièges restants',\n 'picker.overview': 'Vue d\\'ensemble',\n 'picker.tapSeatHint': 'Appuyez sur un siège pour vérifier sa vue',\n 'picker.chartSize': 'Taille du plan',\n 'picker.custom': 'Personnalisé',\n 'picker.categories': 'Catégories',\n 'picker.accessibility': 'Accessibilité',\n 'picker.showAnyAccessible': 'Afficher un siège accessible',\n 'picker.any': 'N\\'importe quel',\n 'picker.yourSeats': 'Vos sièges',\n 'picker.emptySeats': 'Appuyez sur les sièges sur le plan',\n 'picker.emptySeatsWithGa': 'Appuyez sur les sièges sur le plan · appuyez sur une zone debout pour les billets GA',\n 'picker.oneFewer': 'Un de moins',\n 'picker.oneMore': 'Un de plus',\n 'picker.remove': 'Supprimer {label}',\n 'picker.ticketTierFor': 'Catégorie de billet pour {label}',\n 'picker.total': 'Total : {amount}',\n 'picker.viewFromSeat': 'Vue depuis le siège {label}',\n 'picker.real360': 'VRAI 360°',\n 'picker.preview': 'APERÇU',\n 'picker.open360': 'Ouvrir la vue à 360°',\n 'picker.sightline': '≈ {m} m de la scène · vue dégagée',\n 'picker.bookedDemo': 'Réservé ! (démo)',\n 'picker.bookButton.one': 'Réserver {count} billet — {amount}',\n 'picker.bookButton.other': 'Réserver {count} billets — {amount}',\n 'picker.simulateCrowd': 'Simuler la foule : {state}',\n 'picker.on': 'ACTIVÉ',\n 'picker.off': 'DÉSACTIVÉ',\n 'picker.panorama360': 'Photo panoramique 360° du lieu',\n 'picker.illustrationCaption': 'illustration · ≈ {m} m de la scène',\n 'picker.restrictedView': 'Visibilité réduite',\n 'picker.obstructedView': 'Vue obstruée',\n 'picker.premiumSeat': 'Place premium',\n 'picker.hideLimitedView': 'Masquer les places à visibilité réduite',\n};\n"],"mappings":";AAQO,IAAM,KAAW;AAAA;AAAA,EAEtB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA;AAAA,EAGjB,oBAAoB;AAAA,EACpB,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA;AAAA,EAGtB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA;AAAA,EAGjB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,iCAAiC;AAAA,EACjC,mCAAmC;AAAA,EACnC,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,0BAA0B;AAC5B;","names":[]}
1
+ {"version":3,"sources":["../src/i18n/locales/fr.ts"],"sourcesContent":["/**\n * French (fr) bundle — native French translation.\n * Follows the same key structure as en.ts; all placeholders and brand\n * names preserved.\n */\n\nimport type { Dict } from '../index';\n\nexport const fr: Dict = {\n // shared\n 'common.cancel': 'Annuler',\n 'common.close': 'Fermer',\n 'common.done': 'Terminé',\n 'common.copied': '✓ Copié',\n\n // buyer picker (extraction in progress — P4 of the port plan)\n 'picker.holdSeats': 'Réserver les sièges et valider',\n 'picker.completeBooking': 'Terminer la réservation',\n 'picker.seatsHeld': 'Sièges réservés — {time}',\n 'picker.holdExpired': 'Votre réservation a expiré — les sièges ont été libérés. Sélectionnez à nouveau.',\n 'picker.seatTaken': 'Le siège {label} vient d\\'être réservé par un autre acheteur.',\n 'picker.poweredBy': 'Propulsé par SeatLayer',\n 'picker.testMode': 'MODE TEST',\n 'picker.colorblind': 'Couleurs adaptées au daltonisme',\n 'picker.orphanHint': \"Cela laisse un siège isolé — pensez à vous décaler d'un siège.\",\n 'picker.seats.one': '{count} siège',\n 'picker.seats.other': '{count} sièges',\n\n // renderer (drawn on the Konva map — shared by the embed SDK)\n 'map.aria': 'Plan de salle. Utilisez les flèches pour naviguer entre les sièges, Entrée pour sélectionner.',\n 'map.seatsLeft': '{count} LIBRES',\n 'map.statusHeld': 'En attente',\n 'map.statusTaken': 'Pris',\n 'map.fromPrice': 'DÈS {price}',\n\n // buyer picker page (src/pages/PickerPage.tsx)\n 'picker.language': 'Langue',\n 'picker.zoomToFit': 'Ajuster le zoom',\n 'picker.seatCountLabel': 'sièges',\n 'picker.capacity': 'capacité',\n 'picker.viewMode': 'Mode d\\'affichage',\n 'picker.floor': 'Étage',\n 'picker.zoomLevel': 'Niveau de zoom',\n 'picker.rungTip.zones': 'Vue générale — groupes de sections comme Tribune nord ou VIP',\n 'picker.rungTip.sections': 'Blocs de sections — mélange de catégories + teinte de disponibilité',\n 'picker.rungTip.seats': 'Sièges individuels — les blocs se transforment en points',\n 'picker.rungLabel.zones': 'ZONES',\n 'picker.rungLabel.sections': 'SECTIONS',\n 'picker.rungLabel.seats': 'SIÈGES',\n 'picker.sectionSummaryAria': 'Résumé de la section {label}',\n 'picker.closeSectionSummary': 'Fermer le résumé de la section',\n 'picker.seatsLeftInSection.one': '{count} siège restant',\n 'picker.seatsLeftInSection.other': '{count} sièges restants',\n 'picker.overview': 'Vue d\\'ensemble',\n 'picker.tapSeatHint': 'Appuyez sur un siège pour vérifier sa vue',\n 'picker.chartSize': 'Taille du plan',\n 'picker.custom': 'Personnalisé',\n 'picker.categories': 'Catégories',\n 'picker.accessibility': 'Accessibilité',\n 'picker.showAnyAccessible': 'Afficher un siège accessible',\n 'picker.any': 'N\\'importe quel',\n 'picker.yourSeats': 'Vos sièges',\n 'picker.emptySeats': 'Appuyez sur les sièges sur le plan',\n 'picker.emptySeatsWithGa': 'Appuyez sur les sièges sur le plan · appuyez sur une zone debout pour les billets GA',\n 'picker.oneFewer': 'Un de moins',\n 'picker.oneMore': 'Un de plus',\n 'picker.remove': 'Supprimer {label}',\n 'picker.ticketTierFor': 'Catégorie de billet pour {label}',\n 'picker.total': 'Total : {amount}',\n 'picker.viewFromSeat': 'Vue depuis le siège {label}',\n 'picker.real360': 'VRAI 360°',\n 'picker.preview': 'APERÇU',\n 'picker.open360': 'Ouvrir la vue à 360°',\n 'picker.sightline': '≈ {m} m de la scène · vue dégagée',\n 'picker.bookedDemo': 'Réservé ! (démo)',\n 'picker.bookButton.one': 'Réserver {count} billet — {amount}',\n 'picker.bookButton.other': 'Réserver {count} billets — {amount}',\n 'picker.simulateCrowd': 'Simuler la foule : {state}',\n 'picker.on': 'ACTIVÉ',\n 'picker.off': 'DÉSACTIVÉ',\n 'picker.panorama360': 'Photo panoramique 360° du lieu',\n 'picker.illustrationCaption': 'illustration · ≈ {m} m de la scène',\n 'picker.restrictedView': 'Visibilité réduite',\n 'picker.obstructedView': 'Vue obstruée',\n 'picker.premiumSeat': 'Place premium',\n 'picker.hideLimitedView': 'Masquer les places à visibilité réduite',\n 'picker.bestSeatsPremium': 'Meilleures places',\n 'picker.premiumFallbackNote': 'Aucun bloc premium de {count} — affichage des meilleures places disponibles',\n};\n"],"mappings":";AAQO,IAAM,KAAW;AAAA;AAAA,EAEtB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,iBAAiB;AAAA;AAAA,EAGjB,oBAAoB;AAAA,EACpB,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA;AAAA,EAGtB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA;AAAA,EAGjB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,iCAAiC;AAAA,EACjC,mCAAmC;AAAA,EACnC,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,8BAA8B;AAChC;","names":[]}
package/dist/index.cjs CHANGED
@@ -108,7 +108,9 @@ var init_es = __esm({
108
108
  "picker.restrictedView": "Visibilidad restringida",
109
109
  "picker.obstructedView": "Visibilidad obstruida",
110
110
  "picker.premiumSeat": "Asiento premium",
111
- "picker.hideLimitedView": "Ocultar asientos con visibilidad limitada"
111
+ "picker.hideLimitedView": "Ocultar asientos con visibilidad limitada",
112
+ "picker.bestSeatsPremium": "Mejores asientos",
113
+ "picker.premiumFallbackNote": "No hay un bloque premium de {count}: mostrando los mejores disponibles"
112
114
  };
113
115
  }
114
116
  });
@@ -196,7 +198,9 @@ var init_de = __esm({
196
198
  "picker.restrictedView": "Eingeschr\xE4nkte Sicht",
197
199
  "picker.obstructedView": "Sichtbehinderung",
198
200
  "picker.premiumSeat": "Premium-Platz",
199
- "picker.hideLimitedView": "Pl\xE4tze mit eingeschr\xE4nkter Sicht ausblenden"
201
+ "picker.hideLimitedView": "Pl\xE4tze mit eingeschr\xE4nkter Sicht ausblenden",
202
+ "picker.bestSeatsPremium": "Beste Pl\xE4tze",
203
+ "picker.premiumFallbackNote": "Kein Premium-Block mit {count} Pl\xE4tzen \u2014 beste verf\xFCgbare werden angezeigt"
200
204
  };
201
205
  }
202
206
  });
@@ -284,7 +288,9 @@ var init_fr = __esm({
284
288
  "picker.restrictedView": "Visibilit\xE9 r\xE9duite",
285
289
  "picker.obstructedView": "Vue obstru\xE9e",
286
290
  "picker.premiumSeat": "Place premium",
287
- "picker.hideLimitedView": "Masquer les places \xE0 visibilit\xE9 r\xE9duite"
291
+ "picker.hideLimitedView": "Masquer les places \xE0 visibilit\xE9 r\xE9duite",
292
+ "picker.bestSeatsPremium": "Meilleures places",
293
+ "picker.premiumFallbackNote": "Aucun bloc premium de {count} \u2014 affichage des meilleures places disponibles"
288
294
  };
289
295
  }
290
296
  });
@@ -671,8 +677,8 @@ function polygonLabelPoint(outer, holes) {
671
677
  const xs = outer.map((point) => point.x);
672
678
  const ys = outer.map((point) => point.y);
673
679
  const bounds = { minX: Math.min(...xs), maxX: Math.max(...xs), minY: Math.min(...ys), maxY: Math.max(...ys) };
674
- const centroid = polygonCentroid(outer);
675
- if (pointInPolygonWithHoles(centroid, outer, holes)) return centroid;
680
+ const centroid2 = polygonCentroid(outer);
681
+ if (pointInPolygonWithHoles(centroid2, outer, holes)) return centroid2;
676
682
  let best = outer[0];
677
683
  let bestScore = -Infinity;
678
684
  const rings = [outer, ...holes ?? []];
@@ -1158,7 +1164,9 @@ var en = {
1158
1164
  "picker.restrictedView": "Restricted view",
1159
1165
  "picker.obstructedView": "Obstructed view",
1160
1166
  "picker.premiumSeat": "Premium seat",
1161
- "picker.hideLimitedView": "Hide limited-view seats"
1167
+ "picker.hideLimitedView": "Hide limited-view seats",
1168
+ "picker.bestSeatsPremium": "Best seats",
1169
+ "picker.premiumFallbackNote": "No premium block of {count} \u2014 showing best overall"
1162
1170
  };
1163
1171
 
1164
1172
  // src/i18n/index.ts
@@ -3364,7 +3372,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
3364
3372
  * Membership and category mix are still precomputed for the detailed state.
3365
3373
  */
3366
3374
  renderSection(obj) {
3367
- const centroid = polygonLabelPoint(obj.outline, obj.holes);
3375
+ const centroid2 = polygonLabelPoint(obj.outline, obj.holes);
3368
3376
  const palette = overviewPalette(this.canvasBackground);
3369
3377
  const memberIds = [];
3370
3378
  const catCounts = /* @__PURE__ */ new Map();
@@ -3426,8 +3434,8 @@ var _SeatmapRenderer = class _SeatmapRenderer {
3426
3434
  const preferredInk = labelStyle?.color ?? palette.sectionInk;
3427
3435
  const labelScale = (labelStyle?.size ?? 18) / 18;
3428
3436
  const nameLabel = new import_Text.Text({
3429
- x: obj.labelPresentation?.position?.x ?? centroid.x,
3430
- y: obj.labelPresentation?.position?.y ?? centroid.y,
3437
+ x: obj.labelPresentation?.position?.x ?? centroid2.x,
3438
+ y: obj.labelPresentation?.position?.y ?? centroid2.y,
3431
3439
  text: obj.displayLabel ?? obj.label,
3432
3440
  rotation: obj.labelPresentation?.rotation ?? 0,
3433
3441
  visible: obj.labelPresentation?.visible !== false,
@@ -3442,8 +3450,8 @@ var _SeatmapRenderer = class _SeatmapRenderer {
3442
3450
  nameLabel.offsetY(nameLabel.height() / 2);
3443
3451
  bgTarget.add(nameLabel);
3444
3452
  const subLabel = new import_Text.Text({
3445
- x: centroid.x,
3446
- y: centroid.y,
3453
+ x: centroid2.x,
3454
+ y: centroid2.y,
3447
3455
  text: t("map.seatsLeft", { count: free }),
3448
3456
  fontSize: 12,
3449
3457
  fontStyle: "700",
@@ -3462,8 +3470,8 @@ var _SeatmapRenderer = class _SeatmapRenderer {
3462
3470
  outline: obj.outline,
3463
3471
  ...obj.outlinePath ? { outlinePath: obj.outlinePath } : {},
3464
3472
  holes: obj.holes ?? [],
3465
- centroid,
3466
- labelAnchors: polygonLabelCandidates(obj.outline, obj.holes ?? [], centroid),
3473
+ centroid: centroid2,
3474
+ labelAnchors: polygonLabelCandidates(obj.outline, obj.holes ?? [], centroid2),
3467
3475
  zone: obj.zone,
3468
3476
  memberIds,
3469
3477
  total: memberIds.length,
@@ -4823,6 +4831,103 @@ function strandedSingles(seats, statusOf, selectedIds) {
4823
4831
  return out;
4824
4832
  }
4825
4833
 
4834
+ // src/core/bestAvailable.ts
4835
+ function seatIndex2(seat, fallback) {
4836
+ const i = seat.id.lastIndexOf(":");
4837
+ if (i < 0) return fallback;
4838
+ const n = Number(seat.id.slice(i + 1));
4839
+ return Number.isFinite(n) ? n : fallback;
4840
+ }
4841
+ function dist2(a, b) {
4842
+ const dx = a.x - b.x;
4843
+ const dy = a.y - b.y;
4844
+ return dx * dx + dy * dy;
4845
+ }
4846
+ function centroid(seats) {
4847
+ let x = 0;
4848
+ let y = 0;
4849
+ for (const s of seats) {
4850
+ x += s.x;
4851
+ y += s.y;
4852
+ }
4853
+ return { x: x / seats.length, y: y / seats.length };
4854
+ }
4855
+ function isPremium(seat) {
4856
+ return seat.commercial?.premium === true;
4857
+ }
4858
+ function pickBestAvailable(seats, available, opts) {
4859
+ const qty = Math.floor(opts.qty);
4860
+ if (!Number.isFinite(qty) || qty <= 0) return { labels: [], reason: "sold_out" };
4861
+ const { categoryKey, focal, preferPremium } = opts;
4862
+ const rows = /* @__PURE__ */ new Map();
4863
+ const eligibleAll = [];
4864
+ seats.forEach((seat, i) => {
4865
+ const elig = available.has(seat.label) && (!categoryKey || seat.categoryKey === categoryKey);
4866
+ let arr = rows.get(seat.rowId);
4867
+ if (!arr) {
4868
+ arr = [];
4869
+ rows.set(seat.rowId, arr);
4870
+ }
4871
+ arr.push({ seat, index: seatIndex2(seat, i), elig });
4872
+ if (elig) eligibleAll.push(seat);
4873
+ });
4874
+ if (eligibleAll.length === 0) return { labels: [], reason: "sold_out" };
4875
+ let best = null;
4876
+ const better = (c) => {
4877
+ if (!best) return true;
4878
+ if (preferPremium && c.nonPremium !== best.nonPremium) return c.nonPremium < best.nonPremium;
4879
+ if (c.orphan !== best.orphan) return c.orphan < best.orphan;
4880
+ if (c.d2 !== best.d2) return c.d2 < best.d2;
4881
+ const r = c.rowId.localeCompare(best.rowId);
4882
+ if (r !== 0) return r < 0;
4883
+ return c.startIndex < best.startIndex;
4884
+ };
4885
+ for (const [rowId, slotsUnsorted] of rows) {
4886
+ const slots = [...slotsUnsorted].sort((a, b) => a.index - b.index);
4887
+ let i = 0;
4888
+ while (i < slots.length) {
4889
+ if (!slots[i].elig) {
4890
+ i++;
4891
+ continue;
4892
+ }
4893
+ let j = i;
4894
+ while (j < slots.length && slots[j].elig) j++;
4895
+ const segLen = j - i;
4896
+ for (let p = 0; p + qty <= segLen; p++) {
4897
+ const leftRem = p;
4898
+ const rightRem = segLen - (p + qty);
4899
+ const orphan = leftRem === 1 || rightRem === 1 ? 1 : 0;
4900
+ const runSeats = slots.slice(i + p, i + p + qty).map((s) => s.seat);
4901
+ const c = {
4902
+ labels: runSeats.map((s) => s.label),
4903
+ seats: runSeats,
4904
+ rowId,
4905
+ startIndex: slots[i + p].index,
4906
+ orphan,
4907
+ nonPremium: preferPremium ? runSeats.reduce((n, s) => n + (isPremium(s) ? 0 : 1), 0) : 0,
4908
+ d2: dist2(centroid(runSeats), focal)
4909
+ };
4910
+ if (better(c)) best = c;
4911
+ }
4912
+ i = j;
4913
+ }
4914
+ }
4915
+ if (best) return { labels: best.labels };
4916
+ if (eligibleAll.length < qty) return { labels: [], reason: "not_enough_together" };
4917
+ const ranked = eligibleAll.map((seat, i) => ({ seat, i, d2: dist2(seat, focal) })).sort((a, b) => {
4918
+ if (preferPremium) {
4919
+ const pa = isPremium(a.seat) ? 0 : 1;
4920
+ const pb = isPremium(b.seat) ? 0 : 1;
4921
+ if (pa !== pb) return pa - pb;
4922
+ }
4923
+ if (a.d2 !== b.d2) return a.d2 - b.d2;
4924
+ const r = a.seat.rowId.localeCompare(b.seat.rowId);
4925
+ if (r !== 0) return r;
4926
+ return seatIndex2(a.seat, a.i) - seatIndex2(b.seat, b.i);
4927
+ });
4928
+ return { labels: ranked.slice(0, qty).map((r) => r.seat.label) };
4929
+ }
4930
+
4826
4931
  // src/picker/PickerController.ts
4827
4932
  var DEFAULT_MAX_SELECTION = 10;
4828
4933
  var MAX_BACKOFF_MS = 15e3;
@@ -5174,10 +5279,77 @@ var PickerController = class {
5174
5279
  this.setHold({ holdId: result.holdId, labels: combined.map((s) => s.label), expiresAt: result.expiresAt, items: result.items });
5175
5280
  return this.hold_;
5176
5281
  }
5177
- /** Server-picks `qty` best free seats and holds them atomically. Throws on failure. */
5178
- async bestAvailable(qty, categoryKey) {
5282
+ /** True when any seat on the visible chart carries the `premium` commercial
5283
+ * flag — gates the buyer widget's "★ Best seats" premium quick-pick (chip is
5284
+ * present-only, exactly like the accessibility filter chips). */
5285
+ hasPremiumSeats() {
5286
+ for (const seat of this.labelToSeat.values()) {
5287
+ if (seat.commercial?.premium) return true;
5288
+ }
5289
+ return false;
5290
+ }
5291
+ /**
5292
+ * Client-side premium pre-pass: find the best contiguous block of `qty`
5293
+ * PREMIUM-flagged free seats (orphan-avoiding, closest to the focal point)
5294
+ * using the local seat geometry + live availability, mirroring the server's
5295
+ * held-back exclusion via the visible (hidden-stripped) chart and current
5296
+ * seat status. Returns a FULL premium block of `qty`, or null when none
5297
+ * exists (the caller then falls back to the normal server pick).
5298
+ */
5299
+ pickPremiumBlock(qty, categoryKey) {
5300
+ const doc = this.visibleDoc();
5301
+ if (!doc?.objects?.length) return null;
5302
+ const focal = doc.focalPoint ?? { x: 0, y: 0 };
5303
+ const seats = expandChart(doc);
5304
+ const held = new Set(this.hold_?.labels ?? []);
5305
+ const available = /* @__PURE__ */ new Set();
5306
+ for (const seat of seats) {
5307
+ if (held.has(seat.label)) continue;
5308
+ const id = this.labelToId.get(seat.label);
5309
+ const status = id ? this.getStatus(id) : void 0;
5310
+ if ((status ?? "free") === "free") available.add(seat.label);
5311
+ }
5312
+ const pick = pickBestAvailable(seats, available, { qty, categoryKey, focal, preferPremium: true });
5313
+ if (pick.labels.length !== qty) return null;
5314
+ const allPremium = pick.labels.every((l) => this.labelToSeat.get(l)?.commercial?.premium);
5315
+ return allPremium ? [...pick.labels] : null;
5316
+ }
5317
+ /**
5318
+ * Server-picks `qty` best free seats and holds them atomically. Throws on
5319
+ * failure. With `preferPremium`, first tries to hold the best PREMIUM block
5320
+ * locally; when none matches the requested quantity it falls back to the
5321
+ * normal server pick (the widget surfaces a subtle note on that fallback).
5322
+ */
5323
+ async bestAvailable(qty, categoryKey, opts = {}) {
5179
5324
  const r = this.renderer;
5180
5325
  if (!r) return null;
5326
+ if (opts.preferPremium) {
5327
+ const block = this.pickPremiumBlock(qty, categoryKey);
5328
+ if (block) {
5329
+ if (this.hold_ && !await this.release()) return null;
5330
+ try {
5331
+ const selection = block.map((label) => {
5332
+ const seat = this.labelToSeat.get(label);
5333
+ const resolved = seat ? this.toSeat(seat) : null;
5334
+ return { label, ...resolved?.tierId ? { tierId: resolved.tierId } : {} };
5335
+ });
5336
+ const result = await this.api.hold(this.key, selection);
5337
+ r.clearSelection();
5338
+ const ids = block.map((l) => this.labelToId.get(l)).filter((v) => !!v);
5339
+ if (ids.length) r.setStatus(ids, "held");
5340
+ this.setHold({ holdId: result.holdId, labels: [...block], expiresAt: result.expiresAt, items: result.items });
5341
+ const seats = block.map((l) => this.labelToSeat.get(l)).filter((s) => !!s).map((s) => this.toSeat(s));
5342
+ this.opts.onSelectionChange?.(seats);
5343
+ return this.hold_;
5344
+ } catch (err) {
5345
+ const { status, reason } = errInfo(err);
5346
+ if (status === 409 && reason === "event_closed") {
5347
+ this.opts.onSalesClosed?.();
5348
+ throw err;
5349
+ }
5350
+ }
5351
+ }
5352
+ }
5181
5353
  if (this.hold_ && !await this.release()) return null;
5182
5354
  try {
5183
5355
  const result = await this.api.bestAvailable(this.key, qty, categoryKey);