{"version":3,"names":["accordionCss","Accordion","this","updateListener","updateState","getSlottedAccordionHeader","headerElement","slot","querySelector","accordionHeader","assignedElements","find","el","getAttribute","slotToggleIcon","header","existingToggleIcon","hideToggle","iconEl","document","createElement","lazy","classList","add","icon","setAttribute","appendChild","setAria","expanded","root","shadowRoot","button","expandAccordion","initialUpdate","state","contentElement","contentWrapperElement","undefined","currentRaf","cancelAnimationFrame","shouldAnimate","raf","async","contentHeight","offsetHeight","waitForTransition","transitionEndAsync","style","setProperty","removeProperty","collapseAccordion","window","prefersReducedMotion","matchMedia","matches","accordionGroupElement","animated","accordionGroup","accordionValue","value","shouldExpand","Array","isArray","includes","isNext","isPrevious","nextAccordion","getNextSibling","nextAccordionValue","previousAccordion","getPreviousSibling","previousAccordionValue","nextSibling","nextElementSibling","tagName","previousSibling","previousElementSibling","AccordionIds","connectedCallback","closest","addEventListener","disconnectedCallback","removeEventListener","componentDidLoad","toggleExpanded","expand","requestAccordionToggle","render","disabled","headerPart","contentPart","h","Host","class","onClick","id","part","ref","headerEl","name","role","contentEl","contentElWrapper","accordionGroupCss","AccordionGroup","valueChanged","multiple","accordionGroupChange","emit","accordions","getAccordions","accordion","ev","activeElement","accordionEl","closestGroup","startingIndex","findIndex","a","key","findNextAccordion","findPreviousAccordion","length","focus","disabledChanged","accordionExpand","groupValue","processedValue","valueExists","v","filter","prevAccordion","from","querySelectorAll","backdropCss","Backdrop","onMouseDown","emitTap","stopPropagation","preventDefault","tappable","backdropClick","tabindex","visible","AllDaySplitter","Splitter","getKeyInfo","allDay","timed","getKeysForDateSpan","dateSpan","getKeysForEventDef","eventDef","hasBgRendering","DEFAULT_SLAT_LABEL_FORMAT","createFormatter","hour","minute","omitZeroMinute","meridiem","TimeColsAxisCell","props","classNames","isLabeled","ViewContextType","Consumer","context","className","join","isoTimeStr","dateEnv","options","viewApi","labelFormat","slotLabelFormat","renderProps","level","time","date","toDate","view","text","format","ContentContainer","elTag","elClasses","elAttrs","generatorName","customGenerator","slotLabelContent","defaultGenerator","renderInnerContent","classNameGenerator","slotLabelClassNames","didMount","slotLabelDidMount","willUnmount","slotLabelWillUnmount","InnerContent","TimeBodyAxis","BaseComponent","slatMetas","map","slatMeta","Object","assign","DEFAULT_WEEK_NUM_FORMAT","week","AUTO_ALL_DAY_MAX_EVENT_ROWS","TimeColsView","DateComponent","constructor","super","arguments","allDaySplitter","headerElRef","createRef","rootElRef","scrollerElRef","slatCoords","handleScrollTopRequest","scrollTop","scrollerEl","current","renderHeadAxis","rowKey","frameHeight","dateProfile","range","renderRange","dayCnt","diffDays","start","end","navLinkAttrs","buildNavLinkAttrs","weekNumbers","WeekNumberContainer","defaultFormat","height","renderTableRowAxis","rowHeight","allDayText","allDayContent","renderAllDayInner","allDayClassNames","allDayDidMount","allDayWillUnmount","handleSlatCoords","setState","renderSimpleLayout","headerRowContent","timeContent","sections","stickyHeaderDates","getStickyHeaderDates","push","type","isSticky","chunk","elRef","tableClassName","rowContent","content","outerContent","theme","getClass","liquid","expandRows","Boolean","ViewContainer","viewSpec","SimpleScrollGrid","isHeightAuto","forPrint","collapsibleWidth","cols","width","renderHScrollLayout","colCnt","dayMinWidth","ScrollGrid","pluginHooks","scrollGridImpl","Error","stickyFooterScrollbar","getStickyFooterScrollbar","syncRowHeights","chunks","arg","rowSyncHeights","contentArg","colSpan","isNowIndicator","nowIndicator","clientHeight","tableColGroupNode","NowTimer","unit","nowDate","nowIndicatorTop","safeComputeTop","NowIndicatorContainer","elStyle","top","isAxis","renderScrollShim","colGroups","span","minWidth","getAllDayMaxEventProps","dayMaxEvents","dayMaxEventRows","TimeColsSlatsCoords","positions","slotDuration","rangeContainsMarker","currentRange","startOfDayDate","startOfDay","timeMs","valueOf","asRoughMs","slotMinTime","slotMaxTime","computeTimeTop","createDuration","computeDateTop","when","duration","len","els","slatCoverage","milliseconds","slatIndex","slatRemainder","Math","max","min","floor","tops","getHeight","TimeColsSlatsBody","slatElRefs","i","axis","slotLaneContent","slotLaneClassNames","slotLaneDidMount","slotLaneWillUnmount","TimeColsSlats","RefMap","tableMinWidth","clientWidth","minHeight","componentDidMount","updateSizing","componentDidUpdate","componentWillUnmount","onCoords","rootEl","PositionCache","collectSlatEls","currentMap","elMap","splitSegsByCol","segs","segsByCol","col","splitInteractionByCol","ui","byRow","affectedInstances","isEvent","seg","TimeColMoreLink","MoreLinkContainer","bottom","allDayDate","moreCnt","hiddenSegs","allSegs","extraDateSpan","todayRange","popoverContent","renderPlainFgSegs","renderMoreLinkInner","shortText","buildPositioning","segInputs","strictOrder","maxStackCnt","hierarchy","SegHierarchy","hiddenEntries","addSegs","hiddenGroups","groupIntersectingEntries","web","buildWeb","stretchWeb","segRects","webToRects","entriesByLevel","buildNode","cacheable","lateral","siblingRange","findNextLevelSegs","nextLevelRes","buildNodes","entry","nextLevelNodes","thickness","lateralStart","lateralEnd","pairs","sort","cmpDescPressures","extractNode","b","subjectLevel","subjectLateral","levelCoords","subjectEntry","afterSubject","levelCnt","entries","searchIndex","binarySearch","getEntrySpanEnd","topLevelNodes","totalThickness","stretchNode","node","startCoord","prevThickness","buildEntryKey","allThickness","thicknessFraction","endCoord","newChildren","childNode","res","newThickness","rects","processNode","levelCoord","stackDepth","rect","stackForward","processNodes","nodes","keyFunc","workFunc","cache","args","computeSegVCoords","colDate","eventMinHeight","vcoords","spanStart","spanEnd","round","computeFgSegPlacements","segVCoords","eventOrderStrict","eventMaxStack","dumbSegs","index","segPlacements","segRect","dumbSeg","DEFAULT_TIME_FORMAT","TimeColEvent","StandardEvent","isShort","defaultTimeFormat","TimeCol","sortEventSegs","memoize","isSelectMirror","selectMirror","mirrorSegs","eventDrag","eventResize","dateSelectionSegs","interactionAffectedInstances","sortedFgSegs","fgEventSegs","eventOrder","DayCellContainer","extraClassNames","extraDataAttrs","extraRenderProps","renderFillSegs","businessHourSegs","bgEventSegs","renderFgSegs","renderNowIndicator","nowIndicatorSegs","hasCustomDayCellContent","segIsInvisible","isDragging","isResizing","isDateSelecting","renderPositionedFgSegs","eventShortHeight","eventSelection","isMirror","Fragment","renderHiddenGroups","segPlacement","instanceId","eventRange","instance","isVisible","vStyle","computeSegVStyle","hStyle","computeSegHStyle","left","right","isInset","visibility","isSelected","getSegMeta","hiddenGroup","positionCss","compileSegsFromEntries","buildIsoString","computeEarliestSegStart","fillType","children","buildEventRangeKey","BgEvent","renderFill","segHCoords","isRtl","shouldOverlap","slotEventOverlap","nearCoord","farCoord","zIndex","hiddenInstances","segEntries","segEntry","TimeColsContent","splitFgEventSegs","splitBgEventSegs","splitBusinessHourSegs","splitNowIndicatorSegs","splitDateSelectionSegs","splitEventDrag","splitEventResize","cellElRefs","cells","fgEventSegsByRow","bgEventSegsByRow","businessHourSegsByRow","nowIndicatorSegsByRow","dateSelectionSegsByRow","eventDragByRow","eventResizeByRow","cell","updateCoords","onColCoords","collectCellEls","TimeCols","processSlotOptions","handleRootEl","registerInteractiveComponent","isHitComboAllowed","unregisterInteractiveComponent","handleScrollRequest","request","onScrollTopRequest","ceil","handleColCoords","colCoords","onSlatCoords","scrollResponder","createScrollResponder","prevProps","update","detach","queryHit","positionLeft","positionTop","snapDuration","snapsPerSlot","colIndex","leftToIndex","topToIndex","slatTop","slatHeight","partial","localSnapIndex","snapIndex","dayDate","addDurations","multiplyDuration","dayEl","lefts","rights","layer","snapDurationOverride","wholeDivideDurations","DayTimeColsSlicer","Slicer","sliceRange","dayRanges","segRange","intersectRanges","isStart","isEnd","DayTimeCols","buildDayRanges","slicer","timeColsRef","dayTableModel","nextDayThreshold","sliceProps","sliceNowDate","ranges","headerDates","STOCK_SUB_DURATIONS","hours","minutes","seconds","buildSlatMetas","explicitLabelInterval","dayStart","Date","slatTime","slatIterator","labelInterval","computeLabelInterval","metas","toISOString","formatIsoTimeString","slotsPerLabel","DayTimeColsView","buildTimeColsModel","dateProfileGenerator","splitProps","slotLabelInterval","hasAttachedAxis","hasDetachedAxis","headerContent","dayHeaders","DayHeader","dates","datesRepDistinctDays","renderIntro","allDaySlot","DayTable","colGroupNode","renderRowIntro","showWeekNumbers","headerAlignElRef","timeGridContent","daySeries","DaySeriesModel","DayTableModel","OPTION_REFINERS","css_248z","injectStyles","createPlugin","initialView","optionRefiners","views","timeGrid","component","usesMinMaxTime","timeGridDay","days","timeGridWeek","weeks","bookableAvailabilityStylesCss","BookableAvailabilityComponent","client","BookingClient","calendar","refetchEvents","ghostEvent","setGhostEvent","suggestedType","getViewType","changeView","Calendar","calendarRef","locale","plugins","TimeGridPlugin","InteractionPlugin","timeGridWeekMedium","timeGridWeekSmall","scrollTime","scrollTimeReset","headerToolbar","selectable","selectConstraint","editable","eventConstraint","eventDrop","onEdit","bind","select","onSelect","events","getEvents","dayHeaderContent","html","toLocaleDateString","day","weekday","firstDay","successCallback","failureCallback","getCalendarAvailability","page","filters","ReservationRequestFilterDto","then","slots","until","groupId","title","display","color","catch","selection","slotSelectionChange","fromDate","getStartOfDay","untilDate","fromTime","getTimeFromDate","untilTime","event","_a","setProp","conflictsChange","getDateTime","conflicts","getCalendarConflicts","hasConflicts","setDates","addEvent","gotoDate","next","prev","cssClassNames","appearance","BookablesProviderComponent","search","_b","StateStore","categories","_d","_c","detail","getBookables","loading","pageSize","items","excludeCategories","excludeItems","sortType","sortDirection","pagination","__rest","bookables","error","console","log","renderFn","bookingDetailDefaultStylesCss","BookingDetailDefaultComponent","pageId","address","reservationItems","bookerCode","getData","onSlideChange","slidesRef","scrollIntoView","behavior","block","setPage","item","getQueryParam","QueryParamKey","ITEM","token","reservationId","action","createReservation","PublicCreateBookingReservationCommand","e","setFormState","bookableId","bookable","amount","subBookables","settings","Promise","all","getBookable","getSettings","updateAvailability","formState","mergeDeep","some","multiDay","isSameDay","getFullYear","getMonth","getDate","availabilityRef","setEvent","checked","selected","submitReservation","PublicSubmitBookingReservationCommand","fromJS","getTemplate","getBookingFormTemplate","allowTouchMove","slidesPerView","onSubmit","submitBookingRerservation","pager","bookableQuantity","onValueChange","onAmountChange","subBookable","link","targetId","canHaveAmount","onCheckboxChange","ItemLinkProps","htmlFor","required","formatDateForInput","onInput","target","valueAsDate","onMultidayCheckboxChange","onSlotSelectionChange","onConflictsChange","slideNext","placeholder","autoComplete","firstName","lastName","eMail","street","houseNumber","zipCode","city","telephone","PrivacyConfirmationField","formConfirmationHtml","slidePrev","bookingOverviewDefaultStylesCss","BookingOverviewDefaultComponent","onCategoriesChange","coerceNumberArray","onExcludeCategoriesChange","onItemsChange","onExcludeItemsChange","detailId","master","searchLabel","paginationVariant","loadMoreLabel","filteredCategories","moduleType","ModuleType","Booking","src","teaserPictureUrl","truncated","teaserText","Pagination","variant","buttonStylesCss","Button","hasShadowDom","element","form","fakeButton","click","remove","hasIconOnly","href","download","rel","shape","size","TagType","attributes","buttonToggleCss","ButtonToggle","onSelectedChange","coerceBooleanProperty","onDisabledChange","elementId","BUTTON_TOGGLE_ID","emitEvent","change","toggle","buttonToggleGroupCss","ButtonToggleGroup","buttonToggleGroupId","onMultipleChange","setSelection","onButtonToggleChange","indexOf","forEach","deselect","temp","splice","_hiddenInput","invalid","valueChange","createHiddenFormInput","componentWillLoad","isButtonInSelection","categoriesFilterButtonGroupStylesCss","CategoriesFilterButtonGroupComponent","appliedFilterMap","Map","oldValue","categoriesChange","appliedFiltersRef","removeFromAppliedFilters","addToAppliedFilters","onButtonToggleGroupChange","getAppliedFiltersElement","getCategoriesByModuleType","availableCategories","useSubCategories","reduce","acc","curr","subCategories","cat","removeFilter","get","delete","toAdd","addFilter","label","extendedProps","category","onFilterRemove","useCategoryColor","background","showCategoryIcon","iconUrl","set","categoryId","checkboxCss","Checkbox","inputId","checkboxIds","setFocus","indeterminate","onFocus","checkboxFocus","onBlur","checkboxBlur","checkedChanged","isChecked","checkboxChange","focusEl","renderHiddenInput","path","d","interactive","viewBox","clickRangeStylesCss","ClickRangeComponent","increase","step","decrease","resolveTagName","GalleryDisplay","MiniGallery","Gallery","GalleryType","Heading","textAlign","HeadingType","styleMap","Reference","ReferenceTag","toLowerCase","Table","_","BulletList","Paragraph","Video","caption","video","controls","Audio","audio","PanelComponentBuilder","Link","startsWith","MarkTagResolver","MarkType","Bold","Italic","Strike","Subscript","Superscript","Underline","NodeTagResolver","NodeType","HardBreak","HorizontalRule","ListItem","OrderedList","TableHeader","TableRow","TableCell","PanelInfo","PanelTeaser","Vspace","AccordionHeader","AccordionContent","isNodeTagSelfClosing","MarkBuilder","mark","MarkTag","attrs","MarkWrap","marks","ContentNode","data","Text","NodeTag","contentStylesCss","Content","onDocumentChange","Node","JSON","parse","onLightboxOpen","images","startIndex","image","createOverlay","componentProps","contentAccordionStylesCss","ContentAccordionComponent","formFieldStylesCss","FormField","onFocusIn","isFocused","onFocusOut","componentOnReady","nestedInput","validity","dirty","valid","imageCss","Image","onLoad","imgDidLoad","fit","naturalWidth","naturalHeight","_imgRef","ar","currentFit","onError","imgError","onResize","registerIntersectionObserver","onSrcChange","load","IntersectionObserverAvailable","sync","unregisterIntersectionObserver","io","IntersectionObserver","isIntersecting","observe","setTimeout","disconnect","loadError","loadSrc","imgWillLoad","decoding","alt","infoPanelCss","InfoPanel","infoPanelTitleCss","InfoPanelTitle","listStylesCss","ListComponent","listItemStylesCss","ListItemComponent","inheritedAriaAttributes","inheritAriaAttributes","focusable","isFocusable","isClickable","focusableChild","hasStartEl","startEl","clickable","ariaDisabled","inList","hostContext","messageStylesCss","Message","getIconName","iconName","overlayStylesCss","OverlayClasses","overlay","hasBackdrop","cssClass","Overlay","OVERLAY_ID","close","overlayDidDismiss","COUNT","documentElement","containerStyles","maxWidth","maxHeight","OverlayContentComponent","Z_INDEX","onBackdropClick","backdropDismiss","panelStylesCss","Panel","rippleEffectCss","RippleEffect","x","y","resolve","readTask","getBoundingClientRect","hypotenuse","sqrt","maxDim","maxRadius","unbounded","PADDING","initialSize","INITIAL_ORIGIN_SCALE","finalScale","posX","posY","styleX","styleY","moveX","moveY","writeTask","div","container","removeRipple","ripple","debounce","func","wait","timeout","executedFunction","later","clearTimeout","searchStylesCss","Search","debounceFn","inputRef","onClear","appliedFilter","updateFilter","carouselSlideStylesCss","Slide","classesToSelector","classes","trim","replace","swiper","extendParams","on","pfx","bulletElement","hideOnClick","renderBullet","renderProgressbar","renderFraction","renderCustom","progressbarOpposite","dynamicBullets","dynamicMainBullets","formatFractionCurrent","number","formatFractionTotal","bulletClass","bulletActiveClass","modifierClass","currentClass","totalClass","hiddenClass","progressbarFillClass","progressbarOppositeClass","clickableClass","lockClass","horizontalClass","verticalClass","paginationDisabledClass","bullets","bulletSize","dynamicBulletIndex","makeElementsArray","isPaginationDisabled","params","setSideBullets","bulletEl","position","onBulletClick","elementIndex","slidesPerGroup","loop","realIndex","loopedSlides","slides","loopFix","direction","activeSlideIndex","slideTo","slideToLoop","rtl","slidesLength","virtual","enabled","total","snapGrid","activeIndex","firstIndex","lastIndex","midIndex","elementOuterSize","isHorizontal","subEl","previousIndex","suffix","bullet","bulletIndex","firstDisplayedBullet","lastDisplayedBullet","dynamicBulletsLength","bulletsOffset","offsetProp","subElIndex","fractionEl","textContent","totalEl","progressbarDirection","scale","scaleX","scaleY","progressEl","transform","transitionDuration","speed","innerHTML","watchOverflow","isLocked","paginationHTML","numberOfBullets","freeMode","call","init","createElementIfNotDefined","originalParams","isElement","uniqueNavElements","elementParents","destroy","disable","_s","targetEl","contains","navigation","nextEl","prevEl","isHidden","enable","Zoom","getWindow","zoom","maxRatio","minRatio","containerClass","zoomedSlideClass","currentScale","isScaling","fakeGestureTouched","fakeGestureMoved","evCache","gesture","slideEl","slideWidth","slideHeight","imageEl","imageWrapEl","isTouched","isMoved","currentX","currentY","minX","minY","maxX","maxY","startX","startY","touchesStart","touchesCurrent","velocity","prevPositionX","prevPositionY","prevTime","defineProperty","getDistanceBetweenTouches","x1","pageX","y1","pageY","x2","y2","distance","getScaleOrigin","box","getSlideSelector","slideClass","eventWithinSlide","slideSelector","eventWithinZoomContainer","selector","containerEl","onGestureStart","pointerType","scaleStart","originX","originY","transformOrigin","onGestureChange","pointerIndex","cachedEv","pointerId","scaleMove","onGestureEnd","onTouchStart","device","android","cancelable","onTouchMove","allowClick","offsetWidth","getTranslate","scaledWidth","scaledHeight","now","abs","onTouchEnd","momentumDurationX","momentumDurationY","momentumDistanceX","newPositionX","momentumDistanceY","newPositionY","momentumDuration","onTransitionEnd","zoomIn","elementChildren","slidesEl","slideActiveClass","cssMode","wrapperEl","overflow","touchAction","touchX","touchY","offsetX","offsetY","diffX","diffY","translateX","translateY","imageWidth","imageHeight","translateMinX","translateMinY","translateMaxX","translateMaxY","forceZoomRatio","elementOffset","scrollX","scrollY","zoomOut","zoomToggle","getListeners","passiveListener","passiveListeners","passive","capture","activeListenerWithCapture","eventName","animating","in","out","Autoplay","autoplay","running","paused","timeLeft","delay","disableOnInteraction","stopOnLastSlide","reverseDirection","pauseOnMouseEnter","autoplayDelayTotal","autoplayDelayCurrent","autoplayTimeLeft","autoplayStartTime","getTime","wasPaused","pausedByTouch","touchStartTimeout","slideChanged","pausedByInteraction","destroyed","resume","calcTimeLeft","requestAnimationFrame","getSlideDelay","activeSlideEl","currentSlideDelay","parseInt","run","delayForce","Number","isNaN","proceed","isBeginning","rewind","stop","pause","internal","reset","onVisibilityChange","getDocument","visibilityState","onPointerEnter","onPointerLeave","attachMouseEvents","detachMouseEvents","attachDocumentEvents","detachDocumentEvents","effectInit","effect","setTranslate","setTransition","overwriteParams","perspective","recreateShadows","getEffectParams","containerModifierClass","overwriteParamsResult","slideShadows","shadowEl","requireUpdateOnVirtual","effectTarget","effectParams","transformEl","getSlideTransformEl","backfaceVisibility","effectVirtualTransitionEnd","transformElements","allSlides","getSlide","parentElement","slide","parentNode","virtualTranslate","eventTriggered","transitionEndTarget","getSlideIndex","elementTransitionEnd","evt","CustomEvent","bubbles","dispatchEvent","EffectFade","fadeEffect","crossFade","offset","swiperSlideOffset","tx","translate","ty","slideOpacity","progress","opacity","watchSlidesProgress","spaceBetween","carouselStylesCss","SwiperCore","use","Navigation","CarouselComponent","swiperReady","readySwiper","getSwiper","MutationObserver","mut","mutationO","childList","subtree","initSwiper","waitForSlides","updateAutoHeight","runCallbacks","lock","allowSlideNext","allowSlidePrev","finalOptions","normalizeOptions","Swiper","swiperOptions","initialSlide","parallax","centeredSlides","slidesOffsetBefore","slidesOffsetAfter","touchEventsTarget","momentum","momentumRatio","momentumBounce","momentumBounceRatio","momentumVelocityRatio","sticky","minimumVelocity","autoHeight","setWrapperSize","touchRatio","touchAngle","simulateTouch","touchStartPreventDefault","shortSwipes","longSwipes","longSwipesRatio","longSwipesMs","followFinger","threshold","touchMoveStopPropagation","touchReleaseOnEdges","resistance","resistanceRatio","preventClicks","preventClicksPropagation","slideToClickedSlide","noSwiping","runCallbacksOnInit","observer","observeParents","coverflowEffect","rotate","stretch","depth","modifier","flipEffect","limitRotation","cubeEffect","shadow","shadowOffset","shadowScale","a11y","prevSlideMessage","nextSlideMessage","firstSlideMessage","lastSlideMessage","paginationEl","customPaginationElement","customPaginationSelector","renderBulletsWithTitle","scrollbar","scrollbarEl","hide","eventOptions","c7SlidesDidLoad","slideChangeTransitionStart","c7SlideWillChange","slideChangeTransitionEnd","c7SlideDidChange","slideNextTransitionStart","c7SlideNextStart","slidePrevTransitionStart","c7SlidePrevStart","slideNextTransitionEnd","c7SlideNextEnd","slidePrevTransitionEnd","c7SlidePrevEnd","transitionStart","c7SlideTransitionStart","transitionEnd","c7SlideTransitionEnd","sliderMove","c7SlideDrag","reachBeginning","c7SlideReachStart","reachEnd","c7SlideReachEnd","touchStart","c7SlideTouchStart","touchEnd","c7SlideTouchEnd","tap","c7SlideTap","doubleTap","c7SlideDoubleTap","customEvents","mergedEventOptions","s","tileStylesCss","TileComponent","isTargetInteractive","hasFooter","tileBodyStylesCss","TileBody","tileContentStylesCss","TileContentComponent","tileHeaderStylesCss","TileHeaderComponent","tileTitleStylesCss","TileTitleComponent","CACHED_MAP","getIconMap","win","Ionicons","getUrl","url","getSrc","getName","mode","ios","md","getNamedUrl","getAssetPath","toLower","isSrc","isStr","invalidChars","str","test","val","inheritAttributes","attributeObject","attr","hasAttribute","removeAttribute","isRTL","hostEl","dir","validateContent","svgContent","childNodes","nodeName","removeChild","svgElm","firstElementChild","svgClass","isValid","elm","nodeType","isSvgDataUrl","isEncodedDataUrl","ioniconContent","requests","parser","getSvgContent","sanitize","req","fetch","DOMParser","doc","parseFromString","svg","outerHTML","rsp","ok","iconCss","Icon","hostRef","inheritedAttributes","getIonMode","hasAriaHidden","waitUntilVisible","loadIcon","rootMargin","cb","has","ariaLabel","flipRtl","createColorClasses","assetsDirs"],"sources":["./src/components/ui/accordion/accordion.scss?tag=c7-accordion&encapsulation=shadow","./src/components/ui/accordion/accordion.tsx","./src/components/ui/accordion/accordion-group.scss?tag=c7-accordion-group&encapsulation=shadow","./src/components/ui/accordion/accordion-group.tsx","./src/components/utility/backdrop/backdrop.scss?tag=c7-backdrop&encapsulation=shadow","./src/components/utility/backdrop/backdrop.tsx","./node_modules/@fullcalendar/timegrid/internal.js","./node_modules/@fullcalendar/timegrid/index.js","./src/components/booking/utility/bookable-availability/bookable-availability.styles.scss?tag=c7-bookable-availability","./src/components/booking/utility/bookable-availability/bookable-availability.component.tsx","./src/components/booking/utility/bookables-provider/bookables-provider.component.tsx","./src/components/booking/detail/booking-detail-default/booking-detail-default.styles.scss?tag=c7-booking-detail-default","./src/components/booking/detail/booking-detail-default/booking-detail-default.component.tsx","./src/components/booking/overview/booking-overview-default/booking-overview-default.styles.scss?tag=c7-booking-overview-default","./src/components/booking/overview/booking-overview-default/booking-overview-default.component.tsx","./src/components/utility/button/button.styles.scss?tag=c7-button&encapsulation=shadow","./src/components/utility/button/button.tsx","./src/components/ui/controls/button-toggle-group/button-toggle.scss?tag=c7-button-toggle&encapsulation=shadow","./src/components/ui/controls/button-toggle-group/button-toggle.tsx","./src/components/ui/controls/button-toggle-group/button-toggle-group.scss?tag=c7-button-toggle-group&encapsulation=shadow","./src/components/ui/controls/button-toggle-group/button-toggle-group.tsx","./src/components/utility/filters/categories/categories-filter-button-group/categories-filter-button-group.styles.scss?tag=c7-categories-filter-button-group","./src/components/utility/filters/categories/categories-filter-button-group/categories-filter-button-group.component.tsx","./src/components/ui/controls/checkbox/checkbox.scss?tag=c7-checkbox&encapsulation=shadow","./src/components/ui/controls/checkbox/checkbox.tsx","./src/components/ui/controls/click-range/click-range.styles.scss?tag=c7-click-range&encapsulation=shadow","./src/components/ui/controls/click-range/click-range.component.tsx","./src/components/utility/content/gallery/gallery.tsx","./src/components/utility/content/heading/heading.tsx","./src/components/utility/content/reference/reference.tsx","./src/components/utility/content/table/table.tsx","./src/components/utility/content/bullet-list/bullet-list.tsx","./src/components/utility/content/paragraph/paragraph.tsx","./src/components/utility/content/video/video.tsx","./src/components/utility/content/audio/audio.tsx","./src/components/utility/content/panel/panel-builder.tsx","./src/components/utility/content/accordion/accordion.tsx","./src/components/utility/content/link/link.tsx","./src/components/utility/content/content-node.tsx","./src/components/utility/content/content.styles.scss?tag=c7-content","./src/components/utility/content/content.tsx","./src/components/utility/content/accordion/content-accordion.styles.scss?tag=c7-content-accordion","./src/components/utility/content/accordion/content-accordion.component.tsx","./src/components/utility/forms/form-field/form-field.styles.scss?tag=c7-form-field&encapsulation=shadow","./src/components/utility/forms/form-field/form-field.tsx","./src/components/utility/image/image.scss?tag=c7-img&encapsulation=shadow","./src/components/utility/image/image.tsx","./src/components/ui/panel/info-panel.scss?tag=c7-info-panel&encapsulation=shadow","./src/components/ui/panel/info-panel.tsx","./src/components/ui/panel/info-panel-title.scss?tag=c7-info-panel-title&encapsulation=shadow","./src/components/ui/panel/info-panel-title.tsx","./src/components/ui/list/list/list.styles.scss?tag=c7-list","./src/components/ui/list/list/list.component.tsx","./src/components/ui/list/list/list-item.styles.scss?tag=c7-list-item&encapsulation=shadow","./src/components/ui/list/list/list-item.component.tsx","./src/components/ui/message/message.styles.scss?tag=c7-message&encapsulation=shadow","./src/components/ui/message/message.tsx","./src/components/utility/overlay/overlay.styles.scss?tag=c7-overlay","./src/components/utility/overlay/overlay.tsx","./src/components/utility/content/panel/panel.styles.scss?tag=c7-panel","./src/components/utility/content/panel/panel.tsx","./src/components/utility/ripple/ripple-effect.scss?tag=c7-ripple-effect&encapsulation=shadow","./src/components/utility/ripple/ripple-effect.tsx","./src/utils/debounce.ts","./src/components/utility/filters/search/search.styles.scss?tag=c7-search-filter&encapsulation=shadow","./src/components/utility/filters/search/search.tsx","./src/components/ui/carousel/carousel-slide.styles.scss?tag=c7-slide","./src/components/ui/carousel/carousel-slide.component.tsx","./node_modules/swiper/shared/classes-to-selector.js","./node_modules/swiper/modules/pagination/pagination.js","./node_modules/swiper/modules/zoom/zoom.js","./node_modules/swiper/modules/autoplay/autoplay.js","./node_modules/swiper/shared/effect-init.js","./node_modules/swiper/shared/effect-target.js","./node_modules/swiper/shared/effect-virtual-transition-end.js","./node_modules/swiper/modules/effect-fade/effect-fade.js","./src/components/ui/carousel/carousel.styles.scss?tag=c7-slides","./src/components/ui/carousel/carousel.component.tsx","./src/components/ui/list/tile/tile.styles.scss?tag=c7-tile","./src/components/ui/list/tile/tile.component.tsx","./src/components/ui/list/tile/tile-body.styles.scss?tag=c7-tile-body","./src/components/ui/list/tile/tile-body.tsx","./src/components/ui/list/tile/tile-content.styles.scss?tag=c7-tile-content","./src/components/ui/list/tile/tile-content.component.tsx","./src/components/ui/list/tile/tile-header.styles.scss?tag=c7-tile-header","./src/components/ui/list/tile/tile-header.component.tsx","./src/components/ui/list/tile/tile-title.styles.scss?tag=c7-tile-title","./src/components/ui/list/tile/tile-title.component.tsx","./node_modules/ionicons/dist/collection/components/icon/utils.js","./node_modules/ionicons/dist/collection/components/icon/validate.js","./node_modules/ionicons/dist/collection/components/icon/request.js","./node_modules/ionicons/dist/collection/components/icon/icon.css?tag=ion-icon&encapsulation=shadow","./node_modules/ionicons/dist/collection/components/icon/icon.js"],"sourcesContent":["$accordion-background-color: var(--background, transparent) !default;\n$accordion-transition-duration: 300ms !default;\n$accordion-transition-easing: cubic-bezier(0.25, 0.8, 0.5, 1) !default;\n\n$accordion-disabled-opacity: 0.4 !default;\n$accordion-inset-margin: 16px !default;\n\n:host {\n display: block;\n position: relative;\n width: 100%;\n background-color: $accordion-background-color;\n overflow: hidden;\n z-index: 0;\n\n --padding: 0;\n\n}\n\n:host(.accordion-expanding) ::slotted(*[slot=\"header\"]),\n:host(.accordion-expanded) ::slotted(*[slot=\"header\"]) {\n --border-width: 0px;\n}\n\n:host(.accordion-animated) {\n transition: all $accordion-transition-duration $accordion-transition-easing;\n}\n\n:host(.accordion-animated) #content {\n transition: max-height $accordion-transition-duration $accordion-transition-easing;\n}\n\n#content {\n overflow: hidden;\n will-change: max-height;\n}\n\n:host(.accordion-collapsing) #content {\n max-height: 0 !important;\n}\n\n:host(.accordion-collapsed) #content {\n display: none;\n}\n\n:host(.accordion-expanding) #content {\n max-height: 0;\n}\n\n:host(.accordion-disabled) #header,\n:host(.accordion-disabled) #content{\n pointer-events: none;\n}\n\n:host(.accordion-disabled) #header,\n:host(.accordion-disabled) #content {\n opacity: $accordion-disabled-opacity;\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host,\n #content {\n transition: none !important;\n }\n}\n","import { Component, Element, h, Host, Method, Prop, State } from '@stencil/core';\nimport { raf, transitionEndAsync } from '../../../utils/component.utils';\n\nconst enum AccordionState {\n Collapsed = 1 << 0,\n Collapsing = 1 << 1,\n Expanded = 1 << 2,\n Expanding = 1 << 3\n}\n\n@Component({\n tag: 'c7-accordion',\n styleUrl: 'accordion.scss',\n shadow: {\n delegatesFocus: true\n }\n})\nexport class Accordion {\n\n static AccordionIds: number = 0;\n\n private accordionGroupElement?: HTMLC7AccordionGroupElement;\n private updateListener = () => this.updateState(false);\n private headerElement: HTMLDivElement;\n private contentElement: HTMLDivElement;\n private contentWrapperElement: HTMLDivElement;\n private currentRaf: number;\n\n\n @Element() el?: HTMLC7AccordionElement;\n\n @State() state: AccordionState = AccordionState.Collapsed;\n @State() isNext = false;\n @State() isPrevious = false;\n\n\n @Prop() value = `ion-accordion-${Accordion.AccordionIds++}`;\n\n @Prop() disabled = false;\n\n @Prop() hideToggle: boolean;\n\n connectedCallback() {\n const accordionGroupElement = this.accordionGroupElement = this.el && this.el.closest('c7-accordion-group');\n if (accordionGroupElement) {\n this.updateState(true);\n accordionGroupElement.addEventListener('accordionGroupChange', this.updateListener)\n }\n }\n\n disconnectedCallback() {\n const accordionGroupElement = this.accordionGroupElement;\n if (accordionGroupElement) {\n accordionGroupElement.removeEventListener('accordionGroupChange', this.updateListener)\n }\n }\n\n componentDidLoad() {\n this.slotToggleIcon();\n\n raf(() => {\n const expanded = this.state === AccordionState.Expanded || this.state === AccordionState.Expanding;\n this.setAria(expanded);\n });\n }\n\n private getSlottedAccordionHeader = () => {\n\n const {headerElement} = this;\n if (!headerElement) return;\n\n const slot = headerElement.querySelector('slot');\n if (!slot) return;\n\n const accordionHeader = slot.assignedElements && (slot.assignedElements().find((el) => el.getAttribute('slot') === 'header') as HTMLC7AccordionHeaderElement);\n return accordionHeader;\n }\n\n private slotToggleIcon = () => {\n const header = this.getSlottedAccordionHeader();\n if (!header) { return; }\n\n const existingToggleIcon = header.querySelector('.c7-accordion-toggle-icon');\n if (existingToggleIcon || this.hideToggle) { return; }\n\n const iconEl = document.createElement('ion-icon');\n iconEl.slot = 'end';\n iconEl.lazy = false;\n iconEl.classList.add('c7-accordion-toggle-icon');\n iconEl.icon = 'chevron-down-outline';\n iconEl.setAttribute('aria-hidden', 'true');\n\n header.appendChild(iconEl);\n }\n\n private setAria = (expanded = false) => {\n const header = this.getSlottedAccordionHeader();\n if (!header) return;\n\n const root = header.shadowRoot;\n\n const button = root?.querySelector('button');\n\n if (!button) return;\n\n button.setAttribute('aria-expanded', `${expanded}`);\n }\n\n\n private expandAccordion = (initialUpdate = false) => {\n if (initialUpdate) {\n this.state = AccordionState.Expanded;\n return;\n }\n\n if (this.state === AccordionState.Expanded) { return; }\n\n const { contentElement, contentWrapperElement } = this;\n if (contentElement === undefined || contentWrapperElement === undefined) { return; }\n\n if (this.currentRaf !== undefined) {\n cancelAnimationFrame(this.currentRaf);\n }\n\n if (this.shouldAnimate()) {\n raf(() => {\n this.state = AccordionState.Expanding;\n\n this.currentRaf = raf(async () => {\n const contentHeight = contentWrapperElement.offsetHeight;\n const waitForTransition = transitionEndAsync(contentElement, 500);\n contentElement.style.setProperty('max-height', `${contentHeight}px`);\n\n await waitForTransition;\n\n this.state = AccordionState.Expanded;\n contentElement.style.removeProperty('max-height');\n });\n });\n } else {\n this.state = AccordionState.Expanded;\n }\n }\n\n private collapseAccordion = (initialUpdate = false) => {\n if (initialUpdate) {\n this.state = AccordionState.Collapsed;\n return;\n }\n\n if (this.state === AccordionState.Collapsed) { return; }\n\n const { contentElement } = this;\n if (contentElement === undefined) { return; }\n\n if (this.currentRaf !== undefined) {\n cancelAnimationFrame(this.currentRaf);\n }\n\n if (this.shouldAnimate()) {\n this.currentRaf = raf(async () => {\n const contentHeight = contentElement.offsetHeight;\n contentElement.style.setProperty('max-height', `${contentHeight}px`);\n\n raf(async () => {\n const waitForTransition = transitionEndAsync(contentElement, 500);\n\n this.state = AccordionState.Collapsing;\n\n await waitForTransition;\n\n this.state = AccordionState.Collapsed;\n contentElement.style.removeProperty('max-height');\n });\n });\n } else {\n this.state = AccordionState.Collapsed;\n }\n }\n\n private shouldAnimate = () => {\n if (typeof (window as any) === 'undefined') { return false; }\n\n const prefersReducedMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) { return false; }\n if (this.accordionGroupElement && !this.accordionGroupElement.animated) { return false; }\n\n return true;\n }\n\n private updateState = async (initialUpdate = false) => {\n const accordionGroup = this.accordionGroupElement;\n const accordionValue = this.value;\n\n if (!accordionGroup) { return; }\n\n const value = accordionGroup.value;\n\n const shouldExpand = (Array.isArray(value)) ? value.includes(accordionValue) : value === accordionValue;\n\n if (shouldExpand) {\n this.expandAccordion(initialUpdate);\n this.isNext = this.isPrevious = false;\n } else {\n this.collapseAccordion(initialUpdate);\n\n const nextAccordion = this.getNextSibling();\n const nextAccordionValue = nextAccordion && nextAccordion.value;\n\n if (nextAccordionValue !== undefined) {\n this.isPrevious = (Array.isArray(value)) ? value.includes(nextAccordionValue) : value === nextAccordionValue;\n }\n\n const previousAccordion = this.getPreviousSibling();\n const previousAccordionValue = previousAccordion && previousAccordion.value;\n\n if (previousAccordionValue !== undefined) {\n this.isNext = (Array.isArray(value)) ? value.includes(previousAccordionValue) : value === previousAccordionValue;\n }\n }\n }\n\n private getNextSibling = () => {\n if (!this.el) { return; }\n\n const nextSibling = this.el.nextElementSibling;\n\n if (nextSibling?.tagName !== 'C7-ACCORDION') { return; }\n\n return nextSibling as HTMLC7AccordionElement;\n }\n\n private getPreviousSibling = () => {\n if (!this.el) { return; }\n\n const previousSibling = this.el.previousElementSibling;\n\n if (previousSibling?.tagName !== 'C7-ACCORDION') { return; }\n\n return previousSibling as HTMLC7AccordionElement;\n }\n\n @Method()\n toggleExpanded() {\n const { accordionGroupElement, value, state } = this;\n if (accordionGroupElement) {\n const expand = state === AccordionState.Collapsed || state === AccordionState.Collapsing;\n accordionGroupElement.requestAccordionToggle(value, expand);\n }\n }\n\n render() {\n\n const { disabled } = this;\n const expanded = this.state === AccordionState.Expanded || this.state === AccordionState.Expanding;\n const headerPart = expanded ? 'header expanded' : 'header';\n const contentPart = expanded ? 'content expanded' : 'content';\n\n this.setAria(expanded);\n\n return (\n \n this.toggleExpanded()}\n id=\"header\"\n part={headerPart}\n aria-controls=\"content\"\n ref={headerEl => this.headerElement = headerEl}\n >\n \n \n\n this.contentElement = contentEl}\n >\n
this.contentWrapperElement = contentElWrapper}>\n \n
\n \n \n )\n\n }\n\n}\n",":host{\n display: block;\n}\n","import { Component, Host, h, Prop, EventEmitter, Event, Element, Method, Listen, Watch } from '@stencil/core';\n\n@Component({\n tag: 'c7-accordion-group',\n styleUrl: 'accordion-group.scss',\n shadow: true\n})\nexport class AccordionGroup {\n\n @Element() el!: HTMLC7AccordionGroupElement;\n\n @Prop() animated = true;\n\n @Prop() multiple?: boolean;\n\n @Prop({ mutable: true }) value?: string | string[] | null;\n\n @Prop() disabled = false;\n\n @Prop() expand: 'compact' | 'inset' = 'compact';\n\n @Event() accordionGroupChange!: EventEmitter;\n\n @Watch('value')\n valueChanged() {\n const { value, multiple } = this;\n\n if (!multiple && Array.isArray(value)) {\n this.value = value[0];\n } else {\n this.accordionGroupChange.emit({ value: this.value });\n }\n }\n\n @Watch('disabled')\n async disabledChanged() {\n const { disabled } = this;\n const accordions = await this.getAccordions();\n for (const accordion of accordions) {\n accordion.disabled = disabled;\n }\n }\n\n\n @Listen('keydown')\n async onKeydown(ev: KeyboardEvent) {\n const activeElement = document.activeElement;\n if (!activeElement) { return; }\n\n const accordionEl = (activeElement.tagName === 'C7-ACCORDION') ? activeElement : activeElement.closest('c7-accordion');\n if (!accordionEl) { return; }\n\n const closestGroup = accordionEl.closest('c7-accordion-group');\n if (closestGroup !== this.el) { return; }\n\n // If the active accordion is not in the current array of accordions, do not do anything\n const accordions = await this.getAccordions();\n const startingIndex = accordions.findIndex(a => a === accordionEl);\n if (startingIndex === -1) { return; }\n\n let accordion: HTMLC7AccordionElement | undefined;\n if (ev.key === 'ArrowDown') {\n accordion = this.findNextAccordion(accordions, startingIndex);\n } else if (ev.key === 'ArrowUp') {\n accordion = this.findPreviousAccordion(accordions, startingIndex);\n } else if (ev.key === 'Home') {\n accordion = accordions[0];\n } else if (ev.key === 'End') {\n accordion = accordions[accordions.length - 1];\n }\n\n if (accordion !== undefined && accordion !== activeElement) {\n accordion.focus();\n }\n }\n\n async componentDidLoad() {\n if (this.disabled) {\n this.disabledChanged();\n }\n }\n\n\n /**\n * @internal\n */\n @Method()\n async requestAccordionToggle(accordionValue: string | undefined, accordionExpand: boolean) {\n const { multiple, value, disabled } = this;\n if (disabled) { return; }\n\n if (accordionExpand) {\n if (multiple) {\n const groupValue = value || [];\n const processedValue = Array.isArray(groupValue) ? groupValue : [groupValue];\n const valueExists = processedValue.find(v => v === accordionValue);\n if (valueExists === undefined && accordionValue !== undefined) {\n this.value = [...processedValue, accordionValue];\n }\n } else {\n this.value = accordionValue;\n }\n } else {\n if (multiple) {\n const groupValue = value || [];\n const processedValue = Array.isArray(groupValue) ? groupValue : [groupValue];\n this.value = processedValue.filter(v => v !== accordionValue);\n } else {\n this.value = undefined;\n }\n }\n }\n\n private findNextAccordion(accordions: HTMLC7AccordionElement[], startingIndex: number) {\n const nextAccordion = accordions[startingIndex + 1];\n // tslint:disable-next-line:strict-type-predicates\n if (nextAccordion === undefined) {\n return accordions[0];\n }\n\n return nextAccordion;\n }\n\n private findPreviousAccordion(accordions: HTMLC7AccordionElement[], startingIndex: number) {\n const prevAccordion = accordions[startingIndex - 1];\n // tslint:disable-next-line:strict-type-predicates\n if (prevAccordion === undefined) {\n return accordions[accordions.length - 1];\n }\n\n return prevAccordion;\n }\n\n /**\n * @internal\n */\n @Method()\n async getAccordions() {\n return Array.from(this.el.querySelectorAll(':scope > c7-accordion')) as HTMLC7AccordionElement[];\n }\n\n render() {\n\n const { disabled, expand } = this;\n\n return (\n \n \n \n )\n }\n\n}\n",":host{\n display: block;\n position: absolute;\n\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n\n transform: translateZ(0);\n contain: strict;\n cursor: pointer;\n touch-action: none;\n background: var(--c7-backdrop-color, rgba(23, 23, 23, .63));\n backdrop-filter: blur(5px);\n}\n\n:host(.backdrop-hide) {\n background: transparent;\n}\n\n:host(.backdrop-no-tappable) {\n cursor: auto;\n}\n","import { Component, Event, EventEmitter, h, Host, Listen, Prop } from '@stencil/core';\n\n@Component({\n tag: 'c7-backdrop',\n styleUrl: 'backdrop.scss',\n shadow: true\n})\nexport class Backdrop {\n\n @Prop() visible = true;\n\n @Prop() tappable = true;\n\n @Prop() stopPropagation = true;\n\n @Event() backdropClick!: EventEmitter;\n\n @Listen('click')\n protected onMouseDown(ev: TouchEvent) {\n this.emitTap(ev);\n }\n\n private emitTap(ev: Event) {\n if (this.stopPropagation) {\n ev.preventDefault();\n ev.stopPropagation();\n }\n if (this.tappable) {\n this.backdropClick.emit();\n }\n }\n\n render() {\n return (\n \n \n );\n }\n\n}\n","import { Splitter, hasBgRendering, createFormatter, ViewContextType, ContentContainer, BaseComponent, DateComponent, diffDays, buildNavLinkAttrs, WeekNumberContainer, getStickyHeaderDates, ViewContainer, SimpleScrollGrid, getStickyFooterScrollbar, NowTimer, NowIndicatorContainer, renderScrollShim, rangeContainsMarker, startOfDay, asRoughMs, createDuration, RefMap, PositionCache, MoreLinkContainer, SegHierarchy, groupIntersectingEntries, binarySearch, getEntrySpanEnd, buildEntryKey, StandardEvent, memoize, sortEventSegs, DayCellContainer, hasCustomDayCellContent, getSegMeta, buildIsoString, computeEarliestSegStart, buildEventRangeKey, BgEvent, renderFill, addDurations, multiplyDuration, wholeDivideDurations, Slicer, intersectRanges, formatIsoTimeString, DayHeader, DaySeriesModel, DayTableModel } from '@fullcalendar/core/internal';\nimport { createElement, createRef, Fragment } from '@fullcalendar/core/preact';\nimport { DayTable } from '@fullcalendar/daygrid/internal';\n\nclass AllDaySplitter extends Splitter {\n getKeyInfo() {\n return {\n allDay: {},\n timed: {},\n };\n }\n getKeysForDateSpan(dateSpan) {\n if (dateSpan.allDay) {\n return ['allDay'];\n }\n return ['timed'];\n }\n getKeysForEventDef(eventDef) {\n if (!eventDef.allDay) {\n return ['timed'];\n }\n if (hasBgRendering(eventDef)) {\n return ['timed', 'allDay'];\n }\n return ['allDay'];\n }\n}\n\nconst DEFAULT_SLAT_LABEL_FORMAT = createFormatter({\n hour: 'numeric',\n minute: '2-digit',\n omitZeroMinute: true,\n meridiem: 'short',\n});\nfunction TimeColsAxisCell(props) {\n let classNames = [\n 'fc-timegrid-slot',\n 'fc-timegrid-slot-label',\n props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor',\n ];\n return (createElement(ViewContextType.Consumer, null, (context) => {\n if (!props.isLabeled) {\n return (createElement(\"td\", { className: classNames.join(' '), \"data-time\": props.isoTimeStr }));\n }\n let { dateEnv, options, viewApi } = context;\n let labelFormat = // TODO: fully pre-parse\n options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT :\n Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) :\n createFormatter(options.slotLabelFormat);\n let renderProps = {\n level: 0,\n time: props.time,\n date: dateEnv.toDate(props.date),\n view: viewApi,\n text: dateEnv.format(props.date, labelFormat),\n };\n return (createElement(ContentContainer, { elTag: \"td\", elClasses: classNames, elAttrs: {\n 'data-time': props.isoTimeStr,\n }, renderProps: renderProps, generatorName: \"slotLabelContent\", customGenerator: options.slotLabelContent, defaultGenerator: renderInnerContent, classNameGenerator: options.slotLabelClassNames, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, (InnerContent) => (createElement(\"div\", { className: \"fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame\" },\n createElement(InnerContent, { elTag: \"div\", elClasses: [\n 'fc-timegrid-slot-label-cushion',\n 'fc-scrollgrid-shrink-cushion',\n ] })))));\n }));\n}\nfunction renderInnerContent(props) {\n return props.text;\n}\n\nclass TimeBodyAxis extends BaseComponent {\n render() {\n return this.props.slatMetas.map((slatMeta) => (createElement(\"tr\", { key: slatMeta.key },\n createElement(TimeColsAxisCell, Object.assign({}, slatMeta)))));\n }\n}\n\nconst DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: 'short' });\nconst AUTO_ALL_DAY_MAX_EVENT_ROWS = 5;\nclass TimeColsView extends DateComponent {\n constructor() {\n super(...arguments);\n this.allDaySplitter = new AllDaySplitter(); // for use by subclasses\n this.headerElRef = createRef();\n this.rootElRef = createRef();\n this.scrollerElRef = createRef();\n this.state = {\n slatCoords: null,\n };\n this.handleScrollTopRequest = (scrollTop) => {\n let scrollerEl = this.scrollerElRef.current;\n if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer\n scrollerEl.scrollTop = scrollTop;\n }\n };\n /* Header Render Methods\n ------------------------------------------------------------------------------------------------------------------*/\n this.renderHeadAxis = (rowKey, frameHeight = '') => {\n let { options } = this.context;\n let { dateProfile } = this.props;\n let range = dateProfile.renderRange;\n let dayCnt = diffDays(range.start, range.end);\n // only do in day views (to avoid doing in week views that dont need it)\n let navLinkAttrs = (dayCnt === 1)\n ? buildNavLinkAttrs(this.context, range.start, 'week')\n : {};\n if (options.weekNumbers && rowKey === 'day') {\n return (createElement(WeekNumberContainer, { elTag: \"th\", elClasses: [\n 'fc-timegrid-axis',\n 'fc-scrollgrid-shrink',\n ], elAttrs: {\n 'aria-hidden': true,\n }, date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, (InnerContent) => (createElement(\"div\", { className: [\n 'fc-timegrid-axis-frame',\n 'fc-scrollgrid-shrink-frame',\n 'fc-timegrid-axis-frame-liquid',\n ].join(' '), style: { height: frameHeight } },\n createElement(InnerContent, { elTag: \"a\", elClasses: [\n 'fc-timegrid-axis-cushion',\n 'fc-scrollgrid-shrink-cushion',\n 'fc-scrollgrid-sync-inner',\n ], elAttrs: navLinkAttrs })))));\n }\n return (createElement(\"th\", { \"aria-hidden\": true, className: \"fc-timegrid-axis\" },\n createElement(\"div\", { className: \"fc-timegrid-axis-frame\", style: { height: frameHeight } })));\n };\n /* Table Component Render Methods\n ------------------------------------------------------------------------------------------------------------------*/\n // only a one-way height sync. we don't send the axis inner-content height to the DayGrid,\n // but DayGrid still needs to have classNames on inner elements in order to measure.\n this.renderTableRowAxis = (rowHeight) => {\n let { options, viewApi } = this.context;\n let renderProps = {\n text: options.allDayText,\n view: viewApi,\n };\n return (\n // TODO: make reusable hook. used in list view too\n createElement(ContentContainer, { elTag: \"td\", elClasses: [\n 'fc-timegrid-axis',\n 'fc-scrollgrid-shrink',\n ], elAttrs: {\n 'aria-hidden': true,\n }, renderProps: renderProps, generatorName: \"allDayContent\", customGenerator: options.allDayContent, defaultGenerator: renderAllDayInner, classNameGenerator: options.allDayClassNames, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, (InnerContent) => (createElement(\"div\", { className: [\n 'fc-timegrid-axis-frame',\n 'fc-scrollgrid-shrink-frame',\n rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : '',\n ].join(' '), style: { height: rowHeight } },\n createElement(InnerContent, { elTag: \"span\", elClasses: [\n 'fc-timegrid-axis-cushion',\n 'fc-scrollgrid-shrink-cushion',\n 'fc-scrollgrid-sync-inner',\n ] })))));\n };\n this.handleSlatCoords = (slatCoords) => {\n this.setState({ slatCoords });\n };\n }\n // rendering\n // ----------------------------------------------------------------------------------------------------\n renderSimpleLayout(headerRowContent, allDayContent, timeContent) {\n let { context, props } = this;\n let sections = [];\n let stickyHeaderDates = getStickyHeaderDates(context.options);\n if (headerRowContent) {\n sections.push({\n type: 'header',\n key: 'header',\n isSticky: stickyHeaderDates,\n chunk: {\n elRef: this.headerElRef,\n tableClassName: 'fc-col-header',\n rowContent: headerRowContent,\n },\n });\n }\n if (allDayContent) {\n sections.push({\n type: 'body',\n key: 'all-day',\n chunk: { content: allDayContent },\n });\n sections.push({\n type: 'body',\n key: 'all-day-divider',\n outerContent: ( // TODO: rename to cellContent so don't need to define ?\n createElement(\"tr\", { role: \"presentation\", className: \"fc-scrollgrid-section\" },\n createElement(\"td\", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),\n });\n }\n sections.push({\n type: 'body',\n key: 'body',\n liquid: true,\n expandRows: Boolean(context.options.expandRows),\n chunk: {\n scrollerElRef: this.scrollerElRef,\n content: timeContent,\n },\n });\n return (createElement(ViewContainer, { elRef: this.rootElRef, elClasses: ['fc-timegrid'], viewSpec: context.viewSpec },\n createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: 'shrink' }], sections: sections })));\n }\n renderHScrollLayout(headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) {\n let ScrollGrid = this.context.pluginHooks.scrollGridImpl;\n if (!ScrollGrid) {\n throw new Error('No ScrollGrid implementation');\n }\n let { context, props } = this;\n let stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options);\n let stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options);\n let sections = [];\n if (headerRowContent) {\n sections.push({\n type: 'header',\n key: 'header',\n isSticky: stickyHeaderDates,\n syncRowHeights: true,\n chunks: [\n {\n key: 'axis',\n rowContent: (arg) => (createElement(\"tr\", { role: \"presentation\" }, this.renderHeadAxis('day', arg.rowSyncHeights[0]))),\n },\n {\n key: 'cols',\n elRef: this.headerElRef,\n tableClassName: 'fc-col-header',\n rowContent: headerRowContent,\n },\n ],\n });\n }\n if (allDayContent) {\n sections.push({\n type: 'body',\n key: 'all-day',\n syncRowHeights: true,\n chunks: [\n {\n key: 'axis',\n rowContent: (contentArg) => (createElement(\"tr\", { role: \"presentation\" }, this.renderTableRowAxis(contentArg.rowSyncHeights[0]))),\n },\n {\n key: 'cols',\n content: allDayContent,\n },\n ],\n });\n sections.push({\n key: 'all-day-divider',\n type: 'body',\n outerContent: ( // TODO: rename to cellContent so don't need to define ?\n createElement(\"tr\", { role: \"presentation\", className: \"fc-scrollgrid-section\" },\n createElement(\"td\", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),\n });\n }\n let isNowIndicator = context.options.nowIndicator;\n sections.push({\n type: 'body',\n key: 'body',\n liquid: true,\n expandRows: Boolean(context.options.expandRows),\n chunks: [\n {\n key: 'axis',\n content: (arg) => (\n // TODO: make this now-indicator arrow more DRY with TimeColsContent\n createElement(\"div\", { className: \"fc-timegrid-axis-chunk\" },\n createElement(\"table\", { \"aria-hidden\": true, style: { height: arg.expandRows ? arg.clientHeight : '' } },\n arg.tableColGroupNode,\n createElement(\"tbody\", null,\n createElement(TimeBodyAxis, { slatMetas: slatMetas }))),\n createElement(\"div\", { className: \"fc-timegrid-now-indicator-container\" },\n createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, (nowDate) => {\n let nowIndicatorTop = isNowIndicator &&\n slatCoords &&\n slatCoords.safeComputeTop(nowDate); // might return void\n if (typeof nowIndicatorTop === 'number') {\n return (createElement(NowIndicatorContainer, { elClasses: ['fc-timegrid-now-indicator-arrow'], elStyle: { top: nowIndicatorTop }, isAxis: true, date: nowDate }));\n }\n return null;\n })))),\n },\n {\n key: 'cols',\n scrollerElRef: this.scrollerElRef,\n content: timeContent,\n },\n ],\n });\n if (stickyFooterScrollbar) {\n sections.push({\n key: 'footer',\n type: 'footer',\n isSticky: true,\n chunks: [\n {\n key: 'axis',\n content: renderScrollShim,\n },\n {\n key: 'cols',\n content: renderScrollShim,\n },\n ],\n });\n }\n return (createElement(ViewContainer, { elRef: this.rootElRef, elClasses: ['fc-timegrid'], viewSpec: context.viewSpec },\n createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: false, colGroups: [\n { width: 'shrink', cols: [{ width: 'shrink' }] },\n { cols: [{ span: colCnt, minWidth: dayMinWidth }] },\n ], sections: sections })));\n }\n /* Dimensions\n ------------------------------------------------------------------------------------------------------------------*/\n getAllDayMaxEventProps() {\n let { dayMaxEvents, dayMaxEventRows } = this.context.options;\n if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto?\n dayMaxEvents = undefined;\n dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure \"auto\" goes to a real number\n }\n return { dayMaxEvents, dayMaxEventRows };\n }\n}\nfunction renderAllDayInner(renderProps) {\n return renderProps.text;\n}\n\nclass TimeColsSlatsCoords {\n constructor(positions, dateProfile, slotDuration) {\n this.positions = positions;\n this.dateProfile = dateProfile;\n this.slotDuration = slotDuration;\n }\n safeComputeTop(date) {\n let { dateProfile } = this;\n if (rangeContainsMarker(dateProfile.currentRange, date)) {\n let startOfDayDate = startOfDay(date);\n let timeMs = date.valueOf() - startOfDayDate.valueOf();\n if (timeMs >= asRoughMs(dateProfile.slotMinTime) &&\n timeMs < asRoughMs(dateProfile.slotMaxTime)) {\n return this.computeTimeTop(createDuration(timeMs));\n }\n }\n return null;\n }\n // Computes the top coordinate, relative to the bounds of the grid, of the given date.\n // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.\n computeDateTop(when, startOfDayDate) {\n if (!startOfDayDate) {\n startOfDayDate = startOfDay(when);\n }\n return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf()));\n }\n // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).\n // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform.\n // Eventually allow computation with arbirary slat dates.\n computeTimeTop(duration) {\n let { positions, dateProfile } = this;\n let len = positions.els.length;\n // floating-point value of # of slots covered\n let slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration);\n let slatIndex;\n let slatRemainder;\n // compute a floating-point number for how many slats should be progressed through.\n // from 0 to number of slats (inclusive)\n // constrained because slotMinTime/slotMaxTime might be customized.\n slatCoverage = Math.max(0, slatCoverage);\n slatCoverage = Math.min(len, slatCoverage);\n // an integer index of the furthest whole slat\n // from 0 to number slats (*exclusive*, so len-1)\n slatIndex = Math.floor(slatCoverage);\n slatIndex = Math.min(slatIndex, len - 1);\n // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.\n // could be 1.0 if slatCoverage is covering *all* the slots\n slatRemainder = slatCoverage - slatIndex;\n return positions.tops[slatIndex] +\n positions.getHeight(slatIndex) * slatRemainder;\n }\n}\n\nclass TimeColsSlatsBody extends BaseComponent {\n render() {\n let { props, context } = this;\n let { options } = context;\n let { slatElRefs } = props;\n return (createElement(\"tbody\", null, props.slatMetas.map((slatMeta, i) => {\n let renderProps = {\n time: slatMeta.time,\n date: context.dateEnv.toDate(slatMeta.date),\n view: context.viewApi,\n };\n return (createElement(\"tr\", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) },\n props.axis && (createElement(TimeColsAxisCell, Object.assign({}, slatMeta))),\n createElement(ContentContainer, { elTag: \"td\", elClasses: [\n 'fc-timegrid-slot',\n 'fc-timegrid-slot-lane',\n !slatMeta.isLabeled && 'fc-timegrid-slot-minor',\n ], elAttrs: {\n 'data-time': slatMeta.isoTimeStr,\n }, renderProps: renderProps, generatorName: \"slotLaneContent\", customGenerator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount })));\n })));\n }\n}\n\n/*\nfor the horizontal \"slats\" that run width-wise. Has a time axis on a side. Depends on RTL.\n*/\nclass TimeColsSlats extends BaseComponent {\n constructor() {\n super(...arguments);\n this.rootElRef = createRef();\n this.slatElRefs = new RefMap();\n }\n render() {\n let { props, context } = this;\n return (createElement(\"div\", { ref: this.rootElRef, className: \"fc-timegrid-slots\" },\n createElement(\"table\", { \"aria-hidden\": true, className: context.theme.getClass('table'), style: {\n minWidth: props.tableMinWidth,\n width: props.clientWidth,\n height: props.minHeight,\n } },\n props.tableColGroupNode /* relies on there only being a single for the axis */,\n createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas }))));\n }\n componentDidMount() {\n this.updateSizing();\n }\n componentDidUpdate() {\n this.updateSizing();\n }\n componentWillUnmount() {\n if (this.props.onCoords) {\n this.props.onCoords(null);\n }\n }\n updateSizing() {\n let { context, props } = this;\n if (props.onCoords &&\n props.clientWidth !== null // means sizing has stabilized\n ) {\n let rootEl = this.rootElRef.current;\n if (rootEl.offsetHeight) { // not hidden by css\n props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration));\n }\n }\n }\n}\nfunction collectSlatEls(elMap, slatMetas) {\n return slatMetas.map((slatMeta) => elMap[slatMeta.key]);\n}\n\nfunction splitSegsByCol(segs, colCnt) {\n let segsByCol = [];\n let i;\n for (i = 0; i < colCnt; i += 1) {\n segsByCol.push([]);\n }\n if (segs) {\n for (i = 0; i < segs.length; i += 1) {\n segsByCol[segs[i].col].push(segs[i]);\n }\n }\n return segsByCol;\n}\nfunction splitInteractionByCol(ui, colCnt) {\n let byRow = [];\n if (!ui) {\n for (let i = 0; i < colCnt; i += 1) {\n byRow[i] = null;\n }\n }\n else {\n for (let i = 0; i < colCnt; i += 1) {\n byRow[i] = {\n affectedInstances: ui.affectedInstances,\n isEvent: ui.isEvent,\n segs: [],\n };\n }\n for (let seg of ui.segs) {\n byRow[seg.col].segs.push(seg);\n }\n }\n return byRow;\n}\n\nclass TimeColMoreLink extends BaseComponent {\n render() {\n let { props } = this;\n return (createElement(MoreLinkContainer, { elClasses: ['fc-timegrid-more-link'], elStyle: {\n top: props.top,\n bottom: props.bottom,\n }, allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, todayRange: props.todayRange, popoverContent: () => renderPlainFgSegs(props.hiddenSegs, props), defaultGenerator: renderMoreLinkInner }, (InnerContent) => (createElement(InnerContent, { elTag: \"div\", elClasses: ['fc-timegrid-more-link-inner', 'fc-sticky'] }))));\n }\n}\nfunction renderMoreLinkInner(props) {\n return props.shortText;\n}\n\n// segInputs assumed sorted\nfunction buildPositioning(segInputs, strictOrder, maxStackCnt) {\n let hierarchy = new SegHierarchy();\n if (strictOrder != null) {\n hierarchy.strictOrder = strictOrder;\n }\n if (maxStackCnt != null) {\n hierarchy.maxStackCnt = maxStackCnt;\n }\n let hiddenEntries = hierarchy.addSegs(segInputs);\n let hiddenGroups = groupIntersectingEntries(hiddenEntries);\n let web = buildWeb(hierarchy);\n web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0\n let segRects = webToRects(web);\n return { segRects, hiddenGroups };\n}\nfunction buildWeb(hierarchy) {\n const { entriesByLevel } = hierarchy;\n const buildNode = cacheable((level, lateral) => level + ':' + lateral, (level, lateral) => {\n let siblingRange = findNextLevelSegs(hierarchy, level, lateral);\n let nextLevelRes = buildNodes(siblingRange, buildNode);\n let entry = entriesByLevel[level][lateral];\n return [\n Object.assign(Object.assign({}, entry), { nextLevelNodes: nextLevelRes[0] }),\n entry.thickness + nextLevelRes[1], // the pressure builds\n ];\n });\n return buildNodes(entriesByLevel.length\n ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length }\n : null, buildNode)[0];\n}\nfunction buildNodes(siblingRange, buildNode) {\n if (!siblingRange) {\n return [[], 0];\n }\n let { level, lateralStart, lateralEnd } = siblingRange;\n let lateral = lateralStart;\n let pairs = [];\n while (lateral < lateralEnd) {\n pairs.push(buildNode(level, lateral));\n lateral += 1;\n }\n pairs.sort(cmpDescPressures);\n return [\n pairs.map(extractNode),\n pairs[0][1], // first item's pressure\n ];\n}\nfunction cmpDescPressures(a, b) {\n return b[1] - a[1];\n}\nfunction extractNode(a) {\n return a[0];\n}\nfunction findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) {\n let { levelCoords, entriesByLevel } = hierarchy;\n let subjectEntry = entriesByLevel[subjectLevel][subjectLateral];\n let afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness;\n let levelCnt = levelCoords.length;\n let level = subjectLevel;\n // skip past levels that are too high up\n for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1)\n ; // do nothing\n for (; level < levelCnt; level += 1) {\n let entries = entriesByLevel[level];\n let entry;\n let searchIndex = binarySearch(entries, subjectEntry.span.start, getEntrySpanEnd);\n let lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one\n let lateralEnd = lateralStart;\n while ( // loop through entries that horizontally intersect\n (entry = entries[lateralEnd]) && // but not past the whole seg list\n entry.span.start < subjectEntry.span.end) {\n lateralEnd += 1;\n }\n if (lateralStart < lateralEnd) {\n return { level, lateralStart, lateralEnd };\n }\n }\n return null;\n}\nfunction stretchWeb(topLevelNodes, totalThickness) {\n const stretchNode = cacheable((node, startCoord, prevThickness) => buildEntryKey(node), (node, startCoord, prevThickness) => {\n let { nextLevelNodes, thickness } = node;\n let allThickness = thickness + prevThickness;\n let thicknessFraction = thickness / allThickness;\n let endCoord;\n let newChildren = [];\n if (!nextLevelNodes.length) {\n endCoord = totalThickness;\n }\n else {\n for (let childNode of nextLevelNodes) {\n if (endCoord === undefined) {\n let res = stretchNode(childNode, startCoord, allThickness);\n endCoord = res[0];\n newChildren.push(res[1]);\n }\n else {\n let res = stretchNode(childNode, endCoord, 0);\n newChildren.push(res[1]);\n }\n }\n }\n let newThickness = (endCoord - startCoord) * thicknessFraction;\n return [endCoord - newThickness, Object.assign(Object.assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })];\n });\n return topLevelNodes.map((node) => stretchNode(node, 0, 0)[1]);\n}\n// not sorted in any particular order\nfunction webToRects(topLevelNodes) {\n let rects = [];\n const processNode = cacheable((node, levelCoord, stackDepth) => buildEntryKey(node), (node, levelCoord, stackDepth) => {\n let rect = Object.assign(Object.assign({}, node), { levelCoord,\n stackDepth, stackForward: 0 });\n rects.push(rect);\n return (rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1);\n });\n function processNodes(nodes, levelCoord, stackDepth) {\n let stackForward = 0;\n for (let node of nodes) {\n stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward);\n }\n return stackForward;\n }\n processNodes(topLevelNodes, 0, 0);\n return rects; // TODO: sort rects by levelCoord to be consistent with toRects?\n}\n// TODO: move to general util\nfunction cacheable(keyFunc, workFunc) {\n const cache = {};\n return (...args) => {\n let key = keyFunc(...args);\n return (key in cache)\n ? cache[key]\n : (cache[key] = workFunc(...args));\n };\n}\n\nfunction computeSegVCoords(segs, colDate, slatCoords = null, eventMinHeight = 0) {\n let vcoords = [];\n if (slatCoords) {\n for (let i = 0; i < segs.length; i += 1) {\n let seg = segs[i];\n let spanStart = slatCoords.computeDateTop(seg.start, colDate);\n let spanEnd = Math.max(spanStart + (eventMinHeight || 0), // :(\n slatCoords.computeDateTop(seg.end, colDate));\n vcoords.push({\n start: Math.round(spanStart),\n end: Math.round(spanEnd), //\n });\n }\n }\n return vcoords;\n}\nfunction computeFgSegPlacements(segs, segVCoords, // might not have for every seg\neventOrderStrict, eventMaxStack) {\n let segInputs = [];\n let dumbSegs = []; // segs without coords\n for (let i = 0; i < segs.length; i += 1) {\n let vcoords = segVCoords[i];\n if (vcoords) {\n segInputs.push({\n index: i,\n thickness: 1,\n span: vcoords,\n });\n }\n else {\n dumbSegs.push(segs[i]);\n }\n }\n let { segRects, hiddenGroups } = buildPositioning(segInputs, eventOrderStrict, eventMaxStack);\n let segPlacements = [];\n for (let segRect of segRects) {\n segPlacements.push({\n seg: segs[segRect.index],\n rect: segRect,\n });\n }\n for (let dumbSeg of dumbSegs) {\n segPlacements.push({ seg: dumbSeg, rect: null });\n }\n return { segPlacements, hiddenGroups };\n}\n\nconst DEFAULT_TIME_FORMAT = createFormatter({\n hour: 'numeric',\n minute: '2-digit',\n meridiem: false,\n});\nclass TimeColEvent extends BaseComponent {\n render() {\n return (createElement(StandardEvent, Object.assign({}, this.props, { elClasses: [\n 'fc-timegrid-event',\n 'fc-v-event',\n this.props.isShort && 'fc-timegrid-event-short',\n ], defaultTimeFormat: DEFAULT_TIME_FORMAT })));\n }\n}\n\nclass TimeCol extends BaseComponent {\n constructor() {\n super(...arguments);\n this.sortEventSegs = memoize(sortEventSegs);\n }\n // TODO: memoize event-placement?\n render() {\n let { props, context } = this;\n let { options } = context;\n let isSelectMirror = options.selectMirror;\n let mirrorSegs = // yuck\n (props.eventDrag && props.eventDrag.segs) ||\n (props.eventResize && props.eventResize.segs) ||\n (isSelectMirror && props.dateSelectionSegs) ||\n [];\n let interactionAffectedInstances = // TODO: messy way to compute this\n (props.eventDrag && props.eventDrag.affectedInstances) ||\n (props.eventResize && props.eventResize.affectedInstances) ||\n {};\n let sortedFgSegs = this.sortEventSegs(props.fgEventSegs, options.eventOrder);\n return (createElement(DayCellContainer, { elTag: \"td\", elRef: props.elRef, elClasses: [\n 'fc-timegrid-col',\n ...(props.extraClassNames || []),\n ], elAttrs: Object.assign({ role: 'gridcell' }, props.extraDataAttrs), date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraRenderProps: props.extraRenderProps }, (InnerContent) => (createElement(\"div\", { className: \"fc-timegrid-col-frame\" },\n createElement(\"div\", { className: \"fc-timegrid-col-bg\" },\n this.renderFillSegs(props.businessHourSegs, 'non-business'),\n this.renderFillSegs(props.bgEventSegs, 'bg-event'),\n this.renderFillSegs(props.dateSelectionSegs, 'highlight')),\n createElement(\"div\", { className: \"fc-timegrid-col-events\" }, this.renderFgSegs(sortedFgSegs, interactionAffectedInstances, false, false, false)),\n createElement(\"div\", { className: \"fc-timegrid-col-events\" }, this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))),\n createElement(\"div\", { className: \"fc-timegrid-now-indicator-container\" }, this.renderNowIndicator(props.nowIndicatorSegs)),\n hasCustomDayCellContent(options) && (createElement(InnerContent, { elTag: \"div\", elClasses: ['fc-timegrid-col-misc'] }))))));\n }\n renderFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting) {\n let { props } = this;\n if (props.forPrint) {\n return renderPlainFgSegs(sortedFgSegs, props);\n }\n return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting);\n }\n renderPositionedFgSegs(segs, // if not mirror, needs to be sorted\n segIsInvisible, isDragging, isResizing, isDateSelecting) {\n let { eventMaxStack, eventShortHeight, eventOrderStrict, eventMinHeight } = this.context.options;\n let { date, slatCoords, eventSelection, todayRange, nowDate } = this.props;\n let isMirror = isDragging || isResizing || isDateSelecting;\n let segVCoords = computeSegVCoords(segs, date, slatCoords, eventMinHeight);\n let { segPlacements, hiddenGroups } = computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack);\n return (createElement(Fragment, null,\n this.renderHiddenGroups(hiddenGroups, segs),\n segPlacements.map((segPlacement) => {\n let { seg, rect } = segPlacement;\n let instanceId = seg.eventRange.instance.instanceId;\n let isVisible = isMirror || Boolean(!segIsInvisible[instanceId] && rect);\n let vStyle = computeSegVStyle(rect && rect.span);\n let hStyle = (!isMirror && rect) ? this.computeSegHStyle(rect) : { left: 0, right: 0 };\n let isInset = Boolean(rect) && rect.stackForward > 0;\n let isShort = Boolean(rect) && (rect.span.end - rect.span.start) < eventShortHeight; // look at other places for this problem\n return (createElement(\"div\", { className: 'fc-timegrid-event-harness' +\n (isInset ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: Object.assign(Object.assign({ visibility: isVisible ? '' : 'hidden' }, vStyle), hStyle) },\n createElement(TimeColEvent, Object.assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, isShort: isShort }, getSegMeta(seg, todayRange, nowDate)))));\n })));\n }\n // will already have eventMinHeight applied because segInputs already had it\n renderHiddenGroups(hiddenGroups, segs) {\n let { extraDateSpan, dateProfile, todayRange, nowDate, eventSelection, eventDrag, eventResize } = this.props;\n return (createElement(Fragment, null, hiddenGroups.map((hiddenGroup) => {\n let positionCss = computeSegVStyle(hiddenGroup.span);\n let hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs);\n return (createElement(TimeColMoreLink, { key: buildIsoString(computeEarliestSegStart(hiddenSegs)), hiddenSegs: hiddenSegs, top: positionCss.top, bottom: positionCss.bottom, extraDateSpan: extraDateSpan, dateProfile: dateProfile, todayRange: todayRange, nowDate: nowDate, eventSelection: eventSelection, eventDrag: eventDrag, eventResize: eventResize }));\n })));\n }\n renderFillSegs(segs, fillType) {\n let { props, context } = this;\n let segVCoords = computeSegVCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight); // don't assume all populated\n let children = segVCoords.map((vcoords, i) => {\n let seg = segs[i];\n return (createElement(\"div\", { key: buildEventRangeKey(seg.eventRange), className: \"fc-timegrid-bg-harness\", style: computeSegVStyle(vcoords) }, fillType === 'bg-event' ?\n createElement(BgEvent, Object.assign({ seg: seg }, getSegMeta(seg, props.todayRange, props.nowDate))) :\n renderFill(fillType)));\n });\n return createElement(Fragment, null, children);\n }\n renderNowIndicator(segs) {\n let { slatCoords, date } = this.props;\n if (!slatCoords) {\n return null;\n }\n return segs.map((seg, i) => (createElement(NowIndicatorContainer\n // key doesn't matter. will only ever be one\n , { \n // key doesn't matter. will only ever be one\n key: i, elClasses: ['fc-timegrid-now-indicator-line'], elStyle: {\n top: slatCoords.computeDateTop(seg.start, date),\n }, isAxis: false, date: date })));\n }\n computeSegHStyle(segHCoords) {\n let { isRtl, options } = this.context;\n let shouldOverlap = options.slotEventOverlap;\n let nearCoord = segHCoords.levelCoord; // the left side if LTR. the right side if RTL. floating-point\n let farCoord = segHCoords.levelCoord + segHCoords.thickness; // the right side if LTR. the left side if RTL. floating-point\n let left; // amount of space from left edge, a fraction of the total width\n let right; // amount of space from right edge, a fraction of the total width\n if (shouldOverlap) {\n // double the width, but don't go beyond the maximum forward coordinate (1.0)\n farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2);\n }\n if (isRtl) {\n left = 1 - farCoord;\n right = nearCoord;\n }\n else {\n left = nearCoord;\n right = 1 - farCoord;\n }\n let props = {\n zIndex: segHCoords.stackDepth + 1,\n left: left * 100 + '%',\n right: right * 100 + '%',\n };\n if (shouldOverlap && !segHCoords.stackForward) {\n // add padding to the edge so that forward stacked events don't cover the resizer's icon\n props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width\n }\n return props;\n }\n}\nfunction renderPlainFgSegs(sortedFgSegs, { todayRange, nowDate, eventSelection, eventDrag, eventResize }) {\n let hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) ||\n (eventResize ? eventResize.affectedInstances : null) ||\n {};\n return (createElement(Fragment, null, sortedFgSegs.map((seg) => {\n let instanceId = seg.eventRange.instance.instanceId;\n return (createElement(\"div\", { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? 'hidden' : '' } },\n createElement(TimeColEvent, Object.assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, getSegMeta(seg, todayRange, nowDate)))));\n })));\n}\nfunction computeSegVStyle(segVCoords) {\n if (!segVCoords) {\n return { top: '', bottom: '' };\n }\n return {\n top: segVCoords.start,\n bottom: -segVCoords.end,\n };\n}\nfunction compileSegsFromEntries(segEntries, allSegs) {\n return segEntries.map((segEntry) => allSegs[segEntry.index]);\n}\n\nclass TimeColsContent extends BaseComponent {\n constructor() {\n super(...arguments);\n this.splitFgEventSegs = memoize(splitSegsByCol);\n this.splitBgEventSegs = memoize(splitSegsByCol);\n this.splitBusinessHourSegs = memoize(splitSegsByCol);\n this.splitNowIndicatorSegs = memoize(splitSegsByCol);\n this.splitDateSelectionSegs = memoize(splitSegsByCol);\n this.splitEventDrag = memoize(splitInteractionByCol);\n this.splitEventResize = memoize(splitInteractionByCol);\n this.rootElRef = createRef();\n this.cellElRefs = new RefMap();\n }\n render() {\n let { props, context } = this;\n let nowIndicatorTop = context.options.nowIndicator &&\n props.slatCoords &&\n props.slatCoords.safeComputeTop(props.nowDate); // might return void\n let colCnt = props.cells.length;\n let fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt);\n let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt);\n let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt);\n let nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt);\n let dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt);\n let eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt);\n let eventResizeByRow = this.splitEventResize(props.eventResize, colCnt);\n return (createElement(\"div\", { className: \"fc-timegrid-cols\", ref: this.rootElRef },\n createElement(\"table\", { role: \"presentation\", style: {\n minWidth: props.tableMinWidth,\n width: props.clientWidth,\n } },\n props.tableColGroupNode,\n createElement(\"tbody\", { role: \"presentation\" },\n createElement(\"tr\", { role: \"row\" },\n props.axis && (createElement(\"td\", { \"aria-hidden\": true, className: \"fc-timegrid-col fc-timegrid-axis\" },\n createElement(\"div\", { className: \"fc-timegrid-col-frame\" },\n createElement(\"div\", { className: \"fc-timegrid-now-indicator-container\" }, typeof nowIndicatorTop === 'number' && (createElement(NowIndicatorContainer, { elClasses: ['fc-timegrid-now-indicator-arrow'], elStyle: { top: nowIndicatorTop }, isAxis: true, date: props.nowDate })))))),\n props.cells.map((cell, i) => (createElement(TimeCol, { key: cell.key, elRef: this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraRenderProps: cell.extraRenderProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, fgEventSegs: fgEventSegsByRow[i], bgEventSegs: bgEventSegsByRow[i], businessHourSegs: businessHourSegsByRow[i], nowIndicatorSegs: nowIndicatorSegsByRow[i], dateSelectionSegs: dateSelectionSegsByRow[i], eventDrag: eventDragByRow[i], eventResize: eventResizeByRow[i], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint }))))))));\n }\n componentDidMount() {\n this.updateCoords();\n }\n componentDidUpdate() {\n this.updateCoords();\n }\n updateCoords() {\n let { props } = this;\n if (props.onColCoords &&\n props.clientWidth !== null // means sizing has stabilized\n ) {\n props.onColCoords(new PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal\n false));\n }\n }\n}\nfunction collectCellEls(elMap, cells) {\n return cells.map((cell) => elMap[cell.key]);\n}\n\n/* A component that renders one or more columns of vertical time slots\n----------------------------------------------------------------------------------------------------------------------*/\nclass TimeCols extends DateComponent {\n constructor() {\n super(...arguments);\n this.processSlotOptions = memoize(processSlotOptions);\n this.state = {\n slatCoords: null,\n };\n this.handleRootEl = (el) => {\n if (el) {\n this.context.registerInteractiveComponent(this, {\n el,\n isHitComboAllowed: this.props.isHitComboAllowed,\n });\n }\n else {\n this.context.unregisterInteractiveComponent(this);\n }\n };\n this.handleScrollRequest = (request) => {\n let { onScrollTopRequest } = this.props;\n let { slatCoords } = this.state;\n if (onScrollTopRequest && slatCoords) {\n if (request.time) {\n let top = slatCoords.computeTimeTop(request.time);\n top = Math.ceil(top); // zoom can give weird floating-point values. rather scroll a little bit further\n if (top) {\n top += 1; // to overcome top border that slots beyond the first have. looks better\n }\n onScrollTopRequest(top);\n }\n return true;\n }\n return false;\n };\n this.handleColCoords = (colCoords) => {\n this.colCoords = colCoords;\n };\n this.handleSlatCoords = (slatCoords) => {\n this.setState({ slatCoords });\n if (this.props.onSlatCoords) {\n this.props.onSlatCoords(slatCoords);\n }\n };\n }\n render() {\n let { props, state } = this;\n return (createElement(\"div\", { className: \"fc-timegrid-body\", ref: this.handleRootEl, style: {\n // these props are important to give this wrapper correct dimensions for interactions\n // TODO: if we set it here, can we avoid giving to inner tables?\n width: props.clientWidth,\n minWidth: props.tableMinWidth,\n } },\n createElement(TimeColsSlats, { axis: props.axis, dateProfile: props.dateProfile, slatMetas: props.slatMetas, clientWidth: props.clientWidth, minHeight: props.expandRows ? props.clientHeight : '', tableMinWidth: props.tableMinWidth, tableColGroupNode: props.axis ? props.tableColGroupNode : null /* axis depends on the colgroup's shrinking */, onCoords: this.handleSlatCoords }),\n createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bgEventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange, nowDate: props.nowDate, nowIndicatorSegs: props.nowIndicatorSegs, clientWidth: props.clientWidth, tableMinWidth: props.tableMinWidth, tableColGroupNode: props.tableColGroupNode, slatCoords: state.slatCoords, onColCoords: this.handleColCoords, forPrint: props.forPrint })));\n }\n componentDidMount() {\n this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest);\n }\n componentDidUpdate(prevProps) {\n this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile);\n }\n componentWillUnmount() {\n this.scrollResponder.detach();\n }\n queryHit(positionLeft, positionTop) {\n let { dateEnv, options } = this.context;\n let { colCoords } = this;\n let { dateProfile } = this.props;\n let { slatCoords } = this.state;\n let { snapDuration, snapsPerSlot } = this.processSlotOptions(this.props.slotDuration, options.snapDuration);\n let colIndex = colCoords.leftToIndex(positionLeft);\n let slatIndex = slatCoords.positions.topToIndex(positionTop);\n if (colIndex != null && slatIndex != null) {\n let cell = this.props.cells[colIndex];\n let slatTop = slatCoords.positions.tops[slatIndex];\n let slatHeight = slatCoords.positions.getHeight(slatIndex);\n let partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1\n let localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat\n let snapIndex = slatIndex * snapsPerSlot + localSnapIndex;\n let dayDate = this.props.cells[colIndex].date;\n let time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex));\n let start = dateEnv.add(dayDate, time);\n let end = dateEnv.add(start, snapDuration);\n return {\n dateProfile,\n dateSpan: Object.assign({ range: { start, end }, allDay: false }, cell.extraDateSpan),\n dayEl: colCoords.els[colIndex],\n rect: {\n left: colCoords.lefts[colIndex],\n right: colCoords.rights[colIndex],\n top: slatTop,\n bottom: slatTop + slatHeight,\n },\n layer: 0,\n };\n }\n return null;\n }\n}\nfunction processSlotOptions(slotDuration, snapDurationOverride) {\n let snapDuration = snapDurationOverride || slotDuration;\n let snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration);\n if (snapsPerSlot === null) {\n snapDuration = slotDuration;\n snapsPerSlot = 1;\n // TODO: say warning?\n }\n return { snapDuration, snapsPerSlot };\n}\n\nclass DayTimeColsSlicer extends Slicer {\n sliceRange(range, dayRanges) {\n let segs = [];\n for (let col = 0; col < dayRanges.length; col += 1) {\n let segRange = intersectRanges(range, dayRanges[col]);\n if (segRange) {\n segs.push({\n start: segRange.start,\n end: segRange.end,\n isStart: segRange.start.valueOf() === range.start.valueOf(),\n isEnd: segRange.end.valueOf() === range.end.valueOf(),\n col,\n });\n }\n }\n return segs;\n }\n}\n\nclass DayTimeCols extends DateComponent {\n constructor() {\n super(...arguments);\n this.buildDayRanges = memoize(buildDayRanges);\n this.slicer = new DayTimeColsSlicer();\n this.timeColsRef = createRef();\n }\n render() {\n let { props, context } = this;\n let { dateProfile, dayTableModel } = props;\n let { nowIndicator, nextDayThreshold } = context.options;\n let dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv);\n // give it the first row of cells\n // TODO: would move this further down hierarchy, but sliceNowDate needs it\n return (createElement(NowTimer, { unit: nowIndicator ? 'minute' : 'day' }, (nowDate, todayRange) => (createElement(TimeCols, Object.assign({ ref: this.timeColsRef }, this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile: dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate: nowDate, nowIndicatorSegs: nowIndicator && this.slicer.sliceNowDate(nowDate, dateProfile, nextDayThreshold, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords })))));\n }\n}\nfunction buildDayRanges(dayTableModel, dateProfile, dateEnv) {\n let ranges = [];\n for (let date of dayTableModel.headerDates) {\n ranges.push({\n start: dateEnv.add(date, dateProfile.slotMinTime),\n end: dateEnv.add(date, dateProfile.slotMaxTime),\n });\n }\n return ranges;\n}\n\n// potential nice values for the slot-duration and interval-duration\n// from largest to smallest\nconst STOCK_SUB_DURATIONS = [\n { hours: 1 },\n { minutes: 30 },\n { minutes: 15 },\n { seconds: 30 },\n { seconds: 15 },\n];\nfunction buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) {\n let dayStart = new Date(0);\n let slatTime = slotMinTime;\n let slatIterator = createDuration(0);\n let labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration);\n let metas = [];\n while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) {\n let date = dateEnv.add(dayStart, slatTime);\n let isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null;\n metas.push({\n date,\n time: slatTime,\n key: date.toISOString(),\n isoTimeStr: formatIsoTimeString(date),\n isLabeled,\n });\n slatTime = addDurations(slatTime, slotDuration);\n slatIterator = addDurations(slatIterator, slotDuration);\n }\n return metas;\n}\n// Computes an automatic value for slotLabelInterval\nfunction computeLabelInterval(slotDuration) {\n let i;\n let labelInterval;\n let slotsPerLabel;\n // find the smallest stock label interval that results in more than one slots-per-label\n for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) {\n labelInterval = createDuration(STOCK_SUB_DURATIONS[i]);\n slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);\n if (slotsPerLabel !== null && slotsPerLabel > 1) {\n return labelInterval;\n }\n }\n return slotDuration; // fall back\n}\n\nclass DayTimeColsView extends TimeColsView {\n constructor() {\n super(...arguments);\n this.buildTimeColsModel = memoize(buildTimeColsModel);\n this.buildSlatMetas = memoize(buildSlatMetas);\n }\n render() {\n let { options, dateEnv, dateProfileGenerator } = this.context;\n let { props } = this;\n let { dateProfile } = props;\n let dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator);\n let splitProps = this.allDaySplitter.splitProps(props);\n let slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv);\n let { dayMinWidth } = options;\n let hasAttachedAxis = !dayMinWidth;\n let hasDetachedAxis = dayMinWidth;\n let headerContent = options.dayHeaders && (createElement(DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null }));\n let allDayContent = (options.allDaySlot !== false) && ((contentArg) => (createElement(DayTable, Object.assign({}, splitProps.allDay, { dateProfile: dateProfile, dayTableModel: dayTableModel, nextDayThreshold: options.nextDayThreshold, tableMinWidth: contentArg.tableMinWidth, colGroupNode: contentArg.tableColGroupNode, renderRowIntro: hasAttachedAxis ? this.renderTableRowAxis : null, showWeekNumbers: false, expandRows: false, headerAlignElRef: this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }, this.getAllDayMaxEventProps()))));\n let timeGridContent = (contentArg) => (createElement(DayTimeCols, Object.assign({}, splitProps.timed, { dayTableModel: dayTableModel, dateProfile: dateProfile, axis: hasAttachedAxis, slotDuration: options.slotDuration, slatMetas: slatMetas, forPrint: props.forPrint, tableColGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, onSlatCoords: this.handleSlatCoords, expandRows: contentArg.expandRows, onScrollTopRequest: this.handleScrollTopRequest })));\n return hasDetachedAxis\n ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords)\n : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent);\n }\n}\nfunction buildTimeColsModel(dateProfile, dateProfileGenerator) {\n let daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);\n return new DayTableModel(daySeries, false);\n}\n\nexport { DayTimeCols, DayTimeColsSlicer, DayTimeColsView, TimeCols, TimeColsSlatsCoords, TimeColsView, buildDayRanges, buildSlatMetas, buildTimeColsModel };\n","import { createPlugin } from '@fullcalendar/core';\nimport { DayTimeColsView } from './internal.js';\nimport { injectStyles } from '@fullcalendar/core/internal';\nimport '@fullcalendar/core/preact';\nimport '@fullcalendar/daygrid/internal';\n\nconst OPTION_REFINERS = {\n allDaySlot: Boolean,\n};\n\nvar css_248z = \".fc-v-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-v-event .fc-event-main{color:var(--fc-event-text-color);height:100%}.fc-v-event .fc-event-main-frame{display:flex;flex-direction:column;height:100%}.fc-v-event .fc-event-time{flex-grow:0;flex-shrink:0;max-height:100%;overflow:hidden}.fc-v-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-height:0}.fc-v-event .fc-event-title{bottom:0;max-height:100%;overflow:hidden;top:0}.fc-v-event:not(.fc-event-start){border-top-left-radius:0;border-top-right-radius:0;border-top-width:0}.fc-v-event:not(.fc-event-end){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:0}.fc-v-event.fc-event-selected:before{left:-10px;right:-10px}.fc-v-event .fc-event-resizer-start{cursor:n-resize}.fc-v-event .fc-event-resizer-end{cursor:s-resize}.fc-v-event:not(.fc-event-selected) .fc-event-resizer{height:var(--fc-event-resizer-thickness);left:0;right:0}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-start{top:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer{left:50%;margin-left:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-start{top:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc .fc-timegrid .fc-daygrid-body{z-index:2}.fc .fc-timegrid-divider{padding:0 0 2px}.fc .fc-timegrid-body{min-height:100%;position:relative;z-index:1}.fc .fc-timegrid-axis-chunk{position:relative}.fc .fc-timegrid-axis-chunk>table,.fc .fc-timegrid-slots{position:relative;z-index:1}.fc .fc-timegrid-slot{border-bottom:0;height:1.5em}.fc .fc-timegrid-slot:empty:before{content:\\\"\\\\00a0\\\"}.fc .fc-timegrid-slot-minor{border-top-style:dotted}.fc .fc-timegrid-slot-label-cushion{display:inline-block;white-space:nowrap}.fc .fc-timegrid-slot-label{vertical-align:middle}.fc .fc-timegrid-axis-cushion,.fc .fc-timegrid-slot-label-cushion{padding:0 4px}.fc .fc-timegrid-axis-frame-liquid{height:100%}.fc .fc-timegrid-axis-frame{align-items:center;display:flex;justify-content:flex-end;overflow:hidden}.fc .fc-timegrid-axis-cushion{flex-shrink:0;max-width:60px}.fc-direction-ltr .fc-timegrid-slot-label-frame{text-align:right}.fc-direction-rtl .fc-timegrid-slot-label-frame{text-align:left}.fc-liquid-hack .fc-timegrid-axis-frame-liquid{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-timegrid-col-frame{min-height:100%;position:relative}.fc-media-screen.fc-liquid-hack .fc-timegrid-col-frame{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols{bottom:0;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols>table{height:100%}.fc-media-screen .fc-timegrid-col-bg,.fc-media-screen .fc-timegrid-col-events,.fc-media-screen .fc-timegrid-now-indicator-container{left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col-bg{z-index:2}.fc .fc-timegrid-col-bg .fc-non-business{z-index:1}.fc .fc-timegrid-col-bg .fc-bg-event{z-index:2}.fc .fc-timegrid-col-bg .fc-highlight{z-index:3}.fc .fc-timegrid-bg-harness{left:0;position:absolute;right:0}.fc .fc-timegrid-col-events{z-index:3}.fc .fc-timegrid-now-indicator-container{bottom:0;overflow:hidden}.fc-direction-ltr .fc-timegrid-col-events{margin:0 2.5% 0 2px}.fc-direction-rtl .fc-timegrid-col-events{margin:0 2px 0 2.5%}.fc-timegrid-event-harness{position:absolute}.fc-timegrid-event-harness>.fc-timegrid-event{bottom:0;left:0;position:absolute;right:0;top:0}.fc-timegrid-event-harness-inset .fc-timegrid-event,.fc-timegrid-event.fc-event-mirror,.fc-timegrid-more-link{box-shadow:0 0 0 1px var(--fc-page-bg-color)}.fc-timegrid-event,.fc-timegrid-more-link{border-radius:3px;font-size:var(--fc-small-font-size)}.fc-timegrid-event{margin-bottom:1px}.fc-timegrid-event .fc-event-main{padding:1px 1px 0}.fc-timegrid-event .fc-event-time{font-size:var(--fc-small-font-size);margin-bottom:1px;white-space:nowrap}.fc-timegrid-event-short .fc-event-main-frame{flex-direction:row;overflow:hidden}.fc-timegrid-event-short .fc-event-time:after{content:\\\"\\\\00a0-\\\\00a0\\\"}.fc-timegrid-event-short .fc-event-title{font-size:var(--fc-small-font-size)}.fc-timegrid-more-link{background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;margin-bottom:1px;position:absolute;z-index:9999}.fc-timegrid-more-link-inner{padding:3px 2px;top:0}.fc-direction-ltr .fc-timegrid-more-link{right:0}.fc-direction-rtl .fc-timegrid-more-link{left:0}.fc .fc-timegrid-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;border-width:1px 0 0;left:0;position:absolute;right:0;z-index:4}.fc .fc-timegrid-now-indicator-arrow{border-color:var(--fc-now-indicator-color);border-style:solid;margin-top:-5px;position:absolute;z-index:4}.fc-direction-ltr .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 0 5px 6px;left:0}.fc-direction-rtl .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 6px 5px 0;right:0}\";\ninjectStyles(css_248z);\n\nvar index = createPlugin({\n name: '@fullcalendar/timegrid',\n initialView: 'timeGridWeek',\n optionRefiners: OPTION_REFINERS,\n views: {\n timeGrid: {\n component: DayTimeColsView,\n usesMinMaxTime: true,\n allDaySlot: true,\n slotDuration: '00:30:00',\n slotEventOverlap: true, // a bad name. confused with overlap/constraint system\n },\n timeGridDay: {\n type: 'timeGrid',\n duration: { days: 1 },\n },\n timeGridWeek: {\n type: 'timeGrid',\n duration: { weeks: 1 },\n },\n },\n});\n\nexport { index as default };\n","c7-bookable-availability {\n display: block;\n\n\n .c7-bookable-availability-calendar-header {\n margin-bottom: 1rem;\n display: flex;\n justify-content: flex-end;\n }\n\n .fc {\n\n --fc-today-bg-color: transparent;\n --fc-bg-event-opacity: 1;\n --fc-event-bg-color: var(--c7-500);\n --fc-event-border-color: var(--c7-500);\n --fc-event-text-color: var(--c7-500-contrast);\n\n .conflicts {\n --fc-event-bg-color: red;\n --fc-event-border-color: red;\n --fc-event-text-color: white;\n }\n\n .fc-timegrid-slot-minor {\n border-top-color: transparent;\n }\n\n .fc-col-header-cell-cushion {\n padding: 8px 4px;\n\n .day-header-weekday {\n font-weight: initial;\n font-size: .8em;\n }\n }\n\n .fc-bg-event .fc-event-title {\n font-style: normal;\n text-align: center;\n opacity: .32;\n position: sticky;\n top: 0;\n }\n\n\n .fc-scrollgrid-section-header > th {\n border: none;\n\n .fc-scroller {\n overflow: hidden !important;\n }\n }\n\n th.fc-col-header-cell {\n border: none;\n background: #efefef;\n\n &:nth-child(2) {\n border-top-left-radius: 10px;\n }\n\n &:last-child {\n border-top-right-radius: 10px;\n }\n }\n\n .fc-timegrid-axis {\n border: none;\n }\n\n .fc-scrollgrid {\n border: none;\n\n .fc-scrollgrid-section-body > td {\n border: none;\n }\n\n .fc-timegrid-body .fc-timegrid-cols tbody {\n\n td:not(:first-child) .fc-timegrid-col-frame {\n border-bottom: 1px inset var(--fc-border-color);\n }\n\n td:nth-child(2) .fc-timegrid-col-frame {\n border-bottom-left-radius: 10px;\n }\n\n td:last-child .fc-timegrid-col-frame {\n border-right: 1px inset var(--fc-border-color);\n border-bottom-right-radius: 10px;\n }\n\n }\n\n .fc-scrollgrid-section-body .fc-scroller {\n\n &::-webkit-scrollbar {\n width: 5px;\n }\n\n /* Track */\n &::-webkit-scrollbar-track {\n background: transparent;\n }\n\n /* Handle */\n &::-webkit-scrollbar-thumb {\n background: var(--c7-500);\n border-radius: 100px;\n }\n\n /* Handle on hover */\n &::-webkit-scrollbar-thumb:hover {\n background: #555;\n }\n\n }\n }\n\n .fc-timegrid-slot-label {\n border: none;\n font-size: .8em;\n opacity: .64;\n transform: translateY(-50%);\n\n &[data-time=\"00:00:00\"] {\n display: none;\n }\n }\n\n }\n\n\n}\n","import { Component, h, Host, Prop, Watch, Event, EventEmitter, Method, Listen } from '@stencil/core';\nimport { BookingClient, IReservationRequestFilterDto, ReservationRequestFilterDto } from '../../../../api/APIClient';\nimport { Calendar, DateSelectArg, EventDropArg, EventInput } from '@fullcalendar/core';\nimport TimeGridPlugin from '@fullcalendar/timegrid';\nimport InteractionPlugin, { EventResizeDoneArg } from '@fullcalendar/interaction';\nimport { BookingAvailabilitySelectionChange } from './booking-availability.types';\nimport { getDateTime, getStartOfDay, getTimeFromDate } from '../../../../utils/date';\nimport { EventImpl } from '@fullcalendar/core/internal';\n\n@Component({\n tag: 'c7-bookable-availability',\n styleUrl: 'bookable-availability.styles.scss',\n})\nexport class BookableAvailabilityComponent {\n\n @Prop() page!: number;\n\n @Event() slotSelectionChange: EventEmitter;\n\n @Event() conflictsChange: EventEmitter;\n\n @Prop() filters: IReservationRequestFilterDto[] = [];\n @Watch('filters')\n async onBookablesChange() {\n this.calendar.refetchEvents();\n\n if(this.ghostEvent) {\n await this.setGhostEvent(this.ghostEvent.start, this.ghostEvent.end);\n }\n }\n\n @Listen('resize', { target: 'window' })\n async onResize() {\n\n const {type} = this.calendar.view;\n const suggestedType = this.getViewType();\n\n if(suggestedType !== type) {\n this.calendar.changeView(suggestedType);\n }\n\n }\n\n\n private client = new BookingClient();\n\n private calendarRef: HTMLDivElement;\n private calendar: Calendar;\n\n private ghostEvent: EventImpl;\n\n componentDidLoad() {\n\n this.calendar = new Calendar(this.calendarRef, {\n locale: 'de',\n plugins: [ TimeGridPlugin, InteractionPlugin],\n initialView: this.getViewType(),\n views: {\n timeGridWeekMedium: {\n type: 'timeGridWeek',\n duration: {days: 3},\n },\n timeGridWeekSmall: {\n type: 'timeGridWeek',\n duration: {days: 1},\n }\n },\n scrollTime: '08:00',\n scrollTimeReset: false,\n allDaySlot: false,\n height: '500px',\n headerToolbar: false,\n slotDuration: {minutes: 30},\n slotLabelInterval: {hours: 1},\n snapDuration: {minutes: 15},\n selectable: true,\n selectConstraint: 'available',\n editable: true,\n eventConstraint: 'available',\n selectMirror: true,\n eventDrop: this.onEdit.bind(this),\n eventResize: this.onEdit.bind(this),\n select: this.onSelect.bind(this),\n events: this.getEvents.bind(this),\n dayHeaderContent: (arg) => {\n\n const html = `\n
${arg.date.toLocaleDateString('de', {day: '2-digit'})}
\n
${arg.date.toLocaleDateString('de', {weekday: 'long'})}
\n `;\n\n return {html};\n },\n firstDay: 1,\n slotLabelFormat: {\n hour: '2-digit',\n minute: '2-digit',\n }\n });\n\n this.calendar.render();\n }\n\n private getEvents({start, end}, successCallback, failureCallback) {\n return this.client.getCalendarAvailability(\n this.page,\n this.filters.map((filter) => new ReservationRequestFilterDto(filter)),\n start,\n end\n ).then((slots) => {\n const events = slots.map((slot) => {\n const {from: start, until: end} = slot;\n\n return {\n groupId: 'available',\n title: 'Nicht verfügbar',\n start,\n end,\n editable: false,\n display: 'inverse-background',\n color: '#efefef',\n } as EventInput;\n\n\n });\n\n successCallback(events);\n\n }).catch(() => {\n failureCallback([]);\n })\n }\n\n private async onSelect(selection: DateSelectArg) {\n\n const {start, end} = selection;\n\n await this.setGhostEvent(start, end);\n\n this.slotSelectionChange.emit({\n fromDate: getStartOfDay(start),\n untilDate: getStartOfDay(end),\n fromTime: getTimeFromDate(start),\n untilTime: getTimeFromDate(end)\n });\n\n }\n\n private async onEdit({event}: EventResizeDoneArg | EventDropArg) {\n const {start, end} = event;\n\n // since events should only be droppable/resizable if they are not conflicting, we can assume that there are no conflicts\n this.ghostEvent?.setProp('classNames', ['no-conflicts']);\n this.conflictsChange.emit(false);\n\n this.slotSelectionChange.emit({\n fromDate: getStartOfDay(start),\n untilDate: getStartOfDay(end),\n fromTime: getTimeFromDate(start),\n untilTime: getTimeFromDate(end)\n });\n }\n\n @Method()\n async setEvent({fromDate, fromTime, untilDate, untilTime}: BookingAvailabilitySelectionChange) {\n await this.setGhostEvent(getDateTime(fromDate, fromTime), getDateTime(untilDate, untilTime));\n }\n\n private async setGhostEvent(start: Date, end: Date) {\n\n const conflicts = await this.client.getCalendarConflicts(this.page, this.filters.map((filter) => new ReservationRequestFilterDto(filter)), start, end);\n const hasConflicts = conflicts.length > 0;\n this.conflictsChange.emit(hasConflicts);\n const classNames = [hasConflicts ? 'conflicts' : 'no-conflicts'];\n\n if(this.ghostEvent) {\n this.ghostEvent.setDates(start, end);\n this.ghostEvent.setProp('classNames', classNames);\n\n } else {\n\n this.ghostEvent = this.calendar.addEvent({\n title: 'Ihr Buchungszeitraum',\n start,\n end,\n classNames\n })\n\n }\n\n this.calendar.gotoDate(this.ghostEvent.start);\n }\n\n private async next() {\n this.calendar.next();\n }\n\n private async prev() {\n this.calendar.prev();\n }\n\n private getViewType() {\n\n const {clientWidth} = this.calendarRef;\n\n if(clientWidth < 500) {\n return 'timeGridWeekSmall';\n } else if(clientWidth < 800) {\n return 'timeGridWeekMedium';\n }\n\n return 'timeGridWeek';\n }\n\n\n render() {\n\n const cssClassNames = {\n 'c7-bookable-availability': true,\n }\n\n return (\n \n
\n this.prev()}>\n \n Früher\n \n this.next()}>\n \n Später\n \n
\n
this.calendarRef = el} />\n \n )\n\n }\n\n}\n","import { Component, h, Host, Listen, Prop, State } from '@stencil/core';\nimport { BookingBookableTeaserDto, BookingClient } from '../../../../api/APIClient';\nimport { PaginatorProps } from '../../../utility/pagination/pagination';\nimport { StateStore } from '../../../../utils/storage';\nimport { SortProps } from '../../../utility/sort/sort';\nimport { SearchFilterProps } from '../../../utility/filters/search/search';\nimport {CategoryFilterProps} from '../../../utility/filters/categories/categories-filter-circle/categories-filter-circle';\n\nexport type BookablesProviderRenderProps = {\n items: BookingBookableTeaserDto[],\n pagination: PaginatorProps,\n loading: boolean,\n filters?: BookablesFilterProps,\n}\n\nexport type BookablesFilterProps = {\n search: string,\n categories: number[],\n}\n\n\n@Component({\n tag: 'c7-bookables-provider',\n})\nexport class BookablesProviderComponent {\n\n @Prop() page!: number;\n\n @Prop() storeState: boolean;\n\n @Prop() pageSize: number = 20;\n\n @Prop() categories: number[];\n\n @Prop() excludeCategories: number[];\n\n @Prop() items: number[];\n\n @Prop() excludeItems: number[];\n\n @Prop() renderFn!: (props: BookablesProviderRenderProps) => void;\n\n @State() bookables: BookingBookableTeaserDto[] = [];\n\n @State() loading: boolean = false;\n\n @State() pagination: PaginatorProps;\n\n @State() filters: BookablesFilterProps = {\n search: StateStore.state?.search ?? null,\n categories: StateStore.state?.categories ?? null,\n };\n\n @Prop({mutable: true}) sort: SortProps;\n\n @Listen('paginate')\n async onPaginate({detail}: CustomEvent) {\n await this.getBookables(detail);\n }\n\n @Listen('c7-search-filter')\n async onSearchFilterChange({detail}: CustomEvent) {\n this.filters = {...this.filters, ...detail};\n await this.getBookables();\n }\n\n @Listen('c7-category-filter')\n async onCategoriesChange({detail}: CustomEvent) {\n this.filters = {...this.filters, ...detail};\n await this.getBookables();\n }\n\n @Listen('c7-sort')\n async onSortingChange({detail}: CustomEvent) {\n this.sort = {...this.sort, ...detail};\n await this.getBookables();\n }\n\n private client = new BookingClient();\n\n async componentWillLoad() {\n await this.getBookables();\n }\n\n\n private async getBookables(page:number = 1) {\n\n this.loading = true;\n\n try {\n\n const {items, ...pagination} = await this.client.getBookables(\n this.page,\n null,\n page,\n this.pageSize,\n this.filters.categories?.length ? this.filters.categories : this.categories,\n this.items,\n this.excludeCategories,\n this.excludeItems,\n this.sort?.sortType,\n this.sort?.sortDirection,\n this.filters.search,\n )\n\n this.bookables = page > 1 ? [...this.bookables, ...items] : [...items];\n this.pagination = {...pagination};\n\n } catch (error) {\n\n console.log(error);\n\n } finally {\n this.loading = false;\n }\n\n\n }\n\n\n render() {\n\n const cssClassNames = {\n 'c7-bookables-provider': true,\n };\n\n const {bookables, filters, loading, pagination} = this;\n\n return (\n \n {\n this.renderFn({\n items: bookables,\n filters,\n loading,\n pagination,\n })\n }\n \n );\n }\n}\n","c7-booking-detail-default {\n display: block;\n\n\n c7-slides {\n overflow: hidden;\n width: 100%;\n\n c7-slide.swiper-slide {\n width: 100%;\n flex-direction: column;\n align-items: unset;\n justify-content: unset;\n text-align: initial;\n }\n }\n\n c7-list {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 1rem;\n }\n\n hr {\n border-style: solid;\n border-color: #efefef;\n margin: 1rem 0;\n }\n\n .c7-booking-slide-actions {\n margin-top: 2rem;\n display: flex;\n justify-content: flex-end;\n\n c7-button:first-child:not(:only-child) {\n margin-right: auto;\n }\n }\n\n c7-list-item {\n --background: #efefef;\n --border-radius: 10px;\n --min-height: 69px;\n }\n\n .c7-booking-personal-data {\n display: flex;\n flex-wrap: wrap-reverse;\n align-items: flex-end;\n gap: 2rem;\n\n .c7-booker-code-panel {\n flex-basis: 340px;\n }\n\n .c7-booking-address-fields {\n flex: 2 1 auto;\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(max(300px, calc((100% - 1rem) / 2)), 1fr));\n gap: 1rem;\n }\n\n }\n\n\n\n .c7-booking-date {\n width: fit-content;\n display: grid;\n grid-template-columns: auto auto auto;\n gap: 1rem;\n\n label {\n margin-bottom: .5em;\n font-weight: bold;\n }\n\n > div {\n display: flex;\n flex-direction: column;\n }\n\n &.multi-day {\n grid-template-columns: auto auto;\n }\n }\n\n .c7-booking-privacy {\n margin-top: 2rem;\n }\n\n}\n","import { Component, h, Host, Prop, State, Watch, Element, Listen } from '@stencil/core';\nimport {\n BookingBookableDto,\n BookingBookableTeaserDto,\n BookingClient, BookingSettingsDto,\n IAddress,\n IBookingReservationItemDto, PublicCreateBookingReservationCommand,\n PublicSubmitBookingReservationCommand,\n} from '../../../../api/APIClient';\nimport { setPage } from '../../../../utils/page';\nimport { getQueryParam, QueryParamKey } from '../../../../utils/query-params';\nimport { CheckboxChangeEventDetail } from '../../../ui/controls/checkbox/checkbox';\nimport { mergeDeep, PrivacyConfirmationField, serializeFormData } from '../../../utility/forms/form.utils';\nimport { formatDateForInput, isSameDay } from '../../../../utils/date';\nimport { StateStore } from '../../../../utils/storage';\nimport { ItemLinkProps } from '../../../../utils/link';\nimport { SwiperOptions } from 'swiper';\n\n/**\n * @type booking\n * @group detail\n */\n@Component({\n tag: 'c7-booking-detail-default',\n styleUrl: 'booking-detail-default.styles.scss',\n})\nexport class BookingDetailDefaultComponent {\n\n @Element() el!: HTMLC7BookingDetailDefaultElement;\n\n @Prop() page!: number;\n\n /**\n * @group product\n */\n @Prop() item: number;\n @Watch('item')\n async onArticleChange() {\n await this.getData();\n }\n\n /**\n * @group navigation\n */\n @Prop() hideBackLink: boolean;\n\n @State() bookable: BookingBookableDto;\n @State() subBookables: BookingBookableTeaserDto[] = [];\n\n @State() state: 'initial' | 'submitted' | 'submit-error' | 'created' | 'create-error' = 'initial';\n\n @State() multiDay: boolean;\n\n @State() conflicts: boolean = true;\n\n @State() formState = {\n pageId: null,\n address: {} as IAddress,\n reservationItems: [] as IBookingReservationItemDto[],\n fromDate: null,\n untilDate: null,\n fromTime: null,\n untilTime: null,\n bookerCode: null,\n }\n\n private client = new BookingClient();\n private availabilityRef: HTMLC7BookableAvailabilityElement;\n private slidesRef: HTMLC7SlidesElement;\n\n private settings: BookingSettingsDto;\n\n @Listen('c7-slide-did-change')\n onSlideChange() {\n this.slidesRef?.scrollIntoView({behavior: 'smooth', block: 'start'});\n }\n\n\n async componentWillLoad() {\n if(!this.page) {\n await setPage(this);\n }\n\n\n if (!this.item) {\n this.item = +getQueryParam(QueryParamKey.ITEM);\n }\n\n const {token, reservationId, action} = StateStore.state;\n\n if(action && reservationId && token) {\n\n try {\n await this.client.createReservation(this.page, new PublicCreateBookingReservationCommand({\n reservationId,\n token,\n pageId: this.page,\n }));\n\n this.state = 'created';\n } catch (e) {\n this.state = 'create-error';\n }\n\n }\n\n await this.getData();\n\n await this.setFormState({\n pageId: this.page,\n reservationItems: [{\n bookableId: this.bookable.id,\n amount: 1\n }]\n })\n }\n\n\n private async getData() {\n\n const [bookable, {items: subBookables}, settings] = await Promise.all([\n await this.client.getBookable(this.page, this.item),\n await this.client.getBookables(this.page, this.item),\n await this.client.getSettings(this.page)\n ]);\n\n this.bookable = bookable;\n this.subBookables = subBookables;\n this.settings = settings;\n\n }\n\n async setFormState(partial: Partial, updateAvailability:boolean = true) {\n\n\n\n this.formState = {...mergeDeep(this.formState, partial)};\n\n // if state update affects reservation time\n if([partial.fromDate, partial.untilDate, partial.fromTime, partial.untilTime].some((value) => !!value)) {\n\n let {fromDate, untilDate, fromTime, untilTime} = this.formState;\n\n this.multiDay = fromDate && untilDate && !isSameDay(fromDate, untilDate);\n\n if (fromDate && !untilDate || untilDate < fromDate) {\n untilDate = this.multiDay ? new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate() + 1) : fromDate;\n this.formState = {...this.formState, untilDate};\n }\n\n\n if(updateAvailability) {\n await this.availabilityRef?.setEvent({\n fromDate,\n untilDate,\n fromTime,\n untilTime,\n })\n }\n }\n }\n\n\n private async onCheckboxChange({value: bookableId, checked}: CheckboxChangeEventDetail) {\n\n let {reservationItems: selected} = this.formState;\n\n if (checked) {\n\n await this.setFormState({\n reservationItems: [...selected.filter((item) => item.bookableId !== this.bookable.id), {bookableId, amount: 1}]\n })\n\n } else {\n\n selected = selected.filter((item) => item.bookableId !== bookableId);\n\n if (!selected.length) {\n selected = [{\n bookableId: this.bookable.id,\n amount: 1\n }]\n }\n\n await this.setFormState({\n reservationItems: selected\n });\n\n }\n\n }\n\n private async onAmountChange(amount: number, index?: number) {\n\n const {reservationItems: selected} = this.formState;\n\n index = index ?? selected.findIndex((item) => item.bookableId === this.bookable.id);\n\n if (index === -1) return;\n\n selected[index].amount = amount;\n\n await this.setFormState({\n reservationItems: [...selected]\n });\n\n }\n\n private async onMultidayCheckboxChange({checked}: CheckboxChangeEventDetail) {\n\n const {fromDate, untilDate} = this.formState;\n\n if (!fromDate) {\n this.multiDay = checked;\n return;\n }\n\n if(!checked) {\n await this.setFormState({ untilDate: fromDate })\n } else {\n await this.setFormState({ untilDate: new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate() + 1) })\n }\n\n }\n\n private async submitBookingRerservation(ev: Event) {\n\n ev.preventDefault();\n ev.stopPropagation();\n\n try {\n await this.client.submitReservation(this.page, PublicSubmitBookingReservationCommand.fromJS(this.formState));\n this.state = 'submitted';\n } catch (e) {\n this.state = 'submit-error';\n }\n\n\n }\n\n private getTemplate() {\n switch (this.state) {\n case 'submitted':\n return (\n \n

Super, nur noch 1 letzter Schritt

\n

\n Wir haben Ihnen eine E-Mail mit einem Bestätigungslink geschickt. Bitte klicken Sie auf den Link, um Ihre Buchung abzuschließen.\n

\n
\n )\n case 'submit-error':\n return (\n \n

Fehler bei der Formularübermittlung

\n

\n Bitte versuchen Sie es erneut.\n

\n

\n this.state = 'initial'}>Erneut versuchen\n

\n
\n )\n case 'created':\n return (\n \n

Buchungsanfrage erfolgreich übermittelt

\n

Wir haben Ihre Buchungsanfrage erhalten.

\n
\n )\n case 'create-error':\n return (\n \n

Buchungsanfrage fehlgeschlagen

\n

\n\n
\n )\n case 'initial': {\n return this.getBookingFormTemplate();\n }\n }\n }\n\n private getBookingFormTemplate() {\n\n const { bookable, subBookables, multiDay, page, formState: {reservationItems: selected, fromDate, fromTime, untilDate, untilTime}, settings, conflicts } = this;\n\n const options: SwiperOptions = {\n allowTouchMove: false,\n slidesPerView: 1,\n }\n\n return (\n
this.submitBookingRerservation(ev)}>\n this.slidesRef = ref} pager={false} options={options}>\n \n {\n bookable.bookableQuantity > 1 && (\n \n \n {bookable.name}\n this.onAmountChange(detail)} value={1} />\n \n \n )\n }\n {\n bookable.bookableQuantity < 2 && subBookables.length > 0 && (\n
\n

Unterobjekte

\n\n \n {\n subBookables.map((subBookable, index) => {\n\n const { name, link: { targetId }, bookableQuantity } = subBookable;\n const isSelected = selected.some((item) => item.bookableId === targetId);\n const canHaveAmount = bookableQuantity > 1;\n\n return (\n \n this.onCheckboxChange(detail)} />\n\n {name}\n\n {\n !isSelected ? (\n \n Details\n \n ) : canHaveAmount ? (\n this.onAmountChange(detail, index)}\n value={1} />\n ) : null\n }\n\n \n );\n })\n }\n \n
\n )\n }\n
\n
\n

Verfügbarkeit

\n
\n
\n \n \n this.setFormState({ fromDate: valueAsDate })} />\n \n
\n
\n \n \n this.setFormState({ fromTime: value })} />\n \n
\n {\n multiDay && (\n
\n \n \n this.setFormState({ untilDate: valueAsDate })} />\n \n
\n )\n }\n
\n \n \n this.setFormState({ untilTime: value })} />\n \n
\n
\n this.onMultidayCheckboxChange(detail)}>Mehrtägige\n Reservierung\n \n
\n
\n this.availabilityRef = el}\n onSlotSelectionChange={({ detail }) => this.setFormState(detail, false)}\n onConflictsChange={({ detail }) => this.conflicts = detail}\n page={page}\n filters={selected}\n />\n
\n
\n this.slidesRef.slideNext()}>\n \n Weiter\n \n
\n
\n \n
\n

Ihre Daten

\n
\n
\n \n this.setFormState({ address: { firstName } })} />\n \n \n this.setFormState({ address: { lastName } })} />\n \n \n this.setFormState({ address: { eMail } })} />\n \n \n this.setFormState({ address: { street } })} />\n \n \n this.setFormState({ address: { houseNumber } })} />\n \n \n this.setFormState({ address: { zipCode } })} />\n \n \n this.setFormState({ address: { city } })} />\n \n \n this.setFormState({ address: { telephone } })} />\n \n\n
\n\n \n Mieter-Code\n
\n Sie haben einen Mieter-Code?\n
\n \n this.setFormState({ bookerCode })} />\n \n
\n
\n
\n
\n \n
\n
\n this.slidesRef.slidePrev()}>\n \n Zurück\n \n \n Jetzt reservieren\n \n
\n
\n
\n\n\n
\n )\n }\n\n render() {\n\n const cssClassNames = {\n 'c7-booking-detail-default': true,\n }\n\n const { bookable, subBookables, multiDay, page, formState: {reservationItems: selected, fromDate, fromTime, untilDate, untilTime} } = this;\n\n return (\n \n

{bookable.name}

\n
\n \n
\n
\n

Reservierung

\n {this.getTemplate()}\n
\n )\n\n }\n\n}\n","c7-booking-overview-default {\n\n .c7-booking-filters {\n display: flex;\n gap: 2rem;\n justify-content: space-between;\n margin-bottom: 2rem;\n align-items: flex-end;\n }\n\n .c7-booking-objects {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 2rem 1rem;\n }\n\n}\n","import { Component, Fragment, h, Host, Prop, State, Watch } from '@stencil/core';\nimport { Pagination, PaginationVariant } from '../../../utility/pagination/pagination';\nimport { coerceNumberArray } from '../../../../utils/coerce';\nimport { MasterDetailState } from '../../../interfaces/component-properties';\nimport { setPage } from '../../../../utils/page';\nimport { getQueryParam, QueryParamKey } from '../../../../utils/query-params';\nimport { ModuleType } from '../../../../api/APIClient';\nimport { ItemLinkProps } from '../../../../utils/link';\n\n/**\n * @type booking\n * @group overview\n */\n@Component({\n tag: 'c7-booking-overview-default',\n styleUrl: 'booking-overview-default.styles.scss',\n})\nexport class BookingOverviewDefaultComponent {\n\n @Prop({mutable: true}) page!: number;\n\n @Prop() slug: string;\n\n /**\n * @group pagination\n */\n @Prop() paginationVariant: PaginationVariant = 'manual';\n\n /**\n * @group pagination\n */\n @Prop() pageSize: number = 20;\n\n /**\n * @group pagination\n */\n @Prop() loadMoreLabel: string;\n\n /**\n * @group display\n */\n @Prop() searchLabel: string = 'Suchen...';\n\n\n @Prop({mutable: true}) detailId: number;\n\n\n /**\n * @group categories\n */\n @Prop({mutable: true}) categories: number[] | string = [];\n @Watch('categories')\n onCategoriesChange(value: number[] | string) {\n this.categories = coerceNumberArray(value);\n }\n\n /**\n * @group categories\n */\n @Prop({mutable: true}) excludeCategories: number[] | string = [];\n @Watch('excludeCategories')\n onExcludeCategoriesChange(value: number[] | string) {\n this.excludeCategories = coerceNumberArray(value);\n }\n\n /**\n * @group items\n */\n @Prop({mutable: true}) items: number[] | string = [];\n @Watch('items')\n onItemsChange(value: number[] | string) {\n this.items = coerceNumberArray(value);\n }\n\n /**\n * @group items\n */\n @Prop({mutable: true}) excludeItems: number[] | string = [];\n @Watch('excludeItems')\n onExcludeItemsChange(value: number[] | string) {\n this.excludeItems = coerceNumberArray(value);\n }\n\n\n @State() state: MasterDetailState = 'master';\n\n\n async componentWillLoad() {\n\n if (!this.page) {\n await setPage(this)\n }\n\n this.categories = coerceNumberArray(this.categories);\n this.excludeCategories = coerceNumberArray(this.excludeCategories);\n this.items = coerceNumberArray(this.items);\n this.excludeItems = coerceNumberArray(this.excludeItems);\n\n const detailId = getQueryParam(QueryParamKey.ITEM);\n\n if(detailId) {\n this.detailId = +detailId;\n this.state = 'detail';\n }\n }\n\n\n get master() {\n\n const {page, categories, excludeCategories, items, excludeItems, searchLabel, pageSize, paginationVariant, loadMoreLabel} = this;\n\n return (\n {\n\n return (\n \n
\n \n \n
\n
\n {\n bookables.map((bookable) => {\n return (\n \n \n \n \n \n {bookable.name}\n \n \n \n {bookable.teaserText}\n \n\n \n \n )\n })\n }\n
\n \n
\n )\n }}\n />\n )\n }\n\n get detail() {\n\n const {page, detailId} = this;\n\n return (\n \n )\n\n }\n\n\n render() {\n\n const cssClassNames = {\n 'c7-booking-overview-default': true,\n }\n\n const {state} = this;\n\n return (\n \n {state === 'master' ? this.master : this.detail}\n \n )\n }\n\n\n}\n",":host{\n\n --c7-button-width: 100%;\n --c7-button-color: var(--c7-500, rgba(0,0,0, .16));\n --c7-button-color-hover: var(--c7-400, rgba(0,0,0, .1));\n --c7-button-color-secondary: var(--c7-500, dimgrey);\n --c7-button-color-secondary-contrast: var(--c7-500-contrast, white);\n --c7-button-text: var(--c7-500-contrast, black);\n --c7-button-text-hover: var(--c7-400-contrast, black);\n --c7-button-padding: 0 1rem;\n --c7-button-line-height: 44px;\n --c7-button-border-width: 2px;\n --c7-button-border-color: transparent;\n --c7-button-border-color-hover: transparent;\n --c7-button-border-radius: 0px;\n --c7-button-box-shadow: none;\n --c7-button-inner-justify-content: center;\n\n display: inline-block;\n\n text-align: center;\n text-decoration: none;\n text-overflow: ellipsis;\n\n white-space: nowrap;\n\n user-select: none;\n vertical-align: top;\n vertical-align: -webkit-baseline-middle;\n pointer-events: auto;\n\n font-kerning: none;\n\n overflow: hidden;\n\n .button-native {\n display: block;\n white-space: nowrap;\n line-height: var(--c7-button-line-height);\n position: relative;\n text-decoration: none !important;\n font-size: inherit;\n font-family: inherit;\n padding: var(--c7-button-padding);\n border: var(--c7-button-border-width) solid var(--c7-button-border-color);\n border-radius: var(--c7-button-border-radius);\n\n width: var(--c7-button-width);\n height: 100%;\n background-color: var(--c7-button-color);\n color: var(--c7-button-text);\n outline: none;\n contain: layout style;\n cursor: pointer;\n\n\n z-index: 0;\n box-sizing: border-box;\n transition: all .3s ease-in-out;\n box-shadow: var(--c7-button-box-shadow);\n\n &:hover {\n background-color: var(--c7-button-color-hover);\n color: var(--c7-button-text-hover);\n border-color: var(--c7-button-border-color-hover);\n }\n }\n\n .button-native::-moz-focus-inner {\n border: 0;\n }\n\n .button-inner {\n display: flex;\n position: relative;\n\n flex-flow: row nowrap;\n flex-shrink: 0;\n align-items: center;\n justify-content: var(--c7-button-inner-justify-content);\n\n width: 100%;\n height: 100%;\n\n z-index: 1;\n }\n\n ::slotted(c7-icon), ::slotted(ion-icon) {\n font-size: 1.4em;\n pointer-events: none;\n }\n\n ::slotted(c7-icon[slot=\"start\"]), ::slotted(ion-icon[slot=\"start\"]) {\n margin: 0 .3em 0 -.3em;\n }\n\n ::slotted(c7-icon[slot=\"end\"]), ::slotted(ion-icon[slot=\"end\"]) {\n margin: 0 -.2em 0 .3em;\n }\n\n @media (any-hover: hover) {\n &:hover {\n color: var(--c7-button-color-hover);\n }\n\n &:hover .button-native::after {\n background: var(--background-hover);\n\n opacity: var(--background-hover-opacity);\n }\n }\n}\n\n:host(.slot-end-icon-bubble) {\n .button-native {\n padding-right: 10px;\n\n &:hover{\n ::slotted(c7-icon[slot=\"end\"]), ::slotted(ion-icon[slot=\"end\"]) {\n background-color: transparent;\n border-color: var(--c7-button-color-secondary);\n color: var(--c7-button-color-secondary);\n }\n }\n }\n\n ::slotted(c7-icon[slot=\"end\"]), ::slotted(ion-icon[slot=\"end\"]) {\n display: flex;\n justify-content: center;\n align-items: center;\n\n background-color: var(--c7-button-color-secondary);\n color: var(--c7-button-color-secondary-contrast);\n border: 2px solid transparent;\n border-radius: 50px;\n width: 2.5rem;\n height: 2.5rem;\n font-size: 1.25rem;\n margin-left: 1rem;\n margin-top: 5px;\n margin-bottom: 5px;\n transition: border-color .25s ease-in-out, background-color .25s ease-in-out, color .25s ease-in-out;\n }\n}\n\n/** Variables for 'shape' property **/\n:host(.button-square) {\n --c7-button-border-radius: 0;\n}\n\n:host(.button-round) {\n --c7-button-border-radius: 50px;\n}\n\n:host(.button-bubble) {\n --c7-button-border-radius: 100%;\n}\n\n/** Variables for 'appearance' property **/\n:host(.button-outline) {\n --c7-button-color: transparent;\n --c7-button-border-color: var(--c7-button-text);\n}\n\n:host(.button-clear) {\n --c7-button-color: transparent;\n --c7-button-text: initial;\n --c7-button-color-hover: rgba(0,0,0, .05);\n --c7-button-text-hover: initial;\n}\n\n:host(.button-clear.button-primary) {\n --c7-button-text: var(--c7-500);\n --c7-button-text-hover: var(--c7-500);\n}\n\n:host(.icon-only) {\n --c7-button-padding: 0;\n --c7-button-width: var(--c7-button-line-height);\n height: var(--c7-button-width);\n\n}\n\n:host(.button-solid) {\n\n}\n\n:host(.button-disabled) {\n opacity: .1;\n pointer-events: none;\n}\n\n/** Setting accessibility variables **/\n:host(.accessibility) {\n --c7-button-color: black;\n --c7-button-text: white;\n --c7-button-color-hover: #595959;\n --c7-button-text-hover: white;\n}\n","import { Component, h, Host, Element, Prop } from '@stencil/core';\nimport { hasShadowDom } from '../../../utils/helpers';\n\n@Component({\n tag: 'c7-button',\n styleUrl: 'button.styles.scss',\n shadow: true,\n})\nexport class Button {\n\n @Element() element!: HTMLElement;\n\n @Prop({reflect: true}) disabled: boolean;\n\n @Prop({reflect: true, mutable: true}) appearance: 'clear' | 'outline' | 'solid' = 'solid';\n\n @Prop({reflect: true}) color: 'primary';\n\n @Prop() shape: 'round' | 'bubble' | 'square' = 'square';\n\n @Prop() download: string;\n\n @Prop() href: string;\n\n @Prop() target: string;\n\n @Prop() rel: string;\n\n @Prop({reflect: true}) size: 'small' | 'default' | 'large' = 'default';\n\n @Prop() type: 'submit' | 'reset' | 'button' = 'button';\n\n get hasIconOnly() {\n return this.element.querySelector('[slot=\"icon-only\"]') !== null;\n }\n\n private onClick = (event: Event) => {\n if (this.type !== 'button' && hasShadowDom(this.element)) {\n const form = this.element.closest('form');\n\n if (form) {\n event.preventDefault();\n const fakeButton = document.createElement('button');\n fakeButton.type = this.type;\n fakeButton.style.display = 'none';\n form.appendChild(fakeButton);\n fakeButton.click();\n fakeButton.remove();\n }\n }\n }\n\n render() {\n\n const {href, download, target, rel, type, disabled, hasIconOnly, appearance, shape, color, size} = this;\n\n const TagType = !href ? 'button' : 'a';\n const attributes = (TagType === 'button')\n ? { type }\n : { download, href, rel, target }\n\n return (\n this.onClick(ev)}\n aria-disabled = {disabled ? 'true' : null}\n class={{\n 'button-disabled': disabled,\n 'c7-button': true,\n 'icon-only': hasIconOnly,\n [`button-${appearance}`]: !!appearance,\n [`button-${size}`]: !!size,\n [`button-${shape}`]: !!shape,\n [`button-${color}`]: !!this.color\n }}\n >\n \n \n \n \n \n \n \n\n \n\n \n )\n }\n\n}\n",":host{\n\n --background: #efefef;\n --background-hover: var(--c7-500);\n --background-active: var(--c7-500);\n --color: inherit;\n --color-hover: var(--c7-500-contrast);\n --color-active: var(--c7-500-contrast);\n --border: none;\n --border-active: none;\n --border-hover: none;\n --padding-inline: 1rem;\n --padding-block: 0;\n --min-height: 3em;\n --white-space: nowrap;\n\n height: 100%;\n\n ::slotted(ion-icon) {\n vertical-align: text-top;\n }\n\n button {\n\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n border: none;\n\n\n min-height: var(--min-height);\n padding: var(--padding-block) var(--padding-inline);\n\n background: var(--background);\n color: var(--color);\n border-radius: var(--border-radius);\n border: var(--border);\n transition: all .2s ease-in-out;\n\n display: inline-flex;\n flex-wrap: nowrap;\n align-items: center;\n\n .c7-button-toggle-text {\n flex: 1 1 auto;\n white-space: var(--white-space);\n }\n\n .c7-button-toggle-start, .c7-button-toggle-end {\n &:empty {\n display: none;\n }\n }\n\n .c7-button-toggle-start:not(:empty) {\n margin-right: .3rem;\n margin-left: -.3rem;\n }\n\n .c7-button-toggle-end:not(:empty) {\n margin-left: .3rem;\n margin-right: -.3rem;\n }\n\n\n\n &:hover:not(disabled){\n cursor: pointer;\n background: var(--background-hover);\n color: var(--color-hover);\n border: var(--border-hover);\n }\n }\n}\n\n:host(.selected) {\n button {\n background: var(--background-active);\n color: var(--color-active);\n border: var(--border-active);\n }\n}\n","import { Component, Host, h, Prop, Watch, Event, EventEmitter, Method } from '@stencil/core';\nimport { coerceBooleanProperty } from '../../../../utils/coerce';\n\nexport type ButtonToggleChangeEvent = {\n id: string;\n selected: boolean;\n value: any,\n}\n\n@Component({\n tag: 'c7-button-toggle',\n styleUrl: 'button-toggle.scss',\n shadow: {\n delegatesFocus: true\n }\n})\nexport class ButtonToggle {\n\n static BUTTON_TOGGLE_ID = 0;\n\n @Prop({mutable: true}) selected: boolean;\n @Watch('selected')\n onSelectedChange(value: boolean) {\n this.selected = coerceBooleanProperty(value);\n }\n\n @Prop({mutable:true}) disabled: boolean;\n @Watch('disabled')\n onDisabledChange(value: boolean) {\n this.disabled = coerceBooleanProperty(value);\n }\n\n @Prop() value: any;\n\n @Event({eventName: 'c7-button-toggle-change'}) change: EventEmitter;\n\n get elementId() {\n return `c7-button-toggle-${ButtonToggle.BUTTON_TOGGLE_ID++}`;\n }\n\n get event() {\n return {\n id: this.elementId,\n value: this.value,\n selected: this.selected\n }\n }\n\n @Method()\n async toggle(emitEvent: boolean = true) {\n this.selected = !this.selected;\n if (emitEvent) {\n this.change.emit({...this.event});\n }\n }\n\n @Method()\n async select(emitEvent: boolean = true) {\n this.selected = true;\n if (emitEvent) {\n this.change.emit({...this.event});\n }\n }\n\n @Method()\n async deselect(emitEvent: boolean = true) {\n this.selected = false;\n if (emitEvent) {\n this.change.emit({...this.event})\n }\n }\n\n\n render() {\n\n const cssClassNames = {\n 'c7-button-toggle': true,\n 'selected': !!this.selected,\n 'disabled': !!this.disabled\n }\n\n return (\n \n \n \n )\n }\n\n}\n",":host{\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: .5rem;\n border-radius: var(--border-radius);\n position: relative;\n}\n\n:host(.invalid) {\n border: 2px solid red;\n\n}\n","import { Component, Host, h, Prop, Watch, State, Element, Listen, Event, EventEmitter } from '@stencil/core';\nimport { coerceBooleanProperty } from '../../../../utils/coerce';\nimport { ButtonToggleChangeEvent } from './button-toggle';\nimport { createHiddenFormInput } from '../../../../utils/helpers';\n\nexport type ButtonToggleGroupChangeEvent = {\n value: T[]\n}\n\n@Component({\n tag: 'c7-button-toggle-group',\n styleUrl: 'button-toggle-group.scss',\n shadow: {\n delegatesFocus: true\n }\n})\nexport class ButtonToggleGroup {\n\n static buttonToggleGroupId = 0;\n\n @Element() element: HTMLElement;\n\n @Event({eventName: 'c7-button-toggle-group-change'}) valueChange: EventEmitter;\n\n @Prop({mutable: true}) multiple: boolean;\n @Watch('multiple')\n onMultipleChange(value: boolean) {\n this.multiple = coerceBooleanProperty(value);\n }\n\n @Prop() value: any[] = [];\n @Watch('value')\n onValueChange(value) {\n this.selected = value;\n this.setSelection();\n }\n\n @Prop({reflect: true}) disabled: boolean;\n @Prop({reflect:true}) required: boolean;\n @Prop({reflect: true}) name: string = `c7-button-toggle-group-${ButtonToggleGroup.buttonToggleGroupId++}`;\n\n private _hiddenInput: HTMLInputElement;\n\n @State() invalid: boolean = false;\n\n\n @State() selected: number[];\n\n\n\n @Listen('c7-button-toggle-change')\n onButtonToggleChange(event: CustomEvent) {\n const {id, value, selected} = event.detail;\n\n if(!this.multiple) {\n this.selected = this.selected.indexOf(value) !== -1 ? [] : [value];\n this.element.querySelectorAll('c7-button-toggle').forEach((button: HTMLC7ButtonToggleElement) => {\n if (this.selected.indexOf(button.value) === -1 && button.selected) {\n button.deselect(false);\n }\n })\n } else {\n\n const index = this.selected.indexOf(value);\n\n if (index !== - 1) {\n const temp = [...this.selected];\n temp.splice(index, 1);\n this.selected = [...temp];\n } else {\n this.selected = [...this.selected, value];\n }\n\n this.element.querySelectorAll('c7-button-toggle').forEach( (button: HTMLC7ButtonToggleElement) => {\n if (this.selected.indexOf(button.value) === -1 && button.selected) {\n button.deselect(false);\n }\n })\n }\n\n this._hiddenInput.value = this.selected.join(',');\n this.invalid = !!this.required && !this.selected.length;\n this.valueChange.emit({value: this.selected});\n\n }\n\n connectedCallback() {\n this._hiddenInput = createHiddenFormInput(this.element, this.name, this.value, this.disabled, this.required);\n this._hiddenInput?.addEventListener('invalid', () => {\n this.invalid = true;\n })\n }\n\n componentWillLoad() {\n this.selected = this.value;\n }\n\n componentDidLoad() {\n\n if (this.selected.length) {\n this.setSelection()\n }\n\n\n }\n\n private setSelection() {\n\n this._hiddenInput.value = this.selected.join(',');\n\n this.element.querySelectorAll('c7-button-toggle').forEach((button: HTMLC7ButtonToggleElement) => {\n\n const isButtonInSelection = this.selected.indexOf(button.value) !== -1;\n\n if (isButtonInSelection && !button.selected) {\n button.select(false);\n } else if (!isButtonInSelection && button.selected) {\n button.deselect(false);\n }\n });\n }\n\n\n\n render() {\n\n const cssClassNames = {\n 'c7-button-toggle-group': true,\n 'invalid': this.invalid\n }\n\n return (\n \n \n \n )\n }\n\n}\n","c7-categories-filter-button-group {\n display: block;\n\n c7-button-toggle {\n --padding-block: 8px;\n --background-hover: var(--background);\n --background-active: var(--background);\n --color-active: var(--color);\n --color-hover: var(--color);\n --border: 2px solid transparent;\n --border-hover: 2px solid var(--c7-500);\n --border-active: 2px solid var(--c7-500);\n }\n\n .category-icon-wrapper {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n ion-icon {\n vertical-align: baseline;\n }\n }\n}\n","import { Component, Event, EventEmitter, h, Host, Listen, Prop, State, Element, Watch } from '@stencil/core';\nimport { CategoryFilterProps } from '../categories-filter-circle/categories-filter-circle';\nimport { CategoryNameDto, CategoryTeaserDto, ModuleType } from '../../../../../api/APIClient';\nimport { getCategoriesByModuleType } from '../../../../../utils/categories';\nimport { ButtonToggleGroupChangeEvent } from '../../../../ui/controls/button-toggle-group/button-toggle-group';\nimport { AppliedFilter, getAppliedFiltersElement } from '../../applied-filters/applied-filters.utils';\n\n@Component({\n tag: 'c7-categories-filter-button-group',\n styleUrl: \"categories-filter-button-group.styles.scss\",\n shadow: false\n})\nexport class CategoriesFilterButtonGroupComponent {\n\n private appliedFiltersRef?: HTMLC7AppliedFiltersElement;\n private appliedFilterMap: Map> = new Map>();\n\n @Element() el!: HTMLElement;\n\n @Event({eventName: 'c7-category-filter'}) categoriesChange: EventEmitter\n\n @Prop() page!: number;\n\n @Prop() moduleType: ModuleType;\n\n @Prop() categories: number[] = [];\n\n @Prop() excludeCategories: number[] = [];\n\n @Prop({mutable: true}) value: number[] = [];\n @Watch('value')\n async onValueChange(value: number[], oldValue: number[]) {\n\n this.categoriesChange.emit({\n categories: this.value\n });\n\n if(this.appliedFiltersRef) {\n\n const add = value.filter(v => !oldValue.includes(v));\n const remove = oldValue.filter(v => !value.includes(v));\n\n await this.removeFromAppliedFilters(...remove);\n await this.addToAppliedFilters(...add);\n\n }\n\n\n }\n\n @Prop() multiple: boolean;\n\n @Prop() useSubCategories: boolean;\n\n @Prop() useCategoryColor: boolean;\n\n @Prop() showCategoryIcon: boolean;\n\n @State() availableCategories: CategoryTeaserDto[] = [];\n\n @Listen('c7-button-toggle-group-change')\n onButtonToggleGroupChange({detail}: CustomEvent) {\n this.value = detail.value;\n }\n\n async componentWillLoad() {\n\n this.appliedFiltersRef = getAppliedFiltersElement(this.el);\n const categories = await getCategoriesByModuleType(this.moduleType, this.page, this.categories, this.excludeCategories, true);\n this.availableCategories = this.useSubCategories ? categories.reduce((acc, curr) => [...acc, ...curr.subCategories], []) : categories;\n await this.addToAppliedFilters(...this.value);\n\n }\n\n async removeFromAppliedFilters(...categories: number[]) {\n categories.forEach(async (cat) => {\n await this.appliedFiltersRef.removeFilter(this.appliedFilterMap.get(cat));\n this.appliedFilterMap.delete(cat)\n });\n }\n\n async addToAppliedFilters(...categories: number[]) {\n\n const toAdd = this.availableCategories.filter((cat) => categories.includes(cat.id));\n\n toAdd.forEach(async (cat) => {\n const filter = await this.appliedFiltersRef.addFilter({\n label: cat.name,\n extendedProps: {\n category: cat\n },\n remove: this.onFilterRemove.bind(this)\n });\n\n if (this.useCategoryColor && cat.color) {\n filter.style = {\n background: cat.color,\n color: 'white'\n }\n }\n\n if (this.showCategoryIcon && cat.iconUrl) {\n filter.icon = cat.iconUrl;\n }\n\n this.appliedFilterMap.set(cat.id, filter);\n })\n }\n\n private onFilterRemove(filter: AppliedFilter<{category: CategoryNameDto}>) {\n\n const {category} = filter.extendedProps;\n this.appliedFilterMap.delete(category.id);\n this.value = this.value.filter((categoryId) => categoryId !== category.id);\n\n }\n\n\n render() {\n\n const cssClassNames = {\n 'c7-categories-filter-button-group': true\n };\n\n const {availableCategories, value, multiple, showCategoryIcon} = this;\n\n return (\n \n \n {\n availableCategories.map((category) => {\n\n const {iconUrl, color, id, name} = category;\n\n const style = color ? {\n background: color,\n color: 'white'\n } : {};\n\n return (\n \n {\n iconUrl && showCategoryIcon && (\n \n \n \n )\n }\n {name}\n \n )\n })\n }\n \n \n )\n }\n\n}\n",":host {\n --border-radius: calc(var(--size) * 0.125);\n --border-width: 2px;\n --border-style: solid;\n --border-color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.51);\n --checkmark-width: 3;\n --background: transparent;\n --transition: background 180ms cubic-bezier(0.4, 0, 0.2, 1);\n --size: 18px;\n\n --background-checked: var(--c7-500);\n --border-color-checked: var(--c7-500) ;\n --checkmark-color:var(--c7-500-contrast);\n\n\n display: inline-flex;\n gap: .5rem;\n position: relative;\n\n user-select: none;\n z-index: 2;\n\n\n}\n\n::slotted(*) {\n margin-top: 0;\n margin-bottom: 0;\n}\n\nlabel{\n line-height: 1;\n cursor: pointer;\n flex: 1;\n}\n\n\ninput {\n position: absolute;\n\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n\n width: 100%;\n height: 100%;\n\n margin: 0;\n padding: 0;\n\n border: 0;\n outline: 0;\n clip: rect(0 0 0 0);\n\n opacity: 0;\n overflow: hidden;\n\n -webkit-appearance: none;\n -moz-appearance: none;\n}\n\n.checkbox-icon {\n\n display: block;\n position: relative;\n\n width: var(--size);\n height: var(--size);\n\n flex-shrink: 0;\n\n transition: var(--transition);\n\n border-width: var(--border-width);\n border-style: var(--border-style);\n border-color: var(--border-color);\n\n border-radius: var(--border-radius);\n\n background: var(--background);\n\n box-sizing: border-box;\n}\n\n.checkbox-icon path {\n fill: none;\n stroke: var(--checkmark-color);\n stroke-width: var(--checkmark-width);\n\n opacity: 0;\n}\n\n\n// Checked / Indeterminate Checkbox\n// ---------------------------------------------\n\n:host(.checkbox-checked) .checkbox-icon,\n:host(.checkbox-indeterminate) .checkbox-icon {\n border-color: var(--border-color-checked);\n\n background: var(--background-checked);\n}\n\n:host(.checkbox-checked) .checkbox-icon path,\n:host(.checkbox-indeterminate) .checkbox-icon path {\n opacity: 1;\n}\n\n\n// Disabled Checkbox\n// ---------------------------------------------\n\n:host(.checkbox-disabled) {\n pointer-events: none;\n}\n","import { Component, Element, EventEmitter, Prop, Event, Watch, h, Host, Listen } from '@stencil/core';\nimport { renderHiddenInput } from '../../../../utils/helpers';\n\nexport type CheckboxChangeEventDetail = {\n checked: boolean,\n value: any\n}\n\n@Component({\n tag: 'c7-checkbox',\n styleUrl: 'checkbox.scss',\n shadow: true\n})\nexport class Checkbox {\n static checkboxIds: number = 0;\n\n private inputId = `c7-checkbox-${Checkbox.checkboxIds++}`;\n private focusEl?: HTMLElement;\n\n @Element() el!: HTMLElement;\n\n @Prop() name: string = this.inputId;\n\n @Prop({ mutable: true }) checked = false;\n\n @Prop({ mutable: true }) indeterminate = false;\n\n @Prop() required = false;\n\n @Prop() disabled = false;\n\n @Prop() value: any | null = 'on';\n\n @Event() checkboxChange!: EventEmitter;\n\n @Event() checkboxFocus!: EventEmitter;\n\n @Event() checkboxBlur!: EventEmitter;\n\n\n\n\n\n @Watch('checked')\n checkedChanged(isChecked: boolean) {\n this.checkboxChange.emit({\n checked: isChecked,\n value: this.value\n });\n }\n\n\n\n private setFocus() {\n if (this.focusEl) {\n this.focusEl.focus();\n }\n }\n\n private onClick = (ev: Event) => {\n\n if ((ev.target as HTMLElement).tagName === 'A') {\n return;\n }\n\n ev.preventDefault();\n this.setFocus();\n this.checked = !this.checked;\n this.indeterminate = false;\n }\n\n private onFocus = () => {\n this.checkboxFocus.emit();\n }\n\n private onBlur = () => {\n this.checkboxBlur.emit();\n }\n\n render() {\n const {checked, disabled, el, indeterminate, inputId, name, value, required } = this;\n\n renderHiddenInput(true, el, name, (checked ? value : ''), disabled, required);\n\n //let path = indeterminate ? : ;\n let path = indeterminate ? : ;\n\n\n return (\n \n\n \n {path}\n \n \n this.onFocus()}\n onBlur={() => this.onBlur()}\n ref={focusEl => this.focusEl = focusEl}\n />\n \n );\n }\n\n}\n",":host {\n display: inline-block;\n\n .c7-click-range-wrapper {\n display: flex;\n align-items: center;\n\n .c7-click-range-value {\n font-variant-numeric: tabular-nums;\n width: 2ch;\n text-align: center;\n }\n }\n\n}\n","import { Component, h, Host, Prop, Event, EventEmitter } from '@stencil/core';\nimport { renderHiddenInput } from '../../../../utils/helpers';\n\n@Component({\n tag: 'c7-click-range',\n styleUrl: 'click-range.styles.scss',\n shadow: true\n})\nexport class ClickRangeComponent {\n\n static id = 0;\n\n @Event() valueChange: EventEmitter;\n\n @Prop() name: string = `c7-click-range-${ClickRangeComponent.id ++}`;\n\n @Prop({mutable: true}) value: number;\n\n @Prop() required: boolean;\n\n @Prop() min: number;\n\n @Prop() max: number;\n\n @Prop() step: number = 1;\n\n componentWillLoad() {\n this.value = this.value ?? this.min ?? 0\n }\n\n private increase() {\n if (this.value >= this.max) return;\n this.value = this.value + this.step;\n this.valueChange.emit(this.value);\n }\n\n private decrease() {\n if (this.value <= this.min) return;\n this.value = this.value - this.step;\n this.valueChange.emit(this.value);\n }\n\n render() {\n\n const {name, min, max, value, required, step} = this;\n\n const cssClassNames = {\n 'c7-click-range': true\n }\n\n return (\n \n
\n this.decrease()}>\n \n \n
\n {value}\n
\n = max} onClick={() => this.increase()}>\n \n \n
\n
\n )\n\n }\n\n\n}\n","import { GalleryDisplay, GalleryPosition } from '../../../../api/APIClient';\nimport { FunctionalComponent, h } from '@stencil/core';\n\nexport interface GalleryProps {\n width: number;\n position: GalleryPosition;\n display: GalleryDisplay;\n [key:string]: any;\n}\n\nconst resolveTagName = (props: GalleryProps) => {\n\n switch (props.display) {\n case GalleryDisplay.MiniGallery:\n return 'c7-gallery-swipe';\n default: {\n return 'c7-gallery-default';\n }\n }\n}\n\nexport const Gallery: FunctionalComponent = (props, children) => {\n\n const GalleryType = resolveTagName(props);\n\n return (\n \n {children}\n \n );\n};\n","import { FunctionalComponent, h } from '@stencil/core';\n\nexport interface HeadingProps {\n textAlign?: 'center' | 'right' | 'left';\n level: number;\n}\n\nexport const Heading: FunctionalComponent = ({level, textAlign}, children) => {\n const HeadingType = `h${level}`;\n\n let styleMap = null;\n\n if (textAlign) {\n styleMap = {\n textAlign\n };\n }\n\n return (\n \n {children}\n \n )\n}\n","import { FunctionalComponent, h } from '@stencil/core';\nimport { ReferenceType } from '../../../../api/APIClient';\nimport { kebabize } from '../../../../utils/helpers';\n\nexport type ReferenceProps = {\n type?: ReferenceType,\n fileId?: string,\n referenceId?: number,\n target?: string,\n title?: string,\n href?: string\n}\n\nexport const Reference: FunctionalComponent = (props, children) => {\n const ReferenceTag = `c7-ref-${props.type.toLowerCase()}`;\n\n return \n {children}\n \n}\n","import { FunctionalComponent, h } from '@stencil/core';\n\nexport const Table: FunctionalComponent = (_, children) => {\n\n return (\n
\n \n {children}\n
\n
\n )\n}\n","import { FunctionalComponent, h } from '@stencil/core';\n\nexport const BulletList: FunctionalComponent = (_, children) => {\n\n return (\n
    \n {children}\n
\n )\n}\n","import { FunctionalComponent, h } from '@stencil/core';\n\nexport type ParagraphProps = {\n textAlign: 'left' | 'right' | 'center'\n}\n\nexport const Paragraph: FunctionalComponent = ({textAlign}, children) => {\n\n const styleMap = {\n textAlign\n }\n\n return (\n

\n {children}\n

\n )\n}\n","import { FunctionalComponent, h } from '@stencil/core';\n\nexport interface VideoProps {\n src: string,\n title?: string,\n caption?: string\n}\n\nexport const Video: FunctionalComponent = ({src, title, caption}) => {\n return (\n
\n
\n )\n}\n","import { FunctionalComponent, h } from '@stencil/core';\n\nexport interface AudioProps {\n src: string,\n title?: string,\n caption?: string\n}\n\nexport const Audio: FunctionalComponent = ({src, title, caption}) => {\n return (\n
\n
\n )\n}\n","import { NodeType } from '../../../../api/APIClient';\nimport { FunctionalComponent, h } from '@stencil/core';\n\nexport const PanelComponentBuilder = (type: NodeType.PanelInfo | NodeType.PanelTeaser): FunctionalComponent => {\n return (_, children) => (\n \n {children}\n \n )\n}\n","import { FunctionalComponent, h } from '@stencil/core';\n\nexport const Accordion: FunctionalComponent = (_, children) => {\n return (\n \n \n \n {children}\n \n \n \n )\n}\n","import { FunctionalComponent, h } from '@stencil/core';\n\nexport interface LinkProps {\n target?: string,\n title?: string,\n href?: string\n}\n\nexport const Link: FunctionalComponent = (props, children) => {\n\n if (props.href?.startsWith('www.')) {\n props.href = `//${props.href}`;\n }\n\n return (\n \n {children}\n \n )\n\n}\n","import { FunctionalComponent, h } from '@stencil/core';\nimport { Mark, MarkType, Node, NodeType } from '../../../api/APIClient';\nimport { Gallery } from './gallery/gallery';\nimport { Heading } from './heading/heading';\nimport { Reference } from './reference/reference';\nimport { Table } from './table/table';\nimport { BulletList } from './bullet-list/bullet-list';\nimport { Paragraph } from './paragraph/paragraph';\nimport { Video } from './video/video';\nimport { Audio } from './audio/audio';\nimport { PanelComponentBuilder } from './panel/panel-builder';\nimport { Accordion } from './accordion/accordion';\nimport { Link } from './link/link';\n\n\n\nexport interface ContentNodeProps {\n data: Node\n}\n\nconst MarkTagResolver = {\n [MarkType.Bold]: 'strong',\n [MarkType.Link]: Link,\n [MarkType.Italic]: 'em',\n [MarkType.Strike]: 'del',\n [MarkType.Subscript]: 'sub',\n [MarkType.Superscript]: 'sup',\n [MarkType.Underline]: 'u',\n [MarkType.Reference]: Reference\n};\n\nconst NodeTagResolver = {\n [NodeType.Paragraph]: Paragraph,\n [NodeType.HardBreak]: 'br',\n [NodeType.HorizontalRule]: 'hr',\n [NodeType.Heading]: Heading,\n [NodeType.ListItem]: 'li',\n [NodeType.OrderedList]: 'ol',\n [NodeType.Table]: Table,\n [NodeType.TableHeader]: 'th',\n [NodeType.TableRow]: 'tr',\n [NodeType.TableCell]: 'td',\n [NodeType.BulletList]: BulletList,\n [NodeType.Gallery]: Gallery,\n [NodeType.Video]: Video,\n [NodeType.Audio]: Audio,\n [NodeType.PanelInfo]: PanelComponentBuilder(NodeType.PanelInfo),\n [NodeType.PanelTeaser]: PanelComponentBuilder(NodeType.PanelTeaser),\n [NodeType.Vspace]: 'c7-vspace',\n [NodeType.Accordion]: Accordion,\n [NodeType.AccordionHeader]: 'c7-accordion-header',\n [NodeType.AccordionContent]: 'c7-accordion-content'\n};\n\nconst isNodeTagSelfClosing = (node: Node): boolean => {\n return (\n node.type === NodeType.HorizontalRule ||\n node.type === NodeType.HardBreak\n )\n}\n\nexport const MarkBuilder = (mark: Mark, content: any) => {\n const MarkTag = MarkTagResolver[mark.type];\n return (\n \n {content}\n \n )\n}\n\nexport const MarkWrap = (node: Node, content: any) => {\n if(!node.marks?.length) return content;\n\n return node.marks.reduce((acc, curr) => {\n return MarkBuilder(curr, acc);\n }, content)\n}\n\nexport const ContentNode:FunctionalComponent = ({data}) => {\n\n if (data.type === NodeType.Text) {\n return MarkWrap(data, data.text);\n }\n\n return data.content?.map((node) => {\n\n if(node.type === NodeType.Text) return ();\n\n const NodeTag = NodeTagResolver[node.type];\n return MarkWrap(\n node,\n !isNodeTagSelfClosing(node) ?\n (\n \n \n \n ) :\n ()\n );\n });\n}\n",".c7-content {\n\n display: block;\n\n &::after, &::before {\n content: \"\";\n display: block;\n clear: both;\n }\n\n figure.audio, figure.video {\n clear: both;\n margin-block-start: 1rem;\n margin-block-end: 1rem;\n margin-inline-start: 0;\n margin-inline-end: 0;\n }\n\n video, audio {\n width: 100%;\n }\n\n}\n\nc7-message .c7-content {\n > *:first-child {\n margin-top: 0;\n }\n}\n","import { Component, h, Host, Listen, Prop, Watch } from '@stencil/core';\nimport { GalleryImage, Node, NodeType } from '../../../api/APIClient';\nimport { createOverlay } from '../../../utils/overlay';\nimport { ContentNode } from './content-node';\n\n@Component({\n tag: 'c7-content',\n shadow: false,\n styleUrl: 'content.styles.scss'\n})\nexport class Content {\n\n @Prop() document!:Node | any;\n @Watch('document')\n onDocumentChange(value) {\n if (typeof value === 'string') {\n this.document = Node.fromJS(JSON.parse(value));\n }\n }\n\n componentWillLoad() {\n if (typeof this.document === 'string') {\n this.document = Node.fromJS(JSON.parse(this.document));\n }\n }\n\n @Listen('c7-lightbox-open')\n onLightboxOpen({detail}: CustomEvent) {\n const images = this.document.content\n .filter((item) => item.type == NodeType.Gallery)\n .reduce((res: GalleryImage[], curr: Node) => {\n return [...res, ...curr.attrs.images]\n }, []);\n\n const startIndex = images.findIndex((image) => image.id === detail);\n createOverlay({component: 'c7-lightbox', componentProps: {images, startIndex}});\n }\n\n render(){\n return (\n \n \n \n )\n }\n\n}\n",".c7-content-accordion {\n\n display: block;\n\n c7-accordion {\n --padding: 16px;\n }\n\n c7-accordion-header {\n --border: 0 0 1px 0;\n --border-color: #e6e6e6;\n --background-hover: #f6f6f6;\n --transition: background .3s ease-in-out;\n }\n\n c7-accordion-content {\n --border: 0 0 1px 0;\n --border-color: #e6e6e6;\n }\n\n}\n","import { Component, h, Host } from '@stencil/core';\n\n@Component({\n tag: 'c7-content-accordion',\n styleUrl: 'content-accordion.styles.scss',\n})\nexport class ContentAccordionComponent {\n\n\n render() {\n\n const cssClassNames = {\n 'c7-content-accordion': true\n };\n\n return (\n \n \n \n )\n }\n\n}\n","@use \"form-field.variables\" as variables;\n@import \"src/style\";\n\n:host{\n --c7-form-field-width: inherit;\n width: var(--c7-form-field-width);\n display: inline-block;\n position: relative;\n border-radius: var(--border-radius);\n background: var(--c7-form-field-background, #{variables.$default-background});\n\n .c7-form-field-wrapper {\n display: flex;\n border-radius: inherit;\n overflow: hidden;\n min-height: var(--c7-form-field-height, #{variables.$default-height});\n }\n\n ::slotted(input) {\n border: none;\n outline: none;\n padding: 0;\n padding-inline-start: .5rem;\n padding-inline-end: .5rem;\n font-size: var(--c7-form-field-font-size, #{variables.$default-font-size});\n font-family: inherit;\n width: -webkit-fill-available;\n width: -moz-available;\n height: 100%;\n max-height: unset;\n background: transparent;\n line-height: var(--c7-form-field-height, #{variables.$default-height});\n }\n\n\n ::slotted(textarea) {\n border: none;\n outline: none;\n font-family: inherit;\n font-size: var(--c7-form-field-font-size, #{variables.$default-font-size});\n line-height: 1.5;\n width: 100%;\n background: transparent;\n padding: .5em;\n }\n\n ::slotted(select) {\n border: none;\n outline: none;\n font-family: inherit;\n height: var(--c7-form-field-height, #{variables.$default-height});\n width: 100%;\n background: transparent;\n font-size: var(--c7-form-field-font-size, #{variables.$default-font-size});\n }\n\n .c7-form-field-input-wrapper{\n flex: 1 1 auto;\n }\n\n .c7-form-field-prefix, .c7-form-field-suffix {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: inherit;\n }\n\n .c7-form-field-prefix {\n ::slotted(:first-child) {\n margin-left: .5em;\n }\n }\n\n .c7-form-field-suffix {\n ::slotted(:last-child) {\n margin-right: .5em;\n }\n }\n\n}\n\n:host(.c7-form-field-outlined) {\n border-width: 2px;\n border-style: solid;\n border-color: var(--border-color, #{$color-200} );\n transition: border-color 0.2s ease-in-out;\n}\n\n:host(.c7-form-field-outlined:focus-within) {\n --border-color: var(--c7-500);\n}\n\n:host(.c7-form-field-dirty.c7-form-field-invalid) {\n --border-color: red;\n}\n\n\n","import { Component, h, Host, Listen, Prop, State, Element } from '@stencil/core';\nimport { componentOnReady } from '../../../../utils/component.utils';\n\n@Component({\n tag: 'c7-form-field',\n styleUrl: 'form-field.styles.scss',\n shadow: {\n delegatesFocus: true,\n },\n})\nexport class FormField {\n\n @Element() element: HTMLC7FormFieldElement;\n\n @Prop() appearance: 'outlined' = 'outlined';\n\n @State() isFocused: boolean = false;\n\n @State() validity: ValidityState;\n\n @State() dirty: boolean = false;\n\n @Listen('focusin')\n onFocusIn() {\n this.isFocused = true;\n }\n\n @Listen('focusout')\n onFocusOut() {\n this.isFocused = false;\n }\n\n\n componentDidLoad() {\n componentOnReady(this, () => {\n const nestedInput: HTMLInputElement | HTMLTextAreaElement = this.element.querySelector('input, textarea, select');\n const form = this.element.closest('form');\n\n this.validity = nestedInput?.validity;\n\n nestedInput?.addEventListener('blur', (event: Event) => {\n this.dirty = true;\n this.validity = (event.target as HTMLInputElement).validity;\n });\n\n nestedInput?.addEventListener('invalid', (event) => {\n this.dirty = true;\n this.validity = (event.target as HTMLInputElement).validity;\n })\n })\n }\n\n\n\n render() {\n\n const cssClassNames = {\n 'c7-form-field': true,\n [`c7-form-field-${this.appearance}`]: true,\n [`c7-form-field-focused`]: this.isFocused,\n 'c7-form-field-invalid': this.validity ? !this.validity.valid : false,\n 'c7-form-field-dirty': this.dirty\n };\n\n\n return (\n \n
\n \n \n \n \n \n \n \n
\n
\n );\n }\n}\n",":host{\n\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n overflow: hidden;\n object-position: center;\n background-color: var(--c7-img-background, #f6f6f6);\n\n img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: inherit;\n object-position: inherit;\n opacity: 1;\n transition: opacity .3s ease-in-out;\n }\n\n img:not([src]){\n display: none;\n }\n\n}\n\n:host(.c7-img-fit-cover){\n object-fit: var(--c7-img-fit, cover);\n}\n\n:host(.c7-img-fit-contain){\n object-fit: var(--c7-img-fit, contain);\n}\n\n:host(.c7-img-fit-scale-down){\n object-fit: var(--c7-img-fit, scale-down);;\n}\n\n:host(.c7-img-loading) {\n img {\n opacity: 0;\n }\n}\n\n\n","import { Component, h, Host, Prop, Watch, Element, State, Event, EventEmitter, Listen } from '@stencil/core';\nimport {IntersectionObserverAvailable} from '../../../utils/availability';\nimport { componentOnReady, raf } from '../../../utils/component.utils';\n\n@Component({\n tag: 'c7-img',\n styleUrl: 'image.scss',\n shadow: true\n})\nexport class Image {\n\n @Element() element!: HTMLElement;\n\n @Listen('resize', {target: 'window'})\n onResize(){\n this.registerIntersectionObserver();\n }\n\n @Prop({reflect: true}) src?: string;\n @Watch('src')\n onSrcChange() {\n this.load();\n //this.registerIntersectionObserver();\n }\n\n @Prop() alt?: string;\n\n @Prop() sync: boolean = false;\n\n @Prop() fit?: 'cover' | 'contain' | 'scale-down';\n\n @Event() imgWillLoad!: EventEmitter;\n\n @Event() imgDidLoad!: EventEmitter;\n\n @Event() imgError!: EventEmitter;\n\n @State() loadSrc?: string;\n\n @State() loadError?: () => void;\n\n @State() currentFit?: 'cover' | 'contain' | 'scale-down';\n\n private io: IntersectionObserver;\n\n private _imgRef: HTMLImageElement;\n\n private onLoad = () => {\n this.imgDidLoad.emit();\n\n if(!this.fit) {\n const {naturalWidth, naturalHeight} = this._imgRef;\n const ar = naturalWidth / naturalHeight;\n\n this.currentFit = ar < 1.2 || ar > 2 ? 'contain' : 'cover';\n }\n };\n\n private onError = () => {\n this.imgError.emit();\n }\n\n componentWillLoad() {\n if (this.fit) this.currentFit = this.fit;\n }\n\n componentDidLoad() {\n //this.registerIntersectionObserver();\n /*this.load();*/\n raf(() => {\n if(this.element.clientWidth == 0)\n {\n this.componentDidLoad();\n }\n else{\n this.load();\n }\n })\n\n }\n\n private registerIntersectionObserver() {\n\n if(!this.src) {\n return;\n }\n\n if (IntersectionObserverAvailable && !this.sync) {\n this.unregisterIntersectionObserver();\n this.io = new IntersectionObserver(data => {\n if (data[data.length - 1].isIntersecting) {\n this.load();\n this.unregisterIntersectionObserver();\n }\n });\n\n this.io.observe(this.element);\n } else {\n setTimeout(() => this.load(), 200);\n }\n }\n\n private unregisterIntersectionObserver() {\n if(this.io) {\n this.io.disconnect();\n this.io = undefined;\n }\n }\n\n private load() {\n this.loadError = this.onError;\n this.loadSrc = this.src ? `${this.src}${this.src.includes('?') ? '&' : '?'}size=${Math.ceil(this.element.clientWidth / 100) * 100 * 2}&webp=true` : null;\n this.imgWillLoad.emit();\n }\n\n render(){\n\n return (\n \n this._imgRef = el}\n part=\"image\" />\n \n )\n }\n\n}\n",":host{\n --padding: 18px;\n --background: #f6f6f6;\n\n display: flex;\n flex-direction: column;\n gap: .5rem;\n box-sizing: border-box;\n width: 100%;\n background-color: var(--background);\n\n border-radius: var(--border-radius);\n padding: var(--padding);\n}\n\n:host(:empty) {\n display: none;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'c7-info-panel',\n shadow: true,\n styleUrl: 'info-panel.scss',\n})\nexport class InfoPanel {\n\n render() {\n\n const cssClassNames = {\n ['c7-info-panel']: true\n };\n\n return (\n \n \n \n )\n\n }\n\n}\n",":host{\n font-size: 1.2rem;\n font-weight: bolder;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'c7-info-panel-title',\n shadow: true,\n styleUrl: 'info-panel-title.scss'\n})\nexport class InfoPanelTitle {\n\n render() {\n\n const cssClassNames = {\n ['c7-info-panel-title']: true\n };\n\n return (\n \n \n \n )\n }\n}\n","c7-list {\n margin: 0;\n padding: 0;\n display: block;\n contain: content;\n list-style-type: none;\n}\n","import { Component, h, Host, Prop } from '@stencil/core';\n\n@Component({\n tag: 'c7-list',\n styleUrl: 'list.styles.scss',\n})\nexport class ListComponent {\n\n render() {\n\n const cssClassNames = {\n 'c7-list': true\n }\n\n return (\n \n \n \n )\n }\n\n}\n",":host{\n --border-radius: 0px;\n --border-width: 0 0 0 0;\n --border-style: solid;\n --padding-top: 0px;\n --padding-bottom: 0px;\n --padding-end: 0px;\n --padding-start: 16px;\n --inner-border-width: 0 0 0 0;\n --inner-padding-top: 10px;\n --inner-padding-bottom: 11px;\n --inner-padding-start: 0px;\n --inner-padding-end: 16px;\n --inner-box-shadow: none;\n --color-activated: var(--color);\n --color-focused: var(--color);\n --color-hover: var(--color);\n\n --min-height: 48px;\n --background: transparent;\n --background-activated: transparent;\n --background-focused: currentColor;\n --background-hover: currentColor;\n --background-activated-opacity: 0;\n --background-focused-opacity: .12;\n --background-hover-opacity: .04;\n --border-color: transparent;\n --color: inherit;\n --transition: opacity 15ms linear, background-color 15ms linear;\n --start-slot-margin-end: 12px;\n --end-slot-margin-start: 12px;\n\n display: block;\n position: relative;\n\n align-items: center;\n justify-content: space-between;\n\n outline: none;\n color: var(--color);\n\n text-align: initial;\n text-decoration: none;\n overflow: hidden;\n box-sizing: border-box;\n\n\n}\n\n.c7-item-native {\n\n margin: 0;\n padding: var(--padding-top) var(--padding-end) var(--padding-bottom) var(--padding-start);\n\n display: flex;\n position: relative;\n\n align-items: inherit;\n justify-content: inherit;\n\n width: 100%;\n height: 100%;\n min-height: var(--min-height);\n transition: var(--transition);\n\n border-width: var(--border-width);\n border-style: var(--border-style);\n border-color: var(--border-color);\n border-radius: var(--border-radius);\n\n outline: none;\n\n font-family: inherit;\n font-size: inherit;\n font-style: inherit;\n font-weight: inherit;\n letter-spacing: inherit;\n text-decoration: inherit;\n text-indent: inherit;\n text-overflow: inherit;\n text-transform: inherit;\n text-align: inherit;\n white-space: inherit;\n color: inherit;\n\n background: var(--background);\n\n overflow: inherit;\n box-sizing: border-box;\n z-index: 1;\n\n\n\n &::after {\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n opacity: 0;\n transition: var(--transition);\n z-index: -1;\n }\n}\n\n.c7-item-native::-moz-focus-inner {\n border: 0;\n}\n\nbutton, a {\n cursor: pointer;\n user-select: none;\n\n -webkit-user-drag: none;\n}\n\n.c7-item-inner {\n\n margin: 0;\n padding: var(--inner-padding-top) var(--inner-padding-end) var(--inner-padding-bottom) var(--inner-padding-start);\n\n display: flex;\n position: relative;\n\n flex: 1;\n align-items: center;\n\n align-self: stretch;\n\n min-height: inherit;\n\n border-width: var(--inner-border-width);\n border-style: var(--border-style);\n border-color: var(--border-color);\n\n box-shadow: var(--inner-box-shadow);\n overflow: inherit;\n box-sizing: border-box;\n\n > * {\n margin: 0;\n }\n\n}\n\n.c7-item-content {\n display: flex;\n\n flex: 1;\n flex-direction: column;\n\n align-items: flex-start;\n justify-content: center;\n align-self: stretch;\n\n box-sizing: border-box;\n}\n\n::slotted(small) {\n opacity: .74;\n}\n\n::slotted(ion-icon) {\n font-size: 1.2em;\n pointer-events: none;\n}\n\n::slotted(c7-img) {\n width: 44px;\n height: 44px;\n}\n\n::slotted([slot=\"start\"]) {\n margin-right: var(--start-slot-margin-end);\n}\n\n::slotted([slot=\"end\"]) {\n margin-left: var(--end-slot-margin-start);\n}\n\n::slotted(.c7-accordion-toggle-icon) {\n transform: rotate(0);\n transition: transform .2s ease-in-out;\n}\n\n::slotted(:not([slot])) {\n margin: 0;\n}\n\n:host(.interactive:focus-within) .c7-item-native {\n color: var(--color-focused);\n\n &::after {\n background: var(--background-focused);\n opacity: var(--background-focused-opacity);\n }\n}\n\n:host(.interactive:not(.disabled):hover) .c7-item-native {\n color: var(--color-hover);\n &::after {\n background: var(--background-hover);\n opacity: var(--background-hover-opacity);\n }\n}\n\n:host-context(.accordion-expanded),\n:host-context(.accordion-expanding)\n{\n ::slotted(.c7-accordion-toggle-icon) {\n transform: rotate(180deg);\n }\n}\n\n","import { Component, Element, h, Host, Prop, State } from '@stencil/core';\nimport { Attributes } from '@tiptap/core';\nimport { raf } from '../../../../utils/component.utils';\nimport { hostContext, inheritAriaAttributes } from '../../../../utils/helpers';\n\n@Component({\n tag: 'c7-list-item',\n styleUrl: 'list-item.styles.scss',\n shadow: {\n delegatesFocus: true\n }\n})\nexport class ListItemComponent {\n\n private clickListener?: (ev: Event) => void;\n private inheritedAriaAttributes: Attributes = {};\n\n @Element() el!: HTMLC7ListItemElement;\n\n @State() focusable = true;\n\n @Prop() button: boolean;\n\n @Prop() disabled: boolean;\n\n @Prop() download?: string;\n\n @Prop() href?: string;\n\n @Prop() rel?: string;\n\n @Prop() target?: string;\n\n @Prop() type: 'submit' | 'reset' | 'button' = 'button';\n\n\n componentDidLoad() {\n raf(() => {\n this.inheritedAriaAttributes = inheritAriaAttributes(this.el, ['aria-label']);\n this.focusable = this.isFocusable();\n })\n }\n\n private isClickable(): boolean {\n return !!this.href || this.button;\n }\n\n private isFocusable(): boolean {\n const focusableChild = this.el.querySelector('a,button');\n return this.isClickable() || focusableChild !== null;\n }\n\n private hasStartEl() {\n const startEl = this.el.querySelector('[slot=\"start\"]');\n\n if (startEl !== null) {\n this.el.classList.add('item-has-start-slot');\n }\n }\n\n\n render() {\n\n const {\n download,\n disabled,\n href,\n rel,\n target,\n inheritedAriaAttributes,\n type\n } = this;\n\n const clickable = this.isClickable();\n\n const TagType = clickable ? (href === undefined ? 'button' : 'a') : ('div' as any);\n\n const attributes = TagType === 'button' ? {type} : {download, href, rel, target};\n\n const ariaDisabled = disabled ? 'true' : null;\n const inList = hostContext('c7-list', this.el);\n\n return (\n \n \n \n
\n
\n \n
\n \n
\n \n \n )\n }\n\n}\n","@use \"src/style/variables/text\";\n\n:host{\n\n --padding: 2em;\n --background: #e6e6e6;\n --color: inherit;\n\n box-sizing: border-box;\n\n padding: var(--padding);\n border-radius: var(--border-radius);\n display: flex;\n width: 100%;\n align-items: flex-start;\n gap: max(calc(var(--padding) / 2), 1em);\n\n background: var(--background);\n color: var(--color);\n\n\n ion-icon {\n width: 3em;\n height: 3em;\n flex-shrink: 0;\n\n }\n\n .c7-message-content {\n display: flex;\n flex-direction: column;\n gap: .5rem;\n }\n\n\n ::slotted(*) {\n margin: 0;\n }\n}\n\n:host(.c7-message-success) {\n\n ion-icon {\n color: green;\n }\n\n}\n\n:host(.c7-message-error) {\n ion-icon {\n color: red;\n }\n}\n","import { Component, Host, Prop,h } from '@stencil/core';\n\nexport type MessageType = 'info' | 'success' | 'error';\n\n@Component({\n tag: 'c7-message',\n styleUrl: 'message.styles.scss',\n shadow: true\n})\nexport class Message {\n\n @Prop() type: MessageType = 'info';\n\n private getIconName = () => {\n switch (this.type) {\n case 'error': {\n return 'alert-circle-outline'\n }\n case 'success': {\n return 'checkmark-circle-outline'\n }\n default: {\n return 'information-circle';\n }\n }\n }\n\n\n render() {\n\n const {type, getIconName} = this;\n\n const cssClassNames = {\n 'c7-message': true,\n [`c7-message-${type}`]: true\n };\n\n const iconName = this.getIconName()\n\n\n\n return (\n \n \n
\n \n
\n
\n )\n }\n\n}\n",".c7-overlay-no-scroll, .c7-overlay-no-scroll *{\n overflow: hidden;\n}\n\nc7-overlay{\n position: absolute;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: rgba(0,0,0, .7);\n\n\n .c7-overlay-container{\n position: relative;\n }\n}\n","import { Component, h, Host, Listen, Prop, Element, Method, Event, EventEmitter } from '@stencil/core';\n\n\nexport type OverlayProps = {\n width?: string,\n height?: string,\n maxWidth?: string,\n maxHeight?: string,\n cssClass?: string,\n hasBackdrop?: boolean,\n backdropDismiss?: boolean,\n component: T,\n componentProps?: any\n};\n\n\nconst OverlayClasses = (overlay: Overlay) => {\n return {\n ['c7-overlay']: true,\n ['c7-overlay-has-backdrop']: overlay.hasBackdrop,\n [overlay.cssClass]: !!overlay.cssClass\n }\n}\n\n@Component({\n tag: 'c7-overlay',\n styleUrl: 'overlay.styles.scss',\n shadow: false\n})\nexport class Overlay {\n\n static OVERLAY_ID = 0;\n static COUNT = 0;\n static Z_INDEX = 419;\n\n private id: number = Overlay.OVERLAY_ID++;\n\n @Element() element!: HTMLC7OverlayElement;\n\n @Prop() width: string;\n\n @Prop() height: string;\n\n @Prop() maxWidth: string;\n\n @Prop() maxHeight: string;\n\n @Prop() hasBackdrop: boolean;\n\n @Prop() backdropDismiss: boolean;\n\n @Prop() cssClass: string;\n\n @Prop() component!: keyof HTMLElementTagNameMap;\n\n @Prop() componentProps: any;\n\n @Event() overlayDidDismiss: EventEmitter;\n\n @Listen('keyup')\n async onKeyUp(event: KeyboardEvent) {\n if (event.key === 'Esc' || event.key === 'Escape') {\n await this.close();\n }\n }\n\n\n @Method()\n async close() {\n this.overlayDidDismiss.emit();\n this.element.remove();\n }\n\n connectedCallback() {\n if(!Overlay.COUNT) {\n document.documentElement.classList.add('c7-overlay-no-scroll');\n }\n Overlay.COUNT++;\n }\n\n disconnectedCallback(){\n Overlay.COUNT--;\n if(!Overlay.COUNT){\n document.documentElement.classList.remove('c7-overlay-no-scroll')\n }\n }\n\n private get containerStyles(): {[key: string]: string} {\n return {\n width: this.width || '100%',\n height: this.height || '100%',\n maxWidth: this.maxWidth,\n maxHeight: this.maxHeight\n }\n }\n\n render(){\n\n const OverlayContentComponent = this.component;\n\n return (\n \n { this.hasBackdrop && this.backdropDismiss && this.close()} />}\n
\n \n
\n
\n )\n }\n\n}\n",".c7-panel {\n padding: var(--padding, 24px);\n border-radius: var(--border-radius, 0px);\n background: var(--background, #f6f6f6);\n display: block;\n clear: both;\n}\n","import { Component, h, Host} from '@stencil/core';\n\n\n\n@Component({\n tag: 'c7-panel',\n styleUrl: 'panel.styles.scss'\n})\nexport class Panel {\n\n render() {\n\n const cssClassNames = {\n 'c7-panel': true,\n }\n\n return (\n \n \n \n )\n }\n\n}\n","$scale-duration: 225ms;\n$fade-in-duration: 75ms;\n$fade-out-duration: 150ms;\n$opacity-duration: $fade-in-duration + $fade-out-duration;\n\n:host {\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n\n position: absolute;\n\n contain: strict;\n pointer-events: none;\n}\n\n:host(.unbounded) {\n contain: layout size style;\n}\n\n.ripple-effect {\n border-radius: 50%;\n\n position: absolute;\n\n // Should remain static for performance reasons\n background-color: currentColor;\n color: inherit;\n\n contain: strict;\n opacity: 0;\n animation:\n $scale-duration rippleAnimation forwards,\n $fade-in-duration fadeInAnimation forwards;\n\n will-change: transform, opacity;\n pointer-events: none;\n}\n\n.fade-out {\n transform: translate(var(--translate-end)) scale(var(--final-scale, 1));\n animation: $fade-out-duration fadeOutAnimation forwards;\n}\n\n@keyframes rippleAnimation {\n from {\n animation-timing-function: cubic-bezier(.4, 0, .2, 1);\n\n transform: scale(1);\n }\n\n to {\n transform: translate(var(--translate-end)) scale(var(--final-scale, 1));\n }\n}\n\n@keyframes fadeInAnimation {\n from {\n animation-timing-function: linear;\n\n opacity: 0;\n }\n\n to {\n opacity: 0.16;\n }\n}\n\n@keyframes fadeOutAnimation {\n from {\n animation-timing-function: linear;\n\n opacity: 0.16;\n }\n\n to {\n opacity: 0;\n }\n}\n","import { Component, ComponentInterface, Element, Host, Method, Prop, h, readTask, writeTask } from '@stencil/core';\n\n//Shameless Ionic Copy Pasta\n\n@Component({\n tag: 'c7-ripple-effect',\n styleUrl: 'ripple-effect.scss',\n shadow: true\n})\nexport class RippleEffect implements ComponentInterface {\n\n @Element() el!: HTMLElement;\n\n @Prop() type: 'bounded' | 'unbounded' = 'bounded';\n\n /**\n * Adds the ripple effect to the parent element.\n *\n * @param x The horizontal coordinate of where the ripple should start.\n * @param y The vertical coordinate of where the ripple should start.\n */\n @Method()\n async addRipple(x: number, y: number) {\n return new Promise<() => void>(resolve => {\n readTask(() => {\n const rect = this.el.getBoundingClientRect();\n const width = rect.width;\n const height = rect.height;\n const hypotenuse = Math.sqrt(width * width + height * height);\n const maxDim = Math.max(height, width);\n const maxRadius = this.unbounded ? maxDim : hypotenuse + PADDING;\n const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE);\n const finalScale = maxRadius / initialSize;\n let posX = x - rect.left;\n let posY = y - rect.top;\n if (this.unbounded) {\n posX = width * 0.5;\n posY = height * 0.5;\n }\n const styleX = posX - initialSize * 0.5;\n const styleY = posY - initialSize * 0.5;\n const moveX = width * 0.5 - posX;\n const moveY = height * 0.5 - posY;\n\n writeTask(() => {\n const div = document.createElement('div');\n div.classList.add('ripple-effect');\n const style = div.style;\n style.top = styleY + 'px';\n style.left = styleX + 'px';\n style.width = style.height = initialSize + 'px';\n style.setProperty('--final-scale', `${finalScale}`);\n style.setProperty('--translate-end', `${moveX}px, ${moveY}px`);\n\n const container = this.el.shadowRoot || this.el;\n container.appendChild(div);\n setTimeout(() => {\n resolve(() => {\n removeRipple(div);\n });\n }, 225 + 100);\n });\n });\n });\n }\n\n private get unbounded() {\n return this.type === 'unbounded';\n }\n\n render() {\n return (\n \n \n );\n }\n}\n\nconst removeRipple = (ripple: HTMLElement) => {\n ripple.classList.add('fade-out');\n setTimeout(() => {\n ripple.remove();\n }, 200);\n};\n\nconst PADDING = 10;\nconst INITIAL_ORIGIN_SCALE = 0.5;\n","export const debounce = (func, wait) => {\n let timeout;\n\n return function executedFunction(...args) {\n const later = () => {\n clearTimeout(timeout);\n func(...args);\n };\n\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n };\n};\n",":host{\n\n c7-form-field {\n width: 100%;\n }\n\n button {\n background: transparent;\n box-sizing: border-box;\n padding: 0;\n border: none;\n outline: none;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n font-size: inherit;\n cursor: pointer;\n transition: all .3s ease-in-out;\n display: flex;\n align-items: center;\n justify-content: center;\n\n ion-icon {\n font-size: inherit;\n pointer-events: none;\n }\n\n &:hover, &:focus {\n background: #f6f6f6;\n }\n }\n}\n","import { Component, Element, Event, EventEmitter, h, Host, Prop } from '@stencil/core';\nimport { debounce } from '../../../../utils/debounce';\nimport { AppliedFilter, getAppliedFiltersElement } from '../applied-filters/applied-filters.utils';\n\nexport type SearchFilterProps = {\n search?: string\n}\n\n@Component({\n tag: 'c7-search-filter',\n styleUrl: 'search.styles.scss',\n shadow: true\n})\nexport class Search {\n\n @Element() el!: HTMLC7SearchFilterElement;\n\n @Prop() debounce: number = 300;\n\n @Prop() placeholder: string;\n\n @Prop({mutable: true}) value: string;\n\n @Event({eventName: 'c7-search-filter'}) filter: EventEmitter;\n\n //@State() input: string = '';\n\n private inputRef: HTMLInputElement;\n\n private appliedFiltersRef: HTMLC7AppliedFiltersElement;\n private appliedFilter: AppliedFilter;\n\n private debounceFn: () => void;\n\n private onInput(event) {\n\n if(!this.debounceFn) {\n this.debounceFn = debounce(() => {\n this.value = this.inputRef.value;\n this.filter.emit({search: this.value});\n\n if (this.appliedFiltersRef) {\n if (this.value) {\n this.addToAppliedFilters();\n } else {\n this.removeFromAppliedFilters();\n }\n }\n\n\n\n }, this.debounce);\n }\n\n this.debounceFn();\n }\n\n private onClear() {\n this.value = '';\n this.filter.emit({search: this.value});\n\n if (this.appliedFilter) {\n this.removeFromAppliedFilters();\n }\n }\n\n async componentWillLoad() {\n\n this.appliedFiltersRef = getAppliedFiltersElement(this.el);\n\n if (this.value && this.appliedFiltersRef) {\n await this.addToAppliedFilters();\n }\n\n }\n\n private async addToAppliedFilters() {\n if (!this.appliedFilter) {\n this.appliedFilter = await this.appliedFiltersRef.addFilter({\n label: `Suchbegriff „${this.value}“`,\n remove: this.onClear.bind(this)\n })\n } else {\n this.appliedFilter.label = `Suchbegriff „${this.value}“`;\n await this.appliedFiltersRef.updateFilter(this.appliedFilter);\n }\n }\n\n private async removeFromAppliedFilters() {\n await this.appliedFiltersRef.removeFilter(this.appliedFilter);\n this.appliedFilter = null;\n }\n\n render() {\n\n return (\n \n \n \n this.inputRef = el} placeholder={this.placeholder} value={this.value} onInput={(event) => this.onInput(event)}/>\n \n \n \n );\n }\n\n}\n","c7-carousel-slide {\n display: block;\n\n //width: 100%;\n height: 100%;\n}\n\n//.slide-zoom {\n// display: block;\n//\n// width: 100%;\n//\n// text-align: center;\n//}\n\n.swiper-slide {\n display: flex;\n position: relative;\n\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: auto;\n height: 100%;\n\n font-size: 18px;\n\n text-align: center;\n box-sizing: border-box;\n}\n\n//.swiper-slide img {\n// width: auto;\n// //max-width: 100%;\n// height: auto;\n// max-height: 100%;\n//}\n","import { Component, ComponentInterface, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'c7-slide',\n styleUrl: 'carousel-slide.styles.scss',\n shadow: false\n})\nexport class Slide implements ComponentInterface {\n\n render() {\n return (\n \n \n \n );\n }\n}\n","export default function classesToSelector(classes = '') {\n return `.${classes.trim().replace(/([\\.:!\\/])/g, '\\\\$1') // eslint-disable-line\n .replace(/ /g, '.')}`;\n}","import classesToSelector from '../../shared/classes-to-selector.js';\nimport createElementIfNotDefined from '../../shared/create-element-if-not-defined.js';\nimport { elementIndex, elementOuterSize, elementParents } from '../../shared/utils.js';\nexport default function Pagination({\n swiper,\n extendParams,\n on,\n emit\n}) {\n const pfx = 'swiper-pagination';\n extendParams({\n pagination: {\n el: null,\n bulletElement: 'span',\n clickable: false,\n hideOnClick: false,\n renderBullet: null,\n renderProgressbar: null,\n renderFraction: null,\n renderCustom: null,\n progressbarOpposite: false,\n type: 'bullets',\n // 'bullets' or 'progressbar' or 'fraction' or 'custom'\n dynamicBullets: false,\n dynamicMainBullets: 1,\n formatFractionCurrent: number => number,\n formatFractionTotal: number => number,\n bulletClass: `${pfx}-bullet`,\n bulletActiveClass: `${pfx}-bullet-active`,\n modifierClass: `${pfx}-`,\n currentClass: `${pfx}-current`,\n totalClass: `${pfx}-total`,\n hiddenClass: `${pfx}-hidden`,\n progressbarFillClass: `${pfx}-progressbar-fill`,\n progressbarOppositeClass: `${pfx}-progressbar-opposite`,\n clickableClass: `${pfx}-clickable`,\n lockClass: `${pfx}-lock`,\n horizontalClass: `${pfx}-horizontal`,\n verticalClass: `${pfx}-vertical`,\n paginationDisabledClass: `${pfx}-disabled`\n }\n });\n swiper.pagination = {\n el: null,\n bullets: []\n };\n let bulletSize;\n let dynamicBulletIndex = 0;\n const makeElementsArray = el => {\n if (!Array.isArray(el)) el = [el].filter(e => !!e);\n return el;\n };\n function isPaginationDisabled() {\n return !swiper.params.pagination.el || !swiper.pagination.el || Array.isArray(swiper.pagination.el) && swiper.pagination.el.length === 0;\n }\n function setSideBullets(bulletEl, position) {\n const {\n bulletActiveClass\n } = swiper.params.pagination;\n if (!bulletEl) return;\n bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];\n if (bulletEl) {\n bulletEl.classList.add(`${bulletActiveClass}-${position}`);\n bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];\n if (bulletEl) {\n bulletEl.classList.add(`${bulletActiveClass}-${position}-${position}`);\n }\n }\n }\n function onBulletClick(e) {\n const bulletEl = e.target.closest(classesToSelector(swiper.params.pagination.bulletClass));\n if (!bulletEl) {\n return;\n }\n e.preventDefault();\n const index = elementIndex(bulletEl) * swiper.params.slidesPerGroup;\n if (swiper.params.loop) {\n if (swiper.realIndex === index) return;\n if (index < swiper.loopedSlides || index > swiper.slides.length - swiper.loopedSlides) {\n swiper.loopFix({\n direction: index < swiper.loopedSlides ? 'prev' : 'next',\n activeSlideIndex: index,\n slideTo: false\n });\n }\n swiper.slideToLoop(index);\n } else {\n swiper.slideTo(index);\n }\n }\n function update() {\n // Render || Update Pagination bullets/items\n const rtl = swiper.rtl;\n const params = swiper.params.pagination;\n if (isPaginationDisabled()) return;\n let el = swiper.pagination.el;\n el = makeElementsArray(el);\n // Current/Total\n let current;\n const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;\n const total = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;\n if (swiper.params.loop) {\n current = swiper.params.slidesPerGroup > 1 ? Math.floor(swiper.realIndex / swiper.params.slidesPerGroup) : swiper.realIndex;\n } else if (typeof swiper.snapIndex !== 'undefined') {\n current = swiper.snapIndex;\n } else {\n current = swiper.activeIndex || 0;\n }\n // Types\n if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {\n const bullets = swiper.pagination.bullets;\n let firstIndex;\n let lastIndex;\n let midIndex;\n if (params.dynamicBullets) {\n bulletSize = elementOuterSize(bullets[0], swiper.isHorizontal() ? 'width' : 'height', true);\n el.forEach(subEl => {\n subEl.style[swiper.isHorizontal() ? 'width' : 'height'] = `${bulletSize * (params.dynamicMainBullets + 4)}px`;\n });\n if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {\n dynamicBulletIndex += current - (swiper.previousIndex || 0);\n if (dynamicBulletIndex > params.dynamicMainBullets - 1) {\n dynamicBulletIndex = params.dynamicMainBullets - 1;\n } else if (dynamicBulletIndex < 0) {\n dynamicBulletIndex = 0;\n }\n }\n firstIndex = Math.max(current - dynamicBulletIndex, 0);\n lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);\n midIndex = (lastIndex + firstIndex) / 2;\n }\n bullets.forEach(bulletEl => {\n bulletEl.classList.remove(...['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(suffix => `${params.bulletActiveClass}${suffix}`));\n });\n if (el.length > 1) {\n bullets.forEach(bullet => {\n const bulletIndex = elementIndex(bullet);\n if (bulletIndex === current) {\n bullet.classList.add(params.bulletActiveClass);\n }\n if (params.dynamicBullets) {\n if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {\n bullet.classList.add(`${params.bulletActiveClass}-main`);\n }\n if (bulletIndex === firstIndex) {\n setSideBullets(bullet, 'prev');\n }\n if (bulletIndex === lastIndex) {\n setSideBullets(bullet, 'next');\n }\n }\n });\n } else {\n const bullet = bullets[current];\n if (bullet) {\n bullet.classList.add(params.bulletActiveClass);\n }\n if (params.dynamicBullets) {\n const firstDisplayedBullet = bullets[firstIndex];\n const lastDisplayedBullet = bullets[lastIndex];\n for (let i = firstIndex; i <= lastIndex; i += 1) {\n if (bullets[i]) {\n bullets[i].classList.add(`${params.bulletActiveClass}-main`);\n }\n }\n setSideBullets(firstDisplayedBullet, 'prev');\n setSideBullets(lastDisplayedBullet, 'next');\n }\n }\n if (params.dynamicBullets) {\n const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);\n const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;\n const offsetProp = rtl ? 'right' : 'left';\n bullets.forEach(bullet => {\n bullet.style[swiper.isHorizontal() ? offsetProp : 'top'] = `${bulletsOffset}px`;\n });\n }\n }\n el.forEach((subEl, subElIndex) => {\n if (params.type === 'fraction') {\n subEl.querySelectorAll(classesToSelector(params.currentClass)).forEach(fractionEl => {\n fractionEl.textContent = params.formatFractionCurrent(current + 1);\n });\n subEl.querySelectorAll(classesToSelector(params.totalClass)).forEach(totalEl => {\n totalEl.textContent = params.formatFractionTotal(total);\n });\n }\n if (params.type === 'progressbar') {\n let progressbarDirection;\n if (params.progressbarOpposite) {\n progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';\n } else {\n progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';\n }\n const scale = (current + 1) / total;\n let scaleX = 1;\n let scaleY = 1;\n if (progressbarDirection === 'horizontal') {\n scaleX = scale;\n } else {\n scaleY = scale;\n }\n subEl.querySelectorAll(classesToSelector(params.progressbarFillClass)).forEach(progressEl => {\n progressEl.style.transform = `translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`;\n progressEl.style.transitionDuration = `${swiper.params.speed}ms`;\n });\n }\n if (params.type === 'custom' && params.renderCustom) {\n subEl.innerHTML = params.renderCustom(swiper, current + 1, total);\n if (subElIndex === 0) emit('paginationRender', subEl);\n } else {\n if (subElIndex === 0) emit('paginationRender', subEl);\n emit('paginationUpdate', subEl);\n }\n if (swiper.params.watchOverflow && swiper.enabled) {\n subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);\n }\n });\n }\n function render() {\n // Render Container\n const params = swiper.params.pagination;\n if (isPaginationDisabled()) return;\n const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;\n let el = swiper.pagination.el;\n el = makeElementsArray(el);\n let paginationHTML = '';\n if (params.type === 'bullets') {\n let numberOfBullets = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;\n if (swiper.params.freeMode && swiper.params.freeMode.enabled && numberOfBullets > slidesLength) {\n numberOfBullets = slidesLength;\n }\n for (let i = 0; i < numberOfBullets; i += 1) {\n if (params.renderBullet) {\n paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);\n } else {\n paginationHTML += `<${params.bulletElement} class=\"${params.bulletClass}\">`;\n }\n }\n }\n if (params.type === 'fraction') {\n if (params.renderFraction) {\n paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);\n } else {\n paginationHTML = `` + ' / ' + ``;\n }\n }\n if (params.type === 'progressbar') {\n if (params.renderProgressbar) {\n paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);\n } else {\n paginationHTML = ``;\n }\n }\n el.forEach(subEl => {\n if (params.type !== 'custom') {\n subEl.innerHTML = paginationHTML || '';\n }\n if (params.type === 'bullets') {\n swiper.pagination.bullets = [...subEl.querySelectorAll(classesToSelector(params.bulletClass))];\n }\n });\n if (params.type !== 'custom') {\n emit('paginationRender', el[0]);\n }\n }\n function init() {\n swiper.params.pagination = createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, {\n el: 'swiper-pagination'\n });\n const params = swiper.params.pagination;\n if (!params.el) return;\n let el;\n if (typeof params.el === 'string' && swiper.isElement) {\n el = swiper.el.shadowRoot.querySelector(params.el);\n }\n if (!el && typeof params.el === 'string') {\n el = [...document.querySelectorAll(params.el)];\n }\n if (!el) {\n el = params.el;\n }\n if (!el || el.length === 0) return;\n if (swiper.params.uniqueNavElements && typeof params.el === 'string' && Array.isArray(el) && el.length > 1) {\n el = [...swiper.el.querySelectorAll(params.el)];\n // check if it belongs to another nested Swiper\n if (el.length > 1) {\n el = el.filter(subEl => {\n if (elementParents(subEl, '.swiper')[0] !== swiper.el) return false;\n return true;\n })[0];\n }\n }\n if (Array.isArray(el) && el.length === 1) el = el[0];\n Object.assign(swiper.pagination, {\n el\n });\n el = makeElementsArray(el);\n el.forEach(subEl => {\n if (params.type === 'bullets' && params.clickable) {\n subEl.classList.add(params.clickableClass);\n }\n subEl.classList.add(params.modifierClass + params.type);\n subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);\n if (params.type === 'bullets' && params.dynamicBullets) {\n subEl.classList.add(`${params.modifierClass}${params.type}-dynamic`);\n dynamicBulletIndex = 0;\n if (params.dynamicMainBullets < 1) {\n params.dynamicMainBullets = 1;\n }\n }\n if (params.type === 'progressbar' && params.progressbarOpposite) {\n subEl.classList.add(params.progressbarOppositeClass);\n }\n if (params.clickable) {\n subEl.addEventListener('click', onBulletClick);\n }\n if (!swiper.enabled) {\n subEl.classList.add(params.lockClass);\n }\n });\n }\n function destroy() {\n const params = swiper.params.pagination;\n if (isPaginationDisabled()) return;\n let el = swiper.pagination.el;\n if (el) {\n el = makeElementsArray(el);\n el.forEach(subEl => {\n subEl.classList.remove(params.hiddenClass);\n subEl.classList.remove(params.modifierClass + params.type);\n subEl.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);\n if (params.clickable) {\n subEl.removeEventListener('click', onBulletClick);\n }\n });\n }\n if (swiper.pagination.bullets) swiper.pagination.bullets.forEach(subEl => subEl.classList.remove(params.bulletActiveClass));\n }\n on('init', () => {\n if (swiper.params.pagination.enabled === false) {\n // eslint-disable-next-line\n disable();\n } else {\n init();\n render();\n update();\n }\n });\n on('activeIndexChange', () => {\n if (typeof swiper.snapIndex === 'undefined') {\n update();\n }\n });\n on('snapIndexChange', () => {\n update();\n });\n on('snapGridLengthChange', () => {\n render();\n update();\n });\n on('destroy', () => {\n destroy();\n });\n on('enable disable', () => {\n let {\n el\n } = swiper.pagination;\n if (el) {\n el = makeElementsArray(el);\n el.forEach(subEl => subEl.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.pagination.lockClass));\n }\n });\n on('lock unlock', () => {\n update();\n });\n on('click', (_s, e) => {\n const targetEl = e.target;\n let {\n el\n } = swiper.pagination;\n if (!Array.isArray(el)) el = [el].filter(element => !!element);\n if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && el && el.length > 0 && !targetEl.classList.contains(swiper.params.pagination.bulletClass)) {\n if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return;\n const isHidden = el[0].classList.contains(swiper.params.pagination.hiddenClass);\n if (isHidden === true) {\n emit('paginationShow');\n } else {\n emit('paginationHide');\n }\n el.forEach(subEl => subEl.classList.toggle(swiper.params.pagination.hiddenClass));\n }\n });\n const enable = () => {\n swiper.el.classList.remove(swiper.params.pagination.paginationDisabledClass);\n let {\n el\n } = swiper.pagination;\n if (el) {\n el = makeElementsArray(el);\n el.forEach(subEl => subEl.classList.remove(swiper.params.pagination.paginationDisabledClass));\n }\n init();\n render();\n update();\n };\n const disable = () => {\n swiper.el.classList.add(swiper.params.pagination.paginationDisabledClass);\n let {\n el\n } = swiper.pagination;\n if (el) {\n el = makeElementsArray(el);\n el.forEach(subEl => subEl.classList.add(swiper.params.pagination.paginationDisabledClass));\n }\n destroy();\n };\n Object.assign(swiper.pagination, {\n enable,\n disable,\n render,\n update,\n init,\n destroy\n });\n}","import { getWindow } from 'ssr-window';\nimport { elementChildren, elementOffset, elementParents, getTranslate } from '../../shared/utils.js';\nexport default function Zoom({\n swiper,\n extendParams,\n on,\n emit\n}) {\n const window = getWindow();\n extendParams({\n zoom: {\n enabled: false,\n maxRatio: 3,\n minRatio: 1,\n toggle: true,\n containerClass: 'swiper-zoom-container',\n zoomedSlideClass: 'swiper-slide-zoomed'\n }\n });\n swiper.zoom = {\n enabled: false\n };\n let currentScale = 1;\n let isScaling = false;\n let fakeGestureTouched;\n let fakeGestureMoved;\n const evCache = [];\n const gesture = {\n slideEl: undefined,\n slideWidth: undefined,\n slideHeight: undefined,\n imageEl: undefined,\n imageWrapEl: undefined,\n maxRatio: 3\n };\n const image = {\n isTouched: undefined,\n isMoved: undefined,\n currentX: undefined,\n currentY: undefined,\n minX: undefined,\n minY: undefined,\n maxX: undefined,\n maxY: undefined,\n width: undefined,\n height: undefined,\n startX: undefined,\n startY: undefined,\n touchesStart: {},\n touchesCurrent: {}\n };\n const velocity = {\n x: undefined,\n y: undefined,\n prevPositionX: undefined,\n prevPositionY: undefined,\n prevTime: undefined\n };\n let scale = 1;\n Object.defineProperty(swiper.zoom, 'scale', {\n get() {\n return scale;\n },\n set(value) {\n if (scale !== value) {\n const imageEl = gesture.imageEl;\n const slideEl = gesture.slideEl;\n emit('zoomChange', value, imageEl, slideEl);\n }\n scale = value;\n }\n });\n function getDistanceBetweenTouches() {\n if (evCache.length < 2) return 1;\n const x1 = evCache[0].pageX;\n const y1 = evCache[0].pageY;\n const x2 = evCache[1].pageX;\n const y2 = evCache[1].pageY;\n const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n return distance;\n }\n function getScaleOrigin() {\n if (evCache.length < 2) return {\n x: null,\n y: null\n };\n const box = gesture.imageEl.getBoundingClientRect();\n return [(evCache[0].pageX + (evCache[1].pageX - evCache[0].pageX) / 2 - box.x) / currentScale, (evCache[0].pageY + (evCache[1].pageY - evCache[0].pageY) / 2 - box.y) / currentScale];\n }\n function getSlideSelector() {\n return swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;\n }\n function eventWithinSlide(e) {\n const slideSelector = getSlideSelector();\n if (e.target.matches(slideSelector)) return true;\n if (swiper.slides.filter(slideEl => slideEl.contains(e.target)).length > 0) return true;\n return false;\n }\n function eventWithinZoomContainer(e) {\n const selector = `.${swiper.params.zoom.containerClass}`;\n if (e.target.matches(selector)) return true;\n if ([...swiper.el.querySelectorAll(selector)].filter(containerEl => containerEl.contains(e.target)).length > 0) return true;\n return false;\n }\n\n // Events\n function onGestureStart(e) {\n if (e.pointerType === 'mouse') {\n evCache.splice(0, evCache.length);\n }\n if (!eventWithinSlide(e)) return;\n const params = swiper.params.zoom;\n fakeGestureTouched = false;\n fakeGestureMoved = false;\n evCache.push(e);\n if (evCache.length < 2) {\n return;\n }\n fakeGestureTouched = true;\n gesture.scaleStart = getDistanceBetweenTouches();\n if (!gesture.slideEl) {\n gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);\n if (!gesture.slideEl) gesture.slideEl = swiper.slides[swiper.activeIndex];\n let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);\n if (imageEl) {\n imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];\n }\n gesture.imageEl = imageEl;\n if (imageEl) {\n gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];\n } else {\n gesture.imageWrapEl = undefined;\n }\n if (!gesture.imageWrapEl) {\n gesture.imageEl = undefined;\n return;\n }\n gesture.maxRatio = gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;\n }\n if (gesture.imageEl) {\n const [originX, originY] = getScaleOrigin();\n gesture.imageEl.style.transformOrigin = `${originX}px ${originY}px`;\n gesture.imageEl.style.transitionDuration = '0ms';\n }\n isScaling = true;\n }\n function onGestureChange(e) {\n if (!eventWithinSlide(e)) return;\n const params = swiper.params.zoom;\n const zoom = swiper.zoom;\n const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);\n if (pointerIndex >= 0) evCache[pointerIndex] = e;\n if (evCache.length < 2) {\n return;\n }\n fakeGestureMoved = true;\n gesture.scaleMove = getDistanceBetweenTouches();\n if (!gesture.imageEl) {\n return;\n }\n zoom.scale = gesture.scaleMove / gesture.scaleStart * currentScale;\n if (zoom.scale > gesture.maxRatio) {\n zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5;\n }\n if (zoom.scale < params.minRatio) {\n zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5;\n }\n gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;\n }\n function onGestureEnd(e) {\n if (!eventWithinSlide(e)) return;\n if (e.pointerType === 'mouse' && e.type === 'pointerout') return;\n const params = swiper.params.zoom;\n const zoom = swiper.zoom;\n const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);\n if (pointerIndex >= 0) evCache.splice(pointerIndex, 1);\n if (!fakeGestureTouched || !fakeGestureMoved) {\n return;\n }\n fakeGestureTouched = false;\n fakeGestureMoved = false;\n if (!gesture.imageEl) return;\n zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);\n gesture.imageEl.style.transitionDuration = `${swiper.params.speed}ms`;\n gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;\n currentScale = zoom.scale;\n isScaling = false;\n if (zoom.scale === 1) gesture.slideEl = undefined;\n }\n function onTouchStart(e) {\n const device = swiper.device;\n if (!gesture.imageEl) return;\n if (image.isTouched) return;\n if (device.android && e.cancelable) e.preventDefault();\n image.isTouched = true;\n image.touchesStart.x = e.pageX;\n image.touchesStart.y = e.pageY;\n }\n function onTouchMove(e) {\n if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) return;\n const zoom = swiper.zoom;\n if (!gesture.imageEl) return;\n swiper.allowClick = false;\n if (!image.isTouched || !gesture.slideEl) return;\n if (!image.isMoved) {\n image.width = gesture.imageEl.offsetWidth;\n image.height = gesture.imageEl.offsetHeight;\n image.startX = getTranslate(gesture.imageWrapEl, 'x') || 0;\n image.startY = getTranslate(gesture.imageWrapEl, 'y') || 0;\n gesture.slideWidth = gesture.slideEl.offsetWidth;\n gesture.slideHeight = gesture.slideEl.offsetHeight;\n gesture.imageWrapEl.style.transitionDuration = '0ms';\n }\n // Define if we need image drag\n const scaledWidth = image.width * zoom.scale;\n const scaledHeight = image.height * zoom.scale;\n if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return;\n image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);\n image.maxX = -image.minX;\n image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);\n image.maxY = -image.minY;\n image.touchesCurrent.x = evCache.length > 0 ? evCache[0].pageX : e.pageX;\n image.touchesCurrent.y = evCache.length > 0 ? evCache[0].pageY : e.pageY;\n if (!image.isMoved && !isScaling) {\n if (swiper.isHorizontal() && (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x || Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)) {\n image.isTouched = false;\n return;\n }\n if (!swiper.isHorizontal() && (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y || Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)) {\n image.isTouched = false;\n return;\n }\n }\n if (e.cancelable) {\n e.preventDefault();\n }\n e.stopPropagation();\n image.isMoved = true;\n image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX;\n image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY;\n if (image.currentX < image.minX) {\n image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8;\n }\n if (image.currentX > image.maxX) {\n image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8;\n }\n if (image.currentY < image.minY) {\n image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8;\n }\n if (image.currentY > image.maxY) {\n image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8;\n }\n\n // Velocity\n if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;\n if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;\n if (!velocity.prevTime) velocity.prevTime = Date.now();\n velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;\n velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;\n if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;\n if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;\n velocity.prevPositionX = image.touchesCurrent.x;\n velocity.prevPositionY = image.touchesCurrent.y;\n velocity.prevTime = Date.now();\n gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;\n }\n function onTouchEnd() {\n const zoom = swiper.zoom;\n if (!gesture.imageEl) return;\n if (!image.isTouched || !image.isMoved) {\n image.isTouched = false;\n image.isMoved = false;\n return;\n }\n image.isTouched = false;\n image.isMoved = false;\n let momentumDurationX = 300;\n let momentumDurationY = 300;\n const momentumDistanceX = velocity.x * momentumDurationX;\n const newPositionX = image.currentX + momentumDistanceX;\n const momentumDistanceY = velocity.y * momentumDurationY;\n const newPositionY = image.currentY + momentumDistanceY;\n\n // Fix duration\n if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);\n if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);\n const momentumDuration = Math.max(momentumDurationX, momentumDurationY);\n image.currentX = newPositionX;\n image.currentY = newPositionY;\n\n // Define if we need image drag\n const scaledWidth = image.width * zoom.scale;\n const scaledHeight = image.height * zoom.scale;\n image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);\n image.maxX = -image.minX;\n image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);\n image.maxY = -image.minY;\n image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);\n image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);\n gesture.imageWrapEl.style.transitionDuration = `${momentumDuration}ms`;\n gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;\n }\n function onTransitionEnd() {\n const zoom = swiper.zoom;\n if (gesture.slideEl && swiper.previousIndex !== swiper.activeIndex) {\n if (gesture.imageEl) {\n gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';\n }\n if (gesture.imageWrapEl) {\n gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';\n }\n zoom.scale = 1;\n currentScale = 1;\n gesture.slideEl = undefined;\n gesture.imageEl = undefined;\n gesture.imageWrapEl = undefined;\n }\n }\n function zoomIn(e) {\n const zoom = swiper.zoom;\n const params = swiper.params.zoom;\n if (!gesture.slideEl) {\n if (e && e.target) {\n gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);\n }\n if (!gesture.slideEl) {\n if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {\n gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];\n } else {\n gesture.slideEl = swiper.slides[swiper.activeIndex];\n }\n }\n let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);\n if (imageEl) {\n imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];\n }\n gesture.imageEl = imageEl;\n if (imageEl) {\n gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];\n } else {\n gesture.imageWrapEl = undefined;\n }\n }\n if (!gesture.imageEl || !gesture.imageWrapEl) return;\n if (swiper.params.cssMode) {\n swiper.wrapperEl.style.overflow = 'hidden';\n swiper.wrapperEl.style.touchAction = 'none';\n }\n gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);\n let touchX;\n let touchY;\n let offsetX;\n let offsetY;\n let diffX;\n let diffY;\n let translateX;\n let translateY;\n let imageWidth;\n let imageHeight;\n let scaledWidth;\n let scaledHeight;\n let translateMinX;\n let translateMinY;\n let translateMaxX;\n let translateMaxY;\n let slideWidth;\n let slideHeight;\n if (typeof image.touchesStart.x === 'undefined' && e) {\n touchX = e.pageX;\n touchY = e.pageY;\n } else {\n touchX = image.touchesStart.x;\n touchY = image.touchesStart.y;\n }\n const forceZoomRatio = typeof e === 'number' ? e : null;\n if (currentScale === 1 && forceZoomRatio) {\n touchX = undefined;\n touchY = undefined;\n }\n zoom.scale = forceZoomRatio || gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;\n currentScale = forceZoomRatio || gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;\n if (e && !(currentScale === 1 && forceZoomRatio)) {\n slideWidth = gesture.slideEl.offsetWidth;\n slideHeight = gesture.slideEl.offsetHeight;\n offsetX = elementOffset(gesture.slideEl).left + window.scrollX;\n offsetY = elementOffset(gesture.slideEl).top + window.scrollY;\n diffX = offsetX + slideWidth / 2 - touchX;\n diffY = offsetY + slideHeight / 2 - touchY;\n imageWidth = gesture.imageEl.offsetWidth;\n imageHeight = gesture.imageEl.offsetHeight;\n scaledWidth = imageWidth * zoom.scale;\n scaledHeight = imageHeight * zoom.scale;\n translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);\n translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);\n translateMaxX = -translateMinX;\n translateMaxY = -translateMinY;\n translateX = diffX * zoom.scale;\n translateY = diffY * zoom.scale;\n if (translateX < translateMinX) {\n translateX = translateMinX;\n }\n if (translateX > translateMaxX) {\n translateX = translateMaxX;\n }\n if (translateY < translateMinY) {\n translateY = translateMinY;\n }\n if (translateY > translateMaxY) {\n translateY = translateMaxY;\n }\n } else {\n translateX = 0;\n translateY = 0;\n }\n gesture.imageWrapEl.style.transitionDuration = '300ms';\n gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`;\n gesture.imageEl.style.transitionDuration = '300ms';\n gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;\n }\n function zoomOut() {\n const zoom = swiper.zoom;\n const params = swiper.params.zoom;\n if (!gesture.slideEl) {\n if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {\n gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];\n } else {\n gesture.slideEl = swiper.slides[swiper.activeIndex];\n }\n let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);\n if (imageEl) {\n imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];\n }\n gesture.imageEl = imageEl;\n if (imageEl) {\n gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];\n } else {\n gesture.imageWrapEl = undefined;\n }\n }\n if (!gesture.imageEl || !gesture.imageWrapEl) return;\n if (swiper.params.cssMode) {\n swiper.wrapperEl.style.overflow = '';\n swiper.wrapperEl.style.touchAction = '';\n }\n zoom.scale = 1;\n currentScale = 1;\n gesture.imageWrapEl.style.transitionDuration = '300ms';\n gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';\n gesture.imageEl.style.transitionDuration = '300ms';\n gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';\n gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);\n gesture.slideEl = undefined;\n }\n\n // Toggle Zoom\n function zoomToggle(e) {\n const zoom = swiper.zoom;\n if (zoom.scale && zoom.scale !== 1) {\n // Zoom Out\n zoomOut();\n } else {\n // Zoom In\n zoomIn(e);\n }\n }\n function getListeners() {\n const passiveListener = swiper.params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n const activeListenerWithCapture = swiper.params.passiveListeners ? {\n passive: false,\n capture: true\n } : true;\n return {\n passiveListener,\n activeListenerWithCapture\n };\n }\n\n // Attach/Detach Events\n function enable() {\n const zoom = swiper.zoom;\n if (zoom.enabled) return;\n zoom.enabled = true;\n const {\n passiveListener,\n activeListenerWithCapture\n } = getListeners();\n\n // Scale image\n\n swiper.wrapperEl.addEventListener('pointerdown', onGestureStart, passiveListener);\n swiper.wrapperEl.addEventListener('pointermove', onGestureChange, activeListenerWithCapture);\n ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {\n swiper.wrapperEl.addEventListener(eventName, onGestureEnd, passiveListener);\n });\n\n // Move image\n swiper.wrapperEl.addEventListener('pointermove', onTouchMove, activeListenerWithCapture);\n }\n function disable() {\n const zoom = swiper.zoom;\n if (!zoom.enabled) return;\n zoom.enabled = false;\n const {\n passiveListener,\n activeListenerWithCapture\n } = getListeners();\n\n // Scale image\n swiper.wrapperEl.removeEventListener('pointerdown', onGestureStart, passiveListener);\n swiper.wrapperEl.removeEventListener('pointermove', onGestureChange, activeListenerWithCapture);\n ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {\n swiper.wrapperEl.removeEventListener(eventName, onGestureEnd, passiveListener);\n });\n\n // Move image\n swiper.wrapperEl.removeEventListener('pointermove', onTouchMove, activeListenerWithCapture);\n }\n on('init', () => {\n if (swiper.params.zoom.enabled) {\n enable();\n }\n });\n on('destroy', () => {\n disable();\n });\n on('touchStart', (_s, e) => {\n if (!swiper.zoom.enabled) return;\n onTouchStart(e);\n });\n on('touchEnd', (_s, e) => {\n if (!swiper.zoom.enabled) return;\n onTouchEnd(e);\n });\n on('doubleTap', (_s, e) => {\n if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {\n zoomToggle(e);\n }\n });\n on('transitionEnd', () => {\n if (swiper.zoom.enabled && swiper.params.zoom.enabled) {\n onTransitionEnd();\n }\n });\n on('slideChange', () => {\n if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {\n onTransitionEnd();\n }\n });\n Object.assign(swiper.zoom, {\n enable,\n disable,\n in: zoomIn,\n out: zoomOut,\n toggle: zoomToggle\n });\n}","/* eslint no-underscore-dangle: \"off\" */\n/* eslint no-use-before-define: \"off\" */\nimport { getDocument } from 'ssr-window';\nexport default function Autoplay({\n swiper,\n extendParams,\n on,\n emit,\n params\n}) {\n swiper.autoplay = {\n running: false,\n paused: false,\n timeLeft: 0\n };\n extendParams({\n autoplay: {\n enabled: false,\n delay: 3000,\n waitForTransition: true,\n disableOnInteraction: true,\n stopOnLastSlide: false,\n reverseDirection: false,\n pauseOnMouseEnter: false\n }\n });\n let timeout;\n let raf;\n let autoplayDelayTotal = params && params.autoplay ? params.autoplay.delay : 3000;\n let autoplayDelayCurrent = params && params.autoplay ? params.autoplay.delay : 3000;\n let autoplayTimeLeft;\n let autoplayStartTime = new Date().getTime;\n let wasPaused;\n let isTouched;\n let pausedByTouch;\n let touchStartTimeout;\n let slideChanged;\n let pausedByInteraction;\n function onTransitionEnd(e) {\n if (!swiper || swiper.destroyed || !swiper.wrapperEl) return;\n if (e.target !== swiper.wrapperEl) return;\n swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd);\n resume();\n }\n const calcTimeLeft = () => {\n if (swiper.destroyed || !swiper.autoplay.running) return;\n if (swiper.autoplay.paused) {\n wasPaused = true;\n } else if (wasPaused) {\n autoplayDelayCurrent = autoplayTimeLeft;\n wasPaused = false;\n }\n const timeLeft = swiper.autoplay.paused ? autoplayTimeLeft : autoplayStartTime + autoplayDelayCurrent - new Date().getTime();\n swiper.autoplay.timeLeft = timeLeft;\n emit('autoplayTimeLeft', timeLeft, timeLeft / autoplayDelayTotal);\n raf = requestAnimationFrame(() => {\n calcTimeLeft();\n });\n };\n const getSlideDelay = () => {\n let activeSlideEl;\n if (swiper.virtual && swiper.params.virtual.enabled) {\n activeSlideEl = swiper.slides.filter(slideEl => slideEl.classList.contains('swiper-slide-active'))[0];\n } else {\n activeSlideEl = swiper.slides[swiper.activeIndex];\n }\n if (!activeSlideEl) return undefined;\n const currentSlideDelay = parseInt(activeSlideEl.getAttribute('data-swiper-autoplay'), 10);\n return currentSlideDelay;\n };\n const run = delayForce => {\n if (swiper.destroyed || !swiper.autoplay.running) return;\n cancelAnimationFrame(raf);\n calcTimeLeft();\n let delay = typeof delayForce === 'undefined' ? swiper.params.autoplay.delay : delayForce;\n autoplayDelayTotal = swiper.params.autoplay.delay;\n autoplayDelayCurrent = swiper.params.autoplay.delay;\n const currentSlideDelay = getSlideDelay();\n if (!Number.isNaN(currentSlideDelay) && currentSlideDelay > 0 && typeof delayForce === 'undefined') {\n delay = currentSlideDelay;\n autoplayDelayTotal = currentSlideDelay;\n autoplayDelayCurrent = currentSlideDelay;\n }\n autoplayTimeLeft = delay;\n const speed = swiper.params.speed;\n const proceed = () => {\n if (!swiper || swiper.destroyed) return;\n if (swiper.params.autoplay.reverseDirection) {\n if (!swiper.isBeginning || swiper.params.loop || swiper.params.rewind) {\n swiper.slidePrev(speed, true, true);\n emit('autoplay');\n } else if (!swiper.params.autoplay.stopOnLastSlide) {\n swiper.slideTo(swiper.slides.length - 1, speed, true, true);\n emit('autoplay');\n }\n } else {\n if (!swiper.isEnd || swiper.params.loop || swiper.params.rewind) {\n swiper.slideNext(speed, true, true);\n emit('autoplay');\n } else if (!swiper.params.autoplay.stopOnLastSlide) {\n swiper.slideTo(0, speed, true, true);\n emit('autoplay');\n }\n }\n if (swiper.params.cssMode) {\n autoplayStartTime = new Date().getTime();\n requestAnimationFrame(() => {\n run();\n });\n }\n };\n if (delay > 0) {\n clearTimeout(timeout);\n timeout = setTimeout(() => {\n proceed();\n }, delay);\n } else {\n requestAnimationFrame(() => {\n proceed();\n });\n }\n\n // eslint-disable-next-line\n return delay;\n };\n const start = () => {\n swiper.autoplay.running = true;\n run();\n emit('autoplayStart');\n };\n const stop = () => {\n swiper.autoplay.running = false;\n clearTimeout(timeout);\n cancelAnimationFrame(raf);\n emit('autoplayStop');\n };\n const pause = (internal, reset) => {\n if (swiper.destroyed || !swiper.autoplay.running) return;\n clearTimeout(timeout);\n if (!internal) {\n pausedByInteraction = true;\n }\n const proceed = () => {\n emit('autoplayPause');\n if (swiper.params.autoplay.waitForTransition) {\n swiper.wrapperEl.addEventListener('transitionend', onTransitionEnd);\n } else {\n resume();\n }\n };\n swiper.autoplay.paused = true;\n if (reset) {\n if (slideChanged) {\n autoplayTimeLeft = swiper.params.autoplay.delay;\n }\n slideChanged = false;\n proceed();\n return;\n }\n const delay = autoplayTimeLeft || swiper.params.autoplay.delay;\n autoplayTimeLeft = delay - (new Date().getTime() - autoplayStartTime);\n if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) return;\n if (autoplayTimeLeft < 0) autoplayTimeLeft = 0;\n proceed();\n };\n const resume = () => {\n if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop || swiper.destroyed || !swiper.autoplay.running) return;\n autoplayStartTime = new Date().getTime();\n if (pausedByInteraction) {\n pausedByInteraction = false;\n run(autoplayTimeLeft);\n } else {\n run();\n }\n swiper.autoplay.paused = false;\n emit('autoplayResume');\n };\n const onVisibilityChange = () => {\n if (swiper.destroyed || !swiper.autoplay.running) return;\n const document = getDocument();\n if (document.visibilityState === 'hidden') {\n pausedByInteraction = true;\n pause(true);\n }\n if (document.visibilityState === 'visible') {\n resume();\n }\n };\n const onPointerEnter = e => {\n if (e.pointerType !== 'mouse') return;\n pausedByInteraction = true;\n pause(true);\n };\n const onPointerLeave = e => {\n if (e.pointerType !== 'mouse') return;\n if (swiper.autoplay.paused) {\n resume();\n }\n };\n const attachMouseEvents = () => {\n if (swiper.params.autoplay.pauseOnMouseEnter) {\n swiper.el.addEventListener('pointerenter', onPointerEnter);\n swiper.el.addEventListener('pointerleave', onPointerLeave);\n }\n };\n const detachMouseEvents = () => {\n swiper.el.removeEventListener('pointerenter', onPointerEnter);\n swiper.el.removeEventListener('pointerleave', onPointerLeave);\n };\n const attachDocumentEvents = () => {\n const document = getDocument();\n document.addEventListener('visibilitychange', onVisibilityChange);\n };\n const detachDocumentEvents = () => {\n const document = getDocument();\n document.removeEventListener('visibilitychange', onVisibilityChange);\n };\n on('init', () => {\n if (swiper.params.autoplay.enabled) {\n attachMouseEvents();\n attachDocumentEvents();\n autoplayStartTime = new Date().getTime();\n start();\n }\n });\n on('destroy', () => {\n detachMouseEvents();\n detachDocumentEvents();\n if (swiper.autoplay.running) {\n stop();\n }\n });\n on('beforeTransitionStart', (_s, speed, internal) => {\n if (swiper.destroyed || !swiper.autoplay.running) return;\n if (internal || !swiper.params.autoplay.disableOnInteraction) {\n pause(true, true);\n } else {\n stop();\n }\n });\n on('sliderFirstMove', () => {\n if (swiper.destroyed || !swiper.autoplay.running) return;\n if (swiper.params.autoplay.disableOnInteraction) {\n stop();\n return;\n }\n isTouched = true;\n pausedByTouch = false;\n pausedByInteraction = false;\n touchStartTimeout = setTimeout(() => {\n pausedByInteraction = true;\n pausedByTouch = true;\n pause(true);\n }, 200);\n });\n on('touchEnd', () => {\n if (swiper.destroyed || !swiper.autoplay.running || !isTouched) return;\n clearTimeout(touchStartTimeout);\n clearTimeout(timeout);\n if (swiper.params.autoplay.disableOnInteraction) {\n pausedByTouch = false;\n isTouched = false;\n return;\n }\n if (pausedByTouch && swiper.params.cssMode) resume();\n pausedByTouch = false;\n isTouched = false;\n });\n on('slideChange', () => {\n if (swiper.destroyed || !swiper.autoplay.running) return;\n slideChanged = true;\n });\n Object.assign(swiper.autoplay, {\n start,\n stop,\n pause,\n resume\n });\n}","export default function effectInit(params) {\n const {\n effect,\n swiper,\n on,\n setTranslate,\n setTransition,\n overwriteParams,\n perspective,\n recreateShadows,\n getEffectParams\n } = params;\n on('beforeInit', () => {\n if (swiper.params.effect !== effect) return;\n swiper.classNames.push(`${swiper.params.containerModifierClass}${effect}`);\n if (perspective && perspective()) {\n swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);\n }\n const overwriteParamsResult = overwriteParams ? overwriteParams() : {};\n Object.assign(swiper.params, overwriteParamsResult);\n Object.assign(swiper.originalParams, overwriteParamsResult);\n });\n on('setTranslate', () => {\n if (swiper.params.effect !== effect) return;\n setTranslate();\n });\n on('setTransition', (_s, duration) => {\n if (swiper.params.effect !== effect) return;\n setTransition(duration);\n });\n on('transitionEnd', () => {\n if (swiper.params.effect !== effect) return;\n if (recreateShadows) {\n if (!getEffectParams || !getEffectParams().slideShadows) return;\n // remove shadows\n swiper.slides.forEach(slideEl => {\n slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => shadowEl.remove());\n });\n // create new one\n recreateShadows();\n }\n });\n let requireUpdateOnVirtual;\n on('virtualUpdate', () => {\n if (swiper.params.effect !== effect) return;\n if (!swiper.slides.length) {\n requireUpdateOnVirtual = true;\n }\n requestAnimationFrame(() => {\n if (requireUpdateOnVirtual && swiper.slides && swiper.slides.length) {\n setTranslate();\n requireUpdateOnVirtual = false;\n }\n });\n });\n}","import { getSlideTransformEl } from './utils.js';\nexport default function effectTarget(effectParams, slideEl) {\n const transformEl = getSlideTransformEl(slideEl);\n if (transformEl !== slideEl) {\n transformEl.style.backfaceVisibility = 'hidden';\n transformEl.style['-webkit-backface-visibility'] = 'hidden';\n }\n return transformEl;\n}","import { elementTransitionEnd } from './utils.js';\nexport default function effectVirtualTransitionEnd({\n swiper,\n duration,\n transformElements,\n allSlides\n}) {\n const {\n activeIndex\n } = swiper;\n const getSlide = el => {\n if (!el.parentElement) {\n // assume shadow root\n const slide = swiper.slides.filter(slideEl => slideEl.shadowEl && slideEl.shadowEl === el.parentNode)[0];\n return slide;\n }\n return el.parentElement;\n };\n if (swiper.params.virtualTranslate && duration !== 0) {\n let eventTriggered = false;\n let transitionEndTarget;\n if (allSlides) {\n transitionEndTarget = transformElements;\n } else {\n transitionEndTarget = transformElements.filter(transformEl => {\n const el = transformEl.classList.contains('swiper-slide-transform') ? getSlide(transformEl) : transformEl;\n return swiper.getSlideIndex(el) === activeIndex;\n });\n }\n transitionEndTarget.forEach(el => {\n elementTransitionEnd(el, () => {\n if (eventTriggered) return;\n if (!swiper || swiper.destroyed) return;\n eventTriggered = true;\n swiper.animating = false;\n const evt = new window.CustomEvent('transitionend', {\n bubbles: true,\n cancelable: true\n });\n swiper.wrapperEl.dispatchEvent(evt);\n });\n });\n }\n}","import effectInit from '../../shared/effect-init.js';\nimport effectTarget from '../../shared/effect-target.js';\nimport effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';\nimport { getSlideTransformEl } from '../../shared/utils.js';\nexport default function EffectFade({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n fadeEffect: {\n crossFade: false\n }\n });\n const setTranslate = () => {\n const {\n slides\n } = swiper;\n const params = swiper.params.fadeEffect;\n for (let i = 0; i < slides.length; i += 1) {\n const slideEl = swiper.slides[i];\n const offset = slideEl.swiperSlideOffset;\n let tx = -offset;\n if (!swiper.params.virtualTranslate) tx -= swiper.translate;\n let ty = 0;\n if (!swiper.isHorizontal()) {\n ty = tx;\n tx = 0;\n }\n const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs(slideEl.progress), 0) : 1 + Math.min(Math.max(slideEl.progress, -1), 0);\n const targetEl = effectTarget(params, slideEl);\n targetEl.style.opacity = slideOpacity;\n targetEl.style.transform = `translate3d(${tx}px, ${ty}px, 0px)`;\n }\n };\n const setTransition = duration => {\n const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));\n transformElements.forEach(el => {\n el.style.transitionDuration = `${duration}ms`;\n });\n effectVirtualTransitionEnd({\n swiper,\n duration,\n transformElements,\n allSlides: true\n });\n };\n effectInit({\n effect: 'fade',\n swiper,\n on,\n setTranslate,\n setTransition,\n overwriteParams: () => ({\n slidesPerView: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n spaceBetween: 0,\n virtualTranslate: !swiper.params.cssMode\n })\n });\n}","@import '~swiper/swiper-bundle.min.css';\n\nc7-slides {\n display: block;\n user-select: none;\n\n .swiper-wrapper {\n align-items: stretch;\n }\n\n .swiper-button-prev, .swiper-button-next {\n width: 44px;\n background: var(--c7-500);\n --swiper-navigation-color: var(--c7-500-contrast);\n border-radius: 50%;\n\n &::after {\n --swiper-navigation-size: 24px;\n }\n }\n\n}\n","import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, Watch, h } from '@stencil/core';\nimport SwiperCore, {SwiperOptions, Swiper, Pagination, Navigation, Autoplay, EffectFade, Zoom} from 'swiper';\nimport { componentOnReady, raf } from '../../../utils/component.utils';\nimport { NavigationOptions } from 'swiper/types';\n\nSwiperCore.use([\n Navigation,\n Pagination,\n Autoplay,\n EffectFade,\n // Lazy,\n Zoom\n]);\n\n@Component({\n tag: 'c7-slides',\n styleUrl: 'carousel.styles.scss',\n shadow: false,\n})\nexport class CarouselComponent implements ComponentInterface {\n private scrollbarEl?: HTMLElement;\n private swiperReady = false;\n private mutationO?: MutationObserver;\n private readySwiper!: (swiper: Swiper) => void;\n private swiper: Promise = new Promise(resolve => {\n this.readySwiper = resolve;\n });\n\n @Element() el!: HTMLElement;\n\n @Prop() customPaginationElement?: HTMLElement;\n @Prop() customPaginationSelector?: string;\n\n private paginationEl?: HTMLElement;\n\n /**\n * Options to pass to the swiper instance.\n * See http://idangero.us/swiper/swiper-api/ for valid options\n */\n @Prop() options: any = {};\n\n @Watch('options')\n async optionsChanged() {\n if (this.swiperReady) {\n const swiper = await this.getSwiper();\n if (swiper?.params) {\n Object.assign(swiper.params, this.options);\n await this.update();\n }\n }\n }\n\n @Prop() pager = true;\n\n @Prop() scrollbar = false;\n\n @Prop() navigation: boolean;\n\n @Event({ eventName: 'c7-slides-did-load' }) c7SlidesDidLoad!: EventEmitter;\n\n @Event() c7SlideTap!: EventEmitter;\n\n @Event() c7SlideDoubleTap!: EventEmitter;\n\n @Event({ eventName: 'c7-slide-will-change' }) c7SlideWillChange!: EventEmitter;\n\n @Event({ eventName: 'c7-slide-did-change' }) c7SlideDidChange!: EventEmitter;\n\n @Event() c7SlideNextStart!: EventEmitter;\n\n @Event() c7SlidePrevStart!: EventEmitter;\n\n @Event() c7SlideNextEnd!: EventEmitter;\n\n @Event() c7SlidePrevEnd!: EventEmitter;\n\n @Event() c7SlideTransitionStart!: EventEmitter;\n\n @Event({ eventName: 'c7-slide-transition-end' }) c7SlideTransitionEnd!: EventEmitter;\n\n @Event() c7SlideDrag!: EventEmitter;\n\n @Event() c7SlideReachStart!: EventEmitter;\n\n @Event() c7SlideReachEnd!: EventEmitter;\n\n @Event() c7SlideTouchStart!: EventEmitter;\n\n @Event() c7SlideTouchEnd!: EventEmitter;\n\n connectedCallback() {\n // tslint:disable-next-line: strict-type-predicates\n if (typeof MutationObserver !== 'undefined') {\n const mut = (this.mutationO = new MutationObserver(() => {\n if (this.swiperReady) {\n this.update();\n }\n }));\n\n mut.observe(this.el, {\n childList: true,\n subtree: true,\n });\n\n componentOnReady(this.el, () => {\n this.initSwiper();\n });\n }\n }\n\n disconnectedCallback() {\n if (this.mutationO) {\n this.mutationO.disconnect();\n this.mutationO = undefined;\n }\n }\n\n @Method()\n async update() {\n const [swiper] = await Promise.all([this.getSwiper(), waitForSlides(this.el)]);\n swiper.update();\n }\n\n @Method()\n async updateAutoHeight(speed?: number) {\n const swiper = await this.getSwiper();\n swiper.updateAutoHeight(speed);\n }\n\n @Method()\n async slideTo(index: number, speed?: number, runCallbacks?: boolean) {\n const swiper = await this.getSwiper();\n swiper.slideTo(index, speed, runCallbacks);\n }\n\n @Method()\n async slideNext(speed?: number, runCallbacks?: boolean) {\n const swiper = await this.getSwiper();\n swiper.slideNext(speed!, runCallbacks!);\n }\n\n @Method()\n async slidePrev(speed?: number, runCallbacks?: boolean) {\n const swiper = await this.getSwiper();\n swiper.slidePrev(speed, runCallbacks);\n }\n\n @Method()\n async getActiveIndex(): Promise {\n const swiper = await this.getSwiper();\n return swiper.activeIndex;\n }\n\n @Method()\n async getPreviousIndex(): Promise {\n const swiper = await this.getSwiper();\n return swiper.previousIndex;\n }\n\n @Method()\n async length(): Promise {\n const swiper = await this.getSwiper();\n return swiper.slides.length;\n }\n\n @Method()\n async isEnd(): Promise {\n const swiper = await this.getSwiper();\n return swiper.isEnd;\n }\n\n @Method()\n async isBeginning(): Promise {\n const swiper = await this.getSwiper();\n return swiper.isBeginning;\n }\n\n @Method()\n async startAutoplay() {\n const swiper = await this.getSwiper();\n if (swiper.autoplay) {\n swiper.autoplay.start();\n }\n }\n\n @Method()\n async stopAutoplay() {\n const swiper = await this.getSwiper();\n if (swiper.autoplay) {\n swiper.autoplay.stop();\n }\n }\n\n @Method()\n async pauseAutoplay() {\n const swiper = await this.getSwiper();\n if (swiper.autoplay) {\n swiper.autoplay.pause();\n }\n }\n\n @Method()\n async resumeAutoplay() {\n const swiper = await this.getSwiper();\n if (swiper.autoplay) {\n swiper.autoplay.resume();\n }\n }\n\n @Method()\n async lockSwipeToNext(lock: boolean) {\n const swiper = await this.getSwiper();\n swiper.allowSlideNext = !lock;\n }\n\n @Method()\n async lockSwipeToPrev(lock: boolean) {\n const swiper = await this.getSwiper();\n swiper.allowSlidePrev = !lock;\n }\n\n @Method()\n async lockSwipes(lock: boolean) {\n const swiper = await this.getSwiper();\n swiper.allowSlideNext = !lock;\n swiper.allowSlidePrev = !lock;\n swiper.allowTouchMove = !lock;\n }\n\n @Method()\n async getSwiper(): Promise {\n return this.swiper;\n }\n\n private async initSwiper() {\n const finalOptions = this.normalizeOptions();\n await waitForSlides(this.el);\n const swiper = new Swiper(this.el, finalOptions);\n\n this.swiperReady = true;\n this.readySwiper(swiper);\n }\n\n private normalizeOptions(): SwiperOptions {\n const swiperOptions: SwiperOptions = {\n effect: undefined,\n direction: 'horizontal',\n initialSlide: 0,\n loop: false,\n parallax: false,\n slidesPerView: 1,\n spaceBetween: 0,\n speed: 300,\n slidesPerGroup: 1,\n centeredSlides: false,\n slidesOffsetBefore: 0,\n slidesOffsetAfter: 0,\n touchEventsTarget: 'container',\n autoplay: false,\n freeMode: {\n enabled: false,\n momentum: true,\n momentumRatio: 1,\n momentumBounce: true,\n momentumBounceRatio: 1,\n momentumVelocityRatio: 1,\n sticky: false,\n minimumVelocity: 0.02,\n },\n autoHeight: false,\n setWrapperSize: false,\n zoom: {\n maxRatio: 3,\n minRatio: 1,\n toggle: false,\n },\n touchRatio: 1,\n touchAngle: 45,\n simulateTouch: true,\n touchStartPreventDefault: false,\n shortSwipes: true,\n longSwipes: true,\n longSwipesRatio: 0.5,\n longSwipesMs: 300,\n followFinger: true,\n threshold: 0,\n touchMoveStopPropagation: true,\n touchReleaseOnEdges: false,\n resistance: true,\n resistanceRatio: 0.85,\n watchSlidesProgress: false,\n preventClicks: true,\n preventClicksPropagation: true,\n slideToClickedSlide: false,\n // loopAdditionalSlides: 0,\n noSwiping: true,\n runCallbacksOnInit: true,\n observer: true,\n observeParents: true,\n coverflowEffect: {\n rotate: 50,\n stretch: 0,\n depth: 100,\n modifier: 1,\n slideShadows: true,\n },\n flipEffect: {\n slideShadows: true,\n limitRotation: true,\n },\n cubeEffect: {\n slideShadows: true,\n shadow: true,\n shadowOffset: 20,\n shadowScale: 0.94,\n },\n fadeEffect: {\n crossFade: false,\n },\n a11y: {\n prevSlideMessage: 'Previous slide',\n nextSlideMessage: 'Next slide',\n firstSlideMessage: 'This is the first slide',\n lastSlideMessage: 'This is the last slide',\n },\n };\n\n if (this.pager) {\n let pager = this.paginationEl!;\n\n if (this.customPaginationElement) {\n pager = this.customPaginationElement;\n }\n\n if (this.customPaginationSelector) {\n pager = this.el.parentElement.querySelector(this.customPaginationSelector);\n }\n\n swiperOptions.pagination = {\n el: pager as HTMLElement,\n type: 'bullets',\n clickable: true,\n hideOnClick: false,\n renderBullet: this.renderBulletsWithTitle,\n };\n }\n\n if (this.navigation) {\n swiperOptions.navigation = {\n nextEl: '.swiper-button-next',\n prevEl: '.swiper-button-prev',\n } as NavigationOptions;\n }\n\n if (this.scrollbar) {\n swiperOptions.scrollbar = {\n el: this.scrollbarEl!,\n hide: true,\n };\n }\n\n // Keep the event options separate, we dont want users\n // overwriting these\n const eventOptions: SwiperOptions = {\n on: {\n init: () => {\n setTimeout(() => {\n this.c7SlidesDidLoad.emit();\n this.update();\n }, 20);\n },\n slideChangeTransitionStart: this.c7SlideWillChange.emit as any,\n slideChangeTransitionEnd: this.c7SlideDidChange.emit as any,\n slideNextTransitionStart: this.c7SlideNextStart.emit as any,\n slidePrevTransitionStart: this.c7SlidePrevStart.emit as any,\n slideNextTransitionEnd: this.c7SlideNextEnd.emit as any,\n slidePrevTransitionEnd: this.c7SlidePrevEnd.emit as any,\n transitionStart: this.c7SlideTransitionStart.emit as any,\n transitionEnd: this.c7SlideTransitionEnd.emit as any,\n sliderMove: this.c7SlideDrag.emit as any,\n reachBeginning: this.c7SlideReachStart.emit as any,\n reachEnd: this.c7SlideReachEnd.emit as any,\n touchStart: this.c7SlideTouchStart.emit as any,\n touchEnd: this.c7SlideTouchEnd.emit as any,\n tap: this.c7SlideTap.emit as any,\n doubleTap: this.c7SlideDoubleTap.emit as any,\n },\n };\n\n const customEvents = !!this.options && !!this.options.on ? this.options.on : {};\n\n // merge \"on\" event listeners, while giving our event listeners priority\n const mergedEventOptions = { on: { ...customEvents, ...eventOptions.on } };\n\n // Merge the base, user options, and events together then pas to swiper\n return { ...swiperOptions, ...this.options, ...mergedEventOptions };\n }\n\n renderBulletsWithTitle(index: number, className: string) {\n return '';\n }\n\n render() {\n return (\n \n
\n \n
\n {this.pager && !this.customPaginationElement &&
(this.paginationEl = el)}>
}\n {this.scrollbar &&
(this.scrollbarEl = el)}>
}\n {!!this.navigation && [
,
]}\n \n );\n }\n}\n\nconst waitForSlides = (el: HTMLElement) => {\n return Promise.all(\n Array.from(el.querySelectorAll('c7-slide')).map(s => new Promise(resolve => componentOnReady(s, resolve)))\n );\n};\n",".c7-tile {\n\n --border-radius: 10px;\n --background-color: #ffffff;\n --border: none;\n --box-shadow: 0px 3px 15px rgba(0,0,0,0.2);\n --color: inherit;\n --padding: 24px;\n --font-size: 1rem;\n --img-height: 200px;\n\n display: flex;\n flex-direction: column;\n\n c7-img {\n height: var(--img-height);\n }\n\n &.c7-tile-interactive {\n cursor: pointer;\n text-decoration: none;\n\n &:hover {\n text-decoration: none;\n }\n }\n\n a.c7-tile-inner {\n text-decoration: none !important;\n }\n\n .c7-tile-inner {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n flex: 1;\n\n border-radius: var(--border-radius);\n background-color: var(--background-color);\n color: var(--color);\n border: var(--border);\n box-shadow: var(--box-shadow);\n font-size: var(--font-size);\n gap: calc(var(--padding) / 2);\n }\n\n\n}\n","import { Component, Element, h, Host, Listen, Prop } from '@stencil/core';\nimport { raf } from '../../../../utils/component.utils';\nimport { Button } from '../../../utility/button/button';\n\n@Component({\n tag: 'c7-tile',\n styleUrl: 'tile.styles.scss',\n shadow: false\n})\nexport class TileComponent {\n\n @Element() el!: HTMLC7TileElement;\n\n @Prop({mutable: true}) interactive: boolean = false;\n\n @Prop() href?:string;\n\n @Prop() target?: string;\n\n @Prop() rel?: string;\n\n @Prop() download?: string;\n\n @Listen('click')\n onClick(event: Event) {\n\n const target = event.target as HTMLElement\n\n const isTargetInteractive = target.tagName === 'A' || target.tagName === 'BUTTON' || target.tagName === 'C7-BUTTON';\n\n if (!isTargetInteractive && this.interactive) {\n\n const link = this.el.querySelector('c7-tile-title a') as HTMLLinkElement;\n\n if (link) {\n event.stopPropagation();\n link.click();\n }\n }\n\n }\n\n\n componentDidLoad() {\n raf(() => {\n this.interactive = !!this.href || !!this.el.querySelector('c7-tile-title a');\n })\n }\n\n\n get hasFooter() {\n return !!this.el.querySelector('c7-tile-footer');\n }\n\n render() {\n\n const {href, target, rel, download, hasFooter, interactive} = this;\n\n const TagType = !!href ? 'a' : 'div';\n\n const cssClassNames = {\n 'c7-tile': true,\n 'c7-tile-interactive': interactive,\n 'c7-tile-with-footer': hasFooter\n };\n\n\n const attrs = !!href ? {\n href,\n target,\n rel,\n download\n } : {};\n\n return (\n \n \n \n \n \n )\n }\n\n}\n",".c7-tile-body {\n\n display: flex;\n flex-direction: column;\n gap: inherit;\n\n &:first-child {\n padding-top: var(--padding);\n }\n}\n","import { Component, h, Host, Element } from '@stencil/core';\n\n@Component({\n tag: 'c7-tile-body',\n styleUrl: 'tile-body.styles.scss',\n shadow: false\n})\nexport class TileBody {\n\n @Element() el: HTMLElement;\n\n\n render() {\n\n const cssClassNames = {\n 'c7-tile-body': true\n };\n\n return (\n \n \n \n );\n }\n}\n","@use \"src/style/mixins/text\" as text-utils;\n\n.c7-tile-content {\n\n --max-lines: 5;\n\n @include text-utils.reboot-margins;\n\n &.truncated {\n @include text-utils.line-clamp(var(--max-lines));\n }\n\n\n font-size: inherit;\n padding-left: var(--padding);\n padding-right: var(--padding);\n\n &:last-child:not(:empty) {\n margin-bottom: var(--padding);\n }\n\n}\n\n.c7-tile-with-footer {\n .c7-tile-content:last-child:not(:empty) {\n margin-bottom: 0;\n }\n}\n","import { Component, h, Host, Prop, Element } from '@stencil/core';\n\n@Component({\n tag: 'c7-tile-content',\n styleUrl: 'tile-content.styles.scss',\n shadow: false\n})\nexport class TileContentComponent {\n\n @Element() el: HTMLElement;\n\n /**\n * If set to true, text is truncated after --max-lines\n */\n @Prop() truncated: boolean;\n\n render() {\n return (\n \n \n \n )\n }\n\n}\n",".c7-tile-header {\n display: flex;\n flex-direction: column;\n padding-left: var(--padding);\n padding-right: var(--padding);\n gap: inherit;\n\n &:not(.in-tile-body):first-child {\n padding-top: var(--padding);\n }\n}\n","import {Component, h, Host, Element} from '@stencil/core';\n\n@Component({\n tag: 'c7-tile-header',\n styleUrl: 'tile-header.styles.scss',\n shadow: false\n})\nexport class TileHeaderComponent {\n\n @Element() el: HTMLElement;\n\n render() {\n\n const cssClassNames = {\n 'c7-tile-header': true,\n 'in-tile-body': !!this.el.closest('c7-tile-body'),\n };\n\n return (\n \n \n \n )\n }\n\n}\n","@use \"src/style/mixins/text\" as text-utils;\n\n.c7-tile-title {\n\n --max-lines: 2;\n\n font-size: calc(var(--font-size) * 1.5);\n font-weight: bolder;\n line-height: 1.3; //1.6rem why 1.6rem though?\n hyphens: var(--c7-tile-title-hyphens, none);\n word-break: break-word;\n\n @include text-utils.line-clamp(var(--max-lines));\n\n > a {\n color: inherit;\n text-decoration: none;\n cursor: pointer;\n }\n}\n","import { Component, h, Host, Prop } from '@stencil/core';\n\n\n@Component({\n tag: 'c7-tile-title',\n styleUrl: 'tile-title.styles.scss',\n shadow: false\n})\nexport class TileTitleComponent {\n\n @Prop() href?: string;\n\n @Prop() target?: string;\n\n render() {\n\n let { href, target } = this;\n\n return (\n \n { !!href ? () : }\n \n )\n }\n}\n","import { getAssetPath } from '@stencil/core';\nlet CACHED_MAP;\nexport const getIconMap = () => {\n if (typeof window === 'undefined') {\n return new Map();\n }\n else {\n if (!CACHED_MAP) {\n const win = window;\n win.Ionicons = win.Ionicons || {};\n CACHED_MAP = win.Ionicons.map = win.Ionicons.map || new Map();\n }\n return CACHED_MAP;\n }\n};\nexport const addIcons = (icons) => {\n const map = getIconMap();\n Object.keys(icons).forEach(name => map.set(name, icons[name]));\n};\nexport const getUrl = (i) => {\n let url = getSrc(i.src);\n if (url) {\n return url;\n }\n url = getName(i.name, i.icon, i.mode, i.ios, i.md);\n if (url) {\n return getNamedUrl(url);\n }\n if (i.icon) {\n url = getSrc(i.icon);\n if (url) {\n return url;\n }\n url = getSrc(i.icon[i.mode]);\n if (url) {\n return url;\n }\n }\n return null;\n};\nconst getNamedUrl = (iconName) => {\n const url = getIconMap().get(iconName);\n if (url) {\n return url;\n }\n return getAssetPath(`svg/${iconName}.svg`);\n};\nexport const getName = (iconName, icon, mode, ios, md) => {\n // default to \"md\" if somehow the mode wasn't set\n mode = (mode && toLower(mode)) === 'ios' ? 'ios' : 'md';\n // if an icon was passed in using the ios or md attributes\n // set the iconName to whatever was passed in\n if (ios && mode === 'ios') {\n iconName = toLower(ios);\n }\n else if (md && mode === 'md') {\n iconName = toLower(md);\n }\n else {\n if (!iconName && icon && !isSrc(icon)) {\n iconName = icon;\n }\n if (isStr(iconName)) {\n iconName = toLower(iconName);\n }\n }\n if (!isStr(iconName) || iconName.trim() === '') {\n return null;\n }\n // only allow alpha characters and dash\n const invalidChars = iconName.replace(/[a-z]|-|\\d/gi, '');\n if (invalidChars !== '') {\n return null;\n }\n return iconName;\n};\nexport const getSrc = (src) => {\n if (isStr(src)) {\n src = src.trim();\n if (isSrc(src)) {\n return src;\n }\n }\n return null;\n};\nexport const isSrc = (str) => str.length > 0 && /(\\/|\\.)/.test(str);\nexport const isStr = (val) => typeof val === 'string';\nexport const toLower = (val) => val.toLowerCase();\n/**\n * Elements inside of web components sometimes need to inherit global attributes\n * set on the host. For example, the inner input in `ion-input` should inherit\n * the `title` attribute that developers set directly on `ion-input`. This\n * helper function should be called in componentWillLoad and assigned to a variable\n * that is later used in the render function.\n *\n * This does not need to be reactive as changing attributes on the host element\n * does not trigger a re-render.\n */\nexport const inheritAttributes = (el, attributes = []) => {\n const attributeObject = {};\n attributes.forEach(attr => {\n if (el.hasAttribute(attr)) {\n const value = el.getAttribute(attr);\n if (value !== null) {\n attributeObject[attr] = el.getAttribute(attr);\n }\n el.removeAttribute(attr);\n }\n });\n return attributeObject;\n};\n/**\n * Returns `true` if the document or host element\n * has a `dir` set to `rtl`. The host value will always\n * take priority over the root document value.\n */\nexport const isRTL = (hostEl) => {\n if (hostEl) {\n if (hostEl.dir !== '') {\n return hostEl.dir.toLowerCase() === 'rtl';\n }\n }\n return (document === null || document === void 0 ? void 0 : document.dir.toLowerCase()) === 'rtl';\n};\n","import { isStr } from './utils';\nexport const validateContent = (svgContent) => {\n const div = document.createElement('div');\n div.innerHTML = svgContent;\n // setup this way to ensure it works on our buddy IE\n for (let i = div.childNodes.length - 1; i >= 0; i--) {\n if (div.childNodes[i].nodeName.toLowerCase() !== 'svg') {\n div.removeChild(div.childNodes[i]);\n }\n }\n // must only have 1 root element\n const svgElm = div.firstElementChild;\n if (svgElm && svgElm.nodeName.toLowerCase() === 'svg') {\n const svgClass = svgElm.getAttribute('class') || '';\n svgElm.setAttribute('class', (svgClass + ' s-ion-icon').trim());\n // root element must be an svg\n // lets double check we've got valid elements\n // do not allow scripts\n if (isValid(svgElm)) {\n return div.innerHTML;\n }\n }\n return '';\n};\nexport const isValid = (elm) => {\n if (elm.nodeType === 1) {\n if (elm.nodeName.toLowerCase() === 'script') {\n return false;\n }\n for (let i = 0; i < elm.attributes.length; i++) {\n const name = elm.attributes[i].name;\n if (isStr(name) && name.toLowerCase().indexOf('on') === 0) {\n return false;\n }\n }\n for (let i = 0; i < elm.childNodes.length; i++) {\n if (!isValid(elm.childNodes[i])) {\n return false;\n }\n }\n }\n return true;\n};\nexport const isSvgDataUrl = (url) => url.startsWith('data:image/svg+xml');\nexport const isEncodedDataUrl = (url) => url.indexOf(';utf8,') !== -1;\n","import { isEncodedDataUrl, isSvgDataUrl, validateContent } from './validate';\nexport const ioniconContent = new Map();\nconst requests = new Map();\nlet parser;\nexport const getSvgContent = (url, sanitize) => {\n // see if we already have a request for this url\n let req = requests.get(url);\n if (!req) {\n if (typeof fetch !== 'undefined' && typeof document !== 'undefined') {\n /**\n * If the url is a data url of an svg, then try to parse it\n * with the DOMParser. This works with content security policies enabled.\n */\n if (isSvgDataUrl(url) && isEncodedDataUrl(url)) {\n if (!parser) {\n /**\n * Create an instance of the DOM parser. This creates a single\n * parser instance for the entire app, which is more efficient.\n */\n parser = new DOMParser();\n }\n const doc = parser.parseFromString(url, 'text/html');\n const svg = doc.querySelector('svg');\n if (svg) {\n ioniconContent.set(url, svg.outerHTML);\n }\n return Promise.resolve();\n }\n else {\n // we don't already have a request\n req = fetch(url).then((rsp) => {\n if (rsp.ok) {\n return rsp.text().then((svgContent) => {\n if (svgContent && sanitize !== false) {\n svgContent = validateContent(svgContent);\n }\n ioniconContent.set(url, svgContent || '');\n });\n }\n ioniconContent.set(url, '');\n });\n // cache for the same requests\n requests.set(url, req);\n }\n }\n else {\n // set to empty for ssr scenarios and resolve promise\n ioniconContent.set(url, '');\n return Promise.resolve();\n }\n }\n return req;\n};\n",":host {\n display: inline-block;\n\n width: 1em;\n height: 1em;\n\n contain: strict;\n\n fill: currentColor;\n\n box-sizing: content-box !important;\n}\n\n:host .ionicon {\n stroke: currentColor;\n}\n\n.ionicon-fill-none {\n fill: none;\n}\n\n.ionicon-stroke-width {\n stroke-width: 32px;\n stroke-width: var(--ionicon-stroke-width, 32px);\n}\n\n.icon-inner,\n.ionicon,\nsvg {\n display: block;\n\n height: 100%;\n width: 100%;\n}\n\n\n/* Icon RTL\n * -----------------------------------------------------------\n */\n\n:host(.flip-rtl) .icon-inner {\n transform: scaleX(-1);\n}\n\n\n/* Icon Sizes\n * -----------------------------------------------------------\n */\n\n:host(.icon-small) {\n font-size: 18px !important;\n}\n\n:host(.icon-large){\n font-size: 32px !important;\n}\n\n\n/* Icon Colors\n * -----------------------------------------------------------\n */\n\n:host(.ion-color) {\n color: var(--ion-color-base) !important;\n}\n\n:host(.ion-color-primary) {\n --ion-color-base: var(--ion-color-primary, #3880ff);\n}\n\n:host(.ion-color-secondary) {\n --ion-color-base: var(--ion-color-secondary, #0cd1e8);\n}\n\n:host(.ion-color-tertiary) {\n --ion-color-base: var(--ion-color-tertiary, #f4a942);\n}\n\n:host(.ion-color-success) {\n --ion-color-base: var(--ion-color-success, #10dc60);\n}\n\n:host(.ion-color-warning) {\n --ion-color-base: var(--ion-color-warning, #ffce00);\n}\n\n:host(.ion-color-danger) {\n --ion-color-base: var(--ion-color-danger, #f14141);\n}\n\n:host(.ion-color-light) {\n --ion-color-base: var(--ion-color-light, #f4f5f8);\n}\n\n:host(.ion-color-medium) {\n --ion-color-base: var(--ion-color-medium, #989aa2);\n}\n\n:host(.ion-color-dark) {\n --ion-color-base: var(--ion-color-dark, #222428);\n}\n","import { Build, Host, h } from '@stencil/core';\nimport { getSvgContent, ioniconContent } from './request';\nimport { getName, getUrl, inheritAttributes, isRTL } from './utils';\nexport class Icon {\n constructor() {\n this.iconName = null;\n this.inheritedAttributes = {};\n this.isVisible = false;\n /**\n * The mode determines which platform styles to use.\n */\n this.mode = getIonMode();\n /**\n * If enabled, ion-icon will be loaded lazily when it's visible in the viewport.\n * Default, `false`.\n */\n this.lazy = false;\n /**\n * When set to `false`, SVG content that is HTTP fetched will not be checked\n * if the response SVG content has any `