@qite/tide-components 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +392 -421
  2. package/build/build-cjs/index.js +1009 -133
  3. package/build/build-cjs/src/booking-wizard/features/booking/selectors.d.ts +5 -5
  4. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +1 -0
  5. package/build/build-cjs/src/booking-wizard/features/travelers-form/validate-form.d.ts +1 -1
  6. package/build/build-cjs/src/booking-wizard/types.d.ts +15 -0
  7. package/build/build-cjs/src/search-results/components/traject/traject-node-card.d.ts +12 -0
  8. package/build/build-cjs/src/search-results/components/traject/traject-results.d.ts +6 -0
  9. package/build/build-cjs/src/search-results/hooks/use-traject-availability.d.ts +2 -0
  10. package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +21 -2
  11. package/build/build-cjs/src/search-results/types.d.ts +2 -1
  12. package/build/build-cjs/src/search-results/utils/flight-booking-params.d.ts +18 -0
  13. package/build/build-cjs/src/search-results/utils/traject-utils.d.ts +31 -0
  14. package/build/build-cjs/src/shared/booking/travelers-form.d.ts +3 -2
  15. package/build/build-esm/index.js +1010 -134
  16. package/build/build-esm/src/booking-wizard/features/booking/selectors.d.ts +5 -5
  17. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +1 -0
  18. package/build/build-esm/src/booking-wizard/features/travelers-form/validate-form.d.ts +1 -1
  19. package/build/build-esm/src/booking-wizard/types.d.ts +15 -0
  20. package/build/build-esm/src/search-results/components/traject/traject-node-card.d.ts +12 -0
  21. package/build/build-esm/src/search-results/components/traject/traject-results.d.ts +6 -0
  22. package/build/build-esm/src/search-results/hooks/use-traject-availability.d.ts +2 -0
  23. package/build/build-esm/src/search-results/store/search-results-slice.d.ts +21 -2
  24. package/build/build-esm/src/search-results/types.d.ts +2 -1
  25. package/build/build-esm/src/search-results/utils/flight-booking-params.d.ts +18 -0
  26. package/build/build-esm/src/search-results/utils/traject-utils.d.ts +31 -0
  27. package/build/build-esm/src/shared/booking/travelers-form.d.ts +3 -2
  28. package/package.json +2 -2
@@ -199,6 +199,7 @@ var TRAVELERS_FORM$f = {
199
199
  ADULTS: "بالغون",
200
200
  CHILD: "طفل",
201
201
  CHILDREN: "أطفال",
202
+ BABY: "رضيع",
202
203
  GENDER: "اللقب",
203
204
  GENDER_ID: "الجنس حسب جواز السفر/بطاقة الهوية",
204
205
  MALE: "السيد",
@@ -243,6 +244,8 @@ var TRAVELERS_FORM$f = {
243
244
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "المسافر {0}: ليس بالغًا",
244
245
  TRAVELER_X_IS_NO_CHILD: "الغرفة {0} - المسافر {1}: ليس طفلًا",
245
246
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "المسافر {0}: ليس طفلًا",
247
+ TRAVELER_X_IS_NO_BABY: "الغرفة {0} - المسافر {1}: ليس رضيعًا (يجب أن يكون عمره أقل من {2} سنة في تاريخ المغادرة)",
248
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "المسافر {0}: ليس رضيعًا (يجب أن يكون عمره أقل من {1} سنة في تاريخ المغادرة)",
246
249
  NO_MAIN_BOOKER_SELECTED: "لم يتم اختيار حاجز رئيسي",
247
250
  MAIN_BOOKER_FIELD: "الحاجز الرئيسي: {0}",
248
251
  MAIN_BOOKER_EMAIL_IS_INVALID: "الحاجز الرئيسي: البريد الإلكتروني غير صالح",
@@ -635,6 +638,7 @@ var TRAVELERS_FORM$e = {
635
638
  ADULTS: "voksne",
636
639
  CHILD: "barn",
637
640
  CHILDREN: "børn",
641
+ BABY: "baby",
638
642
  GENDER: "Tiltaleform",
639
643
  GENDER_ID: "Køn ifølge pas/ID-kort",
640
644
  MALE: "Hr.",
@@ -679,6 +683,8 @@ var TRAVELERS_FORM$e = {
679
683
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Rejsende {0}: er ikke voksen",
680
684
  TRAVELER_X_IS_NO_CHILD: "Værelse {0} - Rejsende {1}: er ikke barn",
681
685
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Rejsende {0}: er ikke barn",
686
+ TRAVELER_X_IS_NO_BABY: "Værelse {0} - Rejsende {1}: er ikke baby (skal være under {2} år på afrejsedatoen)",
687
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Rejsende {0}: er ikke baby (skal være under {1} år på afrejsedatoen)",
682
688
  NO_MAIN_BOOKER_SELECTED: "Ingen hovedbooker valgt",
683
689
  MAIN_BOOKER_FIELD: "Hovedbooker: {0}",
684
690
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hovedbooker: email er ugyldig",
@@ -1071,6 +1077,7 @@ var TRAVELERS_FORM$d = {
1071
1077
  ADULTS: "Erwachsene",
1072
1078
  CHILD: "Kind",
1073
1079
  CHILDREN: "Kinder",
1080
+ BABY: "Baby",
1074
1081
  GENDER: "Anrede",
1075
1082
  GENDER_ID: "Geschlecht laut Reisepass/Personalausweis",
1076
1083
  MALE: "Herr",
@@ -1115,6 +1122,8 @@ var TRAVELERS_FORM$d = {
1115
1122
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Reisender {0}: ist kein Erwachsener",
1116
1123
  TRAVELER_X_IS_NO_CHILD: "Zimmer {0} - Reisender {1}: ist kein Kind",
1117
1124
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Reisender {0}: ist kein Kind",
1125
+ TRAVELER_X_IS_NO_BABY: "Zimmer {0} - Reisender {1}: ist kein Baby (muss am Abreisedatum jünger als {2} Jahre sein)",
1126
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Reisender {0}: ist kein Baby (muss am Abreisedatum jünger als {1} Jahre sein)",
1118
1127
  NO_MAIN_BOOKER_SELECTED: "Kein Hauptbucher ausgewählt",
1119
1128
  MAIN_BOOKER_FIELD: "Hauptbucher: {0}",
1120
1129
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hauptbucher: E-Mail ist ungültig",
@@ -1508,6 +1517,7 @@ var TRAVELERS_FORM$c = {
1508
1517
  ADULTS: "adults",
1509
1518
  CHILD: "child",
1510
1519
  CHILDREN: "children",
1520
+ BABY: "baby",
1511
1521
  GENDER: "Salutation",
1512
1522
  GENDER_ID: "Gender according to passport/ID card",
1513
1523
  MALE: "Mr.",
@@ -1555,6 +1565,8 @@ var TRAVELERS_FORM$c = {
1555
1565
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Traveler {0}: is not an adult",
1556
1566
  TRAVELER_X_IS_NO_CHILD: "Room {0} - Traveler {1}: is not a child",
1557
1567
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Traveler {0}: is not a child",
1568
+ TRAVELER_X_IS_NO_BABY: "Room {0} - Traveler {1}: is not a baby (must be under {2} years old on the departure date)",
1569
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Traveler {0}: is not a baby (must be under {1} years old on the departure date)",
1558
1570
  NO_MAIN_BOOKER_SELECTED: "No main booker has been selected",
1559
1571
  MAIN_BOOKER_FIELD: "Main booker: {0}",
1560
1572
  MAIN_BOOKER_EMAIL_IS_INVALID: "Main booker: email is invalid",
@@ -1947,6 +1959,7 @@ var TRAVELERS_FORM$b = {
1947
1959
  ADULTS: "adultos",
1948
1960
  CHILD: "niño",
1949
1961
  CHILDREN: "niños",
1962
+ BABY: "bebé",
1950
1963
  GENDER: "Tratamiento",
1951
1964
  GENDER_ID: "Sexo según pasaporte/documento de identidad",
1952
1965
  MALE: "Sr.",
@@ -1991,6 +2004,8 @@ var TRAVELERS_FORM$b = {
1991
2004
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Viajero {0}: no es adulto",
1992
2005
  TRAVELER_X_IS_NO_CHILD: "Habitación {0} - Viajero {1}: no es niño",
1993
2006
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Viajero {0}: no es niño",
2007
+ TRAVELER_X_IS_NO_BABY: "Habitación {0} - Viajero {1}: no es bebé (debe tener menos de {2} años en la fecha de salida)",
2008
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Viajero {0}: no es bebé (debe tener menos de {1} años en la fecha de salida)",
1994
2009
  NO_MAIN_BOOKER_SELECTED: "No se ha seleccionado titular de la reserva",
1995
2010
  MAIN_BOOKER_FIELD: "Titular de la reserva: {0}",
1996
2011
  MAIN_BOOKER_EMAIL_IS_INVALID: "Titular de la reserva: correo electrónico inválido",
@@ -2384,6 +2399,7 @@ var TRAVELERS_FORM$a = {
2384
2399
  ADULTS: "adultes",
2385
2400
  CHILD: "enfant",
2386
2401
  CHILDREN: "enfants",
2402
+ BABY: "bébé",
2387
2403
  GENDER: "Civilité",
2388
2404
  GENDER_ID: "Sexe selon passeport/carte d'identité",
2389
2405
  MALE: "Monsieur",
@@ -2431,6 +2447,8 @@ var TRAVELERS_FORM$a = {
2431
2447
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Voyageur {0} : n'est pas un adulte",
2432
2448
  TRAVELER_X_IS_NO_CHILD: "Chambre {0} - Voyageur {1} : n'est pas un enfant",
2433
2449
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Voyageur {0} : n'est pas un enfant",
2450
+ TRAVELER_X_IS_NO_BABY: "Chambre {0} - Voyageur {1} : n'est pas un bébé (doit avoir moins de {2} ans à la date de départ)",
2451
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Voyageur {0} : n'est pas un bébé (doit avoir moins de {1} ans à la date de départ)",
2434
2452
  NO_MAIN_BOOKER_SELECTED: "Aucun réservant principal n'a été sélectionné",
2435
2453
  MAIN_BOOKER_FIELD: "Principal réservant : {0}",
2436
2454
  MAIN_BOOKER_EMAIL_IS_INVALID: "Principal réservant : e-mail invalide",
@@ -2823,6 +2841,7 @@ var TRAVELERS_FORM$9 = {
2823
2841
  ADULTS: "adultes",
2824
2842
  CHILD: "enfant",
2825
2843
  CHILDREN: "enfants",
2844
+ BABY: "bébé",
2826
2845
  GENDER: "Civilité",
2827
2846
  GENDER_ID: "Sexe selon passeport/carte d'identité",
2828
2847
  MALE: "M.",
@@ -2867,6 +2886,8 @@ var TRAVELERS_FORM$9 = {
2867
2886
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Voyageur {0} : n'est pas un adulte",
2868
2887
  TRAVELER_X_IS_NO_CHILD: "Chambre {0} - Voyageur {1} : n'est pas un enfant",
2869
2888
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Voyageur {0} : n'est pas un enfant",
2889
+ TRAVELER_X_IS_NO_BABY: "Chambre {0} - Voyageur {1} : n'est pas un bébé (doit avoir moins de {2} ans à la date de départ)",
2890
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Voyageur {0} : n'est pas un bébé (doit avoir moins de {1} ans à la date de départ)",
2870
2891
  NO_MAIN_BOOKER_SELECTED: "Aucun titulaire de réservation sélectionné",
2871
2892
  MAIN_BOOKER_FIELD: "Titulaire de la réservation : {0}",
2872
2893
  MAIN_BOOKER_EMAIL_IS_INVALID: "Titulaire de la réservation : email invalide",
@@ -3259,6 +3280,7 @@ var TRAVELERS_FORM$8 = {
3259
3280
  ADULTS: "fullorðnir",
3260
3281
  CHILD: "barn",
3261
3282
  CHILDREN: "börn",
3283
+ BABY: "ungabarn",
3262
3284
  GENDER: "Ávarp",
3263
3285
  GENDER_ID: "Kyn samkvæmt vegabréfi/skilríki",
3264
3286
  MALE: "Herra",
@@ -3303,6 +3325,8 @@ var TRAVELERS_FORM$8 = {
3303
3325
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Farþegi {0}: er ekki fullorðinn",
3304
3326
  TRAVELER_X_IS_NO_CHILD: "Herbergi {0} - Farþegi {1}: er ekki barn",
3305
3327
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Farþegi {0}: er ekki barn",
3328
+ TRAVELER_X_IS_NO_BABY: "Herbergi {0} - Farþegi {1}: er ekki ungabarn (verður að vera undir {2} ára á brottfarardegi)",
3329
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Farþegi {0}: er ekki ungabarn (verður að vera undir {1} ára á brottfarardegi)",
3306
3330
  NO_MAIN_BOOKER_SELECTED: "Enginn aðal bókari valinn",
3307
3331
  MAIN_BOOKER_FIELD: "Aðal bókari: {0}",
3308
3332
  MAIN_BOOKER_EMAIL_IS_INVALID: "Aðal bókari: netfang ógilt",
@@ -3695,6 +3719,7 @@ var TRAVELERS_FORM$7 = {
3695
3719
  ADULTS: "adulti",
3696
3720
  CHILD: "bambino",
3697
3721
  CHILDREN: "bambini",
3722
+ BABY: "neonato",
3698
3723
  GENDER: "Titolo",
3699
3724
  GENDER_ID: "Sesso secondo passaporto/carta d'identità",
3700
3725
  MALE: "Sig.",
@@ -3739,6 +3764,8 @@ var TRAVELERS_FORM$7 = {
3739
3764
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Viaggiatore {0}: non è un adulto",
3740
3765
  TRAVELER_X_IS_NO_CHILD: "Camera {0} - Viaggiatore {1}: non è un bambino",
3741
3766
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Viaggiatore {0}: non è un bambino",
3767
+ TRAVELER_X_IS_NO_BABY: "Camera {0} - Viaggiatore {1}: non è un neonato (deve avere meno di {2} anni alla data di partenza)",
3768
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Viaggiatore {0}: non è un neonato (deve avere meno di {1} anni alla data di partenza)",
3742
3769
  NO_MAIN_BOOKER_SELECTED: "Nessun intestatario della prenotazione selezionato",
3743
3770
  MAIN_BOOKER_FIELD: "Intestatario della prenotazione: {0}",
3744
3771
  MAIN_BOOKER_EMAIL_IS_INVALID: "Intestatario della prenotazione: email non valida",
@@ -4132,6 +4159,7 @@ var TRAVELERS_FORM$6 = {
4132
4159
  ADULTS: "volwassenen",
4133
4160
  CHILD: "kind",
4134
4161
  CHILDREN: "kinderen",
4162
+ BABY: "baby",
4135
4163
  GENDER: "Aanspreking",
4136
4164
  GENDER_ID: "Geslacht volgens paspoort/identiteitskaart",
4137
4165
  MALE: "Meneer",
@@ -4179,6 +4207,8 @@ var TRAVELERS_FORM$6 = {
4179
4207
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Reiziger {0}: is geen volwassene",
4180
4208
  TRAVELER_X_IS_NO_CHILD: "Kamer {0} - Reiziger {1}: is geen kind",
4181
4209
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Reiziger {0}: is geen kind",
4210
+ TRAVELER_X_IS_NO_BABY: "Kamer {0} - Reiziger {1}: is geen baby (moet jonger zijn dan {2} jaar op de heendatum)",
4211
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Reiziger {0}: is geen baby (moet jonger zijn dan {1} jaar op de heendatum)",
4182
4212
  NO_MAIN_BOOKER_SELECTED: "Er werd geen hoofdboeker geselecteerd",
4183
4213
  MAIN_BOOKER_FIELD: "Hoofdboeker: {0}",
4184
4214
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hoofdboeker: e-mail is ongeldig",
@@ -4571,6 +4601,7 @@ var TRAVELERS_FORM$5 = {
4571
4601
  ADULTS: "volwassenen",
4572
4602
  CHILD: "kind",
4573
4603
  CHILDREN: "kinderen",
4604
+ BABY: "baby",
4574
4605
  GENDER: "Aanhef",
4575
4606
  GENDER_ID: "Geslacht volgens paspoort/identiteitskaart",
4576
4607
  MALE: "Dhr.",
@@ -4615,6 +4646,8 @@ var TRAVELERS_FORM$5 = {
4615
4646
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Reiziger {0}: is geen volwassene",
4616
4647
  TRAVELER_X_IS_NO_CHILD: "Kamer {0} - Reiziger {1}: is geen kind",
4617
4648
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Reiziger {0}: is geen kind",
4649
+ TRAVELER_X_IS_NO_BABY: "Kamer {0} - Reiziger {1}: is geen baby (moet jonger zijn dan {2} jaar op de heendatum)",
4650
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Reiziger {0}: is geen baby (moet jonger zijn dan {1} jaar op de heendatum)",
4618
4651
  NO_MAIN_BOOKER_SELECTED: "Geen hoofdboeker geselecteerd",
4619
4652
  MAIN_BOOKER_FIELD: "Hoofdboeker: {0}",
4620
4653
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hoofdboeker: e-mailadres is ongeldig",
@@ -5007,6 +5040,7 @@ var TRAVELERS_FORM$4 = {
5007
5040
  ADULTS: "voksne",
5008
5041
  CHILD: "barn",
5009
5042
  CHILDREN: "barn",
5043
+ BABY: "baby",
5010
5044
  GENDER: "Tiltaleform",
5011
5045
  GENDER_ID: "Kjønn ifølge pass/ID-kort",
5012
5046
  MALE: "Herr",
@@ -5051,6 +5085,8 @@ var TRAVELERS_FORM$4 = {
5051
5085
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Reisende {0}: er ikke voksen",
5052
5086
  TRAVELER_X_IS_NO_CHILD: "Rom {0} – Reisende {1}: er ikke barn",
5053
5087
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Reisende {0}: er ikke barn",
5088
+ TRAVELER_X_IS_NO_BABY: "Rom {0} – Reisende {1}: er ikke baby (må være under {2} år på avreisedatoen)",
5089
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Reisende {0}: er ikke baby (må være under {1} år på avreisedatoen)",
5054
5090
  NO_MAIN_BOOKER_SELECTED: "Ingen hovedbestiller valgt",
5055
5091
  MAIN_BOOKER_FIELD: "Hovedbestiller: {0}",
5056
5092
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hovedbestiller: e-post er ugyldig",
@@ -5443,6 +5479,7 @@ var TRAVELERS_FORM$3 = {
5443
5479
  ADULTS: "dorośli",
5444
5480
  CHILD: "dziecko",
5445
5481
  CHILDREN: "dzieci",
5482
+ BABY: "niemowlę",
5446
5483
  GENDER: "Forma grzecznościowa",
5447
5484
  GENDER_ID: "Płeć według paszportu/dowodu osobistego",
5448
5485
  MALE: "Pan",
@@ -5487,6 +5524,8 @@ var TRAVELERS_FORM$3 = {
5487
5524
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Podróżny {0}: nie jest dorosły",
5488
5525
  TRAVELER_X_IS_NO_CHILD: "Pokój {0} – Podróżny {1}: nie jest dzieckiem",
5489
5526
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Podróżny {0}: nie jest dzieckiem",
5527
+ TRAVELER_X_IS_NO_BABY: "Pokój {0} – Podróżny {1}: nie jest niemowlęciem (musi mieć mniej niż {2} lata w dniu wyjazdu)",
5528
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Podróżny {0}: nie jest niemowlęciem (musi mieć mniej niż {1} lata w dniu wyjazdu)",
5490
5529
  NO_MAIN_BOOKER_SELECTED: "Nie wybrano głównego rezerwującego",
5491
5530
  MAIN_BOOKER_FIELD: "Główny rezerwujący: {0}",
5492
5531
  MAIN_BOOKER_EMAIL_IS_INVALID: "Główny rezerwujący: nieprawidłowy adres e-mail",
@@ -5879,6 +5918,7 @@ var TRAVELERS_FORM$2 = {
5879
5918
  ADULTS: "adultos",
5880
5919
  CHILD: "criança",
5881
5920
  CHILDREN: "crianças",
5921
+ BABY: "bebé",
5882
5922
  GENDER: "Tratamento",
5883
5923
  GENDER_ID: "Sexo conforme passaporte/documento de identidade",
5884
5924
  MALE: "Sr.",
@@ -5923,6 +5963,8 @@ var TRAVELERS_FORM$2 = {
5923
5963
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Viajante {0}: não é adulto",
5924
5964
  TRAVELER_X_IS_NO_CHILD: "Quarto {0} – Viajante {1}: não é criança",
5925
5965
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Viajante {0}: não é criança",
5966
+ TRAVELER_X_IS_NO_BABY: "Quarto {0} – Viajante {1}: não é bebé (deve ter menos de {2} anos na data de partida)",
5967
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Viajante {0}: não é bebé (deve ter menos de {1} anos na data de partida)",
5926
5968
  NO_MAIN_BOOKER_SELECTED: "Nenhum titular da reserva foi selecionado",
5927
5969
  MAIN_BOOKER_FIELD: "Titular da reserva: {0}",
5928
5970
  MAIN_BOOKER_EMAIL_IS_INVALID: "Titular da reserva: o e-mail é inválido",
@@ -6315,6 +6357,7 @@ var TRAVELERS_FORM$1 = {
6315
6357
  ADULTS: "vuxna",
6316
6358
  CHILD: "barn",
6317
6359
  CHILDREN: "barn",
6360
+ BABY: "spädbarn",
6318
6361
  GENDER: "Tilltalsform",
6319
6362
  GENDER_ID: "Kön enligt pass/ID-kort",
6320
6363
  MALE: "Herr",
@@ -6359,6 +6402,8 @@ var TRAVELERS_FORM$1 = {
6359
6402
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Resenär {0}: är inte vuxen",
6360
6403
  TRAVELER_X_IS_NO_CHILD: "Rum {0} – Resenär {1}: är inte barn",
6361
6404
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Resenär {0}: är inte barn",
6405
+ TRAVELER_X_IS_NO_BABY: "Rum {0} – Resenär {1}: är inte spädbarn (måste vara under {2} år på avresedatumet)",
6406
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Resenär {0}: är inte spädbarn (måste vara under {1} år på avresedatumet)",
6362
6407
  NO_MAIN_BOOKER_SELECTED: "Ingen huvudbokare har valts",
6363
6408
  MAIN_BOOKER_FIELD: "Huvudbokare: {0}",
6364
6409
  MAIN_BOOKER_EMAIL_IS_INVALID: "Huvudbokare: e-postadressen är ogiltig",
@@ -6751,6 +6796,7 @@ var TRAVELERS_FORM = {
6751
6796
  ADULTS: "大人",
6752
6797
  CHILD: "子供",
6753
6798
  CHILDREN: "子供",
6799
+ BABY: "乳児",
6754
6800
  GENDER: "敬称",
6755
6801
  GENDER_ID: "パスポート/身分証明書上の性別",
6756
6802
  MALE: "男性",
@@ -6795,6 +6841,8 @@ var TRAVELERS_FORM = {
6795
6841
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "旅行者 {0}: 大人ではありません",
6796
6842
  TRAVELER_X_IS_NO_CHILD: "客室 {0} – 旅行者 {1}: 子供ではありません",
6797
6843
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "旅行者 {0}: 子供ではありません",
6844
+ TRAVELER_X_IS_NO_BABY: "客室 {0} – 旅行者 {1}: 乳児ではありません(出発日時点で{2}歳未満である必要があります)",
6845
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "旅行者 {0}: 乳児ではありません(出発日時点で{1}歳未満である必要があります)",
6798
6846
  NO_MAIN_BOOKER_SELECTED: "代表予約者が選択されていません",
6799
6847
  MAIN_BOOKER_FIELD: "代表予約者: {0}",
6800
6848
  MAIN_BOOKER_EMAIL_IS_INVALID: "代表予約者: メールアドレスが無効です",
@@ -7420,12 +7468,6 @@ var DataType = {
7420
7468
  template: "template",
7421
7469
  };
7422
7470
 
7423
- exports.DateAmountType = void 0;
7424
- (function (DateAmountType) {
7425
- DateAmountType[(DateAmountType["days"] = 0)] = "days";
7426
- DateAmountType[(DateAmountType["months"] = 1)] = "months";
7427
- })(exports.DateAmountType || (exports.DateAmountType = {}));
7428
-
7429
7471
  var DossierType = {
7430
7472
  hotelOnly: 0,
7431
7473
  transportOnly: 1,
@@ -7529,6 +7571,16 @@ var MetaDataType = {
7529
7571
  additionalServices: 7,
7530
7572
  };
7531
7573
 
7574
+ exports.NoteType = void 0;
7575
+ (function (NoteType) {
7576
+ NoteType[(NoteType["notification"] = 0)] = "notification";
7577
+ NoteType[(NoteType["task"] = 1)] = "task";
7578
+ NoteType[(NoteType["calendar"] = 2)] = "calendar";
7579
+ NoteType[(NoteType["callLog"] = 3)] = "callLog";
7580
+ NoteType[(NoteType["opportunity"] = 4)] = "opportunity";
7581
+ NoteType[(NoteType["email"] = 5)] = "email";
7582
+ })(exports.NoteType || (exports.NoteType = {}));
7583
+
7532
7584
  var PaymentType = {
7533
7585
  other: 0,
7534
7586
  bancontact: 1,
@@ -7536,22 +7588,6 @@ var PaymentType = {
7536
7588
  cash: 3,
7537
7589
  };
7538
7590
 
7539
- exports.PortalQsmType = void 0;
7540
- (function (PortalQsmType) {
7541
- PortalQsmType[(PortalQsmType["Multidestination"] = 0)] = "Multidestination";
7542
- PortalQsmType[(PortalQsmType["Accommodation"] = 1)] = "Accommodation";
7543
- PortalQsmType[(PortalQsmType["AccommodationAndFlight"] = 2)] =
7544
- "AccommodationAndFlight";
7545
- PortalQsmType[(PortalQsmType["Flight"] = 3)] = "Flight";
7546
- PortalQsmType[(PortalQsmType["RoundTrip"] = 4)] = "RoundTrip";
7547
- PortalQsmType[(PortalQsmType["GroupTour"] = 5)] = "GroupTour";
7548
- PortalQsmType[(PortalQsmType["Package"] = 6)] = "Package";
7549
- PortalQsmType[(PortalQsmType["Ticket"] = 7)] = "Ticket";
7550
- PortalQsmType[(PortalQsmType["Car"] = 8)] = "Car";
7551
- PortalQsmType[(PortalQsmType["Transfer"] = 9)] = "Transfer";
7552
- PortalQsmType[(PortalQsmType["Cruise"] = 10)] = "Cruise";
7553
- })(exports.PortalQsmType || (exports.PortalQsmType = {}));
7554
-
7555
7591
  var PriceChartType = {
7556
7592
  purchasePrices: 0,
7557
7593
  sellingPrices: 1,
@@ -7656,6 +7692,35 @@ var VendorType = {
7656
7692
  sunnyCars: 20,
7657
7693
  };
7658
7694
 
7695
+ exports.DateAmountType = void 0;
7696
+ (function (DateAmountType) {
7697
+ DateAmountType[(DateAmountType["days"] = 0)] = "days";
7698
+ DateAmountType[(DateAmountType["months"] = 1)] = "months";
7699
+ })(exports.DateAmountType || (exports.DateAmountType = {}));
7700
+
7701
+ exports.PortalQsmType = void 0;
7702
+ (function (PortalQsmType) {
7703
+ PortalQsmType[(PortalQsmType["Multidestination"] = 0)] = "Multidestination";
7704
+ PortalQsmType[(PortalQsmType["Accommodation"] = 1)] = "Accommodation";
7705
+ PortalQsmType[(PortalQsmType["AccommodationAndFlight"] = 2)] =
7706
+ "AccommodationAndFlight";
7707
+ PortalQsmType[(PortalQsmType["Flight"] = 3)] = "Flight";
7708
+ PortalQsmType[(PortalQsmType["RoundTrip"] = 4)] = "RoundTrip";
7709
+ PortalQsmType[(PortalQsmType["GroupTour"] = 5)] = "GroupTour";
7710
+ PortalQsmType[(PortalQsmType["Package"] = 6)] = "Package";
7711
+ PortalQsmType[(PortalQsmType["Ticket"] = 7)] = "Ticket";
7712
+ PortalQsmType[(PortalQsmType["Car"] = 8)] = "Car";
7713
+ PortalQsmType[(PortalQsmType["Transfer"] = 9)] = "Transfer";
7714
+ PortalQsmType[(PortalQsmType["Cruise"] = 10)] = "Cruise";
7715
+ })(exports.PortalQsmType || (exports.PortalQsmType = {}));
7716
+
7717
+ var TrajectNodeType = {
7718
+ regular: 0,
7719
+ connectingNode: 1,
7720
+ poi: 2,
7721
+ subroute: 3,
7722
+ };
7723
+
7659
7724
  /******************************************************************************
7660
7725
  Copyright (c) Microsoft Corporation.
7661
7726
 
@@ -13952,58 +14017,73 @@ var get = function (url, apiKey, token, signal, skipReviver, languageCode) {
13952
14017
  });
13953
14018
  };
13954
14019
 
13955
- var ENDPOINT$9 = "/api/web/booking/v2";
13956
- var ENDPOINT_AVAILABLE_FLIGHTS = ENDPOINT$9 + "/available-flights";
13957
- var ENDPOINT_TRANSPORT_DATES = ENDPOINT$9 + "/transport-dates";
13958
- var ENDPOINT_PRICES = ENDPOINT$9 + "/prices";
13959
- var ENDPOINT_AVAILABLE_COUNTRIES = ENDPOINT$9 + "/available-countries";
13960
- var ENDPOINT_SEARCH = ENDPOINT$9 + "/search";
14020
+ var ENDPOINT$a = "/api/web/booking/v2";
14021
+ var ENDPOINT_AVAILABLE_FLIGHTS = ENDPOINT$a + "/available-flights";
14022
+ var ENDPOINT_TRANSPORT_DATES = ENDPOINT$a + "/transport-dates";
14023
+ var ENDPOINT_PRICES = ENDPOINT$a + "/prices";
14024
+ var ENDPOINT_AVAILABLE_COUNTRIES = ENDPOINT$a + "/available-countries";
14025
+ var ENDPOINT_SEARCH = ENDPOINT$a + "/search";
13961
14026
  var ENDPOINT_SEARCH_WITH_ERROR_MAPPING =
13962
- ENDPOINT$9 + "/search-with-error-mapping";
14027
+ ENDPOINT$a + "/search-with-error-mapping";
13963
14028
  // const ENDPOINT_ELASTIC = `${ENDPOINT}/elastic`; // TODO
13964
- var ENDPOINT_DETAILS = ENDPOINT$9 + "/details";
13965
- var ENDPOINT_DETAILS_WL = ENDPOINT$9 + "/details-wl";
14029
+ var ENDPOINT_DETAILS = ENDPOINT$a + "/details";
14030
+ var ENDPOINT_DETAILS_WL = ENDPOINT$a + "/details-wl";
13966
14031
  var ENDPOINT_ENTRYLIGHT = function (code) {
13967
- return ENDPOINT$9 + "/entry-light/" + code;
14032
+ return ENDPOINT$a + "/entry-light/" + code;
13968
14033
  };
13969
- var ENDPOINT_VALIDATE_VOUCHER = ENDPOINT$9 + "/validate-voucher";
14034
+ var ENDPOINT_VALIDATE_VOUCHER = ENDPOINT$a + "/validate-voucher";
13970
14035
  var ENDPOINT_ALTERNATE_HOTELS = function (transactionId, optionId) {
13971
14036
  return (
13972
- ENDPOINT$9 + "/details/" + transactionId + "/alternate-hotels/" + optionId
14037
+ ENDPOINT$a + "/details/" + transactionId + "/alternate-hotels/" + optionId
13973
14038
  );
13974
14039
  };
13975
14040
  var ENDPOINT_ALTERNATE_FLIGHTS = function (transactionId) {
13976
- return ENDPOINT$9 + "/details/" + transactionId + "/alternate-flights";
14041
+ return ENDPOINT$a + "/details/" + transactionId + "/alternate-flights";
13977
14042
  };
13978
- var ENDPOINT_BOOKABLE_DATES = ENDPOINT$9 + "/bookable-dates";
13979
- var ENDPOINT_PRICE_DETAILS$1 = ENDPOINT$9 + "/price-details";
13980
- var ENDPOINT_BOOK$1 = ENDPOINT$9 + "/book";
13981
- var ENDPOINT_UPDATE = ENDPOINT$9 + "/update";
13982
- var ENDPOINT_AGENTS = ENDPOINT$9 + "/agents";
14043
+ var ENDPOINT_BOOKABLE_DATES = ENDPOINT$a + "/bookable-dates";
14044
+ var ENDPOINT_PRICE_DETAILS$1 = ENDPOINT$a + "/price-details";
14045
+ var ENDPOINT_BOOK$1 = ENDPOINT$a + "/book";
14046
+ var ENDPOINT_UPDATE = ENDPOINT$a + "/update";
14047
+ var ENDPOINT_AGENTS = ENDPOINT$a + "/agents";
13983
14048
  var ENDPOINT_AVAILABLE_ALLOTMENTS = function (eventId, productCode) {
13984
14049
  return (
13985
- ENDPOINT$9 + "/get-allotment-availability/" + eventId + "/" + productCode
14050
+ ENDPOINT$a + "/get-allotment-availability/" + eventId + "/" + productCode
13986
14051
  );
13987
14052
  };
13988
- var ENDPOINT_FLIGHT_POOL = ENDPOINT$9 + "/flight-pool";
13989
- var ENDPOINT_TOUR_CODES = ENDPOINT$9 + "/tourcodes";
14053
+ var ENDPOINT_FLIGHT_POOL = ENDPOINT$a + "/flight-pool";
14054
+ var ENDPOINT_TOUR_CODES = ENDPOINT$a + "/tourcodes";
13990
14055
  var ENDPOINT_CUSTOM_ENTRY_STATUS$1 = function (
13991
14056
  dossierNumber,
13992
14057
  customEntryStatusId
13993
14058
  ) {
13994
14059
  return (
13995
- ENDPOINT$9 +
14060
+ ENDPOINT$a +
13996
14061
  "/custom-entry-status/" +
13997
14062
  dossierNumber +
13998
14063
  "/" +
13999
14064
  customEntryStatusId
14000
14065
  );
14001
14066
  };
14002
- var ENDPOINT_ENTRY_STATUS = function (dossierNumber, entryStatus) {
14003
- return ENDPOINT$9 + "/entry-status/" + dossierNumber + "/" + entryStatus;
14067
+ var ENDPOINT_ENTRY_STATUS = function (
14068
+ dossierNumber,
14069
+ entryStatus,
14070
+ customEntryStatusId
14071
+ ) {
14072
+ return (
14073
+ ENDPOINT$a +
14074
+ "/entry-status/" +
14075
+ dossierNumber +
14076
+ "/" +
14077
+ entryStatus +
14078
+ (customEntryStatusId !== undefined
14079
+ ? "?customEntryStatusId=" + customEntryStatusId
14080
+ : "")
14081
+ );
14004
14082
  };
14005
- var ENDPOINT_ELASTIC = ENDPOINT$9 + "/elastic";
14006
- var ENDPOINT_FLIGHT_LINES = ENDPOINT$9 + "/flightlines";
14083
+ var ENDPOINT_ELASTIC = ENDPOINT$a + "/elastic";
14084
+ var ENDPOINT_FLIGHT_LINES = ENDPOINT$a + "/flightlines";
14085
+ var ENDPOINT_REPRICE_AND_ISSUE_TICKET =
14086
+ ENDPOINT$a + "/reprice-and-issue-ticket";
14007
14087
  var availableFlights = function (config, request, signal) {
14008
14088
  var url = "" + config.host + ENDPOINT_AVAILABLE_FLIGHTS;
14009
14089
  var apiKey = config.apiKey;
@@ -14141,12 +14221,27 @@ var setCustomEntryStatus = function (
14141
14221
  var apiKey = config.apiKey;
14142
14222
  return patch(url, apiKey, null, config.token, signal, true);
14143
14223
  };
14144
- var setEntryStatus = function (config, dossierNumber, entryStatus, signal) {
14224
+ var setEntryStatus = function (
14225
+ config,
14226
+ dossierNumber,
14227
+ entryStatus,
14228
+ customEntryStatusId,
14229
+ signal
14230
+ ) {
14145
14231
  var url =
14146
- "" + config.host + ENDPOINT_ENTRY_STATUS(dossierNumber, entryStatus);
14232
+ "" +
14233
+ config.host +
14234
+ ENDPOINT_ENTRY_STATUS(dossierNumber, entryStatus, customEntryStatusId);
14147
14235
  var apiKey = config.apiKey;
14148
14236
  return patch(url, apiKey, null, config.token, signal, true);
14149
14237
  };
14238
+ // PRICING
14239
+ var repriceAndIssueTicket = function (config, request, signal) {
14240
+ var url = "" + config.host + ENDPOINT_REPRICE_AND_ISSUE_TICKET;
14241
+ var apiKey = config.apiKey;
14242
+ var body = JSON.stringify(request);
14243
+ return post(url, apiKey, body, config.token, signal, true);
14244
+ };
14150
14245
  var flightLines = function (config, request, signal) {
14151
14246
  var url = "" + config.host + ENDPOINT_FLIGHT_LINES;
14152
14247
  var apiKey = config.apiKey;
@@ -14154,12 +14249,12 @@ var flightLines = function (config, request, signal) {
14154
14249
  return post(url, apiKey, body, config.token, signal, true);
14155
14250
  };
14156
14251
 
14157
- var ENDPOINT$8 = "/api/member";
14158
- var ENDPOINT_LOGIN = ENDPOINT$8 + "/login";
14159
- var ENDPOINT_LOGOUT = ENDPOINT$8 + "/logout";
14160
- var ENDPOINT_CONFIRM = ENDPOINT$8 + "/confirm";
14161
- var ENDPOINT_FORGOT_PASSWORD = ENDPOINT$8 + "/forgot-password";
14162
- var ENDPOINT_RESET_PASSWORD = ENDPOINT$8 + "/reset-password";
14252
+ var ENDPOINT$9 = "/api/member";
14253
+ var ENDPOINT_LOGIN = ENDPOINT$9 + "/login";
14254
+ var ENDPOINT_LOGOUT = ENDPOINT$9 + "/logout";
14255
+ var ENDPOINT_CONFIRM = ENDPOINT$9 + "/confirm";
14256
+ var ENDPOINT_FORGOT_PASSWORD = ENDPOINT$9 + "/forgot-password";
14257
+ var ENDPOINT_RESET_PASSWORD = ENDPOINT$9 + "/reset-password";
14163
14258
  var login = function (config, request, signal) {
14164
14259
  var url = "" + config.host + ENDPOINT_LOGIN;
14165
14260
  var apiKey = config.apiKey;
@@ -14191,8 +14286,8 @@ var resetPassword = function (config, request, signal) {
14191
14286
  return post$1(url, apiKey, body, config.token, signal);
14192
14287
  };
14193
14288
 
14194
- var ENDPOINT$7 = "/api/mollie";
14195
- var ENDPOINT_CREATE_PAYMENTS = ENDPOINT$7 + "/create-payment";
14289
+ var ENDPOINT$8 = "/api/mollie";
14290
+ var ENDPOINT_CREATE_PAYMENTS = ENDPOINT$8 + "/create-payment";
14196
14291
  /**
14197
14292
  * api/mollie/create-payment
14198
14293
  * @param request
@@ -14205,13 +14300,14 @@ var getMolliePayment = function (config, request, signal) {
14205
14300
  return post(url, apiKey, body, config.token, signal);
14206
14301
  };
14207
14302
 
14208
- var ENDPOINT$6 = "/api/web/search";
14209
- var ENDPOINT_COUNTRIES = ENDPOINT$6 + "/countries";
14210
- var ENDPOINT_REGIONS = ENDPOINT$6 + "/regions";
14211
- var ENDPOINT_OORDS = ENDPOINT$6 + "/oords";
14212
- var ENDPOINT_LOCATIONS$1 = ENDPOINT$6 + "/locations";
14303
+ var ENDPOINT$7 = "/api/web/search";
14304
+ var ENDPOINT_COUNTRIES = ENDPOINT$7 + "/countries";
14305
+ var ENDPOINT_REGIONS = ENDPOINT$7 + "/regions";
14306
+ var ENDPOINT_OORDS = ENDPOINT$7 + "/oords";
14307
+ var ENDPOINT_LOCATIONS$1 = ENDPOINT$7 + "/locations";
14308
+ var ENDPOINT_GEOGRAPHICAL_REGIONS = ENDPOINT$7 + "/geographicalregions";
14213
14309
  var ENDPOINT_PORTAL = function (portalId) {
14214
- return ENDPOINT$6 + "/portal/" + portalId;
14310
+ return ENDPOINT$7 + "/portal/" + portalId;
14215
14311
  };
14216
14312
  var ENDPOINT_AIRPORT = "/api/web/entity/airport";
14217
14313
  /**
@@ -14266,6 +14362,18 @@ var searchLocations = function (config, searchTerm, signal) {
14266
14362
  var url = "" + config.host + ENDPOINT_LOCATIONS$1 + "?" + filter;
14267
14363
  return get(url, apiKey, config.token, signal, true);
14268
14364
  };
14365
+ /**
14366
+ * api/web/search/geographicalregions
14367
+ * Gets all available Geographical Regions
14368
+ * @param config
14369
+ * @param signal
14370
+ * @returns OK if succeeded.
14371
+ */
14372
+ var getAvailableGeographicalRegions = function (config, signal) {
14373
+ var url = "" + config.host + ENDPOINT_GEOGRAPHICAL_REGIONS;
14374
+ var apiKey = config.apiKey;
14375
+ return get(url, apiKey, config.token, signal, true);
14376
+ };
14269
14377
  var getPortal = function (config, portalId, signal) {
14270
14378
  var url = "" + config.host + ENDPOINT_PORTAL(portalId);
14271
14379
  var apiKey = config.apiKey;
@@ -14434,13 +14542,13 @@ var isValidDate = function (d) {
14434
14542
  return d instanceof Date && !isNaN(d.getTime());
14435
14543
  };
14436
14544
 
14437
- var ENDPOINT$5 = "/api/web/agent";
14438
- var ENDPOINT_GET_PRINT_ACTIONS = ENDPOINT$5 + "/print-action";
14439
- var ENDPOINT_PRINT = ENDPOINT$5 + "/print-action";
14440
- var ENDPOINT_CUSTOM_ENTRY_STATUS = ENDPOINT$5 + "/custom-entry-status";
14441
- var ENDPOINT_ENUM_ENTRY_STATUS = ENDPOINT$5 + "/enum/entry-status";
14545
+ var ENDPOINT$6 = "/api/web/agent";
14546
+ var ENDPOINT_GET_PRINT_ACTIONS = ENDPOINT$6 + "/print-action";
14547
+ var ENDPOINT_PRINT = ENDPOINT$6 + "/print-action";
14548
+ var ENDPOINT_CUSTOM_ENTRY_STATUS = ENDPOINT$6 + "/custom-entry-status";
14549
+ var ENDPOINT_ENUM_ENTRY_STATUS = ENDPOINT$6 + "/enum/entry-status";
14442
14550
  var ENDPOINT_CHANGE_ENTRY_AGENT_SURCHARGE =
14443
- ENDPOINT$5 + "/entry/change-agent-surcharge";
14551
+ ENDPOINT$6 + "/entry/change-agent-surcharge";
14444
14552
  /**
14445
14553
  * api/web/agent/print-action/{print-action-group}
14446
14554
  * @param config
@@ -14474,7 +14582,7 @@ var getEntryList = function (config, filterItem, gridColumns, signal) {
14474
14582
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14475
14583
  })
14476
14584
  .join("&");
14477
- var url = "" + config.host + ENDPOINT$5 + "/entry/list?" + queryString;
14585
+ var url = "" + config.host + ENDPOINT$6 + "/entry/list?" + queryString;
14478
14586
  var apiKey = config.apiKey;
14479
14587
  return get(url, apiKey, config.token, signal, true);
14480
14588
  };
@@ -14485,7 +14593,7 @@ var getEntryListv2 = function (config, filterItem, gridColumns, signal) {
14485
14593
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14486
14594
  })
14487
14595
  .join("&");
14488
- var url = "" + config.host + ENDPOINT$5 + "/v2/entry/list?" + queryString;
14596
+ var url = "" + config.host + ENDPOINT$6 + "/v2/entry/list?" + queryString;
14489
14597
  var apiKey = config.apiKey;
14490
14598
  return get(url, apiKey, config.token, signal, true);
14491
14599
  };
@@ -14496,12 +14604,12 @@ var getEntryTotals = function (config, filterItem, gridColumns, signal) {
14496
14604
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14497
14605
  })
14498
14606
  .join("&");
14499
- var url = "" + config.host + ENDPOINT$5 + "/entry/total?" + queryString;
14607
+ var url = "" + config.host + ENDPOINT$6 + "/entry/total?" + queryString;
14500
14608
  var apiKey = config.apiKey;
14501
14609
  return get(url, apiKey, config.token, signal, true);
14502
14610
  };
14503
14611
  var getEntryDetailv2 = function (config, entryId, signal) {
14504
- var url = "" + config.host + ENDPOINT$5 + "/v2/entry/detail/" + entryId;
14612
+ var url = "" + config.host + ENDPOINT$6 + "/v2/entry/detail/" + entryId;
14505
14613
  var apiKey = config.apiKey;
14506
14614
  return get(url, apiKey, config.token, signal, true);
14507
14615
  };
@@ -14512,7 +14620,7 @@ var getInvoiceList = function (config, filterItem, gridColumns, signal) {
14512
14620
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14513
14621
  })
14514
14622
  .join("&");
14515
- var url = "" + config.host + ENDPOINT$5 + "/invoice/list?" + queryString;
14623
+ var url = "" + config.host + ENDPOINT$6 + "/invoice/list?" + queryString;
14516
14624
  var apiKey = config.apiKey;
14517
14625
  return get(url, apiKey, config.token, signal, true);
14518
14626
  };
@@ -14539,28 +14647,48 @@ var getAllotmentList = function (config, filterItem, gridColumns, signal) {
14539
14647
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14540
14648
  })
14541
14649
  .join("&");
14542
- var url = "" + config.host + ENDPOINT$5 + "/allotment/list?" + queryString;
14650
+ var url = "" + config.host + ENDPOINT$6 + "/allotment/list?" + queryString;
14543
14651
  var apiKey = config.apiKey;
14544
14652
  return get(url, apiKey, config.token, signal, true);
14545
14653
  };
14546
14654
  var getAllotment = function (config, allotmentId, signal) {
14547
- var url = "" + config.host + ENDPOINT$5 + "/allotment/" + allotmentId;
14655
+ var url = "" + config.host + ENDPOINT$6 + "/allotment/" + allotmentId;
14548
14656
  var apiKey = config.apiKey;
14549
14657
  return get(url, apiKey, config.token, signal, true);
14550
14658
  };
14551
14659
 
14552
- var ENDPOINT$4 = "/api/web";
14553
- var ENDPOINT_CREATE_CRM_CONTACT = ENDPOINT$4 + "/crmcontact";
14554
- var ENDPOINT_CONTACT_FORM$1 = ENDPOINT$4 + "/contactform";
14555
- var ENDPOINT_CREATE_AFFILIATES = ENDPOINT$4 + "/affiliates";
14556
- var ENDPOINT_TRANSLATION_DICTIONARY = ENDPOINT$4 + "/translation-dictionary";
14557
- var ENDPOINT_BOOKING_ACCOMMODATION = ENDPOINT$4 + "/booking-accommodation";
14558
- var ENDPOINT_LOCATIONS = ENDPOINT$4 + "/entity/locations";
14660
+ var ENDPOINT$5 = "/api/web";
14661
+ var ENDPOINT_MAIL = ENDPOINT$5 + "/mail";
14662
+ var ENDPOINT_CREATE_CRM_CONTACT = ENDPOINT$5 + "/crmcontact";
14663
+ var ENDPOINT_CONTACT_FORM$1 = ENDPOINT$5 + "/contactform";
14664
+ var ENDPOINT_TRAVEL_AGENTS = ENDPOINT$5 + "/travelagents";
14665
+ var ENDPOINT_CREATE_AFFILIATES = ENDPOINT$5 + "/affiliates";
14666
+ var ENDPOINT_TRANSLATION_DICTIONARY = ENDPOINT$5 + "/translation-dictionary";
14667
+ var ENDPOINT_BOOKING_ACCOMMODATION = ENDPOINT$5 + "/booking-accommodation";
14668
+ var ENDPOINT_OPPORTUNITY = ENDPOINT$5 + "/opportunity";
14669
+ var ENDPOINT_CALCULATE_DEPOSIT = function (entryId) {
14670
+ return ENDPOINT$5 + "/entry/" + entryId + "/calculate-deposit";
14671
+ };
14672
+ var ENDPOINT_LOCATIONS = ENDPOINT$5 + "/entity/locations";
14559
14673
  var ENDPOINT_WEBSITE_CONFIGURATION = function (portalId) {
14560
- return ENDPOINT$4 + "/website/" + portalId + "/configuration";
14674
+ return ENDPOINT$5 + "/website/" + portalId + "/configuration";
14561
14675
  };
14562
14676
  var ENDPOINT_WEBSITE_STYLESHEET = function (styleSheetId) {
14563
- return ENDPOINT$4 + "/style-sheet/" + styleSheetId;
14677
+ return ENDPOINT$5 + "/style-sheet/" + styleSheetId;
14678
+ };
14679
+ /**
14680
+ * api/web/mail
14681
+ * Adds the sender as a person and sends a mail.
14682
+ * @param config
14683
+ * @param request
14684
+ * @param signal
14685
+ * @returns OK if succeeded.
14686
+ */
14687
+ var sendMail = function (config, request, signal) {
14688
+ var url = "" + config.host + ENDPOINT_MAIL;
14689
+ var apiKey = config.apiKey;
14690
+ var body = JSON.stringify(request);
14691
+ return post(url, apiKey, body, config.token, signal);
14564
14692
  };
14565
14693
  /**
14566
14694
  * api/web/crmcontact
@@ -14584,12 +14712,27 @@ var createCrmContact = function (config, request, signal) {
14584
14712
  * @param signal
14585
14713
  * @returns OK if succeeded.
14586
14714
  */
14587
- var ContactForm = function (config, request, signal) {
14715
+ var sendContactForm = function (config, request, signal) {
14588
14716
  var url = "" + config.host + ENDPOINT_CONTACT_FORM$1;
14589
14717
  var apiKey = config.apiKey;
14590
14718
  var body = JSON.stringify(request);
14591
14719
  return post(url, apiKey, body, config.token, signal, true);
14592
14720
  };
14721
+ /**
14722
+ * api/web/travelagents
14723
+ * Searches travel agents (addresses of type Agent). Optionally pass a raw OData
14724
+ * query string (without leading '?'), e.g. "$top=20&$filter=contains(name,'foo')".
14725
+ * @param config
14726
+ * @param odataQuery
14727
+ * @param signal
14728
+ * @returns OK if succeeded.
14729
+ */
14730
+ var getTravelAgents = function (config, odataQuery, signal) {
14731
+ var query = odataQuery ? "?" + odataQuery : "";
14732
+ var url = "" + config.host + ENDPOINT_TRAVEL_AGENTS + query;
14733
+ var apiKey = config.apiKey;
14734
+ return get(url, apiKey, config.token, signal, true);
14735
+ };
14593
14736
  /**
14594
14737
  * api/web/affiliates
14595
14738
  * Gets all Affiliates
@@ -14614,6 +14757,33 @@ var generateBookingAccommodations = function (config, request, signal) {
14614
14757
  var body = JSON.stringify(request);
14615
14758
  return post(url, apiKey, body, config.token, signal);
14616
14759
  };
14760
+ /**
14761
+ * api/web/opportunity
14762
+ * Creates a CRM opportunity from a web contact.
14763
+ * @param config
14764
+ * @param request
14765
+ * @param signal
14766
+ * @returns OK if succeeded.
14767
+ */
14768
+ var createOpportunity = function (config, request, signal) {
14769
+ var url = "" + config.host + ENDPOINT_OPPORTUNITY;
14770
+ var apiKey = config.apiKey;
14771
+ var body = JSON.stringify(request);
14772
+ return post(url, apiKey, body, config.token, signal);
14773
+ };
14774
+ /**
14775
+ * api/web/entry/{entryId}/calculate-deposit
14776
+ * Calculates the deposit amount for an entry.
14777
+ * @param config
14778
+ * @param entryId
14779
+ * @param signal
14780
+ * @returns The deposit amount.
14781
+ */
14782
+ var calculateDeposit = function (config, entryId, signal) {
14783
+ var url = "" + config.host + ENDPOINT_CALCULATE_DEPOSIT(entryId);
14784
+ var apiKey = config.apiKey;
14785
+ return get(url, apiKey, config.token, signal, true);
14786
+ };
14617
14787
  var getLocations = function (config, request, signal) {
14618
14788
  var url = "" + config.host + ENDPOINT_LOCATIONS;
14619
14789
  var apiKey = config.apiKey;
@@ -14631,9 +14801,9 @@ var getStyleSheet = function (config, id, signal) {
14631
14801
  return get(url, apiKey, config.token, signal, true);
14632
14802
  };
14633
14803
 
14634
- var ENDPOINT$3 = "/api/web/contact";
14635
- var ENDPOINT_CONTACT_FORM = ENDPOINT$3 + "/contact-form";
14636
- var ENDPOINT_CONTACT_HAS_TAG = ENDPOINT$3 + "/has-tag";
14804
+ var ENDPOINT$4 = "/api/web/contact";
14805
+ var ENDPOINT_CONTACT_FORM = ENDPOINT$4 + "/contact-form";
14806
+ var ENDPOINT_CONTACT_HAS_TAG = ENDPOINT$4 + "/has-tag";
14637
14807
  /**
14638
14808
  * api/web/contact/contact-form
14639
14809
  * Processes a contact form.
@@ -14655,6 +14825,118 @@ var contactHasTag = function (config, request, signal) {
14655
14825
  return post$1(url, apiKey, body, config.token, signal);
14656
14826
  };
14657
14827
 
14828
+ var ENDPOINT$3 = "/api/web/content";
14829
+ var ENDPOINT_LIVE = ENDPOINT$3 + "/live";
14830
+ var ENDPOINT_DRAFT = ENDPOINT$3 + "/draft";
14831
+ /**
14832
+ * api/web/content/live
14833
+ * Gets all Live content
14834
+ * @param config
14835
+ * @param signal
14836
+ * @returns OK if succeeded.
14837
+ */
14838
+ var getContentLive = function (config, signal) {
14839
+ var url = "" + config.host + ENDPOINT_LIVE;
14840
+ var apiKey = config.apiKey;
14841
+ return get(url, apiKey, config.token, signal, true);
14842
+ };
14843
+ /**
14844
+ * api/web/content/draft
14845
+ * Gets all Draft (Internal) content
14846
+ * @param config
14847
+ * @param signal
14848
+ * @returns OK if succeeded.
14849
+ */
14850
+ var getContentDraft = function (config, signal) {
14851
+ var url = "" + config.host + ENDPOINT_DRAFT;
14852
+ var apiKey = config.apiKey;
14853
+ return get(url, apiKey, config.token, signal, true);
14854
+ };
14855
+ /**
14856
+ * api/web/content/live/by-property
14857
+ * Gets Live content matching a property value (or values).
14858
+ * @param config
14859
+ * @param request
14860
+ * @param signal
14861
+ * @returns OK if succeeded.
14862
+ */
14863
+ var getContentLiveByProperty = function (config, request, signal) {
14864
+ var url = "" + config.host + ENDPOINT_LIVE + "/by-property";
14865
+ var apiKey = config.apiKey;
14866
+ var body = JSON.stringify(request);
14867
+ return post(url, apiKey, body, config.token, signal, true);
14868
+ };
14869
+ /**
14870
+ * api/web/content/draft/by-property
14871
+ * Gets Draft (Internal) content matching a property value (or values).
14872
+ * @param config
14873
+ * @param request
14874
+ * @param signal
14875
+ * @returns OK if succeeded.
14876
+ */
14877
+ var getContentDraftByProperty = function (config, request, signal) {
14878
+ var url = "" + config.host + ENDPOINT_DRAFT + "/by-property";
14879
+ var apiKey = config.apiKey;
14880
+ var body = JSON.stringify(request);
14881
+ return post(url, apiKey, body, config.token, signal, true);
14882
+ };
14883
+ /**
14884
+ * api/web/content/live/by-template
14885
+ * Gets Live content of a given template.
14886
+ * @param config
14887
+ * @param request
14888
+ * @param signal
14889
+ * @returns OK if succeeded.
14890
+ */
14891
+ var getContentLiveByTemplate = function (config, request, signal) {
14892
+ var url = "" + config.host + ENDPOINT_LIVE + "/by-template";
14893
+ var apiKey = config.apiKey;
14894
+ var body = JSON.stringify(request);
14895
+ return post(url, apiKey, body, config.token, signal, true);
14896
+ };
14897
+ /**
14898
+ * api/web/content/draft/by-template
14899
+ * Gets Draft (Internal) content of a given template.
14900
+ * @param config
14901
+ * @param request
14902
+ * @param signal
14903
+ * @returns OK if succeeded.
14904
+ */
14905
+ var getContentDraftByTemplate = function (config, request, signal) {
14906
+ var url = "" + config.host + ENDPOINT_DRAFT + "/by-template";
14907
+ var apiKey = config.apiKey;
14908
+ var body = JSON.stringify(request);
14909
+ return post(url, apiKey, body, config.token, signal, true);
14910
+ };
14911
+ /**
14912
+ * api/web/content/live/children
14913
+ * Gets the Live children of a parent item.
14914
+ * @param config
14915
+ * @param request
14916
+ * @param signal
14917
+ * @returns OK if succeeded.
14918
+ */
14919
+ var getContentLiveChildren = function (config, request, signal) {
14920
+ var url = "" + config.host + ENDPOINT_LIVE + "/children";
14921
+ var apiKey = config.apiKey;
14922
+ var body = JSON.stringify(request);
14923
+ return post(url, apiKey, body, config.token, signal, true);
14924
+ };
14925
+ /**
14926
+ * api/web/content/draft/children
14927
+ * Gets the Draft (Internal) children of a parent item.
14928
+ * @param config
14929
+ * @param request
14930
+ * @param signal
14931
+ * @returns OK if succeeded.
14932
+ */
14933
+ var getContentDraftChildren = function (config, request, signal) {
14934
+ var url = "" + config.host + ENDPOINT_DRAFT + "/children";
14935
+ var apiKey = config.apiKey;
14936
+ var body = JSON.stringify(request);
14937
+ return post(url, apiKey, body, config.token, signal, true);
14938
+ };
14939
+
14658
14940
  var ENDPOINT$2 = "/api/web/file";
14659
14941
  var ENDPOINT_FEED = ENDPOINT$2 + "/feed";
14660
14942
  /**
@@ -14693,6 +14975,7 @@ var ENDPOINT_FLIGHTS = ENDPOINT$1 + "/flights";
14693
14975
  var ENDPOINT_PRICE_DETAILS = ENDPOINT$1 + "/price-details";
14694
14976
  var ENDPOINT_BOOK = ENDPOINT$1 + "/book";
14695
14977
  var ENDPOINT_ITINERARY = ENDPOINT$1 + "/itinerary";
14978
+ var ENDPOINT_TRAJECT = ENDPOINT$1 + "/traject";
14696
14979
  var ENDPOINT_ENTRY = function (magicLinkCode) {
14697
14980
  return ENDPOINT$1 + "/entry/" + magicLinkCode;
14698
14981
  };
@@ -14724,6 +15007,12 @@ var getEntry = function (config, magicLinkCode, signal) {
14724
15007
  var url = "" + config.host + ENDPOINT_ENTRY(magicLinkCode);
14725
15008
  return get(url, apiKey, config.token, signal, true);
14726
15009
  };
15010
+ var getTrajectEntry = function (config, request, signal) {
15011
+ var url = "" + config.host + ENDPOINT_TRAJECT;
15012
+ var apiKey = config.apiKey;
15013
+ var body = JSON.stringify(request);
15014
+ return post(url, apiKey, body, config.token, signal, true);
15015
+ };
14727
15016
  var getPriceDetails = function (config, request, signal) {
14728
15017
  var url = "" + config.host + ENDPOINT_PRICE_DETAILS;
14729
15018
  var apiKey = config.apiKey;
@@ -14781,7 +15070,6 @@ var submitForm = function (config, id, request, signal) {
14781
15070
  };
14782
15071
 
14783
15072
  exports.AllotmentType = AllotmentType;
14784
- exports.ContactForm = ContactForm;
14785
15073
  exports.DataType = DataType;
14786
15074
  exports.DossierType = DossierType;
14787
15075
  exports.EntryLineFlag = EntryLineFlag;
@@ -14799,6 +15087,7 @@ exports.RoomType = RoomType;
14799
15087
  exports.SaleType = SaleType;
14800
15088
  exports.ServiceTokenError = ServiceTokenError;
14801
15089
  exports.ServiceType = ServiceType;
15090
+ exports.TrajectNodeType = TrajectNodeType;
14802
15091
  exports.VendorType = VendorType;
14803
15092
  exports.agents = agents;
14804
15093
  exports.alternateFlights = alternateFlights;
@@ -14808,12 +15097,14 @@ exports.availableFlights = availableFlights;
14808
15097
  exports.book = book;
14809
15098
  exports.bookPackagingEntry = bookPackagingEntry;
14810
15099
  exports.bookableDates = bookableDates;
15100
+ exports.calculateDeposit = calculateDeposit;
14811
15101
  exports.changeEntryAgentSurcharge = changeEntryAgentSurcharge;
14812
15102
  exports.clearServiceTokenCache = clearServiceTokenCache;
14813
15103
  exports.confirm = confirm;
14814
15104
  exports.contactForm = contactForm;
14815
15105
  exports.contactHasTag = contactHasTag;
14816
15106
  exports.createCrmContact = createCrmContact;
15107
+ exports.createOpportunity = createOpportunity;
14817
15108
  exports.createParams = createParams;
14818
15109
  exports.details = details;
14819
15110
  exports.detailsWL = detailsWL;
@@ -14827,6 +15118,15 @@ exports.getAirports = getAirports;
14827
15118
  exports.getAllotment = getAllotment;
14828
15119
  exports.getAllotmentAvailability = getAllotmentAvailability;
14829
15120
  exports.getAllotmentList = getAllotmentList;
15121
+ exports.getAvailableGeographicalRegions = getAvailableGeographicalRegions;
15122
+ exports.getContentDraft = getContentDraft;
15123
+ exports.getContentDraftByProperty = getContentDraftByProperty;
15124
+ exports.getContentDraftByTemplate = getContentDraftByTemplate;
15125
+ exports.getContentDraftChildren = getContentDraftChildren;
15126
+ exports.getContentLive = getContentLive;
15127
+ exports.getContentLiveByProperty = getContentLiveByProperty;
15128
+ exports.getContentLiveByTemplate = getContentLiveByTemplate;
15129
+ exports.getContentLiveChildren = getContentLiveChildren;
14830
15130
  exports.getCountries = getCountries;
14831
15131
  exports.getCustomEntryStatus = getCustomEntryStatus;
14832
15132
  exports.getEntry = getEntry;
@@ -14844,7 +15144,9 @@ exports.getPortal = getPortal;
14844
15144
  exports.getPriceDetails = getPriceDetails;
14845
15145
  exports.getPrintActions = getPrintActions;
14846
15146
  exports.getStyleSheet = getStyleSheet;
15147
+ exports.getTrajectEntry = getTrajectEntry;
14847
15148
  exports.getTranslationDictionary = getTranslationDictionary;
15149
+ exports.getTravelAgents = getTravelAgents;
14848
15150
  exports.getWebsiteConfiguration = getWebsiteConfiguration;
14849
15151
  exports.login = login;
14850
15152
  exports.logout = logout;
@@ -14852,6 +15154,7 @@ exports.priceDetails = priceDetails;
14852
15154
  exports.prices = prices;
14853
15155
  exports.print = print;
14854
15156
  exports.readForm = readForm;
15157
+ exports.repriceAndIssueTicket = repriceAndIssueTicket;
14855
15158
  exports.resetPassword = resetPassword;
14856
15159
  exports.search = search;
14857
15160
  exports.searchCountries = searchCountries;
@@ -14864,6 +15167,8 @@ exports.searchPackagingExcursions = searchPackagingExcursions;
14864
15167
  exports.searchPackagingFlights = searchPackagingFlights;
14865
15168
  exports.searchRegions = searchRegions;
14866
15169
  exports.searchWithErrorMapping = searchWithErrorMapping;
15170
+ exports.sendContactForm = sendContactForm;
15171
+ exports.sendMail = sendMail;
14867
15172
  exports.setCustomEntryStatus = setCustomEntryStatus;
14868
15173
  exports.setEntryStatus = setEntryStatus;
14869
15174
  exports.startTransaction = startTransaction;
@@ -18073,6 +18378,9 @@ function useViewTransitionState(to, opts) {
18073
18378
  }
18074
18379
 
18075
18380
  const CHILD_MAX_AGE = 17;
18381
+ // Maximum age (inclusive) at which a child still counts as a baby. Overridable
18382
+ // through settings.maxBabyAge (see TIDE-3269).
18383
+ const BABY_MAX_AGE = 1;
18076
18384
  const initialState$6 = {
18077
18385
  formValues: undefined
18078
18386
  };
@@ -18103,20 +18411,16 @@ const makeSelectFormRooms = (maxChildAge = CHILD_MAX_AGE) => toolkit.createSelec
18103
18411
  children: []
18104
18412
  };
18105
18413
  x.pax.forEach((p) => {
18106
- if (p.age && p.age > maxChildAge) {
18414
+ // typeof, not truthiness: a baby booked as age 0 has to be classified instead of
18415
+ // being dropped from the form altogether (TIDE-3269).
18416
+ const age = typeof p.age === 'number' ? p.age : p.dateOfBirth ? dateFns.differenceInYears(new Date(), new Date(p.dateOfBirth)) : undefined;
18417
+ if (age === undefined)
18418
+ return;
18419
+ if (age > maxChildAge) {
18107
18420
  formRoom.adults.push({ id: p.id, age: 30 });
18108
18421
  }
18109
- else if (p.age && p.age <= maxChildAge) {
18110
- formRoom.children.push({ id: p.id, age: p.age });
18111
- }
18112
- else if (p.dateOfBirth) {
18113
- const age = dateFns.differenceInYears(new Date(), new Date(p.dateOfBirth));
18114
- if (age > maxChildAge) {
18115
- formRoom.adults.push({ id: p.id, age: 30 });
18116
- }
18117
- else {
18118
- formRoom.children.push({ id: p.id, age: age });
18119
- }
18422
+ else {
18423
+ formRoom.children.push({ id: p.id, age });
18120
18424
  }
18121
18425
  });
18122
18426
  formRooms.push(formRoom);
@@ -18361,22 +18665,22 @@ const selectRequestRooms = (state) => state.booking.package?.options.find((x) =>
18361
18665
  const selectOfficeId = (state) => state.booking.officeId;
18362
18666
  const selectLanguageCode = (state) => state.booking.languageCode;
18363
18667
  const selectCurrencyCode = (state) => state.booking.package?.currencyCode ?? 'EUR';
18364
- const selectDefaultStaticTranslations = (state) => getTranslations(state.booking.languageCode);
18365
18668
  const selectLanguage = (state) => state.booking.languageCode;
18366
18669
  const selectAllDynamicTranslations = (state) => state.booking.translations;
18367
18670
  const selectDynamicTranslations = toolkit.createSelector([selectAllDynamicTranslations, selectLanguage], (allDynamicTranslations, language) => {
18368
18671
  return allDynamicTranslations?.find((x) => x.language == language)?.value ?? {};
18369
18672
  });
18370
- const selectTranslations = toolkit.createSelector([selectDefaultStaticTranslations, selectDynamicTranslations], (defaultStaticTranslations, dynamicTranslations) => {
18371
- const merged = {};
18372
- for (const key of Array.from(new Set([...Object.keys(defaultStaticTranslations), ...Object.keys(dynamicTranslations)]))) {
18373
- merged[key] = {
18374
- ...(defaultStaticTranslations[key] || {}),
18375
- ...(dynamicTranslations[key] || {})
18376
- };
18377
- }
18378
- return merged;
18379
- });
18673
+ // Host override files are hand-maintained, and a null only ever blanks a key the component
18674
+ // then reads, so treat it like a missing key (lodash merge already skips undefined).
18675
+ const withoutNulls = (value) => lodash.isPlainObject(value)
18676
+ ? lodash.mapValues(lodash.pickBy(value, (x) => x !== null), withoutNulls)
18677
+ : value;
18678
+ // getTranslations deep-merges the overrides over a clone of the built-in translations, so a
18679
+ // host override of a nested group (TRAVELERS_FORM.VALIDATION, TRAVELERS_FORM.COUNTRIES)
18680
+ // only replaces the keys it actually contains. Merging per section one level deep dropped
18681
+ // every other built-in key of such a group, which made those keys resolve to undefined and
18682
+ // crash format() in the consuming component.
18683
+ const selectTranslations = toolkit.createSelector([selectLanguage, selectDynamicTranslations], (language, dynamicTranslations) => getTranslations(language, lodash.isEmpty(dynamicTranslations) ? undefined : withoutNulls(dynamicTranslations)));
18380
18684
  const selectBookingOptions = (state) => state.booking.bookingOptions;
18381
18685
  const selectBookingType = (state) => state.booking.bookingType;
18382
18686
  const selectTagIds = (state) => state.booking.tagIds;
@@ -22596,7 +22900,7 @@ function getAge(birthDateText, startDateText) {
22596
22900
  }
22597
22901
  return age;
22598
22902
  }
22599
- const validateForm$1 = (values, agentRequired, bookingType, translations, formFields, mainBookerFormFields, maxChildAge = CHILD_MAX_AGE) => {
22903
+ const validateForm$1 = (values, agentRequired, bookingType, translations, formFields, mainBookerFormFields, maxChildAge = CHILD_MAX_AGE, maxBabyAge = BABY_MAX_AGE) => {
22600
22904
  const errors = {};
22601
22905
  const isFormFieldPresent = (type) => {
22602
22906
  return formFields?.some((f) => f.type === type) ?? true;
@@ -22619,6 +22923,14 @@ const validateForm$1 = (values, agentRequired, bookingType, translations, formFi
22619
22923
  ? format$1(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_CHILD, [room, pax])
22620
22924
  : format$1(translations.TRAVELERS_FORM.VALIDATION.SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD, [pax]);
22621
22925
  };
22926
+ const formatTravelerIsNoBaby = (room, pax) => {
22927
+ // The message states the boundary the traveler has to stay under, so we pass
22928
+ // the first age that is too old rather than the inclusive maxBabyAge.
22929
+ const tooOldAge = maxBabyAge + 1;
22930
+ return values.rooms.length > 1
22931
+ ? format$1(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_BABY, [room, pax, tooOldAge])
22932
+ : format$1(translations.TRAVELERS_FORM.VALIDATION.SINGLE_ROOM_TRAVELER_X_IS_NO_BABY, [pax, tooOldAge]);
22933
+ };
22622
22934
  const formatTravelerFieldInvalidCharacters = (room, pax, field) => {
22623
22935
  return values.rooms.length > 1
22624
22936
  ? format$1(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD_INVALID_CHARACTERS, [room, pax, field])
@@ -22663,10 +22975,10 @@ const validateForm$1 = (values, agentRequired, bookingType, translations, formFi
22663
22975
  }
22664
22976
  if (isFormFieldPresent('firstName')) {
22665
22977
  if (lodash.isEmpty(child.firstName)) {
22666
- lodash.set(errors, `children[${index}].firstName`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
22978
+ lodash.set(errors, `rooms[${rIndex}].children[${index}].firstName`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
22667
22979
  }
22668
22980
  else if (hasInvalidNameCharacters(child.firstName)) {
22669
- lodash.set(errors, `children[${index}].firstName`, formatTravelerFieldInvalidCharacters(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
22981
+ lodash.set(errors, `rooms[${rIndex}].children[${index}].firstName`, formatTravelerFieldInvalidCharacters(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
22670
22982
  }
22671
22983
  }
22672
22984
  if (isFormFieldPresent('lastName')) {
@@ -22681,8 +22993,16 @@ const validateForm$1 = (values, agentRequired, bookingType, translations, formFi
22681
22993
  if (lodash.isEmpty(child.birthDate)) {
22682
22994
  lodash.set(errors, `rooms[${rIndex}].children[${index}].birthDate`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.BIRTHDATE));
22683
22995
  }
22996
+ else if (child.isBaby && values.startDate) {
22997
+ // A baby only has to be under the maxBabyAge on departure, so we check the startDate here instead of the endDate (TIDE-3269)
22998
+ const age = getAge(child.birthDate, values.startDate);
22999
+ if (age > maxBabyAge) {
23000
+ lodash.set(errors, `rooms[${rIndex}].children[${index}].birthDate`, formatTravelerIsNoBaby(rIndex + 1, r.adults.length + index + 1));
23001
+ }
23002
+ }
22684
23003
  else if (values.endDate) {
22685
- // You need to be under the maxChildAge until the end of the trip, so we check the endDate here instead of the startDate
23004
+ // You need to be under the maxChildAge until the end of the trip, so we check the endDate here instead of the startDate.
23005
+ // Babies land here too when there is no startDate to check them against, so they keep at least the child age check.
22686
23006
  const age = getAge(child.birthDate, values.endDate);
22687
23007
  if (age > maxChildAge) {
22688
23008
  lodash.set(errors, `rooms[${rIndex}].children[${index}].birthDate`, formatTravelerIsNoChild(rIndex + 1, r.adults.length + index + 1));
@@ -22888,7 +23208,14 @@ const TypeAheadInput = ({ name, value, placeholder, options, onChange, onSelect,
22888
23208
  })))));
22889
23209
  };
22890
23210
 
22891
- function createTraveler(traveler, followNumber, personTranslation, isCompact) {
23211
+ // A traveler is a baby when the age they were booked with is at or below the baby
23212
+ // boundary. Babies get their own label and birth date validation (TIDE-3269). Only
23213
+ // meaningful for the regular form: the compact form asks for an age instead of a birth
23214
+ // date, so it has nothing to validate and its own age input already states the age.
23215
+ function isBabyAge(age, maxBabyAge = BABY_MAX_AGE) {
23216
+ return typeof age === 'number' && age <= maxBabyAge;
23217
+ }
23218
+ function createTraveler(traveler, followNumber, personTranslation, isCompact, maxBabyAge) {
22892
23219
  if (isCompact) {
22893
23220
  return {
22894
23221
  id: traveler.id,
@@ -22896,7 +23223,13 @@ function createTraveler(traveler, followNumber, personTranslation, isCompact) {
22896
23223
  lastName: `${followNumber.number++}`,
22897
23224
  birthDate: '',
22898
23225
  gender: '',
22899
- age: traveler.age || 30
23226
+ // Keep a booked age of 0 instead of submitting and pricing the traveler as a 30 year
23227
+ // old, while still falling back for a missing or unusable age. `??` alone would let a
23228
+ // NaN (unparseable date of birth upstream) reach the age input and the booked pax.
23229
+ // See TIDE-3269.
23230
+ age: Number.isFinite(traveler.age) ? traveler.age : 30
23231
+ // No isBaby here on purpose: the age below is editable and nothing revalidates it
23232
+ // in compact mode, so a stored flag would end up contradicting the entered age.
22900
23233
  };
22901
23234
  }
22902
23235
  return {
@@ -22904,17 +23237,18 @@ function createTraveler(traveler, followNumber, personTranslation, isCompact) {
22904
23237
  firstName: '',
22905
23238
  lastName: '',
22906
23239
  birthDate: '',
22907
- gender: ''
23240
+ gender: '',
23241
+ isBaby: isBabyAge(traveler.age, maxBabyAge)
22908
23242
  };
22909
23243
  }
22910
- function createInitialValuesFromRooms(formRooms, startDate, endDate, agentAdressId, personTranslation, isCompact) {
23244
+ function createInitialValuesFromRooms(formRooms, startDate, endDate, agentAdressId, personTranslation, isCompact, maxBabyAge) {
22911
23245
  const followNumber = { number: 1 };
22912
23246
  const initialValues = {
22913
23247
  startDate,
22914
23248
  endDate,
22915
23249
  rooms: formRooms.map((room) => ({
22916
- adults: room.adults.map((traveler) => createTraveler(traveler, followNumber, personTranslation, isCompact)),
22917
- children: room.children.map((traveler) => createTraveler(traveler, followNumber, personTranslation, isCompact))
23250
+ adults: room.adults.map((traveler) => createTraveler(traveler, followNumber, personTranslation, isCompact, maxBabyAge)),
23251
+ children: room.children.map((traveler) => createTraveler(traveler, followNumber, personTranslation, isCompact, maxBabyAge))
22918
23252
  })),
22919
23253
  mainBookerId: -1,
22920
23254
  street: '',
@@ -22956,7 +23290,8 @@ function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, a
22956
23290
  firstName: roomTraveler.firstName ?? '',
22957
23291
  lastName: roomTraveler.lastName ?? '',
22958
23292
  birthDate: roomTraveler.dateOfBirth ? dateFns.format(new Date(roomTraveler.dateOfBirth), 'yyyy-MM-dd') : '',
22959
- gender: ''
23293
+ gender: '',
23294
+ isBaby: isBabyAge(roomTraveler.age)
22960
23295
  };
22961
23296
  })
22962
23297
  };
@@ -23180,7 +23515,7 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
23180
23515
  translations.TRAVELERS_FORM.TRAVELER,
23181
23516
  " ",
23182
23517
  room.adults.length + index + 1),
23183
- React__default["default"].createElement("p", { className: "form__region-label" }, translations.TRAVELERS_FORM.CHILD)),
23518
+ React__default["default"].createElement("p", { className: "form__region-label" }, travelerValues.isBaby ? translations.TRAVELERS_FORM.BABY : translations.TRAVELERS_FORM.CHILD)),
23184
23519
  renderTravelerFields(travelerValues, `rooms[${roomIndex}].children[${index}]`, false, roomIndex, index)))),
23185
23520
  !useCompactForm && travelersFirstStep && (React__default["default"].createElement("div", { className: "form__region" },
23186
23521
  React__default["default"].createElement("button", { type: "button", className: "cta cta--select", onClick: () => handleAddTraveler(roomIndex) }, translations.TRAVELERS_FORM.ADD_TRAVELER)))))),
@@ -23256,13 +23591,17 @@ const TravelersForm = () => {
23256
23591
  const useCompactForm = !!settings.travellers.compactForm && !!settings.agentAdressId;
23257
23592
  const showAllCountries = !!settings.travellers.showAllCountries;
23258
23593
  const initialValues = reactRedux.useSelector(selectTravelersFormValues) ??
23259
- createInitialValuesFromRooms(formRooms, startDate, endDate, agentAdressId, translations.TRAVELERS_FORM.PERSON, useCompactForm);
23594
+ createInitialValuesFromRooms(formRooms, startDate, endDate, agentAdressId, translations.TRAVELERS_FORM.PERSON, useCompactForm, settings.maxBabyAge);
23260
23595
  const [showAgentSelection, setShowAgentSelection] = React.useState(!settings.agentAdressId && !settings.hideAgentSelection);
23261
23596
  const formik$1 = formik.useFormik({
23262
23597
  initialValues,
23263
23598
  validate: useCompactForm
23264
23599
  ? () => { }
23265
- : (values) => validateForm$1(values, settings.agentRequired, bookingType, translations, settings.travellers.formFields, settings.travellers.mainBookerFormFields, settings.maxChildAge),
23600
+ : (values) => validateForm$1(
23601
+ // The travel dates are captured into initialValues once and then persisted in
23602
+ // redux, so validating against the values would use the dates of whichever
23603
+ // package option was selected first. Age checks need the current ones.
23604
+ { ...values, startDate, endDate }, settings.agentRequired, bookingType, translations, settings.travellers.formFields, settings.travellers.mainBookerFormFields, settings.maxChildAge, settings.maxBabyAge),
23266
23605
  onSubmit: (values) => {
23267
23606
  dispatch(setFormValues(values));
23268
23607
  if (useCompactForm) {
@@ -27029,7 +27368,9 @@ const initialState$1 = {
27029
27368
  confirmedExcursionsByDay: {},
27030
27369
  bookPackagingEntry: false,
27031
27370
  currentStep: 0,
27032
- bookingNumber: undefined
27371
+ bookingNumber: undefined,
27372
+ trajectNodeAvailability: {},
27373
+ trajectFlightsResolved: false
27033
27374
  };
27034
27375
  const searchResultsSlice = toolkit.createSlice({
27035
27376
  name: 'searchResults',
@@ -27208,10 +27549,59 @@ const searchResultsSlice = toolkit.createSlice({
27208
27549
  },
27209
27550
  setBookingNumber(state, action) {
27210
27551
  state.bookingNumber = action.payload;
27552
+ },
27553
+ setTrajectNodeLoading(state, action) {
27554
+ const lineGuid = action.payload;
27555
+ state.trajectNodeAvailability[lineGuid] = {
27556
+ lineGuid,
27557
+ status: 'loading',
27558
+ results: state.trajectNodeAvailability[lineGuid]?.results ?? [],
27559
+ selectedCode: state.trajectNodeAvailability[lineGuid]?.selectedCode ?? null,
27560
+ preferredUnavailable: false
27561
+ };
27562
+ },
27563
+ setTrajectNodeAvailability(state, action) {
27564
+ const { lineGuid, results, selectedCode, preferredUnavailable } = action.payload;
27565
+ state.trajectNodeAvailability[lineGuid] = {
27566
+ lineGuid,
27567
+ status: selectedCode ? 'resolved' : 'unavailable',
27568
+ results,
27569
+ selectedCode,
27570
+ preferredUnavailable
27571
+ };
27572
+ },
27573
+ setTrajectNodeSelection(state, action) {
27574
+ const { lineGuid, code } = action.payload;
27575
+ const node = state.trajectNodeAvailability[lineGuid];
27576
+ if (!node)
27577
+ return;
27578
+ node.selectedCode = code;
27579
+ node.status = 'resolved';
27580
+ },
27581
+ updateEditableEntryLine(state, action) {
27582
+ if (!state.editablePackagingEntry)
27583
+ return;
27584
+ const index = (state.editablePackagingEntry.lines ?? []).findIndex((x) => x.guid === action.payload.guid);
27585
+ if (index === -1)
27586
+ return;
27587
+ state.editablePackagingEntry.lines[index] = action.payload;
27588
+ },
27589
+ removeEditableEntryLines(state, action) {
27590
+ if (!state.editablePackagingEntry)
27591
+ return;
27592
+ const guids = new Set(action.payload);
27593
+ state.editablePackagingEntry.lines = (state.editablePackagingEntry.lines ?? []).filter((x) => !guids.has(x.guid));
27594
+ },
27595
+ setTrajectFlightsResolved(state, action) {
27596
+ state.trajectFlightsResolved = action.payload;
27597
+ },
27598
+ resetTrajectAvailability(state) {
27599
+ state.trajectNodeAvailability = {};
27600
+ state.trajectFlightsResolved = false;
27211
27601
  }
27212
27602
  }
27213
27603
  });
27214
- const { setResults, setFilteredResults, setSelectedSearchResult, setPackagingAccoResults, setFilteredPackagingAccoResults, setFilteredPackagingFlightResults, setPackagingAccoSearchDetails, setSelectedPackagingAccoResult, setPackagingFlightResults, setSelectedPackagingFlight, setSelectedFlight, setSelectedFlightDetails, setBookingPackageDetails, selectFlight, setIsLoading, setFlightsLoading, setInitialFilters, setFilters, resetFilters, setInitialFlightFilters, setFlightFilters, resetFlightFilters, setSortType, setFlightSortType, setActiveTab, setCurrentPage, resetSearchState, setFlyInIsOpen, setEditablePackagingEntry, setTransactionId, setFlyInType, setPriceDetails, setItinerary, setSelectedOutwardKey, setSelectedReturnKey, resetFlightSelection, setExcursionSearchParams, setSelectedExcursionSearchResult, confirmExcursionForDay, removeConfirmedExcursionForDay, clearConfirmedExcursionsForDay, setBookPackagingEntry, setCurrentStep, setBookingNumber } = searchResultsSlice.actions;
27604
+ const { setResults, setFilteredResults, setSelectedSearchResult, setPackagingAccoResults, setFilteredPackagingAccoResults, setFilteredPackagingFlightResults, setPackagingAccoSearchDetails, setSelectedPackagingAccoResult, setPackagingFlightResults, setSelectedPackagingFlight, setSelectedFlight, setSelectedFlightDetails, setBookingPackageDetails, selectFlight, setIsLoading, setFlightsLoading, setInitialFilters, setFilters, resetFilters, setInitialFlightFilters, setFlightFilters, resetFlightFilters, setSortType, setFlightSortType, setActiveTab, setCurrentPage, resetSearchState, setFlyInIsOpen, setEditablePackagingEntry, setTransactionId, setFlyInType, setPriceDetails, setItinerary, setSelectedOutwardKey, setSelectedReturnKey, resetFlightSelection, setExcursionSearchParams, setSelectedExcursionSearchResult, confirmExcursionForDay, removeConfirmedExcursionForDay, clearConfirmedExcursionsForDay, setBookPackagingEntry, setCurrentStep, setBookingNumber, setTrajectNodeLoading, setTrajectNodeAvailability, setTrajectNodeSelection, setTrajectFlightsResolved, resetTrajectAvailability, updateEditableEntryLine, removeEditableEntryLines } = searchResultsSlice.actions;
27215
27605
  var searchResultsReducer = searchResultsSlice.reducer;
27216
27606
 
27217
27607
  const ItemPicker = ({ items, selection, selectedSortByType, label, placeholder, classModifier, onPick, valueFormatter }) => {
@@ -29374,7 +29764,7 @@ const HotelCard = ({ result, translations }) => {
29374
29764
  React__default["default"].createElement("button", { type: "button", className: `cta ${selectedPackagingAccoResultCode === result.code ? 'cta--selected' : 'cta--select'}`, onClick: () => handleChange(result.code) }, selectedPackagingAccoResultCode === result.code ? translations?.SHARED.SELECTED : translations?.SHARED.SELECT)))));
29375
29765
  };
29376
29766
 
29377
- const getLocation = (locationName, regionName, countryName, fallback) => {
29767
+ const getLocation$1 = (locationName, regionName, countryName, fallback) => {
29378
29768
  if (locationName || regionName) {
29379
29769
  return `${locationName || regionName}${countryName ? `, ${countryName}` : ''}`;
29380
29770
  }
@@ -29386,7 +29776,7 @@ const getBaseHotelResult = (searchResult, cmsItem, languageCode, translations) =
29386
29776
  title: cmsItem?.content?.general?.title || searchResult.name,
29387
29777
  image: cmsItem?.content?.images?.thumbnailPicture?.url,
29388
29778
  description: cmsItem?.content?.descriptions?.introductionTitle || '',
29389
- location: getLocation(searchResult.locationName, searchResult.regionName, searchResult.countryName, cmsItem?.parentItem?.name),
29779
+ location: getLocation$1(searchResult.locationName, searchResult.regionName, searchResult.countryName, cmsItem?.parentItem?.name),
29390
29780
  price: formatPrice$3(searchResult.price, searchResult.currencyCode, languageCode),
29391
29781
  ctaText: translations?.SRP.VIEW_DETAILS
29392
29782
  });
@@ -32558,6 +32948,482 @@ const BookPackagingEntry = ({ activeSearchSeed, isLoading, isConfirmationPage })
32558
32948
  React__default["default"].createElement(WLSidebar, { activeSearchSeed: activeSearchSeed, packagingAccoResult: selectedPackagingAccoResult }))));
32559
32949
  };
32560
32950
 
32951
+ const REGULAR_TRAJECT_NODE_TYPE = 0;
32952
+ const isSearchableTrajectNode = (node) => node.serviceType === ACCOMMODATION_SERVICE_TYPE || node.serviceType === EXCURSION_SERVICE_TYPE;
32953
+ const isTrajectFlightNode = (node) => node.serviceType === FLIGHT_SERVICE_TYPE;
32954
+ const getTrajectNodesWithLines = (trajectEntry) => {
32955
+ const linesByGuid = new Map((trajectEntry.entry.lines ?? []).map((line) => [line.guid, line]));
32956
+ return [...(trajectEntry.nodes ?? [])]
32957
+ .sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
32958
+ .map((node) => ({ node, line: linesByGuid.get(node.lineGuid) }))
32959
+ .filter((x) => !!x.line);
32960
+ };
32961
+ const buildDestination = (line) => {
32962
+ if (line.location?.id)
32963
+ return { id: line.location.id, isLocation: true };
32964
+ if (line.oord?.id)
32965
+ return { id: line.oord.id, isOord: true };
32966
+ if (line.region?.id)
32967
+ return { id: line.region.id, isRegion: true };
32968
+ if (line.country?.id)
32969
+ return { id: line.country.id, isCountry: true };
32970
+ return { id: 0 };
32971
+ };
32972
+ const buildTrajectNodeRequest = ({ node, line }, context, productCode) => ({
32973
+ transactionId: context.transactionId,
32974
+ officeId: context.officeId,
32975
+ agentId: context.agentId ?? null,
32976
+ catalogueId: context.catalogueId,
32977
+ searchConfigurationId: context.searchConfigurationId,
32978
+ portalId: context.portalId ?? null,
32979
+ vendorConfigurationId: node.externalVendorId ?? null,
32980
+ language: context.language,
32981
+ serviceType: node.serviceType,
32982
+ fromDate: toDateOnlyString(line.from),
32983
+ toDate: toDateOnlyString(line.to),
32984
+ destination: buildDestination(line),
32985
+ productCode,
32986
+ rooms: context.rooms,
32987
+ tagIds: []
32988
+ });
32989
+ const getPreferredCodes = (node) => {
32990
+ const codes = [node.code, node.preferredAccommodationCode, ...(node.alternativeAccommodationCodes ?? [])];
32991
+ return codes.filter((code) => !!code && code.trim().length > 0).filter((code, index, all) => all.indexOf(code) === index);
32992
+ };
32993
+ const matchesCode = (result, code) => {
32994
+ if (result.code === code)
32995
+ return true;
32996
+ return (result.rooms ?? []).some((room) => (room.options ?? []).some((option) => option.accommodationCode === code));
32997
+ };
32998
+ const getPackagingRoomsFromEntry = (entry) => {
32999
+ const paxById = new Map((entry.pax ?? []).map((p) => [p.id, p]));
33000
+ const rooms = (entry.rooms ?? []).map((room) => ({
33001
+ travellers: (room.paxIds ?? []).map((paxId) => {
33002
+ const pax = paxById.get(paxId);
33003
+ return {
33004
+ id: paxId,
33005
+ age: pax?.age ?? null,
33006
+ dateOfBirth: pax?.dateOfBirth ?? null
33007
+ };
33008
+ })
33009
+ }));
33010
+ return rooms.filter((room) => room.travellers.length > 0);
33011
+ };
33012
+ const pickCheapest = (results) => [...results].sort((a, b) => a.price - b.price)[0] ?? null;
33013
+ const applyResultToLine = (line, result) => {
33014
+ const option = (result.rooms ?? []).flatMap((room) => room.options ?? []).find((x) => x.isSelected) ?? (result.rooms ?? [])[0]?.options?.[0];
33015
+ return {
33016
+ ...line,
33017
+ productName: result.name ?? line.productName,
33018
+ productCode: result.code ?? line.productCode,
33019
+ accommodationCode: option?.accommodationCode ?? line.accommodationCode,
33020
+ accommodationName: option?.accommodationName ?? line.accommodationName,
33021
+ regimeCode: option?.regimeCode ?? line.regimeCode,
33022
+ regimeName: option?.regimeName ?? line.regimeName,
33023
+ latitude: result.latitude ?? line.latitude,
33024
+ longitude: result.longitude ?? line.longitude,
33025
+ isChanged: true
33026
+ };
33027
+ };
33028
+ const toDateOnlyUtcString = (value) => {
33029
+ const date = new Date(value);
33030
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())).toISOString();
33031
+ };
33032
+ const toTimeOnlyString = (value) => {
33033
+ const date = new Date(value);
33034
+ const hh = String(date.getUTCHours()).padStart(2, '0');
33035
+ const mm = String(date.getUTCMinutes()).padStart(2, '0');
33036
+ const ss = String(date.getUTCSeconds()).padStart(2, '0');
33037
+ return `${hh}:${mm}:${ss}`;
33038
+ };
33039
+ const mapFlightSegmentsToFlightLines = (segments) => segments.map((segment) => ({
33040
+ airlineCode: segment.marketingAirlineCode,
33041
+ airlineDescription: segment.marketingAirlineName,
33042
+ operatingAirlineCode: segment.operatingAirlineCode,
33043
+ operatingAirlineDescription: segment.operatingAirlineName,
33044
+ flightNumber: segment.flightNumber,
33045
+ operatingFlightNumber: segment.operatingFlightNumber ?? null,
33046
+ departureDate: toDateOnlyUtcString(segment.departureDateTime),
33047
+ departureTime: toTimeOnlyString(segment.departureDateTime),
33048
+ departureAirportCode: segment.departureAirportCode,
33049
+ departureAirportDescription: segment.departureAirportName,
33050
+ arrivalDate: toDateOnlyUtcString(segment.arrivalDateTime),
33051
+ arrivalTime: toTimeOnlyString(segment.arrivalDateTime),
33052
+ arrivalAirportCode: segment.arrivalAirportCode,
33053
+ arrivalAirportDescription: segment.arrivalAirportName,
33054
+ durationInTicks: segment.durationInTicks
33055
+ }));
33056
+ const applyFlightToLine = (line, flight, isOutbound) => {
33057
+ const segments = (isOutbound ? flight.outward?.segments : flight.return?.segments) ?? [];
33058
+ if (!segments.length)
33059
+ return line;
33060
+ const firstSegment = segments[0];
33061
+ const lastSegment = segments[segments.length - 1];
33062
+ return {
33063
+ ...line,
33064
+ from: new Date(firstSegment.departureDateTime).toISOString(),
33065
+ to: new Date(lastSegment.arrivalDateTime).toISOString(),
33066
+ productName: `${firstSegment.departureAirportName} - ${lastSegment.arrivalAirportName} (${firstSegment.marketingAirlineName})`,
33067
+ productCode: `${firstSegment.departureAirportCode} ${lastSegment.arrivalAirportCode}/${firstSegment.marketingAirlineCode}`,
33068
+ accommodationName: firstSegment.metaData?.farePriceClassName ?? line.accommodationName,
33069
+ accommodationCode: firstSegment.metaData?.fareCode ?? line.accommodationCode,
33070
+ flightInformation: {
33071
+ pnr: '',
33072
+ flightLines: mapFlightSegmentsToFlightLines(segments)
33073
+ },
33074
+ isChanged: true
33075
+ };
33076
+ };
33077
+ const pairTrajectFlights = (nodes) => {
33078
+ const flights = nodes.filter((x) => isTrajectFlightNode(x.node));
33079
+ return {
33080
+ outbound: flights[0] ?? null,
33081
+ inbound: flights.length > 1 ? flights[flights.length - 1] : null,
33082
+ unsupported: flights.slice(1, Math.max(flights.length - 1, 1))
33083
+ };
33084
+ };
33085
+
33086
+ const getLocation = (result) => {
33087
+ const place = result.locationName || result.regionName || result.oordName;
33088
+ if (!place)
33089
+ return result.countryName ?? '';
33090
+ return result.countryName ? `${place}, ${result.countryName}` : place;
33091
+ };
33092
+ const TrajectNodeCard = ({ result, isSelected, languageCode, translations, onSelect, showNights }) => {
33093
+ const selectedOption = lodash.first(result.rooms)?.options?.find((x) => x.isSelected) ?? lodash.first(result.rooms)?.options?.[0];
33094
+ const price = formatPrice$3(result.price, result.currencyCode, languageCode);
33095
+ const nights = calculateNights(new Date(result.fromDate), new Date(result.toDate));
33096
+ const selectButton = (React__default["default"].createElement("button", { type: "button", className: `cta ${isSelected ? 'cta--selected' : 'cta--select'}`, onClick: onSelect }, isSelected ? translations?.SHARED.SELECTED : translations?.SHARED.SELECT));
33097
+ if (result.contents?.length) {
33098
+ return (React__default["default"].createElement("div", { className: `search__result-card__wrapper search__result-card__wrapper--custom ${isSelected ? 'search__result-card__wrapper--selected' : ''}` },
33099
+ React__default["default"].createElement("div", { className: "search__result-card__top", dangerouslySetInnerHTML: { __html: he.decode(result.contents) } }),
33100
+ React__default["default"].createElement("div", { className: "search__result-card__footer" }, selectButton)));
33101
+ }
33102
+ return (React__default["default"].createElement("div", { className: `search__result-card__wrapper ${isSelected ? 'search__result-card__wrapper--selected' : ''}` },
33103
+ React__default["default"].createElement("div", { className: "search__result-card__content" },
33104
+ React__default["default"].createElement("div", { className: "search__result-card__content__wrapper" },
33105
+ React__default["default"].createElement("div", { className: "search__result-card__header" },
33106
+ React__default["default"].createElement("div", { className: "search__result-card__header__wrapper" },
33107
+ !!result.stars && (React__default["default"].createElement("div", { className: "rating" }, [...Array(result.stars)].map((_, index) => (React__default["default"].createElement(Icon, { name: "ui-star", key: `rating-star-${index + 1}`, width: 14, height: 14 }))))),
33108
+ React__default["default"].createElement("h3", { className: "search__result-card__title" }, result.name)),
33109
+ React__default["default"].createElement("div", { className: "search__result-card__price__wrapper" },
33110
+ React__default["default"].createElement("span", { className: "search__result-card__price__label" }, translations?.SHARED.TOTAL_PRICE),
33111
+ React__default["default"].createElement("span", { className: "search__result-card__price" }, price))),
33112
+ React__default["default"].createElement("span", { className: "search__result-card__location" },
33113
+ React__default["default"].createElement(Icon, { name: "ui-location", height: 16 }),
33114
+ getLocation(result)),
33115
+ React__default["default"].createElement("div", { className: "search__result-card__options" },
33116
+ showNights && nights > 0 && (React__default["default"].createElement("div", { className: "search__result-card__option" },
33117
+ React__default["default"].createElement(Icon, { name: "ui-bed", height: 16 }),
33118
+ nights,
33119
+ " ",
33120
+ translations?.SRP.NIGHTS)),
33121
+ selectedOption?.accommodationName && (React__default["default"].createElement("div", { className: "search__result-card__option" },
33122
+ React__default["default"].createElement(Icon, { name: "ui-bed", height: 16 }),
33123
+ selectedOption.accommodationName)),
33124
+ selectedOption?.regimeName && (React__default["default"].createElement("div", { className: "search__result-card__option" },
33125
+ React__default["default"].createElement(Icon, { name: "ui-utensils", height: 16 }),
33126
+ selectedOption.regimeName)))),
33127
+ React__default["default"].createElement("div", { className: "search__result-card__footer" }, selectButton))));
33128
+ };
33129
+
33130
+ const getNodeIcon = (node) => {
33131
+ if (isTrajectFlightNode(node))
33132
+ return 'ui-flight';
33133
+ if (node.serviceType === EXCURSION_SERVICE_TYPE)
33134
+ return 'ui-excursion';
33135
+ if (node.serviceType === ACCOMMODATION_SERVICE_TYPE)
33136
+ return 'ui-bed';
33137
+ return 'ui-location';
33138
+ };
33139
+ const TrajectResults = ({ isLoading }) => {
33140
+ const context = React.useContext(SearchResultsConfigurationContext);
33141
+ const dispatch = reactRedux.useDispatch();
33142
+ const translations = getTranslations(context?.languageCode ?? 'en-GB');
33143
+ const locale = getLocale(context?.languageCode ?? 'en-GB');
33144
+ const { trajectNodeAvailability, flightsLoading, trajectFlightsResolved, selectedOutwardKey, selectedReturnKey } = reactRedux.useSelector((state) => state.searchResults);
33145
+ const uniqueOutwardFlights = reactRedux.useSelector(selectUniqueOutwardFlights);
33146
+ const uniqueReturnFlights = reactRedux.useSelector(selectUniqueReturnFlights);
33147
+ const selectedOutward = reactRedux.useSelector(selectSelectedOutward);
33148
+ const selectedReturn = reactRedux.useSelector(selectSelectedReturn);
33149
+ const [expandedNodes, setExpandedNodes] = React.useState({});
33150
+ const trajectEntry = context?.trajectEntry;
33151
+ const nodesWithLines = React.useMemo(() => (trajectEntry ? getTrajectNodesWithLines(trajectEntry) : []), [trajectEntry]);
33152
+ const flightPairing = React.useMemo(() => pairTrajectFlights(nodesWithLines), [nodesWithLines]);
33153
+ const lineByNodeId = React.useMemo(() => new Map(nodesWithLines.map((x) => [x.node.nodeId, x])), [nodesWithLines]);
33154
+ const nodesByDay = React.useMemo(() => {
33155
+ const map = new Map();
33156
+ [...(trajectEntry?.nodes ?? [])]
33157
+ .sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
33158
+ .forEach((node) => {
33159
+ if (!map.has(node.dayOrder))
33160
+ map.set(node.dayOrder, []);
33161
+ map.get(node.dayOrder).push(node);
33162
+ });
33163
+ return map;
33164
+ }, [trajectEntry]);
33165
+ if (!context || !trajectEntry)
33166
+ return null;
33167
+ const toggleExpanded = (lineGuid) => setExpandedNodes((prev) => ({ ...prev, [lineGuid]: !prev[lineGuid] }));
33168
+ const handleSelect = (item, code) => {
33169
+ const availability = trajectNodeAvailability[item.line.guid];
33170
+ const result = availability?.results.find((x) => x.code === code);
33171
+ if (!result)
33172
+ return;
33173
+ dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code }));
33174
+ dispatch(updateEditableEntryLine(applyResultToLine(item.line, result)));
33175
+ };
33176
+ const renderServiceNode = (item) => {
33177
+ const { node, line } = item;
33178
+ const availability = trajectNodeAvailability[line.guid];
33179
+ const isExpanded = !!expandedNodes[line.guid];
33180
+ const results = availability?.results ?? [];
33181
+ const selected = results.find((x) => x.code === availability?.selectedCode) ?? null;
33182
+ const alternatives = results.filter((x) => x.code !== availability?.selectedCode);
33183
+ // No entry yet means the node's search has been queued but not dispatched — still loading.
33184
+ const status = availability?.status ?? 'loading';
33185
+ return (React__default["default"].createElement(React__default["default"].Fragment, { key: line.guid },
33186
+ React__default["default"].createElement("div", { className: "search__results__label search__results__label--secondary" },
33187
+ React__default["default"].createElement("div", { className: "search__results__label__date" },
33188
+ React__default["default"].createElement("p", { className: "search__results__label__date-date" }, dateFns.format(new Date(line.from), 'd', { locale })),
33189
+ React__default["default"].createElement("p", null, dateFns.format(new Date(line.from), 'MMM', { locale }))),
33190
+ React__default["default"].createElement("div", { className: "search__results__label__text" },
33191
+ React__default["default"].createElement(Icon, { name: getNodeIcon(node), height: 16 }),
33192
+ React__default["default"].createElement("h3", null,
33193
+ React__default["default"].createElement("strong", null, node.name)))),
33194
+ status === 'loading' && (React__default["default"].createElement(Spinner, { label: node.serviceType === EXCURSION_SERVICE_TYPE ? translations.SRP.LOADING_EXCURSIONS : translations.SRP.LOADING_ACCOMMODATIONS })),
33195
+ status === 'unavailable' && React__default["default"].createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
33196
+ status === 'resolved' && selected && (React__default["default"].createElement(React__default["default"].Fragment, null,
33197
+ availability.preferredUnavailable && node.preferredAccommodationName && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
33198
+ React__default["default"].createElement("span", null,
33199
+ node.preferredAccommodationName,
33200
+ " \u2014 ",
33201
+ translations.SRP.NO_RESULTS))),
33202
+ React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--extended" },
33203
+ React__default["default"].createElement(TrajectNodeCard, { result: selected, isSelected: true, languageCode: context.languageCode, translations: translations, onSelect: () => handleSelect(item, selected.code), showNights: node.serviceType === ACCOMMODATION_SERVICE_TYPE }),
33204
+ isExpanded &&
33205
+ alternatives.map((result) => (React__default["default"].createElement(TrajectNodeCard, { key: result.code, result: result, isSelected: false, languageCode: context.languageCode, translations: translations, onSelect: () => handleSelect(item, result.code), showNights: node.serviceType === ACCOMMODATION_SERVICE_TYPE })))),
33206
+ alternatives.length > 0 && (React__default["default"].createElement("div", { className: "search__results__cards__actions" },
33207
+ React__default["default"].createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => toggleExpanded(line.guid) }, isExpanded ? translations.SRP.SHOW_LESS : `${translations.SRP.SHOW_MORE} (${alternatives.length})`)))))));
33208
+ };
33209
+ const renderFlightNode = (item) => {
33210
+ const { node, line } = item;
33211
+ const isOutbound = flightPairing.outbound?.node.nodeId === node.nodeId;
33212
+ const isInbound = flightPairing.inbound?.node.nodeId === node.nodeId;
33213
+ // A middle leg of a multi-flight traject: the round-trip flight search cannot express it.
33214
+ if (!isOutbound && !isInbound) {
33215
+ return (React__default["default"].createElement(React__default["default"].Fragment, { key: line.guid },
33216
+ React__default["default"].createElement("div", { className: "search__results__label search__results__label--secondary" },
33217
+ React__default["default"].createElement("div", { className: "search__results__label__date" },
33218
+ React__default["default"].createElement("p", { className: "search__results__label__date-date" }, dateFns.format(new Date(line.from), 'd', { locale })),
33219
+ React__default["default"].createElement("p", null, dateFns.format(new Date(line.from), 'MMM', { locale }))),
33220
+ React__default["default"].createElement("div", { className: "search__results__label__text" },
33221
+ React__default["default"].createElement(Icon, { name: "ui-flight", height: 16 }),
33222
+ React__default["default"].createElement("h3", null,
33223
+ React__default["default"].createElement("strong", null, node.name)))),
33224
+ React__default["default"].createElement("div", { className: "no-results" },
33225
+ node.departureAirportCode,
33226
+ " \u2192 ",
33227
+ node.arrivalAirportCode)));
33228
+ }
33229
+ const flights = isOutbound ? uniqueOutwardFlights : uniqueReturnFlights;
33230
+ const selectedFlight = isOutbound ? selectedOutward : selectedReturn;
33231
+ const selectedKey = isOutbound ? selectedOutwardKey : selectedReturnKey;
33232
+ const visible = flights.filter((x) => getFlightKey(isOutbound ? x.outward.segments : x.return.segments) !== selectedKey);
33233
+ return (React__default["default"].createElement(React__default["default"].Fragment, { key: line.guid },
33234
+ React__default["default"].createElement("div", { className: "search__results__label search__results__label--secondary" },
33235
+ React__default["default"].createElement("div", { className: "search__results__label__date" },
33236
+ React__default["default"].createElement("p", { className: "search__results__label__date-date" }, dateFns.format(new Date(line.from), 'd', { locale })),
33237
+ React__default["default"].createElement("p", null, dateFns.format(new Date(line.from), 'MMM', { locale }))),
33238
+ React__default["default"].createElement("div", { className: "search__results__label__text" },
33239
+ React__default["default"].createElement(Icon, { name: "ui-flight", height: 16 }),
33240
+ React__default["default"].createElement("h3", null,
33241
+ translations.SRP.SELECT,
33242
+ " ",
33243
+ React__default["default"].createElement("strong", null, isOutbound ? translations.SRP.DEPARTURE : translations.SRP.RETURN)))),
33244
+ flightsLoading || !trajectFlightsResolved ? (React__default["default"].createElement(Spinner, { label: translations.SRP.LOADING_FLIGHTS })) : flights.length === 0 ? (React__default["default"].createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS)) : (React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--extended" },
33245
+ selectedFlight && (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${selectedKey}`, item: isOutbound ? selectedFlight.outward : selectedFlight.return, guid: selectedFlight.outwardGuid, selectedGuid: selectedFlight.outwardGuid, isOutward: isOutbound, showSelectedState: true, price: selectedFlight.price, onSelect: isOutbound ? () => dispatch(setSelectedOutwardKey(null)) : undefined })),
33246
+ visible.map((result) => (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: isOutbound ? result.outward : result.return, guid: result.outwardGuid, isOutward: isOutbound, price: result.price, currentSelectedPrice: selectedFlight?.price, onSelect: () => dispatch(isOutbound ? setSelectedOutwardKey(getFlightKey(result.outward.segments)) : setSelectedReturnKey(getFlightKey(result.return.segments))) })))))));
33247
+ };
33248
+ /** Connecting markers and points of interest: shown for context, nothing to book. */
33249
+ const renderContextNode = (node) => (React__default["default"].createElement("div", { className: "search__results__cards__actions", key: `${node.nodeId}-context` },
33250
+ React__default["default"].createElement("span", null,
33251
+ React__default["default"].createElement(Icon, { name: "ui-car", height: 14 }),
33252
+ " ",
33253
+ node.name,
33254
+ node.distanceInKm ? ` — ${Math.round(node.distanceInKm)} km` : '')));
33255
+ if (isLoading)
33256
+ return React__default["default"].createElement(Spinner, { label: translations.SRP.LOADING_ITINERARY });
33257
+ return (React__default["default"].createElement(React__default["default"].Fragment, null, trajectEntry.traject.days.map((day) => {
33258
+ const dayNodes = nodesByDay.get(day.order) ?? [];
33259
+ if (!dayNodes.length)
33260
+ return null;
33261
+ return (React__default["default"].createElement(React__default["default"].Fragment, { key: `day-${day.order}` },
33262
+ React__default["default"].createElement("div", { className: "search__results__label" },
33263
+ React__default["default"].createElement("div", { className: "search__results__label__text" },
33264
+ React__default["default"].createElement("h2", null,
33265
+ translations.ITINERARY.DAY,
33266
+ " ",
33267
+ day.order + 1,
33268
+ day.name ? ` — ${day.name}` : ''),
33269
+ React__default["default"].createElement("span", null, dateFns.format(new Date(day.date), 'EEEE d MMMM yyyy', { locale })))),
33270
+ dayNodes.map((node) => {
33271
+ if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE)
33272
+ return renderContextNode(node);
33273
+ const item = lineByNodeId.get(node.nodeId);
33274
+ if (!item)
33275
+ return renderContextNode(node);
33276
+ return isTrajectFlightNode(node) ? renderFlightNode(item) : renderServiceNode(item);
33277
+ })));
33278
+ })));
33279
+ };
33280
+
33281
+ const useTrajectAvailability = () => {
33282
+ const context = React.useContext(SearchResultsConfigurationContext);
33283
+ const dispatch = reactRedux.useDispatch();
33284
+ const trajectEntry = context?.trajectEntry;
33285
+ const selectedCombinationFlight = reactRedux.useSelector(selectSelectedCombinationFlight);
33286
+ React.useEffect(() => {
33287
+ if (!context || !trajectEntry)
33288
+ return;
33289
+ const controller = new AbortController();
33290
+ dispatch(resetTrajectAvailability());
33291
+ const config = {
33292
+ host: context.tideConnection.host,
33293
+ apiKey: context.tideConnection.apiKey
33294
+ };
33295
+ const searchContext = {
33296
+ transactionId: trajectEntry.entry.transactionId,
33297
+ officeId: context.tideConnection.officeId ?? 1,
33298
+ catalogueId: context.searchConfiguration.defaultCatalogueId ?? lodash.first(context.tideConnection.catalogueIds) ?? 1,
33299
+ searchConfigurationId: context.searchConfiguration.id,
33300
+ portalId: context.portalId ?? null,
33301
+ agentId: context.agentId ?? null,
33302
+ language: context.languageCode ?? 'en-GB',
33303
+ rooms: getPackagingRoomsFromEntry(trajectEntry.entry)
33304
+ };
33305
+ const nodesWithLines = getTrajectNodesWithLines(trajectEntry);
33306
+ const resolveNode = async (item) => {
33307
+ const lineGuid = item.line.guid;
33308
+ const search = item.node.serviceType === EXCURSION_SERVICE_TYPE ? build.searchPackagingExcursions : build.searchPackagingAccommodations;
33309
+ dispatch(setTrajectNodeLoading(lineGuid));
33310
+ try {
33311
+ const preferredCodes = getPreferredCodes(item.node);
33312
+ let results = [];
33313
+ let picked = null;
33314
+ // Try the traject's own product/hotel codes first, in configured order.
33315
+ for (const code of preferredCodes) {
33316
+ const attempt = await search(config, buildTrajectNodeRequest(item, searchContext, code), controller.signal);
33317
+ const hit = (attempt ?? []).find((result) => matchesCode(result, code));
33318
+ if (hit) {
33319
+ results = attempt;
33320
+ picked = hit;
33321
+ break;
33322
+ }
33323
+ }
33324
+ let preferredUnavailable = false;
33325
+ // Nothing configured was available — fall back to the cheapest result in the destination.
33326
+ if (!picked) {
33327
+ results = (await search(config, buildTrajectNodeRequest(item, searchContext, ''), controller.signal)) ?? [];
33328
+ picked = pickCheapest(results);
33329
+ preferredUnavailable = preferredCodes.length > 0;
33330
+ }
33331
+ if (controller.signal.aborted)
33332
+ return null;
33333
+ dispatch(setTrajectNodeAvailability({
33334
+ lineGuid,
33335
+ results,
33336
+ selectedCode: picked?.code ?? null,
33337
+ preferredUnavailable
33338
+ }));
33339
+ if (!picked)
33340
+ return lineGuid;
33341
+ dispatch(updateEditableEntryLine(applyResultToLine(item.line, picked)));
33342
+ return null;
33343
+ }
33344
+ catch (error) {
33345
+ if (controller.signal.aborted)
33346
+ return null;
33347
+ console.error('Failed to resolve traject node availability', item.node.name, error);
33348
+ dispatch(setTrajectNodeAvailability({ lineGuid, results: [], selectedCode: null, preferredUnavailable: false }));
33349
+ return lineGuid;
33350
+ }
33351
+ };
33352
+ const resolveFlights = async () => {
33353
+ const { outbound, inbound } = pairTrajectFlights(nodesWithLines);
33354
+ if (!outbound) {
33355
+ dispatch(setTrajectFlightsResolved(true));
33356
+ return;
33357
+ }
33358
+ dispatch(setFlightsLoading(true));
33359
+ try {
33360
+ const pax = trajectEntry.entry.pax ?? [];
33361
+ const ageOf = (p) => p.age ?? 30;
33362
+ const adults = pax.filter((p) => ageOf(p) >= 12).length;
33363
+ const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12).length;
33364
+ const babies = pax.filter((p) => ageOf(p) < 2).length;
33365
+ const request = {
33366
+ transactionId: trajectEntry.entry.transactionId,
33367
+ officeId: searchContext.officeId,
33368
+ catalogueId: searchContext.catalogueId,
33369
+ agentId: searchContext.agentId,
33370
+ language: searchContext.language,
33371
+ departureAirportCode: outbound.node.departureAirportCode ?? '',
33372
+ arrivalAirportCode: outbound.node.arrivalAirportCode ?? '',
33373
+ returnAirportCode: inbound?.node.arrivalAirportCode ?? outbound.node.departureAirportCode ?? null,
33374
+ luggageIncluded: null,
33375
+ maxStops: null,
33376
+ travelClass: null,
33377
+ pax: lodash.concat(Array.from({ length: adults }, (_, index) => ({ id: index, age: 31 })), Array.from({ length: kids }, (_, index) => ({ id: index + adults, age: 8 })), Array.from({ length: babies }, (_, index) => ({ id: index + adults + kids, age: 1 }))),
33378
+ outward: { date: dateToDateStruct(new Date(outbound.line.from)) },
33379
+ return: { date: dateToDateStruct(new Date((inbound ?? outbound).line.from)) }
33380
+ };
33381
+ const flights = (await build.searchPackagingFlights(config, request, controller.signal)) ?? [];
33382
+ if (controller.signal.aborted)
33383
+ return;
33384
+ dispatch(setPackagingFlightResults(flights));
33385
+ const firstFlight = lodash.first(flights);
33386
+ if (firstFlight) {
33387
+ dispatch(setSelectedOutwardKey(getFlightKey(firstFlight.outward.segments)));
33388
+ dispatch(setSelectedReturnKey(getFlightKey(firstFlight.return.segments)));
33389
+ }
33390
+ }
33391
+ catch (error) {
33392
+ if (!controller.signal.aborted)
33393
+ console.error('Failed to resolve traject flights', error);
33394
+ }
33395
+ finally {
33396
+ if (!controller.signal.aborted) {
33397
+ dispatch(setFlightsLoading(false));
33398
+ dispatch(setTrajectFlightsResolved(true));
33399
+ }
33400
+ }
33401
+ };
33402
+ (async () => {
33403
+ const searchable = nodesWithLines.filter((x) => isSearchableTrajectNode(x.node));
33404
+ const [unresolved] = await Promise.all([Promise.all(searchable.map(resolveNode)), resolveFlights()]);
33405
+ if (controller.signal.aborted)
33406
+ return;
33407
+ // A node with no availability anywhere cannot be priced or booked, so its line comes off
33408
+ // the entry. The card stays visible and reports the gap.
33409
+ const emptyLineGuids = unresolved.filter((guid) => !!guid);
33410
+ if (emptyLineGuids.length)
33411
+ dispatch(removeEditableEntryLines(emptyLineGuids));
33412
+ })();
33413
+ return () => controller.abort();
33414
+ }, [trajectEntry]);
33415
+ // Keep the traject's own flight lines in step with whatever outward/return the user picks.
33416
+ React.useEffect(() => {
33417
+ if (!trajectEntry || !selectedCombinationFlight)
33418
+ return;
33419
+ const { outbound, inbound } = pairTrajectFlights(getTrajectNodesWithLines(trajectEntry));
33420
+ if (outbound)
33421
+ dispatch(updateEditableEntryLine(applyFlightToLine(outbound.line, selectedCombinationFlight, true)));
33422
+ if (inbound)
33423
+ dispatch(updateEditableEntryLine(applyFlightToLine(inbound.line, selectedCombinationFlight, false)));
33424
+ }, [trajectEntry, selectedCombinationFlight]);
33425
+ };
33426
+
32561
33427
  const SearchResultsContainer = ({ onBookingStarted }) => {
32562
33428
  const currentSearch = typeof window !== 'undefined' ? window.location.search : '';
32563
33429
  const dispatch = reactRedux.useDispatch();
@@ -32565,6 +33431,8 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
32565
33431
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
32566
33432
  const { results, filteredResults, packagingAccoResults, filteredPackagingAccoResults, isLoading, flightsLoading, initialFilters, filters, flightFilters, selectedSortType, selectedFlightSortType, selectedSearchResult, selectedPackagingAccoResultCode, flyInIsOpen, packagingAccoSearchDetails, editablePackagingEntry, transactionId, flyInType, packagingFlightResults, confirmedExcursionsByDay, bookPackagingEntry } = reactRedux.useSelector((state) => state.searchResults);
32567
33433
  const isMobile = useMediaQuery('(max-width: 1200px)');
33434
+ // Resolves live availability per traject node; no-op unless a traject entry is configured.
33435
+ useTrajectAvailability();
32568
33436
  const [initialFiltersSet, setInitialFiltersSet] = React.useState(false);
32569
33437
  const [initialFlightFiltersSet, setInitialFlightFiltersSet] = React.useState(false);
32570
33438
  const [filtersOpen, setFiltersOpen] = React.useState(false);
@@ -33338,6 +34206,9 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
33338
34206
  const fetchItinerary = async () => {
33339
34207
  if (!context || !context.packagingEntry || !editablePackagingEntry || lodash.isEmpty(editablePackagingEntry.lines))
33340
34208
  return;
34209
+ // The traject view renders its own day-by-day column, so the generated itinerary is unused.
34210
+ if (context.trajectEntry)
34211
+ return;
33341
34212
  setItineraryIsLoading(true);
33342
34213
  try {
33343
34214
  const config = {
@@ -33408,6 +34279,10 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
33408
34279
  React.useEffect(() => {
33409
34280
  if (!context)
33410
34281
  return;
34282
+ // A traject entry already has its lines; they are updated per node rather than rebuilt from
34283
+ // a single hotel/flight selection, which would discard the node-to-line mapping.
34284
+ if (context.trajectEntry)
34285
+ return;
33411
34286
  const seed = activeSearchSeed;
33412
34287
  if (!seed)
33413
34288
  return;
@@ -33796,7 +34671,8 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
33796
34671
  React__default["default"].createElement("div", { className: "search__results__cards search__results__cards--extended" },
33797
34672
  selectedReturnKey && selectedReturn && (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${selectedReturnKey}`, item: selectedReturn.return, guid: selectedReturn.outwardGuid, selectedGuid: selectedReturn.outwardGuid, isOutward: false, showSelectedState: true, price: selectedReturn.price })),
33798
34673
  uniqueReturnFlights.map((result) => (React__default["default"].createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: result.return, onSelect: () => dispatch(setSelectedReturnKey(getFlightKey(result.return.segments))), guid: result.outwardGuid, isOutward: false, currentSelectedPrice: selectedReturn?.price, price: result.price })))))),
33799
- context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.packagingEntry && (React__default["default"].createElement(FullItinerary, { isLoading: itineraryIsLoading })))),
34674
+ context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.trajectEntry && (React__default["default"].createElement(TrajectResults, { isLoading: isLoading })),
34675
+ context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.packagingEntry && !context.trajectEntry && (React__default["default"].createElement(FullItinerary, { isLoading: itineraryIsLoading })))),
33800
34676
  React__default["default"].createElement(FlyIn, { srpType: context.searchConfiguration.qsmType, isOpen: flyInIsOpen, setIsOpen: handleFlyInToggle, handleConfirm: () => handleConfirmHotelSwap(), onPanelRef: (el) => (panelRef.current = el), detailsLoading: detailsIsLoading, flyInType: flyInType, isPackageEditFlow: !!context.packagingEntry, sortByTypes: sortByTypes, activeSearchSeed: activeSearchSeed, toggleFilters: () => setFiltersOpen(!filtersOpen), filtersOpen: filtersOpen })))))))));
33801
34677
  };
33802
34678