{"version":3,"names":["ADJACENT_MINI_CABIN_PLACE_ALIGNMENT","OPEN_PLAN_COACH_PREFIX","WHEELCHAIR_COUCHETTE_DANI","PRIORITY_SEAT_SEVERELY_DISABLED_PASSENGER","journeyData","reservationMode","JourneyStore","getInstance","instances","has","set","get","constructor","mode","this","njOffer","njAccommodation","njProduct","additionalRequest","additionalOffer","additionalProduct","readFromSession","isEmpty","replaceData","dataStore","getSessionData","_b","_a","connection","departure","asOffsetTime","_d","_c","arrival","_f","_e","_h","_g","storeInSession","removeSessionData","setSessionData","triggerPrebookPrepare","preparePrebookRequestBody","triggerEvent","name","window","dispatchEvent","CustomEvent","detail","data","clearAll","setNjOffer","offer","accommodation","setNjProduct","product","setAdditionalRequest","request","clearAdditionalRequest","setFinalOffer","clearFinalOffer","isChosenNjConnection","from","dep_dt","train","isChosenAdditionalConnection","sectionsListEqual","sections","hasSelectedOffer","hasSelectedProduct","getNjOffer","getNjAccommodation","getNjProduct","getAdditionalRequest","getAdditionalOffer","getFinalOffer","getFinalProduct","price","Map","ProductKey","ProductType","DayProductType","njProductTitles","nonFlexibleProductNames","semiFlexibleProductNames","flexibleProductNames","isNJProduct","find","title","toLowerCase","includes","getProductKey","type","NonFlexible","Sparschiene","SemiFlexible","Komfortticket","Flexible","Standardticket","getProductType","getProductTypeForName","de","split","map","nameLower","item","getDayProductType","prodGroupLabels","Unknown","NonRefundable","Refundable","Standard","console","warn","getCombinedProductType","njIndex","resultType","resultIndex","productDetails","isSectionInScopes","scope","productType","productIndex","getDayProductTypeIndex","getProductNameKey","replace","translateProductDetailName","i18n","getMessage","translateProductName","key","getProductInfo","translateAccommodationType","accommodationType","getProductCancellation","departureDate","getCancellationForType","SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_FULL_REFUND","SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_PARTIAL_REFUND","SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND","today","now","daysUntilDeparture","diff","getCancellationDate","getCancellationLabelForType","daysBeforeDeparture","formatNumericDate","subtract","ADDITIONAL_INFORMATION_DIALOGUES","AccommodationType","Se","rootUrl","getLang","Le","Be","ADDITIONAL_INFORMATION_DIALOGUE_EURO_NIGHT","SelectedClasses","isSupportedOffer","offerName","offerNameLowerCased","isSupportedCompartment","compartment","special","externalIdentifier","calculateSelectableCompartmentPricesForOffer","reservationKey","compartmentPrices","reservationSegement","reservation","reservationSegments","compartments","basePrice","privateVariations","privateVariation","surchargePrice","push","calculateSelectableCompartmentPricesForOffers","offers","offerPrices","i","length","selectCompartment","selectedInternalProduct","JSON","parse","stringify","selected","ticket","reservationSegementsLoop","id","compartmentId","accommodationClass","class2","selectedReservationKey","charAt","toUpperCase","slice","count","privateVariationCount","spotLocations","spotLocation","spotLocationSelected","spotLocationsSelected","value","param","placeAlignment","orders","paymentInformationPrice","ReservationMode","Outward","Return","store","finalProduct","offerData","prebookOffers","filter","buildPrebookData","maxTrainChanges","objects","rfpIndex","Math","round","requestBody","paymentInformation","amount","paymentMethod","email","DATA_STORE_KEY_PREBOOK","Event","removeJourney","returnData","returnDataValue","DATA_STORE_KEY_RETURN_VALUE","DATA_STORE_KEY_OUTWARD_VALUE","mapThirdGender","prebookData","order","object","gender","isBusinessClass","priceClass","hasPriceClass","getLowerPriceClass","getPriceClassKey","getCompartmentsForClass","segment","lowerPriceClass","getPriceForClass","priceKey","undefined","getMatchingPriceClass","translatePriceClassName","getStopsForScopes","scopes","getStopsForScope","getStopAtIndex","sectionIndex","stopIndex","passlist","getTrainsForScopes","trains","getSectionTrainName","category","getSectionTrainCategory","some","isSectionInScope","getOfferParts","excludedIndex","details","sort","a","b","min","obj","index","getOfferName","val","self","indexOf","join","getAttribute","section","attributes","att","attributeType","toString","trim","svalue","getTrainCategoryForName","match","getSectionTrainDirection","sectionsEqual","departureTimestamp","arrivalTimestamp","getCompartmentById","identifier","getCompartmentPrice","variation","reduce","getOfferPrice","priceClassKey","translateCompartmentName","buildAdditionalOptions","minPrice","segments","segmentIndex","entries","surcharge","minSurcharge","localeCompare","result","selectedClass","forEach","compartmentData","groupTicketDetailsByScope","tickets","groupedTickets","ticketDetails","flat","passengerType","passenger","isReservation","createInitialGroup","updateGroup","ticketsCount","sum","passangerType","passengers","passengerIndex","ticketPrice","groupedTicketDetails","getTicketDetailsFromPrebook","globallyPriced","productPriceClass","allocations","allocation","getProductDetailsForScope","freeFollowupReservationApplied","productScope","doesPassengerRequireWheelchair","DATA_STORE_KEY_PASSENGERS","accessibilityOptions","njChallengedOptions","wheelchair","hasWheelchairCompartment"],"sources":["src/components/nj-offer-list/OfferListConstants.ts","src/global/JourneyStore.ts","src/utils/products.ts","src/components/nj-reservation/nj-reservation-utils.ts","src/utils/price-class.ts","src/utils/offers.ts"],"sourcesContent":["export const ADJACENT_MINI_CABIN_PLACE_ALIGNMENT = \"SIDE_BY_SIDE\";\n\nexport const OPEN_PLAN_COACH_PREFIX = \"centralGangwayCoach\";\nexport const WHEELCHAIR_COUCHETTE_DANI = \"wheelchairCouchette\";\nexport const PRIORITY_SEAT_SEVERELY_DISABLED_PASSENGER = \"serverlyDisabledPerson\";\n","import {Dayjs} from \"dayjs\";\n\nimport {ApiProduct, ConnectionWithOffersV6, ReservationCompartment} from \"../api/Ticketshop\";\nimport {AccommodationType} from \"../components/nj-connection/AccommodationType\";\nimport {preparePrebookRequestBody} from \"../components/nj-reservation/nj-reservation-utils\";\nimport {ReservationMode} from \"../components/nj-reservation/ReservationMode\";\n\nimport {asOffsetTime} from \"../utils/date\";\nimport {sectionsListEqual} from \"../utils/offers\";\nimport {PriceClass} from \"../utils/price-class\";\nimport {ProductType} from \"../utils/products\";\nimport {dataStore} from \"./DataStore\";\n\nexport interface NjOfferData {\n    connection: NjConnectionData;\n    offer: ConnectionWithOffersV6;\n}\n\nexport interface NjConnectionData {\n    train: string;\n\ttrainCount?: number;\n\n    from: NjFromStationData;\n    to: NjToStationData;\n\n    dani?: boolean;\n    seatAsIC?: boolean;\n\tseatAsICText?: string;\n\n    departure: Dayjs;\n    arrival: Dayjs;\n    duration_fmt?: string;\n}\n\nexport interface NjStationData {\n    name: string;\n    number: string;\n}\n\nexport interface NjToStationData extends NjStationData {\n    arr_date: string;\n    arr_dt: number;\n    arr_time: string;\n}\n\nexport interface NjFromStationData extends NjStationData {\n    dep_date: string;\n    dep_dt: number;\n    dep_time: string;\n}\n\nexport interface NjProductData {\n    ticket: string,\n    id: string,\n    offer: any,\n    reservationMode: ReservationMode,\n    price: number,\n    spotLocationsSelected: any[],\n    spotLocationsAll: any,\n    productType: ProductType,\n    apiProduct: ApiProduct,\n    compartment: ReservationCompartment,\n    privateVariationCount: number,\n}\n\nexport interface AdditionalProductData {\n    njIndex: number;\n    price: number;\n    priceClass: PriceClass;\n    offer: ApiProduct,\n    compartments: ProductCompartmentData[];\n}\n\nexport interface FinalProductData {\n    njProduct: NjProductData;\n    additionalProduct?: AdditionalProductData;\n    price: number;\n}\n\nexport interface ProductCompartmentData {\n    segmentIndex: number;\n    identifier: string;\n    spotLocation?: string;\n    privateVariationCount?: number;\n}\n\nexport interface AdditionalRequest {\n    finalFrom: any;\n    finalTo: any;\n}\n\nexport interface JourneyStoreEvent extends CustomEvent<JourneyStoreEventData> {\n}\n\nexport interface JourneyStoreEventData {\n    reservationMode: ReservationMode;\n}\n\n\nexport function journeyData(reservationMode: ReservationMode): JourneyStore {\n    return JourneyStore.getInstance(reservationMode);\n}\n\nexport class JourneyStore {\n\n    private static readonly instances = new Map<ReservationMode, JourneyStore>();\n\n    static getInstance(reservationMode: ReservationMode): JourneyStore {\n        if (!JourneyStore.instances.has(reservationMode)) {\n            JourneyStore.instances.set(reservationMode, new JourneyStore(reservationMode));\n        }\n        return JourneyStore.instances.get(reservationMode);\n    }\n\n    private readonly reservationMode: ReservationMode;\n\n    private njOffer: NjOfferData | null = null;\n    private njAccommodation: AccommodationType | null = null;\n    private njProduct: NjProductData | null = null;\n\n    private additionalRequest: AdditionalRequest | null = null;\n    private additionalOffer: NjOfferData | null = null;\n    private additionalProduct: AdditionalProductData | null = null;\n\n    private constructor(mode: ReservationMode) {\n        this.reservationMode = mode;\n        this.readFromSession();\n    }\n\n    private isEmpty(): boolean {\n        return !this.njOffer && !this.njAccommodation && !this.njProduct\n            && !this.additionalRequest && !this.additionalOffer && !this.additionalProduct;\n    }\n\n    private readFromSession() {\n        this.replaceData(dataStore().getSessionData(this.reservationMode));\n\t\tif (this.njOffer?.connection?.departure) {\n\t\t\tthis.njOffer.connection.departure = asOffsetTime(this.njOffer.connection.departure);\n\t\t}\n\t\tif (this.njOffer?.connection?.arrival) {\n\t\t\tthis.njOffer.connection.arrival = asOffsetTime(this.njOffer.connection.arrival);\n\t\t}\n\t\tif (this.additionalOffer?.connection?.departure) {\n\t\t\tthis.additionalOffer.connection.departure = asOffsetTime(this.additionalOffer.connection.departure);\n\t\t}\n\t\tif (this.additionalOffer?.connection?.arrival) {\n\t\t\tthis.additionalOffer.connection.arrival = asOffsetTime(this.additionalOffer.connection.arrival);\n\t\t}\n    }\n\n    private storeInSession() {\n        if (this.isEmpty()) {\n            dataStore().removeSessionData(this.reservationMode);\n        } else {\n            dataStore().setSessionData(this.reservationMode, this);\n        }\n    }\n\n    private triggerPrebookPrepare() {\n        preparePrebookRequestBody();\n    }\n\n    private triggerEvent(name: string) {\n        window.dispatchEvent(new CustomEvent<JourneyStoreEventData>(name, {detail: {reservationMode: this.reservationMode}}));\n    }\n\n    replaceData(data: JourneyStore) {\n        this.njOffer = data?.njOffer || null;\n        this.njAccommodation = data?.njAccommodation || null;\n        this.njProduct = data?.njProduct || null;\n\n        this.additionalRequest = data?.additionalRequest || null;\n        this.additionalOffer = data?.additionalOffer || null;\n        this.additionalProduct = data?.additionalProduct || null;\n\n        this.storeInSession();\n    }\n\n    clearAll() {\n        this.njOffer = null;\n        this.njAccommodation = null;\n        this.njProduct = null;\n\n        this.additionalRequest = null;\n        this.additionalOffer = null;\n        this.additionalProduct = null;\n\n        this.storeInSession();\n    }\n\n    setNjOffer(connection: NjConnectionData, offer: ConnectionWithOffersV6, accommodation: AccommodationType) {\n        // Update the connection\n        this.njOffer = {connection, offer};\n        this.njAccommodation = accommodation;\n\n        // Invalidate the product and additional connection\n        this.njProduct = null;\n        this.additionalOffer = null;\n        this.additionalProduct = null;\n\n        // Store and trigger events\n        this.storeInSession();\n        this.triggerPrebookPrepare();\n        this.triggerEvent('njConnectionSelected');\n    }\n\n    setNjProduct(product: NjProductData, accommodation?: AccommodationType) {\n        // Update the data and optionally the accommodation\n        this.njProduct = product;\n        if (accommodation) {\n            this.njAccommodation = accommodation;\n        }\n\n        // Invalidate the additional product\n        this.additionalProduct = null;\n\n        // Store and trigger events\n        this.triggerPrebookPrepare();\n        this.triggerEvent('productSelected');\n        this.storeInSession();\n    }\n\n    setAdditionalRequest(request: AdditionalRequest) {\n        this.additionalRequest = request;\n\n        // Store and trigger events\n        this.storeInSession();\n        this.triggerEvent('njAdditionalRequestUpdated');\n    }\n\n    clearAdditionalRequest() {\n        // Remove the request data and all selections\n        this.additionalRequest = null;\n        this.additionalOffer = null;\n        this.additionalProduct = null;\n\n        // Store and trigger events\n        this.storeInSession();\n        this.triggerPrebookPrepare();\n        this.triggerEvent('njAdditionalRequestUpdated');\n    }\n\n    setFinalOffer(connection: NjConnectionData, offer: ConnectionWithOffersV6, product: AdditionalProductData) {\n        this.additionalOffer = {connection, offer};\n        this.additionalProduct = product;\n\n        // Store and trigger events\n        this.storeInSession();\n        this.triggerPrebookPrepare();\n        this.triggerEvent('njAdditionalSelected');\n    }\n\n    clearFinalOffer() {\n        this.additionalOffer = null;\n        this.additionalProduct = null;\n\n        // Store and trigger events\n        this.storeInSession();\n        this.triggerPrebookPrepare();\n        this.triggerEvent('njAdditionalSelected');\n    }\n\n    isChosenNjConnection(data: NjConnectionData): boolean {\n        return this.njOffer && this.njOffer.connection.from.dep_dt === data.from.dep_dt && this.njOffer.connection.train === data.train;\n    }\n\n    isChosenAdditionalConnection(data: ConnectionWithOffersV6): boolean {\n        // TODO Should we also consider offer prices here?\n        return this.additionalOffer && sectionsListEqual(this.additionalOffer.offer.sections, data.sections);\n    }\n\n    hasSelectedOffer(): boolean {\n        return !!this.njOffer;\n    }\n\n    hasSelectedProduct(): boolean {\n        return !!this.njProduct;\n    }\n\n    getNjOffer(): NjOfferData | null {\n        return this.njOffer;\n    }\n\n    getNjAccommodation(): AccommodationType | null {\n        return this.njAccommodation;\n    }\n\n    getNjProduct(): NjProductData | null {\n        return this.njProduct;\n    }\n\n    getAdditionalRequest(): AdditionalRequest | null {\n        return this.additionalRequest;\n    }\n\n    getAdditionalOffer(): NjOfferData | null {\n        // The final offer is the additional offer if an additional product was selected, otherwise the direct NJ offer only\n        return this.additionalOffer;\n    }\n\n    getFinalOffer(): NjOfferData | null {\n        // The final offer is the additional offer if an additional product was selected, otherwise the direct NJ offer only\n        return this.additionalProduct ? this.additionalOffer : this.njOffer;\n    }\n\n    getFinalProduct(): FinalProductData | null {\n        if (!this.njProduct) {\n            // No NJ product means no product at all\n            return null;\n        }\n\n        return {\n            njProduct: this.njProduct,\n            additionalProduct: this.additionalProduct,\n            price: this.additionalProduct ? this.additionalProduct.price : this.njProduct.price,\n        };\n    }\n}\n","import {Dayjs} from \"dayjs\";\n\nimport {ApiProduct, MultilangText, ProductDetail} from \"../api/Ticketshop\";\nimport {formatNumericDate, now} from \"./date\";\nimport {i18n} from \"./I18n\";\nimport {isSectionInScopes} from \"./offers\";\n\nexport enum ProductKey {\n\tSparschiene = 'Sparschiene',\n\tKomfortticket = 'Komfortticket',\n\tStandardticket = 'Standardticket',\n}\n\nexport enum ProductType {\n    NonFlexible = 'NonFlexible',\n    SemiFlexible = 'SemiFlexible',\n    Flexible = 'Flexible',\n    Bike = 'Bike',\n}\n\nexport enum DayProductType {\n    Standard = 'Standard',\n    Refundable = 'Refundable',\n    NonRefundable = 'NonRefundable',\n    Unknown = 'Unknown',\n}\n\nconst njProductTitles = ['nachtverkehr']\nconst nonFlexibleProductNames = ['sparschiene', 'non flexible ticket', 'super saver ticket'];\nconst semiFlexibleProductNames = ['komfortticket', 'sparschiene komfort', 'reservierung/zuschlag'];\nconst flexibleProductNames = ['standardticket', 'standard-ticket', 'flexible ticket', 'standard ticket'];\n// const bikeProductNames = ['fahrradticket'];\n\nexport function isNJProduct(product: ProductDetail): boolean {\n    return !!njProductTitles.find(title => product.title.toLowerCase().includes(title));\n}\n\nexport function getProductKey(type: ProductType): ProductKey {\n\tswitch (type) {\n\t\tcase ProductType.NonFlexible:\n\t\t\treturn ProductKey.Sparschiene;\n\t\tcase ProductType.SemiFlexible:\n\t\t\treturn ProductKey.Komfortticket;\n\t\tcase ProductType.Flexible:\n\t\t\treturn ProductKey.Standardticket;\n\t}\n}\n\nexport function getProductType(product: ProductDetail): ProductType | null {\n    return isNJProduct(product) ? getProductTypeForName(product.name.de) : null;\n}\n\nexport function getProductTypeForName(name: string): ProductType {\n    if (!name) {\n        return null;\n    }\n\n\tif (name.includes(' + ')) {\n\t\treturn name.split(' + ').map(getProductTypeForName).find(type => !!type);\n\t}\n\n    const nameLower = name.toLowerCase();\n\n    // if (bikeProductNames.find(item => nameLower.includes(item))) {\n    //     return ProductType.Bike;\n    // }\n\n    if (semiFlexibleProductNames.find(item => nameLower.includes(item))) {\n        return ProductType.SemiFlexible;\n    }\n\n    if (nonFlexibleProductNames.find(item => nameLower.includes(item))) {\n        return ProductType.NonFlexible;\n    }\n\n    if (flexibleProductNames.find(item => nameLower.includes(item))) {\n        return ProductType.Flexible;\n    }\n}\n\nexport function getDayProductType(product: ProductDetail): DayProductType {\n    if (!product.prodGroupLabels) {\n        return DayProductType.Unknown;\n    }\n\n    if (product.prodGroupLabels.includes('Kein Storno')) {\n        return DayProductType.NonRefundable;\n    }\n\n    if (product.prodGroupLabels.includes('Zugbindung')) {\n        return DayProductType.Refundable;\n    }\n\n    if (product.prodGroupLabels.includes('Vollstorno') &&\n        (product.prodGroupLabels.includes('Keine Bindung') || product.prodGroupLabels.includes('Zeitbindung'))) {\n        return DayProductType.Standard;\n    }\n\n    console.warn('Unknown product type for labels ' + product.prodGroupLabels);\n    return DayProductType.Unknown;\n}\n\nexport function getCombinedProductType(offer: ApiProduct, njIndex: number): DayProductType {\n    let resultType = null;\n    let resultIndex = 0;\n\n    for (const product of offer.productDetails) {\n        if (isSectionInScopes(product.scope, njIndex)) {\n            // Ignore ticket for the NJ\n            continue;\n        }\n\n        const productType = getDayProductType(product);\n        const productIndex = getDayProductTypeIndex(productType);\n        if (productIndex > resultIndex) {\n            resultType = productType;\n            resultIndex = productIndex;\n        }\n    }\n\n    return resultType;\n}\n\nexport function getDayProductTypeIndex(productType?: DayProductType): number {\n    switch (productType) {\n        case DayProductType.Unknown:\n            return 1;\n        case DayProductType.Standard:\n            return 2;\n        case DayProductType.Refundable:\n            return 3;\n        case DayProductType.NonRefundable:\n            return 4;\n        default:\n            return 0;\n    }\n}\n\nexport function getProductNameKey(name: MultilangText): string | null {\n    // Product key is just the german name without whitespace and punctuation\n    return name.de?.replace(/[^a-z\\d]/gi, '');\n}\n\nexport function translateProductDetailName(product: ProductDetail): string {\n    const type = getProductType(product);\n    if (type) {\n        return i18n.getMessage(`ticket-type.${type}`);\n    }\n\n    return translateProductName(product.name);\n}\n\nexport function translateProductName(name: MultilangText): string {\n    const key = getProductNameKey(name);\n    return i18n.getMessage(`ts.product.name.${key}`, '', null, name);\n}\n\nexport function getProductInfo(product: ProductDetail) {\n    const key = getProductNameKey(product.name);\n    return i18n.getMessage(`ts.product.info.${key}`);\n}\n\nexport function translateAccommodationType(accommodationType: string): string | null {\n    return ['SE', 'LE', 'BE'].includes(accommodationType)\n        ? i18n.getMessage(`ts.accommodation.${accommodationType}`)\n        : null;\n}\n\nexport function getProductCancellation(product: ProductDetail, departureDate: Dayjs): string | null {\n    const type = getProductType(product);\n    return getCancellationForType(type, departureDate) || getProductInfo(product);\n}\n\nconst SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_FULL_REFUND = 15;\nconst SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_PARTIAL_REFUND = 14;\nconst SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND = 1;\n\nexport function getCancellationForType(type: ProductType, departureDate: Dayjs): string | null {\n    switch (type) {\n        case ProductType.NonFlexible:\n            return i18n.getMessage(\"ticket-type.NonFlexible.cancellation\");\n        case ProductType.SemiFlexible:\n\t\t\tconst today = now();\n\t\t\tconst daysUntilDeparture = departureDate.diff(today, \"days\");\n\t\t\tif (daysUntilDeparture >= SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_FULL_REFUND) {\n\t\t\t\treturn i18n.getMessage(\"ticket-type.SemiFlexible.cancellation\", \"\", [\n\t\t\t\t\tgetCancellationDate(SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_FULL_REFUND, departureDate),\n\t\t\t\t\tgetCancellationDate(SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_PARTIAL_REFUND, departureDate),\n\t\t\t\t\tgetCancellationDate(SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND, departureDate),\n\t\t\t\t]);\n\t\t\t} else if (daysUntilDeparture === SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND) {\n\t\t\t\treturn i18n.getMessage(\"ticket-type.SemiFlexible.cancellation.partial-only-last-day\", \"\", [\n\t\t\t\t\tgetCancellationDate(daysUntilDeparture, departureDate)\n\t\t\t\t]);\n\t\t\t} else if (daysUntilDeparture >= SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND) {\n\t\t\t\treturn i18n.getMessage(\"ticket-type.SemiFlexible.cancellation.partial-only\", \"\", [\n\t\t\t\t\tgetCancellationDate(daysUntilDeparture, departureDate),\n\t\t\t\t\tgetCancellationDate(SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND, departureDate),\n\t\t\t\t]);\n\t\t\t} else {\n\t\t\t\treturn i18n.getMessage(\"ticket-type.SemiFlexible.cancellation.cancellation-deadline-expired\");\n\t\t\t}\n        case ProductType.Flexible:\n            return i18n.getMessage(\"ticket-type.Flexible.cancellation\");\n    }\n}\n\nexport function getCancellationLabelForType(type: ProductType): string | null {\n    switch (type) {\n        case ProductType.NonFlexible:\n            return i18n.getMessage('ticket-type.NonFlexible.cancellation.label');\n        case ProductType.SemiFlexible:\n            return i18n.getMessage('ticket-type.SemiFlexible.cancellation.label');\n        case ProductType.Flexible:\n            return i18n.getMessage('ticket-type.Flexible.cancellation.label');\n    }\n}\n\nfunction getCancellationDate(daysBeforeDeparture: number, departureDate: Dayjs) {\n    return formatNumericDate(departureDate.subtract(daysBeforeDeparture, \"days\"));\n}\n","import {\n\tApiProduct,\n\tConnectionFilter,\n\tPrebookApiProduct,\n\tPrebookOrderV4,\n\tPrebookReservationCompartmentV3,\n\tPrebookV4Request,\n\tReservationCompartment\n} from '../../api/Ticketshop';\nimport {DATA_STORE_KEY_OUTWARD_VALUE, DATA_STORE_KEY_PREBOOK, DATA_STORE_KEY_RETURN_VALUE, dataStore} from '../../global/DataStore';\nimport {journeyData} from \"../../global/JourneyStore\";\nimport {buildPrebookData} from \"../../utils/offers\";\nimport { AccommodationType } from '../nj-connection/AccommodationType';\nimport { ReservationMode } from './ReservationMode';\nimport {rootUrl} from \"../../helpers/utils\";\nimport {i18n} from \"../../utils/I18n\";\nimport {getProductKey, getProductTypeForName} from \"../../utils/products\";\n\nexport const ADDITIONAL_INFORMATION_DIALOGUES = {\n\t[AccommodationType.Se]: `${rootUrl()}/${i18n.getLang()}/komfortkategorien/sitzwagen-buchungstool`,\n\t[AccommodationType.Le]: `${rootUrl()}/${i18n.getLang()}/komfortkategorien/liegewagen-buchungstool`,\n\t[AccommodationType.Be]: `${rootUrl()}/${i18n.getLang()}/komfortkategorien/schlafwagen-buchungstool`,\n};\nexport const ADDITIONAL_INFORMATION_DIALOGUE_EURO_NIGHT = `${rootUrl()}/${i18n.getLang()}/komfortkategorien/euronight-buchungstool`;\n\nenum SelectedClasses {\n  class1 = 'class1',\n  class2 = 'class2',\n  classBusiness = 'classBusiness',\n  // noclass = 'noclass',\n}\n\n/**\n * Check if the offer is a combined offer which we do not support.\n *\n * A combined offer can arise, if two adults and two children travel\n * and the cheapest price whould be two Sparschiene and two Komforttickets.\n * However a combined offer with Bikes is ok for us.\n * Is there a better way to filter combined offers?\n */\nexport function isSupportedOffer(offerName: string) {\n  const offerNameLowerCased = offerName.toLowerCase();\n\n  // Unsupported offers by name\n  if (offerNameLowerCased.includes('super ticket')) return false;\n  if (offerNameLowerCased.includes('sparschiene') && offerNameLowerCased.includes('komfortticket')) return false;\n\n  // If the offer is not skipped by the name, check if it is not a combined offer, should mean, we support it.\n  if (!offerNameLowerCased.includes(' + ')) return true;\n\n  // \"Fahrradticket\" may include \" + \" in name, but we support it\n  if (offerNameLowerCased.includes('Fahrradticket')) return true;\n\n  return true;\n}\n\nexport function isSupportedCompartment(compartment: ReservationCompartment|PrebookReservationCompartmentV3) {\n  if (!compartment.special) return true;\n\n  // Skip compartments only for bikes, we have them in the other offers included\n  if (compartment.externalIdentifier === 'bicycle') return false;\n\n  return true;\n}\n\n/**\n * Price calculation for compartments.\n * For nightjets there is always a reservation necessary and always class2.\n *\n * Based on \"OEBB_External_API_-_Service_Booking_ohne_Finalize.pdf\" (p. 7, 2020-06-05):\n * 3.1.3 How to calculate the price\n *\n * Ticket without reservation\n * Take the price from the attributes priceClass1 or priceClass2 from the node\n * productSummary.\n *\n * Ticket with reservation business class\n * It is important to select the compartment with the attribute isBusinessClass = true.\n * Take the price from the attributes priceClass1 in the node productSummary and the\n * price for the reservation for business class \"priceBusinessClass\" from the node\n * reservation.\n *\n * Ticket with reservation 1st or 2nd classes\n * It is important to select the compartment with a same class as the ticket for each\n * scope.\n * (accommodationClasses in the node compartments)\n * Take the price from the attributes priceClass1 or priceClass2 from the node\n * productSummary and the price for the reservation for the same class \"priceClass1\" or\n * \"priceClass2\" from the node reservation. The surchargePrice for every selected\n * compartment has to be added.\n *\n * Tickets with reservation privateVariations\n * Additional to the rules before the surchargePrice in the privateVariation must be added\n */\nexport function calculateSelectableCompartmentPricesForOffer(offer: ApiProduct, reservationKey: string = 'priceClass2'): number[] {\n  const compartmentPrices: number[] = [];\n\n  reservationSegementsLoop: for (const reservationSegement of offer.reservation.reservationSegments) {\n    compartmentsLoop: for (const compartment of reservationSegement.compartments) {\n      if (!isSupportedCompartment(compartment)) continue;\n\n      let basePrice: number = offer[reservationKey];\n      if (offer.reservation[reservationKey]) basePrice += offer.reservation[reservationKey]; // Should always be 0 for nightjet trains, anyways we use it.\n\n      if (compartment.privateVariations) {\n        for (const privateVariation of compartment.privateVariations) {\n          if (privateVariation.surchargePrice) {\n            compartmentPrices.push(basePrice + privateVariation.surchargePrice);\n          } else {\n            compartmentPrices.push(basePrice);\n          }\n        }\n      } else {\n        if (compartment.surchargePrice) {\n          compartmentPrices.push(basePrice + compartment.surchargePrice);\n        } else {\n          compartmentPrices.push(basePrice);\n        }\n      }\n    }\n  }\n\n  return compartmentPrices;\n}\n\nexport function calculateSelectableCompartmentPricesForOffers(offers: ApiProduct[]) {\n  const offerPrices: number[][] = [];\n\n  for (let i = 0; i < offers.length; i++) {\n    const offer = offers[i];\n    const compartmentPrices: number[] = calculateSelectableCompartmentPricesForOffer(offer);\n\n    offerPrices[i] = compartmentPrices;\n  }\n\n  return offerPrices;\n}\n\n/**\n * Select compartment and calculate price again for cross check\n */\nexport function selectCompartment(\n  offers: PrebookApiProduct[],\n  selectedInternalProduct: any,\n  accommodationType: AccommodationType,\n): [PrebookApiProduct[], number] {\n  let price: number = 0;\n  offers = JSON.parse(JSON.stringify(offers));\n\n  for (const offer of offers) {\n    let selected: SelectedClasses;\n\n    // Skip if not supported offer or offer not matching selected offer name\n    if (\n      !selectedInternalProduct\n      || !isSupportedOffer(offer.name)\n      || getProductKey(getProductTypeForName(offer.name)) !== selectedInternalProduct.ticket\n    ) continue;\n\n    reservationSegementsLoop: for (const reservationSegement of offer.reservation.reservationSegments) {\n      compartmentsLoop: for (const compartment of reservationSegement.compartments) {\n        if (!isSupportedCompartment(compartment)) continue;\n\n        if (\n          compartment.id == selectedInternalProduct.offer.compartmentId\n          && compartment.externalIdentifier == selectedInternalProduct.offer.externalIdentifier\n          && compartment.accommodationType == accommodationType\n        ) {\n          selected = (compartment.accommodationClass[0] as SelectedClasses) ?? SelectedClasses.class2;\n          const selectedReservationKey: string = 'price' + selected.charAt(0).toUpperCase() + selected.slice(1);\n          compartment.selected = true;\n\n          price += offer[selectedReservationKey];\n          if (offer.reservation[selectedReservationKey]) price += offer.reservation[selectedReservationKey];\n\n          if (compartment.privateVariations) {\n            for (const privateVariation of compartment.privateVariations) {\n              if (privateVariation.count === selectedInternalProduct.offer.privateVariationCount) {\n                privateVariation.selected = true;\n\n                if (privateVariation.surchargePrice) price += privateVariation.surchargePrice;\n              }\n            }\n          } else {\n            if (compartment.surchargePrice) price += compartment.surchargePrice;\n\n            // Select spot location, only one is allowed\n            if (compartment.spotLocations) {\n              for (const spotLocation of compartment.spotLocations) {\n                for (const spotLocationSelected of selectedInternalProduct.spotLocationsSelected) {\n\t\t\t\t\tif (spotLocationSelected.value === spotLocation.param || (\"placeAlignment\" in spotLocation && spotLocationSelected.value === (spotLocation as any).placeAlignment)) {\n\t\t\t\t\t\tspotLocation.selected = true;\n\t\t\t\t\t}\n                }\n              }\n            }\n          }\n\n          break reservationSegementsLoop;\n        }\n      }\n    }\n\n    if (selected) {\n      offer.selected = selected;\n      offer.reservation.selected = selected;\n    }\n  }\n\n  return [\n    offers,\n    price,\n  ];\n}\n\nexport function preparePrebookRequestBody() {\n    const orders: PrebookOrderV4[] = [];\n    let paymentInformationPrice: number = 0;\n\n    for (const mode of [ReservationMode.Outward, ReservationMode.Return]) {\n      const store = journeyData(mode);\n\n      const finalProduct = store.getFinalProduct();\n      const offerData = store.getFinalOffer();\n\n      if (offerData) {\n        let prebookOffers: PrebookApiProduct[], price: number, filter: ConnectionFilter;\n        if (finalProduct?.additionalProduct) {\n          price = finalProduct.price;\n          prebookOffers = [buildPrebookData(finalProduct)];\n\t\t  filter = {};\n        } else {\n          // TODO This can probably be handled with the same logic as additional trains\n          [prebookOffers, price] = selectCompartment(offerData.offer.offers, store.getNjProduct(), store.getNjAccommodation());\n\t\t  filter = {maxTrainChanges: 0};\n        }\n\n        orders.push({\n          objects: [],\n          offers: prebookOffers,\n          sections: offerData.offer.sections,\n          filter,\n          rfpIndex: 0,\n        });\n        paymentInformationPrice += price;\n      }\n    }\n\n\tpaymentInformationPrice = Math.round(paymentInformationPrice * 100) / 100;\n    const requestBody = {\n      paymentInformation: {\n        amount: paymentInformationPrice,\n        paymentMethod: \"EXTERNAL\",\n        email: null,\n      },\n      orders,\n    };\n\n    dataStore().setSessionData(DATA_STORE_KEY_PREBOOK, requestBody);\n\n    window.dispatchEvent(new Event('prebookRequestPrepared'));\n}\n\nexport function removeJourney(reservationMode: ReservationMode) {\n  // Set return journey as outward journey if outward journey is removed\n  if (reservationMode === ReservationMode.Outward) {\n    const returnData = journeyData(ReservationMode.Return);\n    let returnDataValue = dataStore().getSessionData(DATA_STORE_KEY_RETURN_VALUE, null);\n\n    if (returnDataValue) returnDataValue = returnDataValue.replace(ReservationMode.Return, ReservationMode.Outward);\n\n    journeyData(ReservationMode.Outward).replaceData(returnData);\n    dataStore().setSessionData(DATA_STORE_KEY_OUTWARD_VALUE, returnDataValue);\n  }\n\n  // Always remove return journey, because if needed we switched it before\n  journeyData(ReservationMode.Return).clearAll();\n  dataStore().removeSessionData(DATA_STORE_KEY_RETURN_VALUE);\n  preparePrebookRequestBody();\n\n  window.dispatchEvent(new Event('journeyRemoved'));\n}\n\nexport function mapThirdGender(prebookData: PrebookV4Request): void {\n\t// warning: this function modifies the parameter and is therefore stateless\n\tfor (const order of prebookData.orders) {\n\t\tfor (const object of order.objects) {\n\t\t\tif (object.gender === \"diverse\") {\n\t\t\t\tobject.gender = \"male\";\n\t\t\t}\n\t\t}\n\t}\n}\n","import {ProductDetailObject, ReservationCompartment, ReservationSegment} from \"../api/Ticketshop\";\nimport {i18n} from \"./I18n\";\n\nexport type PriceClass = 'class1' | 'class2' | 'businessClass' | 'classBusiness' | 'noclass';\n\nexport function isBusinessClass(priceClass: PriceClass): boolean {\n    return priceClass === 'businessClass' || priceClass === 'classBusiness';\n}\n\nexport function hasPriceClass(compartment: ReservationCompartment, priceClass: PriceClass): boolean {\n    if (compartment.isBusinessClass) {\n        return isBusinessClass(priceClass);\n    }\n    return (compartment.accommodationClass as any).includes(priceClass);\n}\n\nexport function getLowerPriceClass(priceClass: PriceClass): PriceClass | null {\n    switch (priceClass) {\n        case 'classBusiness':\n        case 'businessClass':\n            return 'class1';\n        case 'class1':\n            return 'class2';\n        default:\n            return null;\n    }\n}\n\nexport function getPriceClassKey(priceClass: PriceClass): 'priceClass1' | 'priceClass2' | 'priceBusinessClass' | 'priceNoClass' {\n    switch (priceClass) {\n        case 'class1':\n            return 'priceClass1';\n        case 'class2':\n            return 'priceClass2';\n        case 'businessClass':\n        case 'classBusiness':\n            return 'priceBusinessClass';\n        case \"noclass\":\n            return 'priceNoClass';\n    }\n}\n\n\n/**\n * Filters the list of compartments by price class\n * @param segment The reservation segment\n * @param priceClass The preferred price class\n * @return A list of compartments in the highest available price class based on the requested one\n */\nexport function getCompartmentsForClass(segment: ReservationSegment, priceClass: PriceClass): ReservationCompartment[] {\n    if (!segment.compartments) {\n        return [];\n    }\n\n    // Filter by available classes\n    const compartments = segment.compartments?.filter(compartment => !compartment.special && hasPriceClass(compartment, priceClass));\n    if (compartments.length) {\n        // Found something, use it\n        return compartments;\n    }\n\n    // Move down to second class\n    const lowerPriceClass = getLowerPriceClass(priceClass);\n    if (lowerPriceClass) {\n        return getCompartmentsForClass(segment, getLowerPriceClass(priceClass));\n    }\n\n    // Nothing found (does this ever happen?)\n    return [];\n}\n\nexport function getPriceForClass(product: ProductDetailObject, priceClass: PriceClass): number {\n    const priceKey = getPriceClassKey(priceClass);\n    if (product[priceKey] !== undefined) {\n        // Price for the requested class exists, use it\n        return product[priceKey];\n    }\n\n    // Move down to lower class\n    const lowerPriceClass = getLowerPriceClass(priceClass);\n    if (lowerPriceClass) {\n        return getPriceForClass(product, lowerPriceClass);\n    }\n\n    // No price at all, use 0\n    return 0;\n}\n\nexport function getMatchingPriceClass(product: ProductDetailObject, priceClass: PriceClass): PriceClass | null {\n    const priceKey = getPriceClassKey(priceClass);\n    if (product[priceKey] !== undefined) {\n        // Price class exists, use it\n        return priceClass;\n    }\n\n    // Move down to lower class\n    const lowerPriceClass = getLowerPriceClass(priceClass);\n    if (lowerPriceClass) {\n        return getMatchingPriceClass(product, lowerPriceClass);\n    }\n\n    // No price at all, do not use any class\n    return null;\n}\n\nexport function translatePriceClassName(priceClass: PriceClass): string {\n    return i18n.getMessage(isBusinessClass(priceClass) ? 'ts.class.business' : `ts.class.${priceClass}`);\n}\n","import {\n    ApiProduct,\n    ConnectionSection,\n    ConnectionWithOffersV6,\n    PrebookApiProduct,\n    PrebookObjectV4,\n    PrebookReservationCompartmentV3,\n    PrivateVariation,\n    ProductDetail,\n    ReservationCompartment,\n    ReservationSegment,\n    SectionAttribute,\n    SectionStop\n} from \"../api/Ticketshop\";\nimport {WHEELCHAIR_COUCHETTE_DANI} from \"../components/nj-offer-list/OfferListConstants\";\nimport {isSupportedCompartment} from \"../components/nj-reservation/nj-reservation-utils\";\nimport {FinalProductData, NjProductData} from \"../global/JourneyStore\";\nimport {i18n} from \"./I18n\";\nimport {getCompartmentsForClass, getMatchingPriceClass, getPriceClassKey, getPriceForClass, PriceClass} from \"./price-class\";\nimport {translateProductDetailName} from \"./products\";\nimport {DATA_STORE_KEY_PASSENGERS, dataStore} from \"../global/DataStore\";\n\ntype NullableSectionStop = SectionStop | null;\n\n/**\n * Loads station information for scopes (e.g. first class availability)\n * @param sections The connection sections list\n * @param scopes An array of scopes\n * @return An array of station pairs\n */\nexport function getStopsForScopes(sections: ConnectionSection[] | undefined, scopes?: number[][]): [NullableSectionStop, NullableSectionStop][] | null {\n    return scopes?.map(scope => getStopsForScope(sections, scope));\n}\n\n/**\n * Loads the station information for a single scope (e.g. first class availability)\n * @param sections The connection sections list\n * @param scope A four-element array containing the section and stop indices of the station\n * @return A pair of stations\n */\nexport function getStopsForScope(sections: ConnectionSection[] | undefined, scope: number[]): [NullableSectionStop, NullableSectionStop] {\n    return [getStopAtIndex(sections, scope[0], scope[1]), getStopAtIndex(sections, scope[2], scope[3])];\n}\n\n/**\n * Loads the station information by index\n * @param sections The connection sections list\n * @param sectionIndex The index of the section\n * @param stopIndex The index of the stop\n * @return A single station iff the indices were valid\n */\nexport function getStopAtIndex(sections: ConnectionSection[] | undefined, sectionIndex: number, stopIndex: number): NullableSectionStop {\n    return sections?.[sectionIndex]?.passlist?.[stopIndex] ?? null;\n}\n\n/**\n * Gets the train names for the sections within the given scopes\n * @param sections The sections of the offer\n * @param scopes The requested scopes\n * @return A list of train names and categories\n */\nexport function getTrainsForScopes(sections: ConnectionSection[] | undefined, scopes?: number[][]): { name: string, category: string }[] {\n    const trains = [];\n    if (!scopes || !sections) {\n        return trains;\n    }\n\n    for (const scope of scopes) {\n        for (let i = scope[0]; i <= scope[2]; i++) {\n            const name = getSectionTrainName(sections[i]);\n            const category = getSectionTrainCategory(sections[i]);\n            if (name && (!trains.length || trains[trains.length - 1].name !== name)) {\n                trains.push({name, category});\n            }\n        }\n    }\n\n    return trains;\n}\n\nexport function isSectionInScopes(scopes: number[][], sectionIndex: number) {\n    return scopes.some(scope => isSectionInScope(scope, sectionIndex));\n}\n\nexport function isSectionInScope(scope: number[], sectionIndex: number) {\n    return sectionIndex >= scope[0] && sectionIndex <= scope[2];\n}\n\nexport function getOfferParts(offer: ApiProduct, excludedIndex?: number): ProductDetail[] {\n    return offer.productDetails\n        .filter(details => excludedIndex === undefined || !isSectionInScopes(details.scope, excludedIndex))\n        .sort((a, b) =>\n            // First sort by scope, then by associated passengers\n            a.scope[0][0] !== b.scope[0][0]\n                ? a.scope[0][0] - b.scope[0][0]\n                : Math.min(...a.objects.map(obj => obj.index)) - Math.min(...b.objects.map(obj => obj.index))\n        );\n}\n\nexport function getOfferName(offer: ApiProduct, excludedIndex?: number) {\n    return getOfferParts(offer, excludedIndex)\n        .map(details => translateProductDetailName(details))\n        .filter((val, index, self) => self.indexOf(val) === index)\n        .join(' + ');\n}\n\n/**\n * Gets a section attribute by attribute type\n * @param section The section data\n * @param type The attribute type\n * @return The attribute if it exists\n */\nexport function getAttribute(section: ConnectionSection | undefined, type: string): SectionAttribute | null {\n    return section?.attributes?.find(att => att.attributeType === type) ?? null;\n}\n\n/**\n * Gets the train name of a section\n * @param section The section data\n * @return The train name iff it is set\n */\nexport function getSectionTrainName(section?: ConnectionSection): string | null {\n    return getAttribute(section, 'name')?.value?.toString().trim() ?? null;\n}\n\n/**\n * Gets the train category of a section\n * @param section The section data\n * @return The train category iff it is set\n */\nexport function getSectionTrainCategory(section?: ConnectionSection): string | null {\n    return getAttribute(section, 'cat')?.svalue?.trim() ?? null;\n}\n\n/**\n * Gets the train category from a train name\n * @param name The train name\n * @return The train category iff it is present in the train name\n */\nexport function getTrainCategoryForName(name?: string): string | null {\n    return name?.match(/^[a-z]+/i)?.[0] ?? null;\n}\n\n/**\n * Gets the train direction of a section\n * @param section The section data\n * @return The train direction iff it is set\n */\nexport function getSectionTrainDirection(section?: ConnectionSection): string | null {\n    return getAttribute(section, 'dir')?.value.toString().trim() ?? null;\n}\n\nexport function sectionsListEqual(a: ConnectionSection[], b: ConnectionSection[]): boolean {\n    if (a.length !== b.length) {\n        // Fail fast: Not the same number of sections\n        return false;\n    }\n\n    for (let i = 0; i < a.length; i++) {\n        // Compare each pair of sections, fail if they are different\n        if (!sectionsEqual(a[i], b[i])) {\n            return false;\n        }\n    }\n\n    // Nothing failed, so we have a match\n    return true;\n}\n\nexport function sectionsEqual(a: ConnectionSection, b: ConnectionSection): boolean {\n    // Consider sections to be equal if the times and the train name matches\n    return a.departureTimestamp === b.departureTimestamp && a.arrivalTimestamp === b.arrivalTimestamp\n        && getSectionTrainName(a) === getSectionTrainName(b);\n}\n\n/**\n * Loads the compartment in a reservation segment based on the compartment identifier\n * @param segment The reservation segment\n * @param identifier The compartment identifier\n * @return The compartment iff it was found\n */\nexport function getCompartmentById(segment: ReservationSegment, identifier: string): ReservationCompartment | null {\n    return segment.compartments?.find(compartment =>\n        // TODO Do we need more than the externalIdentifier here?\n        isSupportedCompartment(compartment) && compartment.externalIdentifier === identifier\n    ) ?? null;\n}\n\n/**\n * Calculates the surcharge of compartment\n * @param compartment The compartment\n * @param privateVariationCount The number of private compartments\n * @return The surcharge with the given product (which might be zero)\n */\nexport function getCompartmentPrice(compartment: ReservationCompartment, privateVariationCount?: number): number {\n    if (compartment.privateVariations) {\n        return compartment.privateVariations\n            .filter(variation => variation.count === privateVariationCount)\n            .map(variation => variation.surchargePrice || 0)\n            .reduce((a, b) => a + b, 0);\n    } else {\n        return compartment.surchargePrice || 0;\n    }\n}\n\n/**\n * Calculates the total price for a given compartment\n * @param offer The base offer\n * @param compartment The chosen compartment\n * @param priceClass The price class to calculate the price for\n * @return A price or null if the given price class is not available\n */\nexport function getOfferPrice(offer: ApiProduct, compartment: ReservationCompartment | PrivateVariation, priceClass: PriceClass = 'class2'): number | null {\n    const priceClassKey = getPriceClassKey(priceClass);\n\n    let basePrice = offer[priceClassKey];\n    if (basePrice === undefined) {\n        // No base price for the chosen price class: Do no show as offer\n        return null;\n    }\n\n    if (offer.reservation && offer.reservation[priceClassKey]) {\n        // Add the general reservation fee\n        basePrice += offer.reservation[priceClassKey];\n    }\n\n    if (compartment && compartment.surchargePrice) {\n        basePrice += compartment.surchargePrice;\n    }\n\n    return basePrice;\n}\n\nexport function translateCompartmentName(compartment: ReservationCompartment): string {\n    return i18n.getMessage(\n        `ts.reservation.compartment.${compartment.externalIdentifier}`, '', null, compartment.name\n    );\n}\n\n/**\n * Builds the available product options and calculates the prices for a combination of NJ and additional trains\n * @param offer The offer data\n * @param njProduct The NJ product data\n * @param njIndex The section index of the NJ part\n * @param priceClass The requested price class for the product\n * @return The price or null iff the requested options are not available\n */\nexport function buildAdditionalOptions(offer: ApiProduct, njProduct: NjProductData, njIndex: number, priceClass: PriceClass): AdditionalProductOptions | null {\n    const priceClassKey = getPriceClassKey(priceClass);\n\n    let basePrice = offer[priceClassKey];\n    if (basePrice === undefined) {\n        // No base price for the chosen price class: Do not show any offers\n        return null;\n    }\n\n    if (offer.reservation && offer.reservation[priceClassKey]) {\n        // Add the general reservation fee\n        basePrice += offer.reservation[priceClassKey];\n    }\n\n    // We use two prices here: The base price is necessary to calculate the total base on the selected compartments\n    // The minimum price is used for displaying the best price based on the cheapest matching compartments\n    let minPrice = basePrice;\n\n    // Load all reservable segments and group them by journey section index\n    const segments = new Map<number, AdditionalProductSegment>();\n    for (const [segmentIndex, segment] of offer.reservation?.reservationSegments.entries()) {\n        const sectionIndex = segment.scope[0];\n        if (sectionIndex === njIndex) {\n            // We are in the section of the NJ train: Use the previous compartment choice\n            const compartment = getCompartmentById(segment, njProduct.compartment.externalIdentifier);\n            if (!compartment) {\n                // The offer does not contain the chosen NJ compartment, so the user should not book it at all\n                return null;\n            }\n\n            // The price of the NJ compartment must be paid in any case\n            const surcharge = getCompartmentPrice(compartment, njProduct.privateVariationCount);\n            minPrice += surcharge;\n\n            segments.set(sectionIndex, {\n                minSurcharge: surcharge,\n                compartments: [\n                    {\n                        segmentIndex, compartment, surcharge,\n                        privateVariationCount: njProduct.privateVariationCount,\n                        spotLocation: njProduct.spotLocationsSelected[0],\n                    }\n                ],\n            });\n        } else {\n            const compartments = getCompartmentsForClass(segment, priceClass)\n                .sort((a, b) => a.externalIdentifier.localeCompare(b.externalIdentifier))\n                .map(compartment => ({\n                    segmentIndex, compartment,\n                    surcharge: getCompartmentPrice(compartment),\n                    // TODO Choose default private variation count if necessary\n                }));\n\n            if (compartments.length) {\n                const minSurcharge = compartments\n                    .map(compartment => compartment.surcharge)\n                    .reduce((a, b) => Math.min(a, b));\n                minPrice += minSurcharge;\n\n                segments.set(sectionIndex, {minSurcharge, compartments});\n            }\n        }\n    }\n\n    const surcharge = minPrice - njProduct.price;\n    return {offer, priceClass, basePrice, minPrice, surcharge, segments};\n}\n\n/**\n * Builds prebook data for an offer\n * @param finalProduct The NJ and additional product data\n * @return The prebook object with the selected options marked\n */\nexport function buildPrebookData(finalProduct: FinalProductData): PrebookApiProduct {\n    const additionalProduct = finalProduct.additionalProduct;\n\n    // Work on a deep copy of the offer object\n    const result = JSON.parse(JSON.stringify(additionalProduct.offer)) as PrebookApiProduct;\n\n    // Fix the price class name, it differs on different parts of the API :(\n    const selectedClass = additionalProduct.priceClass === 'businessClass' ? 'classBusiness' : additionalProduct.priceClass;\n\n    // Select the requested price class\n    result.selected = selectedClass;\n\n    if (!result.reservation) {\n        // No reservation - nothing else to do (should never happen with NJ)\n        return result;\n    }\n\n    if (selectedClass !== 'noclass') {\n        result.reservation.selected = selectedClass;\n    }\n\n    additionalProduct.compartments.forEach(compartmentData => {\n        const segment = result.reservation.reservationSegments[compartmentData.segmentIndex];\n        const compartment = getCompartmentById(segment, compartmentData.identifier) as PrebookReservationCompartmentV3;\n        if (!compartment) {\n            // This should never happen, only existing compartments can be selected\n            // TODO Do we need to handle this?\n            return;\n        }\n\n        // Mark the compartment itself as selected\n        compartment.selected = true;\n        if (compartment.privateVariations) {\n            // Select the correct private variation\n            compartment.privateVariations\n                .filter(privateVariation => privateVariation.count === compartmentData.privateVariationCount)\n                .forEach(privateVariation => privateVariation.selected = true);\n        } else if (compartment.spotLocations) {\n            // Select spot locations in the compartment\n            compartment.spotLocations\n                .filter(spotLocation => spotLocation.param === compartmentData.spotLocation)\n                .forEach(spotLocation => spotLocation.selected = true);\n        }\n    });\n\n\n    return result;\n}\n\n/**\n * Groups the ticket details by scope from the prebook data\n * @param tickets The ticket data\n * @return A list of ticket details\n */\nexport function groupTicketDetailsByScope(tickets: Ticket[]): TicketsGroupedByScope {\n\n    return tickets.reduce((groupedTickets: TicketsGroupedByScope, ticket: Ticket) => {\n        const scope = ticket.ticketDetails.scopes.flat().join('-');\n        const passengerType = ticket.passenger.type  + (ticket.ticketDetails.isReservation ? '-reservation' : '');\n\n        if (!groupedTickets[scope]) {\n            groupedTickets[scope] = {};\n        }\n\n        if (!groupedTickets[scope][passengerType]) {\n            groupedTickets[scope][passengerType] = createInitialGroup(ticket);\n        } else {\n            updateGroup(groupedTickets[scope][passengerType], ticket);\n        }\n\n        return groupedTickets;\n\n    }, {} );\n}\n\nfunction createInitialGroup(ticket: Ticket) {\n    return {\n        ticketsCount: 1,\n        sum: ticket.ticketDetails.price,\n        ticketDetails: ticket.ticketDetails,\n        passangerType: ticket.passenger.type,\n        passengers: [{\n            passenger: ticket.passenger,\n            passengerIndex: ticket.passengerIndex,\n            ticketPrice: ticket.ticketDetails.price\n        }]\n    };\n}\n\nfunction updateGroup(groupedTicketDetails: GroupedTicketDetails, ticket: Ticket) {\n    if (ticket.ticketDetails.price !== 0) {\n        groupedTicketDetails.ticketsCount++;\n        groupedTicketDetails.sum += ticket.ticketDetails.price;\n    }\n    groupedTicketDetails.passengers.push({\n        passenger: ticket.passenger,\n        passengerIndex: ticket.passengerIndex,\n        ticketPrice: ticket.ticketDetails.price\n    });\n}\n\n/**\n * Loads the ticket details for each passenger from the prebook data\n * @param product The product data with selected flags set\n * @param passengers The passenger data\n * @return A list of ticket details\n */\nexport function getTicketDetailsFromPrebook(product: PrebookApiProduct, passengers: PrebookObjectV4[]): Ticket[] {\n    const result: Ticket[] = []\n\n    const priceClass = product.selected;\n\n    // Add product based prices\n    product.productDetails\n        // Ignore globally priced items, they are included in the reservation price\n        .filter(product => !product.globallyPriced)\n        .forEach(product => product.objects\n            .forEach(passenger => {\n                result.push({\n                    ticketDetails: {\n                        scopes: product.scope,\n                        price: getPriceForClass(passenger, priceClass),\n                        productDetails: product,\n                        productPriceClass: getMatchingPriceClass(passenger, priceClass),\n                        isReservation: false,\n                    },\n                    passenger: passengers[passenger.index],\n                    passengerIndex: passenger.index\n                })\n            })\n        );\n\n    // Add reservation based prices\n    product.reservation?.reservationSegments.forEach(segment =>\n        segment.compartments\n            ?.filter(item => item.selected || item.special)\n            .forEach(compartment => {\n                if (compartment.privateVariations) {\n                    // Find the selected private allocation\n                    const variation = compartment.privateVariations.find(item => item.selected);\n                    if (!variation) {\n                        // TODO This should never happen, should we handle it somehow?\n                        return;\n                    }\n\n                    variation.allocations.forEach(allocation =>\n                        allocation.objects.forEach(object =>\n                            result.push({\n                                ticketDetails: {\n                                    scopes: [segment.scope],\n                                    price: object.price,\n                                    productDetails: getProductDetailsForScope(product, segment.scope, object.index),\n                                    compartment: compartment,\n                                    isReservation: true,\n                                },\n                                passenger: passengers[object.index],\n                                passengerIndex: object.index\n                            })\n                        )\n                    );\n                } else if (compartment.objects) {\n\n                    // Regular reservations\n                    compartment.objects.forEach(object => {\n\t\t\t\t\t\tlet price = object.price;\n\t\t\t\t\t\tif (compartment.freeFollowupReservationApplied === true) {\n\t\t\t\t\t\t\tprice = 0;\n\t\t\t\t\t\t}\n\n                        result.push({\n                            ticketDetails: {\n                                scopes: [segment.scope],\n                                price,\n                                productDetails: getProductDetailsForScope(product, segment.scope, object.index),\n                                compartment: compartment,\n                                isReservation: true,\n                            },\n                            passenger: passengers[object.index],\n                            passengerIndex: object.index\n                        })\n\t\t\t\t\t});\n                } else {\n                    // TODO This should never happen, should we handle it somehow?\n                }\n            })\n    );\n\n    result.sort((a, b) => a.passengerIndex - b.passengerIndex);\n\n    result.sort((a, b) => {\n        if (a.ticketDetails.scopes[0][0] !== b.ticketDetails.scopes[0][0]) {\n            return a.ticketDetails.scopes[0][0] - b.ticketDetails.scopes[0][0];\n        }\n        if (a.ticketDetails.isReservation !== b.ticketDetails.isReservation) {\n            return a.ticketDetails.isReservation ? 1 : -1;\n        }\n        return 0;\n    })\n\n    return result;\n}\n\nfunction getProductDetailsForScope(product: PrebookApiProduct, scope: number[], passengerIndex: number): ProductDetail | null {\n    return product.productDetails.find(item =>\n        // Only consider globally priced tickets\n        item.globallyPriced &&\n        // Only consider products for the requested passenger\n        item.objects.find(object => object.index === passengerIndex) &&\n        // Only consider products in the requested scope\n        item.scope.find(productScope => productScope[0] <= scope[0] && productScope[2] >= scope[2])\n    ) ?? null;\n}\n\nexport interface GroupedTicketDetails {\n    ticketsCount: number,\n    sum: number,\n    ticketDetails: TicketDetails,\n    passangerType: string,\n    passengers: Passenger[];\n}\n\nexport interface TicketsGroupedByScope {\n    [keyScope: string]: {\n        [keyType: string]: GroupedTicketDetails\n    }\n}\n\nexport interface Ticket {\n    passengerIndex: number;\n    passenger: PrebookObjectV4;\n    ticketDetails: TicketDetails;\n}\n\nexport interface Passenger {\n    passengerIndex: number;\n    passenger: PrebookObjectV4;\n    ticketPrice: number;\n}\n\nexport interface TicketDetails {\n    scopes: number[][];\n    price: number;\n    productDetails?: ProductDetail;\n    productPriceClass?: PriceClass;\n    compartment?: ReservationCompartment;\n    isReservation: boolean;\n}\n\nexport interface AdditionalConnectionWithOffers extends ConnectionWithOffersV6 {\n    njIndex: number;\n}\n\nexport interface AdditionalProductOptions {\n    offer: ApiProduct;\n    priceClass: PriceClass;\n    basePrice: number;\n    minPrice: number;\n    surcharge: number;\n    segments: Map<number, AdditionalProductSegment>;\n}\n\nexport interface AdditionalProductSegment {\n    minSurcharge: number;\n    compartments: AdditionalProductCompartment[];\n}\n\nexport interface AdditionalProductCompartment {\n    segmentIndex: number;\n    surcharge: number;\n    privateVariationCount?: number;\n    spotLocation?: string;\n    compartment: ReservationCompartment;\n}\n\nexport function doesPassengerRequireWheelchair(): boolean {\n\tconst passengers = dataStore().getSessionData(DATA_STORE_KEY_PASSENGERS);\n\tfor (const passenger of passengers) {\n\t\tconst accessibilityOptions = passenger.njChallengedOptions;\n\t\tif (accessibilityOptions !== undefined && accessibilityOptions !== null && accessibilityOptions.wheelchair === true) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function hasWheelchairCompartment(compartments: any[]): boolean {\n\treturn compartments.find(compartment => compartment.externalIdentifier === WHEELCHAIR_COUCHETTE_DANI);\n}\n"],"mappings":"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"}