@egjs/flicking 3.9.0 → 3.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"flicking.pkgd.min.js","sources":["../src/consts.ts","../src/utils.ts","../src/components/Panel.ts","../src/components/PanelManager.ts","../src/states/State.ts","../src/states/IdleState.ts","../src/states/HoldingState.ts","../src/states/DraggingState.ts","../src/states/AnimatingState.ts","../src/states/DisabledState.ts","../src/components/StateMachine.ts","../src/moves/Snap.ts","../src/moves/MoveType.ts","../src/moves/FreeScroll.ts","../src/components/Viewport.ts","../src/components/AutoResizer.ts","../src/Flicking.ts","../src/index.umd.ts"],"sourcesContent":["/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { FlickingOptions, EventType, Direction, AxesEventType, StateType, MoveTypeSnapOption, MoveTypeFreeScrollOption, FlickingMethodsKeys } from \"./types\";\n\nexport const MOVE_TYPE: {\n SNAP: \"snap\";\n FREE_SCROLL: \"freeScroll\";\n} = {\n SNAP: \"snap\",\n FREE_SCROLL: \"freeScroll\",\n};\n\nexport const DEFAULT_MOVE_TYPE_OPTIONS: {\n snap: MoveTypeSnapOption,\n freeScroll: MoveTypeFreeScrollOption,\n} = {\n snap: {\n type: \"snap\",\n count: 1,\n },\n freeScroll: {\n type: \"freeScroll\",\n },\n};\nexport const isBrowser = typeof document !== \"undefined\";\n\n/**\n * Default options for creating Flicking.\n * @ko 플리킹을 만들 때 사용하는 기본 옵션들\n * @private\n * @memberof eg.Flicking\n */\nexport const DEFAULT_OPTIONS: Readonly<FlickingOptions> = {\n classPrefix: \"eg-flick\",\n deceleration: 0.0075,\n horizontal: true,\n circular: false,\n infinite: false,\n infiniteThreshold: 0,\n lastIndex: Infinity,\n threshold: 40,\n duration: 100,\n panelEffect: x => 1 - Math.pow(1 - x, 3),\n defaultIndex: 0,\n inputType: [\"touch\", \"mouse\"],\n thresholdAngle: 45,\n bounce: 10,\n autoResize: false,\n adaptive: false,\n zIndex: 2000,\n bound: false,\n overflow: false,\n hanger: \"50%\",\n anchor: \"50%\",\n gap: 0,\n moveType: DEFAULT_MOVE_TYPE_OPTIONS.snap,\n useOffset: false,\n isEqualSize: false,\n isConstantSize: false,\n renderOnlyVisible: false,\n renderExternal: false,\n resizeOnContentsReady: false,\n iOSEdgeSwipeThreshold: 30,\n collectStatistics: true,\n useResizeObserver: true,\n};\n\nexport const DEFAULT_VIEWPORT_CSS = {\n position: \"relative\",\n zIndex: DEFAULT_OPTIONS.zIndex,\n overflow: \"hidden\",\n};\n\nexport const DEFAULT_CAMERA_CSS = {\n width: \"100%\",\n height: \"100%\",\n willChange: \"transform\",\n};\n\nexport const DEFAULT_PANEL_CSS = {\n position: \"absolute\",\n};\n\nexport const EVENTS: EventType = {\n HOLD_START: \"holdStart\",\n HOLD_END: \"holdEnd\",\n MOVE_START: \"moveStart\",\n MOVE: \"move\",\n MOVE_END: \"moveEnd\",\n CHANGE: \"change\",\n RESTORE: \"restore\",\n SELECT: \"select\",\n NEED_PANEL: \"needPanel\",\n VISIBLE_CHANGE: \"visibleChange\",\n CONTENT_ERROR: \"contentError\",\n};\n\nexport const AXES_EVENTS: AxesEventType = {\n HOLD: \"hold\",\n CHANGE: \"change\",\n RELEASE: \"release\",\n ANIMATION_END: \"animationEnd\",\n FINISH: \"finish\",\n};\n\nexport const STATE_TYPE: StateType = {\n IDLE: 0,\n HOLDING: 1,\n DRAGGING: 2,\n ANIMATING: 3,\n DISABLED: 4,\n};\n\nexport const DIRECTION: Direction = {\n PREV: \"PREV\",\n NEXT: \"NEXT\",\n};\nexport const FLICKING_METHODS: {[key in FlickingMethodsKeys]: true} = {\n prev: true,\n next: true,\n moveTo: true,\n getIndex: true,\n getAllPanels: true,\n getCurrentPanel: true,\n getElement: true,\n getSize: true,\n getPanel: true,\n getPanelCount: true,\n getStatus: true,\n getVisiblePanels: true,\n enableInput: true,\n disableInput: true,\n destroy: true,\n resize: true,\n setStatus: true,\n isPlaying: true,\n};\n\n// Check whether browser supports transform: translate3d\n// https://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support\nexport let checkTranslateSupport = () => {\n const transforms = {\n webkitTransform: \"-webkit-transform\",\n msTransform: \"-ms-transform\",\n MozTransform: \"-moz-transform\",\n OTransform: \"-o-transform\",\n transform: \"transform\",\n };\n\n if (!isBrowser) {\n return {\n name: transforms.transform,\n has3d: true,\n };\n }\n const supportedStyle = document.documentElement.style;\n let transformName = \"\";\n for (const prefixedTransform in transforms) {\n if (prefixedTransform in supportedStyle) {\n transformName = prefixedTransform;\n }\n }\n\n if (!transformName) {\n throw new Error(\"Browser doesn't support CSS3 2D Transforms.\");\n }\n\n const el = document.createElement(\"div\");\n\n document.documentElement.insertBefore(el, null);\n\n el.style[transformName] = \"translate3d(1px, 1px, 1px)\";\n const styleVal = window.getComputedStyle(el).getPropertyValue(transforms[transformName]);\n\n el.parentElement!.removeChild(el);\n\n const transformInfo = {\n name: transformName,\n has3d: styleVal.length > 0 && styleVal !== \"none\",\n };\n\n checkTranslateSupport = () => transformInfo;\n\n return transformInfo;\n};\n\nexport const TRANSFORM = checkTranslateSupport();\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { ElementLike, OriginalStyle, BoundingBox } from \"./types\";\nimport Flicking from \"./Flicking\";\nimport { FLICKING_METHODS } from \"./consts\";\n\nexport function merge(target: object, ...srcs: object[]): object {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n target[key] = value;\n });\n });\n\n return target;\n}\n\nexport function parseElement(element: ElementLike | ElementLike[]): HTMLElement[] {\n if (!Array.isArray(element)) {\n element = [element];\n }\n\n const elements: HTMLElement[] = [];\n element.forEach(el => {\n if (isString(el)) {\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = el;\n\n elements.push(...toArray(tempDiv.children) as HTMLElement[]);\n while (tempDiv.firstChild) {\n tempDiv.removeChild(tempDiv.firstChild);\n }\n } else {\n elements.push(el as HTMLElement);\n }\n });\n\n return elements;\n}\n\nexport function isString(value: any): value is string {\n return typeof value === \"string\";\n}\n\n// Get class list of element as string array\nexport function classList(element: HTMLElement): string[] {\n return element.classList\n ? toArray(element.classList)\n : element.className.split(\" \");\n}\n\n// Add class to specified element\nexport function addClass(element: HTMLElement, className: string): void {\n if (element.classList) {\n element.classList.add(className);\n } else {\n if (!hasClass(element, className)) {\n element.className = (`${element.className} ${className}`).replace(/\\s{2,}/g, \" \");\n }\n }\n}\n\nexport function hasClass(element: HTMLElement, className: string): boolean {\n if (element.classList) {\n return element.classList.contains(className);\n } else {\n return (element.className.split(\" \").indexOf(className) >= 0);\n }\n}\n\nexport function applyCSS(element: HTMLElement, cssObj: object): void {\n Object.keys(cssObj).forEach(property => {\n element.style[property] = cssObj[property];\n });\n}\n\nexport function clamp(val: number, min: number, max: number) {\n return Math.max(Math.min(val, max), min);\n}\n\n// Min: inclusive, Max: exclusive\nexport function isBetween(val: number, min: number, max: number) {\n return val >= min && val <= max;\n}\n\nexport interface ArrayLike<T> {\n length: number;\n [index: number]: T;\n}\n\nexport function toArray<T>(iterable: ArrayLike<T>): T[] {\n return [].slice.call(iterable);\n}\n\nexport function isArray(arr: any): boolean {\n return arr && arr.constructor === Array;\n}\n\nexport function parseArithmeticExpression(cssValue: number | string, base: number, defaultVal?: number): number {\n // Set base / 2 to default value, if it's undefined\n const defaultValue = defaultVal != null ? defaultVal : base / 2;\n const cssRegex = /(?:(\\+|\\-)\\s*)?(\\d+(?:\\.\\d+)?(%|px)?)/g;\n\n if (typeof cssValue === \"number\") {\n return clamp(cssValue, 0, base);\n }\n\n let idx = 0;\n let calculatedValue = 0;\n let matchResult = cssRegex.exec(cssValue);\n while (matchResult != null) {\n let sign = matchResult[1];\n const value = matchResult[2];\n const unit = matchResult[3];\n\n let parsedValue = parseFloat(value);\n\n if (idx <= 0) {\n sign = sign || \"+\";\n }\n\n // Return default value for values not in good form\n if (!sign) {\n return defaultValue;\n }\n\n if (unit === \"%\") {\n parsedValue = (parsedValue / 100) * base;\n }\n\n calculatedValue += sign === \"+\"\n ? parsedValue\n : -parsedValue;\n\n // Match next occurrence\n ++idx;\n matchResult = cssRegex.exec(cssValue);\n }\n\n // None-matched\n if (idx === 0) {\n return defaultValue;\n }\n\n // Clamp between 0 ~ base\n return clamp(calculatedValue, 0, base);\n}\n\nexport function getProgress(pos: number, range: number[]) {\n // start, anchor, end\n // -1 , 0 , 1\n const [min, center, max] = range;\n\n if (pos > center && (max - center)) {\n // 0 ~ 1\n return (pos - center) / (max - center);\n } else if (pos < center && (center - min)) {\n // -1 ~ 0\n return (pos - center) / (center - min);\n } else if (pos !== center && max - min) {\n return (pos - min) / (max - min);\n }\n return 0;\n}\n\nexport function findIndex<T>(iterable: T[], callback: (el: T) => boolean): number {\n for (let i = 0; i < iterable.length; i += 1) {\n const element = iterable[i];\n if (element != null && callback(element)) {\n return i;\n }\n }\n\n return -1;\n}\n\n// return [0, 1, ...., max - 1]\nexport function counter(max: number): number[] {\n const counterArray: number[] = [];\n for (let i = 0; i < max; i += 1) {\n counterArray[i] = i;\n }\n return counterArray;\n}\n\n// Circulate number between range [min, max]\n/*\n * \"indexed\" means min and max is not same, so if it's true \"min - 1\" should be max\n * While if it's false, \"min - 1\" should be \"max - 1\"\n * use `indexed: true` when it should be used for circulating integers like index\n * or `indexed: false` when it should be used for something like positions.\n */\nexport function circulate(value: number, min: number, max: number, indexed: boolean): number {\n const size = indexed\n ? max - min + 1\n : max - min;\n if (value < min) {\n const offset = indexed\n ? (min - value - 1) % size\n : (min - value) % size;\n value = max - offset;\n } else if (value > max) {\n const offset = indexed\n ? (value - max - 1) % size\n : (value - max) % size;\n value = min + offset;\n }\n\n return value;\n}\n\nexport function restoreStyle(element: HTMLElement, originalStyle: OriginalStyle): void {\n originalStyle.className\n ? element.setAttribute(\"class\", originalStyle.className)\n : element.removeAttribute(\"class\");\n originalStyle.style\n ? element.setAttribute(\"style\", originalStyle.style)\n : element.removeAttribute(\"style\");\n}\n\n/**\n * Decorator that makes the method of flicking available in the framework.\n * @ko 프레임워크에서 플리킹의 메소드를 사용할 수 있게 하는 데코레이터.\n * @memberof eg.Flicking\n * @private\n * @example\n * ```js\n * import Flicking, { withFlickingMethods } from \"@egjs/flicking\";\n *\n * class Flicking extends React.Component<Partial<FlickingProps & FlickingOptions>> {\n * &#64;withFlickingMethods\n * private flicking: Flicking;\n * }\n * ```\n */\nexport function withFlickingMethods(prototype: any, flickingName: string) {\n Object.keys(FLICKING_METHODS).forEach((name: keyof Flicking) => {\n if (prototype[name]) {\n return;\n }\n prototype[name] = function(...args) {\n const result = this[flickingName][name](...args);\n\n // fix `this` type to return your own `flicking` instance to the instance using the decorator.\n if (result === this[flickingName]) {\n return this;\n } else {\n return result;\n }\n };\n });\n}\n\nexport function getBbox(element: HTMLElement, useOffset: boolean) {\n let bbox: BoundingBox;\n if (useOffset) {\n bbox = {\n x: 0,\n y: 0,\n width: element.offsetWidth,\n height: element.offsetHeight,\n };\n } else {\n const clientRect = element.getBoundingClientRect();\n bbox = {\n x: clientRect.left,\n y: clientRect.top,\n width: clientRect.width,\n height: clientRect.height,\n };\n }\n return bbox;\n}\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Viewport from \"./Viewport\";\nimport { OriginalStyle, FlickingPanel, ElementLike, DestroyOption, BoundingBox } from \"../types\";\nimport { DEFAULT_PANEL_CSS, EVENTS } from \"../consts\";\nimport { addClass, applyCSS, parseArithmeticExpression, parseElement, getProgress, restoreStyle, hasClass, getBbox } from \"../utils\";\n\nclass Panel implements FlickingPanel {\n public viewport: Viewport;\n public prevSibling: Panel | null;\n public nextSibling: Panel | null;\n\n protected state: {\n index: number;\n position: number;\n relativeAnchorPosition: number;\n size: number;\n isClone: boolean;\n isVirtual: boolean;\n // Index of cloned panel, zero-based integer(original: -1, cloned: [0, 1, 2, ...])\n // if cloneIndex is 0, that means it's first cloned panel of original panel\n cloneIndex: number;\n originalStyle: OriginalStyle;\n cachedBbox: BoundingBox | null;\n };\n private element: HTMLElement;\n private original?: Panel;\n private clonedPanels: Panel[];\n\n public constructor(\n element?: HTMLElement | null,\n index?: number,\n viewport?: Viewport,\n ) {\n this.viewport = viewport!;\n this.prevSibling = null;\n this.nextSibling = null;\n this.clonedPanels = [];\n\n this.state = {\n index: index!,\n position: 0,\n relativeAnchorPosition: 0,\n size: 0,\n isClone: false,\n isVirtual: false,\n cloneIndex: -1,\n originalStyle: {\n className: \"\",\n style: \"\",\n },\n cachedBbox: null,\n };\n this.setElement(element);\n }\n\n public resize(givenBbox?: BoundingBox): void {\n const state = this.state;\n const options = this.viewport.options;\n const bbox = givenBbox\n ? givenBbox\n : this.getBbox();\n this.state.cachedBbox = bbox;\n const prevSize = state.size;\n\n state.size = options.horizontal\n ? bbox.width\n : bbox.height;\n\n if (prevSize !== state.size) {\n state.relativeAnchorPosition = parseArithmeticExpression(options.anchor, state.size);\n }\n\n if (!state.isClone) {\n this.clonedPanels.forEach(panel => {\n const cloneState = panel.state;\n\n cloneState.size = state.size;\n cloneState.cachedBbox = state.cachedBbox;\n cloneState.relativeAnchorPosition = state.relativeAnchorPosition;\n });\n }\n }\n\n public unCacheBbox(): void {\n this.state.cachedBbox = null;\n }\n\n public getProgress() {\n const viewport = this.viewport;\n const options = viewport.options;\n const panelCount = viewport.panelManager.getPanelCount();\n const scrollAreaSize = viewport.getScrollAreaSize();\n\n const relativeIndex = (options.circular ? Math.floor(this.getPosition() / scrollAreaSize) * panelCount : 0) + this.getIndex();\n const progress = relativeIndex - viewport.getCurrentProgress();\n\n return progress;\n }\n\n public getOutsetProgress() {\n const viewport = this.viewport;\n const outsetRange = [\n -this.getSize(),\n viewport.getRelativeHangerPosition() - this.getRelativeAnchorPosition(),\n viewport.getSize(),\n ];\n const relativePanelPosition = this.getPosition() - viewport.getCameraPosition();\n const outsetProgress = getProgress(relativePanelPosition, outsetRange);\n\n return outsetProgress;\n }\n\n public getVisibleRatio() {\n const viewport = this.viewport;\n const panelSize = this.getSize();\n const relativePanelPosition = this.getPosition() - viewport.getCameraPosition();\n const rightRelativePanelPosition = relativePanelPosition + panelSize;\n\n const visibleSize = Math.min(viewport.getSize(), rightRelativePanelPosition) - Math.max(relativePanelPosition, 0);\n const visibleRatio = visibleSize >= 0\n ? visibleSize / panelSize\n : 0;\n\n return visibleRatio;\n }\n\n public focus(duration?: number): void {\n const viewport = this.viewport;\n const currentPanel = viewport.getCurrentPanel();\n const hangerPosition = viewport.getHangerPosition();\n const anchorPosition = this.getAnchorPosition();\n if (hangerPosition === anchorPosition || !currentPanel) {\n return;\n }\n\n const currentPosition = currentPanel.getPosition();\n const eventType = currentPosition === this.getPosition()\n ? \"\"\n : EVENTS.CHANGE;\n\n viewport.moveTo(this, viewport.findEstimatedPosition(this), eventType, null, duration);\n }\n\n public update(updateFunction: ((element: HTMLElement) => any) | null = null, shouldResize: boolean = true): void {\n const identicalPanels = this.getIdenticalPanels();\n\n if (updateFunction) {\n identicalPanels.forEach(eachPanel => {\n updateFunction(eachPanel.getElement());\n });\n }\n\n if (shouldResize) {\n identicalPanels.forEach(eachPanel => {\n eachPanel.unCacheBbox();\n });\n this.viewport.addVisiblePanel(this);\n this.viewport.resize();\n }\n }\n\n public prev(): FlickingPanel | null {\n const viewport = this.viewport;\n const options = viewport.options;\n const prevSibling = this.prevSibling;\n\n if (!prevSibling) {\n return null;\n }\n\n const currentIndex = this.getIndex();\n const currentPosition = this.getPosition();\n const prevPanelIndex = prevSibling.getIndex();\n const prevPanelPosition = prevSibling.getPosition();\n const prevPanelSize = prevSibling.getSize();\n\n const hasEmptyPanelBetween = currentIndex - prevPanelIndex > 1;\n const notYetMinPanel = options.infinite\n && currentIndex > 0\n && prevPanelIndex > currentIndex;\n\n if (hasEmptyPanelBetween || notYetMinPanel) {\n // Empty panel exists between\n return null;\n }\n\n const newPosition = currentPosition - prevPanelSize - options.gap;\n\n let prevPanel = prevSibling;\n if (prevPanelPosition !== newPosition) {\n prevPanel = prevSibling.clone(prevSibling.getCloneIndex(), true);\n prevPanel.setPosition(newPosition);\n }\n\n return prevPanel;\n }\n\n public next(): FlickingPanel | null {\n const viewport = this.viewport;\n const options = viewport.options;\n const nextSibling = this.nextSibling;\n const lastIndex = viewport.panelManager.getLastIndex();\n\n if (!nextSibling) {\n return null;\n }\n\n const currentIndex = this.getIndex();\n const currentPosition = this.getPosition();\n const nextPanelIndex = nextSibling.getIndex();\n const nextPanelPosition = nextSibling.getPosition();\n\n const hasEmptyPanelBetween = nextPanelIndex - currentIndex > 1;\n const notYetMaxPanel = options.infinite\n && currentIndex < lastIndex\n && nextPanelIndex < currentIndex;\n\n if (hasEmptyPanelBetween || notYetMaxPanel) {\n return null;\n }\n\n const newPosition = currentPosition + this.getSize() + options.gap;\n\n let nextPanel = nextSibling;\n if (nextPanelPosition !== newPosition) {\n nextPanel = nextSibling.clone(nextSibling.getCloneIndex(), true);\n nextPanel.setPosition(newPosition);\n }\n\n return nextPanel;\n }\n\n public insertBefore(element: ElementLike | ElementLike[]): FlickingPanel[] {\n const viewport = this.viewport;\n const parsedElements = parseElement(element);\n const firstPanel = viewport.panelManager.firstPanel()!;\n const prevSibling = this.prevSibling;\n // Finding correct inserting index\n // While it should insert removing empty spaces,\n // It also should have to be bigger than prevSibling' s index\n const targetIndex = prevSibling && firstPanel.getIndex() !== this.getIndex()\n ? Math.max(prevSibling.getIndex() + 1, this.getIndex() - parsedElements.length)\n : Math.max(this.getIndex() - parsedElements.length, 0);\n\n return viewport.insert(targetIndex, parsedElements);\n }\n\n public insertAfter(element: ElementLike | ElementLike[]): FlickingPanel[] {\n return this.viewport.insert(this.getIndex() + 1, element);\n }\n\n public remove(): FlickingPanel {\n this.viewport.remove(this.getIndex());\n\n return this;\n }\n\n public destroy(option: Partial<DestroyOption>): void {\n if (!option.preserveUI) {\n const originalStyle = this.state.originalStyle;\n\n restoreStyle(this.element, originalStyle);\n }\n\n // release resources\n for (const x in this) {\n (this as any)[x] = null;\n }\n }\n\n public getElement(): HTMLElement {\n return this.element;\n }\n\n public getAnchorPosition(): number {\n return this.state.position + this.state.relativeAnchorPosition;\n }\n\n public getRelativeAnchorPosition(): number {\n return this.state.relativeAnchorPosition;\n }\n\n public getIndex(): number {\n return this.state.index;\n }\n\n public getPosition(): number {\n return this.state.position;\n }\n\n public getSize(): number {\n return this.state.size;\n }\n\n public getBbox(): BoundingBox {\n const state = this.state;\n const viewport = this.viewport;\n const element = this.element;\n const options = viewport.options;\n\n if (!element) {\n state.cachedBbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n } else if (!state.cachedBbox) {\n const wasVisible = Boolean(element.parentNode);\n const cameraElement = viewport.getCameraElement();\n if (!wasVisible) {\n cameraElement.appendChild(element);\n viewport.addVisiblePanel(this);\n }\n state.cachedBbox = getBbox(element, options.useOffset);\n\n if (!wasVisible && viewport.options.renderExternal) {\n cameraElement.removeChild(element);\n }\n }\n return state.cachedBbox!;\n }\n\n public isClone(): boolean {\n return this.state.isClone;\n }\n\n public getOverlappedClass(classes: string[]): string | undefined {\n const element = this.element;\n\n for (const className of classes) {\n if (hasClass(element, className)) {\n return className;\n }\n }\n }\n\n public getCloneIndex(): number {\n return this.state.cloneIndex;\n }\n\n public getClonedPanels(): Panel[] {\n const state = this.state;\n\n return state.isClone\n ? this.original!.getClonedPanels()\n : this.clonedPanels;\n }\n\n public getIdenticalPanels(): Panel[] {\n const state = this.state;\n\n return state.isClone\n ? this.original!.getIdenticalPanels()\n : [this, ...this.clonedPanels];\n }\n\n public getOriginalPanel(): Panel {\n return this.state.isClone\n ? this.original!\n : this;\n }\n\n public setIndex(index: number): void {\n const state = this.state;\n\n state.index = index;\n this.clonedPanels.forEach(panel => panel.state.index = index);\n }\n\n public setPosition(pos: number): this {\n this.state.position = pos;\n\n return this;\n }\n\n public setPositionCSS(offset: number = 0): void {\n if (!this.element) {\n return;\n }\n const state = this.state;\n const pos = state.position;\n const options = this.viewport.options;\n const elementStyle = this.element.style;\n const currentElementStyle = options.horizontal\n ? elementStyle.left\n : elementStyle.top;\n const styleToApply = `${pos - offset}px`;\n\n if (!state.isVirtual && currentElementStyle !== styleToApply) {\n options.horizontal\n ? elementStyle.left = styleToApply\n : elementStyle.top = styleToApply;\n }\n }\n\n public clone(cloneIndex: number, isVirtual: boolean = false, element?: HTMLElement | null): Panel {\n const state = this.state;\n const viewport = this.viewport;\n let cloneElement = element;\n\n if (!cloneElement && this.element) {\n cloneElement = isVirtual ? this.element : this.element.cloneNode(true) as HTMLElement;\n }\n const clonedPanel = new Panel(cloneElement, state.index, viewport);\n const clonedState = clonedPanel.state;\n\n clonedPanel.original = state.isClone\n ? this.original\n : this;\n clonedState.isClone = true;\n clonedState.isVirtual = isVirtual;\n clonedState.cloneIndex = cloneIndex;\n // Inherit some state values\n clonedState.size = state.size;\n clonedState.relativeAnchorPosition = state.relativeAnchorPosition;\n clonedState.originalStyle = state.originalStyle;\n clonedState.cachedBbox = state.cachedBbox;\n\n if (!isVirtual) {\n this.clonedPanels.push(clonedPanel);\n } else {\n clonedPanel.prevSibling = this.prevSibling;\n clonedPanel.nextSibling = this.nextSibling;\n }\n\n return clonedPanel;\n }\n\n public removeElement(): void {\n if (!this.viewport.options.renderExternal) {\n const element = this.element;\n element.parentNode && element.parentNode.removeChild(element);\n }\n\n // Do the same thing for clones\n if (!this.state.isClone) {\n this.removeClonedPanelsAfter(0);\n }\n }\n\n public removeClonedPanelsAfter(start: number): void {\n const options = this.viewport.options;\n const removingPanels = this.clonedPanels.splice(start);\n\n if (!options.renderExternal) {\n removingPanels.forEach(panel => {\n panel.removeElement();\n });\n }\n }\n\n public setElement(element?: HTMLElement | null): void {\n if (!element) {\n return;\n }\n const currentElement = this.element;\n if (element !== currentElement) {\n const options = this.viewport.options;\n\n if (currentElement) {\n if (options.horizontal) {\n element.style.left = currentElement.style.left;\n } else {\n element.style.top = currentElement.style.top;\n }\n } else {\n const originalStyle = this.state.originalStyle;\n\n originalStyle.className = element.getAttribute(\"class\");\n originalStyle.style = element.getAttribute(\"style\");\n }\n\n this.element = element;\n\n if (options.classPrefix) {\n addClass(element, `${options.classPrefix}-panel`);\n }\n\n // Update size info after applying panel css\n applyCSS(this.element, DEFAULT_PANEL_CSS);\n }\n }\n}\n\nexport default Panel;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Panel from \"./Panel\";\nimport { FlickingOptions } from \"../types\";\nimport { findIndex, counter } from \"../utils\";\n\nclass PanelManager {\n private cameraElement: HTMLElement;\n private options: FlickingOptions;\n private panels: Panel[];\n private clones: Panel[][];\n // index range of existing panels\n private range: {\n min: number;\n max: number;\n };\n private length: number;\n private lastIndex: number;\n private cloneCount: number;\n\n constructor(\n cameraElement: HTMLElement,\n options: FlickingOptions,\n ) {\n this.cameraElement = cameraElement;\n this.panels = [];\n this.clones = [];\n this.range = {\n min: -1,\n max: -1,\n };\n this.length = 0;\n this.cloneCount = 0;\n this.options = options;\n this.lastIndex = options.lastIndex;\n }\n\n public firstPanel(): Panel | undefined {\n return this.panels[this.range.min];\n }\n\n public lastPanel(): Panel | undefined {\n return this.panels[this.range.max];\n }\n\n public allPanels(): ReadonlyArray<Panel> {\n return [\n ...this.panels,\n ...this.clones.reduce((allClones, clones) => [...allClones, ...clones], []),\n ];\n }\n\n public originalPanels(): ReadonlyArray<Panel> {\n return this.panels;\n }\n\n public clonedPanels(): ReadonlyArray<Panel[]> {\n return this.clones;\n }\n\n public replacePanels(newPanels: Panel[], newClones: Panel[][]): void {\n this.panels = newPanels;\n this.clones = newClones;\n\n this.range = {\n min: findIndex(newPanels, panel => Boolean(panel)),\n max: newPanels.length - 1,\n };\n this.length = newPanels.filter(panel => Boolean(panel)).length;\n }\n\n public has(index: number): boolean {\n return !!this.panels[index];\n }\n\n public get(index: number): Panel | undefined {\n return this.panels[index];\n }\n\n public getPanelCount(): number {\n return this.length;\n }\n\n public getLastIndex(): number {\n return this.lastIndex;\n }\n\n public getRange(): Readonly<{ min: number, max: number }> {\n return this.range;\n }\n\n public getCloneCount(): number {\n return this.cloneCount;\n }\n\n public setLastIndex(lastIndex: number): void {\n this.lastIndex = lastIndex;\n\n const firstPanel = this.firstPanel();\n const lastPanel = this.lastPanel();\n\n if (!firstPanel || !lastPanel) {\n return; // no meaning of updating range & length\n }\n\n // Remove panels above new last index\n const range = this.range;\n if (lastPanel.getIndex() > lastIndex) {\n const removingPanels = this.panels.splice(lastIndex + 1);\n this.length -= removingPanels.length;\n\n const firstRemovedPanel = removingPanels.filter(panel => !!panel)[0];\n const possibleLastPanel = firstRemovedPanel.prevSibling;\n if (possibleLastPanel) {\n range.max = possibleLastPanel.getIndex();\n } else {\n range.min = -1;\n range.max = -1;\n }\n\n if (this.shouldRender()) {\n removingPanels.forEach(panel => panel.removeElement());\n }\n }\n }\n\n public setCloneCount(cloneCount: number): void {\n this.cloneCount = cloneCount;\n }\n\n // Insert at index\n // Returns pushed elements from index, inserting at 'empty' position doesn't push elements behind it\n public insert(index: number, newPanels: Panel[]): number {\n const panels = this.panels;\n const range = this.range;\n const isCircular = this.options.circular;\n const lastIndex = this.lastIndex;\n\n // Find first panel that index is greater than inserting index\n const nextSibling = this.findFirstPanelFrom(index);\n\n // if it's null, element will be inserted at last position\n // https://developer.mozilla.org/ko/docs/Web/API/Node/insertBefore#Syntax\n const firstPanel = this.firstPanel();\n const siblingElement = nextSibling\n ? nextSibling.getElement()\n : isCircular && firstPanel\n ? firstPanel.getClonedPanels()[0].getElement()\n : null;\n\n // Insert panels before sibling element\n this.insertNewPanels(newPanels, siblingElement);\n\n let pushedIndex = newPanels.length;\n // Like when setting index 50 while visible panels are 0, 1, 2\n if (index > range.max) {\n newPanels.forEach((panel, offset) => {\n panels[index + offset] = panel;\n });\n } else {\n const panelsAfterIndex = panels.slice(index, index + newPanels.length);\n // Find empty from beginning\n let emptyPanelCount = findIndex(panelsAfterIndex, panel => !!panel);\n if (emptyPanelCount < 0) {\n // All empty\n emptyPanelCount = panelsAfterIndex.length;\n }\n pushedIndex = newPanels.length - emptyPanelCount;\n\n // Insert removing empty panels\n panels.splice(index, emptyPanelCount, ...newPanels);\n\n // Remove panels after last index\n if (panels.length > lastIndex + 1) {\n const removedPanels = panels.splice(lastIndex + 1)\n .filter(panel => Boolean(panel));\n this.length -= removedPanels.length;\n\n // Find first\n const newLastIndex = lastIndex - findIndex(this.panels.concat().reverse(), panel => !!panel);\n\n // Can be filled with empty after newLastIndex\n this.panels.splice(newLastIndex + 1);\n this.range.max = newLastIndex;\n\n if (this.shouldRender()) {\n removedPanels.forEach(panel => panel.removeElement());\n }\n }\n }\n\n // Update index of previous panels\n if (pushedIndex > 0) {\n panels.slice(index + newPanels.length).forEach(panel => {\n panel.setIndex(panel.getIndex() + pushedIndex);\n });\n }\n\n // Update state\n this.length += newPanels.length;\n this.updateIndex(index);\n\n if (isCircular) {\n this.addNewClones(index, newPanels, newPanels.length - pushedIndex, nextSibling);\n const clones = this.clones;\n const panelCount = this.panels.length;\n if (clones[0] && clones[0].length > lastIndex + 1) {\n clones.forEach(cloneSet => {\n cloneSet.splice(panelCount);\n });\n }\n }\n\n return pushedIndex;\n }\n\n public replace(index: number, newPanels: Panel[]): Panel[] {\n const panels = this.panels;\n const range = this.range;\n const options = this.options;\n const isCircular = options.circular;\n\n // Find first panel that index is greater than inserting index\n const nextSibling = this.findFirstPanelFrom(index + newPanels.length);\n\n // if it's null, element will be inserted at last position\n // https://developer.mozilla.org/ko/docs/Web/API/Node/insertBefore#Syntax\n const firstPanel = this.firstPanel();\n const siblingElement = nextSibling\n ? nextSibling.getElement()\n : isCircular && firstPanel\n ? firstPanel.getClonedPanels()[0].getElement()\n : null;\n\n // Insert panels before sibling element\n this.insertNewPanels(newPanels, siblingElement);\n\n if (index > range.max) {\n // Temporarily insert null at index to use splice()\n (panels[index] as any) = null;\n }\n const replacedPanels = panels.splice(index, newPanels.length, ...newPanels);\n const wasNonEmptyCount = replacedPanels.filter(panel => Boolean(panel)).length;\n\n // Suppose inserting [1, 2, 3] at 0 position when there were [empty, 1]\n // So length should be increased by 3(inserting panels) - 1(non-empty panels)\n this.length += newPanels.length - wasNonEmptyCount;\n this.updateIndex(index);\n\n if (isCircular) {\n this.addNewClones(index, newPanels, newPanels.length, nextSibling);\n }\n\n if (this.shouldRender()) {\n replacedPanels.forEach(panel => panel && panel.removeElement());\n }\n\n return replacedPanels;\n }\n\n public remove(index: number, deleteCount: number = 1): Panel[] {\n const isCircular = this.options.circular;\n const panels = this.panels;\n const clones = this.clones;\n // Delete count should be equal or larger than 0\n deleteCount = Math.max(deleteCount, 0);\n\n const deletedPanels = panels\n .splice(index, deleteCount)\n .filter(panel => !!panel);\n\n if (this.shouldRender()) {\n deletedPanels.forEach(panel => panel.removeElement());\n }\n\n if (isCircular) {\n clones.forEach(cloneSet => {\n cloneSet.splice(index, deleteCount);\n });\n }\n\n // Update indexes\n panels\n .slice(index)\n .forEach(panel => {\n panel.setIndex(panel.getIndex() - deleteCount);\n });\n\n // Check last panel is empty\n let lastIndex = panels.length - 1;\n if (!panels[lastIndex]) {\n const reversedPanels = panels.concat().reverse();\n const nonEmptyIndexFromLast = findIndex(reversedPanels, panel => !!panel);\n lastIndex = nonEmptyIndexFromLast < 0\n ? -1 // All empty\n : lastIndex - nonEmptyIndexFromLast;\n\n // Remove all empty panels from last\n panels.splice(lastIndex + 1);\n if (isCircular) {\n clones.forEach(cloneSet => {\n cloneSet.splice(lastIndex + 1);\n });\n }\n }\n\n // Update range & length\n this.range = {\n min: findIndex(panels, panel => !!panel),\n max: lastIndex,\n };\n this.length -= deletedPanels.length;\n\n if (this.length <= 0) {\n // Reset clones\n this.clones = [];\n this.cloneCount = 0;\n }\n\n return deletedPanels;\n }\n\n public chainAllPanels() {\n const allPanels = this.allPanels().filter(panel => !!panel);\n const allPanelsCount = allPanels.length;\n\n if (allPanelsCount <= 1) {\n return;\n }\n\n allPanels.slice(1, allPanels.length - 1).forEach((panel, idx) => {\n const prevPanel = allPanels[idx];\n const nextPanel = allPanels[idx + 2];\n\n panel.prevSibling = prevPanel;\n panel.nextSibling = nextPanel;\n });\n\n const firstPanel = allPanels[0];\n const lastPanel = allPanels[allPanelsCount - 1];\n\n firstPanel.prevSibling = null;\n firstPanel.nextSibling = allPanels[1];\n lastPanel.prevSibling = allPanels[allPanelsCount - 2];\n lastPanel.nextSibling = null;\n\n if (this.options.circular) {\n firstPanel.prevSibling = lastPanel;\n lastPanel.nextSibling = firstPanel;\n }\n }\n\n public insertClones(cloneIndex: number, index: number, clonedPanels: Panel[], deleteCount: number = 0): void {\n const clones = this.clones;\n const lastIndex = this.lastIndex;\n\n if (!clones[cloneIndex]) {\n const newClones: Panel[] = [];\n clonedPanels.forEach((panel, offset) => {\n newClones[index + offset] = panel;\n });\n\n clones[cloneIndex] = newClones;\n } else {\n const insertTarget = clones[cloneIndex];\n\n if (index >= insertTarget.length) {\n clonedPanels.forEach((panel, offset) => {\n insertTarget[index + offset] = panel;\n });\n } else {\n insertTarget.splice(index, deleteCount, ...clonedPanels);\n // Remove panels after last index\n if (clonedPanels.length > lastIndex + 1) {\n clonedPanels.splice(lastIndex + 1);\n }\n }\n }\n }\n\n // clones are operating in set\n public removeClonesAfter(cloneIndex: number): void {\n const panels = this.panels;\n\n panels.forEach(panel => {\n panel.removeClonedPanelsAfter(cloneIndex);\n });\n this.clones.splice(cloneIndex);\n }\n\n public findPanelOf(element: HTMLElement): Panel | undefined {\n const allPanels = this.allPanels();\n for (const panel of allPanels) {\n if (!panel) {\n continue;\n }\n const panelElement = panel.getElement();\n if (panelElement.contains(element)) {\n return panel;\n }\n }\n }\n\n public findFirstPanelFrom(index: number): Panel | undefined {\n for (const panel of this.panels.slice(index)) {\n if (panel && panel.getIndex() >= index && panel.getElement().parentNode) {\n return panel;\n }\n }\n }\n\n private addNewClones(index: number, originalPanels: Panel[], deleteCount: number, nextSibling: Panel | undefined) {\n const cameraElement = this.cameraElement;\n const cloneCount = this.getCloneCount();\n const lastPanel = this.lastPanel();\n const lastPanelClones: Panel[] = lastPanel\n ? lastPanel.getClonedPanels()\n : [];\n const nextSiblingClones: Panel[] = nextSibling\n ? nextSibling.getClonedPanels()\n : [];\n\n for (const cloneIndex of counter(cloneCount)) {\n const cloneNextSibling = nextSiblingClones[cloneIndex];\n const lastPanelSibling = lastPanelClones[cloneIndex];\n\n const cloneSiblingElement = cloneNextSibling\n ? cloneNextSibling.getElement()\n : lastPanelSibling\n ? lastPanelSibling.getElement().nextElementSibling\n : null;\n\n const newClones = originalPanels.map(panel => {\n const clone = panel.clone(cloneIndex);\n\n if (this.shouldRender()) {\n cameraElement.insertBefore(clone.getElement(), cloneSiblingElement);\n }\n\n return clone;\n });\n\n this.insertClones(cloneIndex, index, newClones, deleteCount);\n }\n }\n\n private updateIndex(insertingIndex: number) {\n const panels = this.panels;\n const range = this.range;\n\n const newLastIndex = panels.length - 1;\n if (newLastIndex > range.max) {\n range.max = newLastIndex;\n }\n if (insertingIndex < range.min || range.min < 0) {\n range.min = insertingIndex;\n }\n }\n\n private insertNewPanels(newPanels: Panel[], siblingElement: HTMLElement | null) {\n if (this.shouldRender()) {\n const fragment = document.createDocumentFragment();\n newPanels.forEach(panel => fragment.appendChild(panel.getElement()));\n this.cameraElement.insertBefore(fragment, siblingElement);\n }\n }\n\n private shouldRender(): boolean {\n const options = this.options;\n\n return !options.renderExternal && !options.renderOnlyVisible;\n }\n}\n\nexport default PanelManager;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnAnimationEnd, OnChange, OnFinish, OnHold, OnRelease } from \"@egjs/axes\";\nimport Panel from \"../components/Panel\";\nimport { ValueOf, Direction, StateType, FlickingContext } from \"../types\";\n\nabstract class State {\n public delta: number = 0;\n public direction: ValueOf<Direction> | null = null;\n public targetPanel: Panel | null = null;\n public lastPosition: number = 0;\n public abstract readonly type: ValueOf<StateType>;\n public abstract readonly holding: boolean;\n public abstract readonly playing: boolean;\n\n public onEnter(prevState: State): void {\n this.delta = prevState.delta;\n this.direction = prevState.direction;\n this.targetPanel = prevState.targetPanel;\n this.lastPosition = prevState.lastPosition;\n }\n\n public onExit(nextState: State): void {\n // DO NOTHING\n }\n\n public onHold(e: OnHold, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onChange(e: OnChange, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onRelease(e: OnRelease, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onAnimationEnd(e: OnAnimationEnd, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onFinish(e: OnFinish, context: FlickingContext): void {\n // DO NOTHING\n }\n}\n\nexport default State;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnHold, OnChange } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { EVENTS, STATE_TYPE } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass IdleState extends State {\n public readonly type = STATE_TYPE.IDLE;\n public readonly holding = false;\n public readonly playing = false;\n\n public onEnter() {\n this.direction = null;\n this.targetPanel = null;\n this.delta = 0;\n this.lastPosition = 0;\n }\n\n public onHold(e: OnHold, { flicking, viewport, triggerEvent, transitTo }: FlickingContext): void {\n // Shouldn't do any action until any panels on flicking area\n if (flicking.getPanelCount() <= 0) {\n if (viewport.options.infinite) {\n viewport.moveCamera(viewport.getCameraPosition(), e);\n }\n transitTo(STATE_TYPE.DISABLED);\n return;\n }\n\n this.lastPosition = viewport.getCameraPosition();\n triggerEvent(EVENTS.HOLD_START, e, true)\n .onSuccess(() => {\n transitTo(STATE_TYPE.HOLDING);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n // By methods call\n public onChange(e: OnChange, context: FlickingContext): void {\n const { triggerEvent, transitTo } = context;\n\n triggerEvent(EVENTS.MOVE_START, e, false)\n .onSuccess(() => {\n // Trigger AnimatingState's onChange, to trigger \"move\" event immediately\n transitTo(STATE_TYPE.ANIMATING)\n .onChange(e, context);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n}\n\nexport default IdleState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnChange, OnRelease, OnFinish } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { STATE_TYPE, EVENTS, DIRECTION } from \"../consts\";\nimport { FlickingContext, SelectEvent } from \"../types\";\n\nclass HoldingState extends State {\n public readonly type = STATE_TYPE.HOLDING;\n public readonly holding = true;\n public readonly playing = true;\n\n private releaseEvent: any = null;\n\n public onChange(e: OnChange, context: FlickingContext): void {\n const { flicking, triggerEvent, transitTo } = context;\n\n const offset = flicking.options.horizontal\n ? e.inputEvent.offsetX\n : e.inputEvent.offsetY;\n this.direction = offset < 0\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n triggerEvent(EVENTS.MOVE_START, e, true)\n .onSuccess(() => {\n // Trigger DraggingState's onChange, to trigger \"move\" event immediately\n transitTo(STATE_TYPE.DRAGGING)\n .onChange(e, context);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onRelease(e: OnRelease, context: FlickingContext): void {\n const { viewport, triggerEvent, transitTo } = context;\n\n triggerEvent(EVENTS.HOLD_END, e, true);\n\n if (e.delta.flick !== 0) {\n // Sometimes \"release\" event on axes triggered before \"change\" event\n // Especially if user flicked panel fast in really short amount of time\n // if delta is not zero, that means above case happened.\n\n // Event flow should be HOLD_START -> MOVE_START -> MOVE -> HOLD_END\n // At least one move event should be included between holdStart and holdEnd\n e.setTo({ flick: viewport.getCameraPosition() }, 0);\n transitTo(STATE_TYPE.IDLE);\n return;\n }\n\n if (!e.inputEvent.srcEvent.cancelable) {\n // Released by scrolling\n return;\n }\n\n // Can't handle select event here,\n // As \"finish\" axes event happens\n this.releaseEvent = e;\n }\n\n public onFinish(e: OnFinish, { viewport, triggerEvent, transitTo }: FlickingContext): void {\n // Should transite to IDLE state before select event\n // As user expects hold is already finished\n transitTo(STATE_TYPE.IDLE);\n\n if (!this.releaseEvent) {\n return;\n }\n\n // Handle release event here\n // To prevent finish event called twice\n const releaseEvent = this.releaseEvent;\n\n // Static click\n const srcEvent = releaseEvent.inputEvent.srcEvent;\n\n let clickedElement: HTMLElement;\n if (srcEvent.type === \"touchend\") {\n const touchEvent = srcEvent as TouchEvent;\n const touch = touchEvent.changedTouches[0];\n clickedElement = document.elementFromPoint(touch.clientX, touch.clientY) as HTMLElement;\n } else {\n clickedElement = srcEvent.target;\n }\n const clickedPanel = viewport.panelManager.findPanelOf(clickedElement);\n const cameraPosition = viewport.getCameraPosition();\n\n if (clickedPanel) {\n const clickedPanelPosition = clickedPanel.getPosition();\n const direction = clickedPanelPosition > cameraPosition\n ? DIRECTION.NEXT\n : clickedPanelPosition < cameraPosition\n ? DIRECTION.PREV\n : null;\n\n // Don't provide axes event, to use axes instance instead\n triggerEvent<SelectEvent>(EVENTS.SELECT, releaseEvent, true, {\n direction, // Direction to the clicked panel\n index: clickedPanel.getIndex(),\n panel: clickedPanel,\n element: clickedElement,\n });\n }\n }\n}\n\nexport default HoldingState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnChange, OnRelease } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { STATE_TYPE, EVENTS } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass DraggingState extends State {\n public readonly type = STATE_TYPE.DRAGGING;\n public readonly holding = true;\n public readonly playing = true;\n\n public onChange(e: OnChange, { moveCamera, transitTo }: FlickingContext): void {\n if (!e.delta.flick) {\n return;\n }\n\n moveCamera(e)\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onRelease(e: OnRelease, context: FlickingContext): void {\n const { flicking, viewport, triggerEvent, transitTo, stopCamera } = context;\n\n const delta = this.delta;\n const absDelta = Math.abs(delta);\n const options = flicking.options;\n const horizontal = options.horizontal;\n const moveType = viewport.moveType;\n const inputEvent = e.inputEvent;\n\n const velocity = horizontal\n ? inputEvent.velocityX\n : inputEvent.velocityY;\n const inputDelta = horizontal\n ? inputEvent.deltaX\n : inputEvent.deltaY;\n const isNextDirection = Math.abs(velocity) > 1\n ? velocity < 0\n : absDelta > 0\n ? delta > 0\n : inputDelta < 0;\n\n const swipeDistance = viewport.options.bound\n ? Math.max(absDelta, Math.abs(inputDelta))\n : absDelta;\n const swipeAngle = inputEvent.deltaX\n ? Math.abs(180 * Math.atan(inputEvent.deltaY / inputEvent.deltaX) / Math.PI)\n : 90;\n const belowAngleThreshold = horizontal\n ? swipeAngle <= options.thresholdAngle\n : swipeAngle > options.thresholdAngle;\n const overThreshold = swipeDistance >= options.threshold\n && belowAngleThreshold;\n\n const moveTypeContext = {\n viewport,\n axesEvent: e,\n state: this,\n swipeDistance,\n isNextDirection,\n };\n\n // Update last position to cope with Axes's animating behavior\n // Axes uses start position when animation start\n triggerEvent(EVENTS.HOLD_END, e, true);\n\n const targetPanel = this.targetPanel;\n if (!overThreshold && targetPanel) {\n // Interrupted while animating\n const interruptDestInfo = moveType.findPanelWhenInterrupted(moveTypeContext);\n\n viewport.moveTo(\n interruptDestInfo.panel,\n interruptDestInfo.destPos,\n interruptDestInfo.eventType,\n e,\n interruptDestInfo.duration,\n );\n transitTo(STATE_TYPE.ANIMATING);\n return;\n }\n\n const currentPanel = viewport.getCurrentPanel();\n const nearestPanel = viewport.getNearestPanel();\n\n if (!currentPanel || !nearestPanel) {\n // There're no panels\n (e as any).stop();\n transitTo(STATE_TYPE.IDLE);\n return;\n }\n\n const destInfo = overThreshold\n ? moveType.findTargetPanel(moveTypeContext)\n : moveType.findRestorePanel(moveTypeContext);\n\n viewport.moveTo(\n destInfo.panel,\n destInfo.destPos,\n destInfo.eventType,\n e,\n destInfo.duration,\n ).onSuccess(() => {\n transitTo(STATE_TYPE.ANIMATING);\n }).onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n stopCamera(e);\n });\n }\n}\n\nexport default DraggingState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnChange, OnFinish, OnHold } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { STATE_TYPE, EVENTS } from \"../consts\";\nimport { FlickingContext } from \"../types\";\nimport { circulate } from \"../utils\";\n\nclass AnimatingState extends State {\n public readonly type = STATE_TYPE.ANIMATING;\n public readonly holding = false;\n public readonly playing = true;\n\n public onHold(e: OnHold, { viewport, triggerEvent, transitTo }: FlickingContext): void {\n const options = viewport.options;\n const scrollArea = viewport.getScrollArea();\n const scrollAreaSize = viewport.getScrollAreaSize();\n const loopCount = Math.floor((this.lastPosition + this.delta - scrollArea.prev) / scrollAreaSize);\n\n const targetPanel = this.targetPanel;\n if (options.circular && loopCount !== 0 && targetPanel) {\n const cloneCount = viewport.panelManager.getCloneCount();\n const originalTargetPosition = targetPanel.getPosition();\n\n // cloneIndex is from -1 to cloneCount - 1\n const newCloneIndex = circulate(targetPanel.getCloneIndex() - loopCount, -1, cloneCount - 1, true);\n const newTargetPosition = originalTargetPosition - loopCount * scrollAreaSize;\n const newTargetPanel = targetPanel.getIdenticalPanels()[newCloneIndex + 1].clone(newCloneIndex, true);\n\n // Set new target panel considering looped count\n newTargetPanel.setPosition(newTargetPosition);\n this.targetPanel = newTargetPanel;\n }\n\n // Reset last position and delta\n this.delta = 0;\n this.lastPosition = viewport.getCameraPosition();\n\n // Update current panel as current nearest panel\n viewport.setCurrentPanel(viewport.getNearestPanel()!);\n triggerEvent(EVENTS.HOLD_START, e, true)\n .onSuccess(() => {\n transitTo(STATE_TYPE.DRAGGING);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onChange(e: OnChange, { moveCamera, transitTo }: FlickingContext): void {\n if (!e.delta.flick) {\n return;\n }\n\n moveCamera(e)\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onFinish(e: OnFinish, { flicking, viewport, triggerEvent, transitTo }: FlickingContext) {\n const isTrusted = e && e.isTrusted;\n\n viewport.options.bound\n ? viewport.setCurrentPanel(this.targetPanel!)\n : viewport.setCurrentPanel(viewport.getNearestPanel()!);\n\n if (flicking.options.adaptive) {\n viewport.updateAdaptiveSize();\n }\n\n transitTo(STATE_TYPE.IDLE);\n viewport.updateCameraPosition();\n triggerEvent(EVENTS.MOVE_END, e, isTrusted, {\n direction: this.direction,\n });\n }\n}\n\nexport default AnimatingState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnAnimationEnd, OnChange, OnRelease } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { STATE_TYPE } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass DisabledState extends State {\n public readonly type = STATE_TYPE.DISABLED;\n public readonly holding = false;\n public readonly playing = true;\n\n public onAnimationEnd(e: OnAnimationEnd, { transitTo }: FlickingContext): void {\n transitTo(STATE_TYPE.IDLE);\n }\n\n public onChange(e: OnChange, { viewport, transitTo }: FlickingContext): void {\n // Can stop Axes's change event\n e.stop();\n\n // Should update axes position as it's already changed at this moment\n viewport.updateAxesPosition(viewport.getCameraPosition());\n transitTo(STATE_TYPE.IDLE);\n }\n\n public onRelease(e: OnRelease, { transitTo }: FlickingContext): void {\n // This is needed when stopped hold start event\n if (e.delta.flick === 0) {\n transitTo(STATE_TYPE.IDLE);\n }\n }\n}\n\nexport default DisabledState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport State from \"../states/State\";\nimport { AxesEventType, ValueOf, FlickingContext, StateType } from \"../types\";\nimport { AXES_EVENTS, STATE_TYPE } from \"../consts\";\nimport IdleState from \"../states/IdleState\";\nimport HoldingState from \"../states/HoldingState\";\nimport DraggingState from \"../states/DraggingState\";\nimport AnimatingState from \"../states/AnimatingState\";\nimport DisabledState from \"../states/DisabledState\";\n\nclass StateMachine {\n private state: State = new IdleState();\n\n public fire(eventType: ValueOf<AxesEventType>, e: any, context: FlickingContext) {\n const currentState = this.state;\n switch (eventType) {\n case AXES_EVENTS.HOLD:\n currentState.onHold(e, context);\n break;\n case AXES_EVENTS.CHANGE:\n currentState.onChange(e, context);\n break;\n case AXES_EVENTS.RELEASE:\n currentState.onRelease(e, context);\n break;\n case AXES_EVENTS.ANIMATION_END:\n currentState.onAnimationEnd(e, context);\n break;\n case AXES_EVENTS.FINISH:\n currentState.onFinish(e, context);\n break;\n }\n }\n\n public getState(): State {\n return this.state;\n }\n\n public transitTo = (nextStateType: ValueOf<StateType>): State => {\n const currentState = this.state;\n\n if (currentState.type !== nextStateType) {\n let nextState: State;\n\n switch (nextStateType) {\n case STATE_TYPE.IDLE:\n nextState = new IdleState();\n break;\n case STATE_TYPE.HOLDING:\n nextState = new HoldingState();\n break;\n case STATE_TYPE.DRAGGING:\n nextState = new DraggingState();\n break;\n case STATE_TYPE.ANIMATING:\n nextState = new AnimatingState();\n break;\n case STATE_TYPE.DISABLED:\n nextState = new DisabledState();\n break;\n }\n\n currentState.onExit(nextState!);\n nextState!.onEnter(currentState);\n\n this.state = nextState!;\n }\n return this.state;\n }\n}\n\nexport default StateMachine;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport MoveType from \"./MoveType\";\nimport { MOVE_TYPE, EVENTS } from \"../consts\";\nimport { MoveTypeContext, DestinationInfo } from \"../types\";\nimport { clamp } from \"../utils\";\n\nclass Snap extends MoveType {\n protected readonly type: string = MOVE_TYPE.SNAP;\n protected count: number;\n\n constructor(count: number) {\n super();\n this.count = count;\n }\n\n public findTargetPanel(ctx: MoveTypeContext): DestinationInfo {\n const { viewport, axesEvent, swipeDistance } = ctx;\n const snapCount = this.count;\n const eventDelta = Math.abs(axesEvent.delta.flick);\n const currentPanel = viewport.getCurrentPanel()!;\n const nearestPanel = viewport.getNearestPanel()!;\n const minimumDistanceToChange = this.calcBrinkOfChange(ctx);\n const nearestIsCurrent = nearestPanel.getIndex() === currentPanel.getIndex();\n\n // This can happen when bounce is 0\n const shouldMoveWhenBounceIs0 = viewport.canSetBoundMode() && nearestIsCurrent;\n const shouldMoveToAdjacent = !viewport.isOutOfBound()\n && (swipeDistance <= minimumDistanceToChange || shouldMoveWhenBounceIs0);\n\n if (snapCount > 1 && eventDelta > minimumDistanceToChange) {\n return this.findSnappedPanel(ctx);\n } else if (shouldMoveToAdjacent) {\n return this.findAdjacentPanel(ctx);\n } else {\n return {\n panel: nearestPanel,\n duration: viewport.options.duration,\n destPos: viewport.findEstimatedPosition(nearestPanel),\n // As swipeDistance holds mouse/touch position change regardless of bounce option value\n // swipDistance > minimumDistanceToChange can happen in bounce area\n // Second condition is for handling that.\n eventType: (swipeDistance <= minimumDistanceToChange)\n || (viewport.isOutOfBound() && nearestIsCurrent)\n ? EVENTS.RESTORE\n : EVENTS.CHANGE,\n };\n }\n }\n\n protected findSnappedPanel(ctx: MoveTypeContext): DestinationInfo {\n const { axesEvent, viewport, state, isNextDirection } = ctx;\n\n const eventDelta = Math.abs(axesEvent.delta.flick);\n const minimumDistanceToChange = this.calcBrinkOfChange(ctx);\n const snapCount = this.count;\n const options = viewport.options;\n const scrollAreaSize = viewport.getScrollAreaSize();\n const halfGap = options.gap / 2;\n const estimatedHangerPos = axesEvent.destPos.flick + viewport.getRelativeHangerPosition();\n\n let panelToMove = viewport.getNearestPanel()!;\n let cycleIndex = panelToMove.getCloneIndex() + 1; // 0(original) or 1(clone)\n let passedPanelCount = 0;\n\n while (passedPanelCount < snapCount) {\n // Since panelToMove holds also cloned panels, we should use original panel's position\n const originalPanel = panelToMove.getOriginalPanel();\n const panelPosition = originalPanel.getPosition() + cycleIndex * scrollAreaSize;\n const panelSize = originalPanel.getSize();\n\n const panelNextPosition = panelPosition + panelSize + halfGap;\n const panelPrevPosition = panelPosition - halfGap;\n\n // Current panelToMove contains destPos\n if (\n (isNextDirection && panelNextPosition > estimatedHangerPos)\n || (!isNextDirection && panelPrevPosition < estimatedHangerPos)\n ) {\n break;\n }\n\n const siblingPanel = isNextDirection\n ? panelToMove.nextSibling\n : panelToMove.prevSibling;\n if (!siblingPanel) {\n break;\n }\n\n const panelIndex = panelToMove.getIndex();\n const siblingIndex = siblingPanel.getIndex();\n if ((isNextDirection && siblingIndex <= panelIndex)\n || (!isNextDirection && siblingIndex >= panelIndex)\n ) {\n cycleIndex = isNextDirection\n ? cycleIndex + 1\n : cycleIndex - 1;\n }\n panelToMove = siblingPanel;\n passedPanelCount += 1;\n }\n\n const originalPosition = panelToMove.getOriginalPanel().getPosition();\n\n if (cycleIndex !== 0) {\n panelToMove = panelToMove.clone(panelToMove.getCloneIndex(), true);\n panelToMove.setPosition(originalPosition + cycleIndex * scrollAreaSize);\n }\n\n const defaultDuration = viewport.options.duration;\n const duration = clamp(axesEvent.duration, defaultDuration, defaultDuration * passedPanelCount);\n\n return {\n panel: panelToMove,\n destPos: viewport.findEstimatedPosition(panelToMove),\n duration,\n eventType: Math.max(eventDelta, state.delta) > minimumDistanceToChange\n ? EVENTS.CHANGE\n : EVENTS.RESTORE,\n };\n }\n\n private findAdjacentPanel(ctx: MoveTypeContext): DestinationInfo {\n const { viewport, isNextDirection } = ctx;\n\n const options = viewport.options;\n const currentIndex = viewport.getCurrentIndex();\n const currentPanel = viewport.panelManager.get(currentIndex)!;\n const hangerPosition = viewport.getHangerPosition();\n const scrollArea = viewport.getScrollArea();\n\n const firstClonedPanel = currentPanel.getIdenticalPanels()[1];\n const lapped = options.circular\n && (Math.abs(currentPanel.getAnchorPosition() - hangerPosition)\n > Math.abs(firstClonedPanel.getAnchorPosition() - hangerPosition));\n\n // If lapped in circular mode, use first cloned panel as base panel\n const basePanel = lapped\n ? firstClonedPanel\n : currentPanel;\n const basePosition = basePanel.getPosition();\n\n const adjacentPanel = isNextDirection\n ? basePanel.nextSibling\n : basePanel.prevSibling;\n\n const eventType = adjacentPanel\n ? EVENTS.CHANGE\n : EVENTS.RESTORE;\n const panelToMove = adjacentPanel\n ? adjacentPanel\n : basePanel;\n const targetRelativeAnchorPosition = panelToMove.getRelativeAnchorPosition();\n\n const estimatedPanelPosition = options.circular\n ? isNextDirection\n ? basePosition + basePanel.getSize() + targetRelativeAnchorPosition + options.gap\n : basePosition - (panelToMove.getSize() - targetRelativeAnchorPosition) - options.gap\n : panelToMove.getAnchorPosition();\n const estimatedPosition = estimatedPanelPosition - viewport.getRelativeHangerPosition();\n const destPos = viewport.canSetBoundMode()\n ? clamp(estimatedPosition, scrollArea.prev, scrollArea.next)\n : estimatedPosition;\n\n return {\n panel: panelToMove,\n destPos,\n duration: options.duration,\n eventType,\n };\n }\n}\n\nexport default Snap;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { MoveTypeStringOption, MoveTypeContext, DestinationInfo } from \"../types\";\nimport Panel from \"../components/Panel\";\nimport { EVENTS } from \"../consts\";\n\nabstract class MoveType {\n protected readonly abstract type: string;\n\n public abstract findTargetPanel(ctx: MoveTypeContext): DestinationInfo;\n\n public is(type: MoveTypeStringOption): boolean {\n return type === this.type;\n }\n\n public findRestorePanel(ctx: MoveTypeContext): DestinationInfo {\n const viewport = ctx.viewport;\n const options = viewport.options;\n\n const panel = options.circular\n ? this.findRestorePanelInCircularMode(ctx)\n : viewport.getCurrentPanel()!;\n\n return {\n panel,\n destPos: viewport.findEstimatedPosition(panel),\n duration: options.duration,\n eventType: EVENTS.RESTORE,\n };\n }\n\n public findPanelWhenInterrupted(ctx: MoveTypeContext): DestinationInfo {\n const { state, viewport } = ctx;\n const targetPanel = state.targetPanel!;\n\n return {\n panel: targetPanel,\n destPos: viewport.findEstimatedPosition(targetPanel),\n duration: viewport.options.duration,\n eventType: \"\",\n };\n }\n\n // Calculate minimum distance to \"change\" panel\n protected calcBrinkOfChange(ctx: MoveTypeContext): number {\n const { viewport, isNextDirection } = ctx;\n\n const options = viewport.options;\n const currentPanel = viewport.getCurrentPanel()!;\n const halfGap = options.gap / 2;\n\n const relativeAnchorPosition = currentPanel.getRelativeAnchorPosition();\n\n // Minimum distance needed to decide prev/next panel as nearest\n /*\n * | Prev | Next |\n * |--------|--------------|\n * [][ |<-Anchor ][] <- Panel + Half-Gap\n */\n let minimumDistanceToChange = isNextDirection\n ? currentPanel.getSize() - relativeAnchorPosition + halfGap\n : relativeAnchorPosition + halfGap;\n\n minimumDistanceToChange = Math.max(minimumDistanceToChange, options.threshold);\n\n return minimumDistanceToChange;\n }\n\n private findRestorePanelInCircularMode(ctx: MoveTypeContext): Panel {\n const viewport = ctx.viewport;\n const originalPanel = viewport.getCurrentPanel()!.getOriginalPanel();\n const hangerPosition = viewport.getHangerPosition();\n\n const firstClonedPanel = originalPanel.getIdenticalPanels()[1];\n const lapped = Math.abs(originalPanel.getAnchorPosition() - hangerPosition)\n > Math.abs(firstClonedPanel.getAnchorPosition() - hangerPosition);\n\n return (!ctx.isNextDirection && lapped)\n ? firstClonedPanel\n : originalPanel;\n }\n}\n\nexport default MoveType;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Snap from \"./Snap\";\nimport { MOVE_TYPE, EVENTS } from \"../consts\";\nimport { MoveTypeContext, DestinationInfo } from \"../types\";\nimport { circulate, clamp } from \"../utils\";\n\nclass FreeScroll extends Snap {\n protected readonly type: string = MOVE_TYPE.FREE_SCROLL;\n\n constructor() {\n // Set snap count to Infinity\n super(Infinity);\n }\n\n public findTargetPanel(ctx: MoveTypeContext): DestinationInfo {\n const { axesEvent, state, viewport } = ctx;\n const destPos = axesEvent.destPos.flick;\n const minimumDistanceToChange = this.calcBrinkOfChange(ctx);\n const scrollArea = viewport.getScrollArea();\n const currentPanel = viewport.getCurrentPanel()!;\n const options = viewport.options;\n\n const delta = Math.abs(axesEvent.delta.flick + state.delta);\n if (delta > minimumDistanceToChange) {\n const destInfo = super.findSnappedPanel(ctx);\n\n destInfo.duration = axesEvent.duration;\n destInfo.destPos = destPos;\n destInfo.eventType = !options.circular && destInfo.panel === currentPanel\n ? \"\"\n : EVENTS.CHANGE;\n\n return destInfo;\n } else {\n let estimatedPosition = options.circular\n ? circulate(destPos, scrollArea.prev, scrollArea.next, false)\n : destPos;\n estimatedPosition = clamp(estimatedPosition, scrollArea.prev, scrollArea.next);\n estimatedPosition += viewport.getRelativeHangerPosition();\n\n const estimatedPanel = viewport.findNearestPanelAt(estimatedPosition)!;\n\n return {\n panel: estimatedPanel,\n destPos,\n duration: axesEvent.duration,\n eventType: \"\",\n };\n }\n }\n\n public findRestorePanel(ctx: MoveTypeContext): DestinationInfo {\n return this.findTargetPanel(ctx);\n }\n\n public findPanelWhenInterrupted(ctx: MoveTypeContext): DestinationInfo {\n const { viewport } = ctx;\n\n return {\n panel: viewport.getNearestPanel()!,\n destPos: viewport.getCameraPosition(),\n duration: 0,\n eventType: \"\",\n };\n }\n\n protected calcBrinkOfChange(ctx: MoveTypeContext): number {\n const { viewport, isNextDirection } = ctx;\n\n const options = viewport.options;\n const currentPanel = viewport.getCurrentPanel()!;\n const halfGap = options.gap / 2;\n\n const lastPosition = viewport.stateMachine.getState().lastPosition;\n const currentPanelPosition = currentPanel.getPosition();\n\n // As camera can stop anywhere in free scroll mode,\n // minimumDistanceToChange should be calculated differently.\n // Ref #191(https://github.com/naver/egjs-flicking/issues/191)\n const lastHangerPosition = lastPosition + viewport.getRelativeHangerPosition();\n\n const scrollAreaSize = viewport.getScrollAreaSize();\n let minimumDistanceToChange = isNextDirection\n ? currentPanelPosition + currentPanel.getSize() - lastHangerPosition + halfGap\n : lastHangerPosition - currentPanelPosition + halfGap;\n minimumDistanceToChange = Math.abs(minimumDistanceToChange % scrollAreaSize);\n\n return Math.min(minimumDistanceToChange, scrollAreaSize - minimumDistanceToChange);\n }\n}\n\nexport default FreeScroll;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport Flicking from \"../Flicking\";\nimport Panel from \"./Panel\";\nimport PanelManager from \"./PanelManager\";\nimport StateMachine from \"./StateMachine\";\nimport MoveType from \"../moves/MoveType\";\nimport { FlickingOptions, FlickingPanel, FlickingStatus, ElementLike, EventType, TriggerCallback, NeedPanelEvent, FlickingEvent, MoveTypeObjectOption, OriginalStyle, Plugin, DestroyOption, BoundingBox } from \"../types\";\nimport { DEFAULT_VIEWPORT_CSS, DEFAULT_CAMERA_CSS, TRANSFORM, DEFAULT_OPTIONS, EVENTS, DIRECTION, STATE_TYPE, MOVE_TYPE } from \"../consts\";\nimport { clamp, applyCSS, toArray, parseArithmeticExpression, isBetween, isArray, parseElement, hasClass, restoreStyle, circulate, findIndex, getBbox } from \"../utils\";\nimport Snap from \"../moves/Snap\";\nimport FreeScroll from \"../moves/FreeScroll\";\n\nexport default class Viewport {\n public options: FlickingOptions;\n public stateMachine: StateMachine;\n public panelManager: PanelManager;\n public moveType: MoveType;\n\n private flicking: Flicking;\n private axes: Axes;\n private panInput: PanInput | null;\n\n private viewportElement: HTMLElement;\n private cameraElement: HTMLElement;\n\n private triggerEvent: Flicking[\"triggerEvent\"];\n private axesHandlers: { [key: string]: any };\n\n private currentPanel: Panel | undefined;\n private nearestPanel: Panel | undefined;\n private visiblePanels: Panel[];\n\n private plugins: Plugin[] = [];\n private panelBboxes: { [className: string]: BoundingBox };\n private state: {\n size: number;\n position: number;\n panelMaintainRatio: number;\n relativeHangerPosition: number;\n positionOffset: number;\n scrollArea: {\n prev: number;\n next: number;\n };\n translate: {\n name: string,\n has3d: boolean,\n };\n infiniteThreshold: number;\n checkedIndexes: Array<[number, number]>;\n isAdaptiveCached: boolean;\n isViewportGiven: boolean;\n isCameraGiven: boolean;\n originalViewportStyle: OriginalStyle;\n originalCameraStyle: OriginalStyle;\n cachedBbox: BoundingBox | null;\n };\n\n constructor(\n flicking: Flicking,\n options: FlickingOptions,\n triggerEvent: Flicking[\"triggerEvent\"],\n ) {\n this.flicking = flicking;\n this.triggerEvent = triggerEvent;\n\n this.state = {\n size: 0,\n position: 0,\n panelMaintainRatio: 0,\n relativeHangerPosition: 0,\n positionOffset: 0,\n scrollArea: {\n prev: 0,\n next: 0,\n },\n translate: TRANSFORM,\n infiniteThreshold: 0,\n checkedIndexes: [],\n isAdaptiveCached: false,\n isViewportGiven: false,\n isCameraGiven: false,\n originalViewportStyle: {\n className: null,\n style: null,\n },\n originalCameraStyle: {\n className: null,\n style: null,\n },\n cachedBbox: null,\n };\n this.options = options;\n this.stateMachine = new StateMachine();\n this.visiblePanels = [];\n this.panelBboxes = {};\n\n this.build();\n }\n\n public moveTo(\n panel: Panel,\n destPos: number,\n eventType: EventType[\"CHANGE\"] | EventType[\"RESTORE\"] | \"\",\n axesEvent: any,\n duration: number = this.options.duration,\n ): TriggerCallback {\n const state = this.state;\n const currentState = this.stateMachine.getState();\n const currentPosition = state.position;\n\n const isTrusted = axesEvent\n ? axesEvent.isTrusted\n : false;\n const direction = destPos === currentPosition\n ? null\n : destPos > currentPosition\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n let eventResult: TriggerCallback;\n if (eventType === EVENTS.CHANGE) {\n eventResult = this.triggerEvent(EVENTS.CHANGE, axesEvent, isTrusted, {\n index: panel.getIndex(),\n panel,\n direction,\n });\n } else if (eventType === EVENTS.RESTORE) {\n eventResult = this.triggerEvent(EVENTS.RESTORE, axesEvent, isTrusted);\n } else {\n eventResult = {\n onSuccess(callback: () => void): TriggerCallback {\n callback();\n return this;\n },\n onStopped(): TriggerCallback {\n return this;\n },\n };\n }\n\n eventResult.onSuccess(() => {\n currentState.delta = 0;\n currentState.lastPosition = this.getCameraPosition();\n currentState.targetPanel = panel;\n currentState.direction = destPos === currentPosition\n ? null\n : destPos > currentPosition\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n if (destPos === currentPosition) {\n // no move\n this.nearestPanel = panel;\n this.currentPanel = panel;\n }\n\n if (axesEvent && axesEvent.setTo) {\n // freeScroll only occurs in release events\n axesEvent.setTo({ flick: destPos }, duration);\n } else {\n this.axes.setTo({ flick: destPos }, duration);\n }\n });\n\n return eventResult;\n }\n\n public moveCamera(pos: number, axesEvent?: any): void {\n const state = this.state;\n const options = this.options;\n const transform = state.translate.name;\n const scrollArea = state.scrollArea;\n\n // Update position & nearestPanel\n if (options.circular && !isBetween(pos, scrollArea.prev, scrollArea.next)) {\n pos = circulate(pos, scrollArea.prev, scrollArea.next, false);\n }\n state.position = pos;\n this.nearestPanel = this.findNearestPanel();\n const nearestPanel = this.nearestPanel;\n const originalNearestPosition = nearestPanel\n ? nearestPanel.getPosition()\n : 0;\n\n // From 0(panel position) to 1(panel position + panel size)\n // When it's on gap area value will be (val > 1 || val < 0)\n if (nearestPanel) {\n const hangerPosition = this.getHangerPosition();\n const panelPosition = nearestPanel.getPosition();\n const panelSize = nearestPanel.getSize();\n const halfGap = options.gap / 2;\n\n // As panel's range is from panel position - half gap ~ panel pos + panel size + half gap\n state.panelMaintainRatio = (hangerPosition - panelPosition + halfGap) / (panelSize + 2 * halfGap);\n } else {\n state.panelMaintainRatio = 0;\n }\n\n this.checkNeedPanel(axesEvent);\n\n // Possibly modified after need panel, if it's looped\n const modifiedNearestPosition = nearestPanel\n ? nearestPanel.getPosition()\n : 0;\n\n pos += (modifiedNearestPosition - originalNearestPosition);\n state.position = pos;\n\n this.updateVisiblePanels();\n\n // Offset is needed to fix camera layer size in visible-only rendering mode\n const posOffset = options.renderOnlyVisible\n ? state.positionOffset\n : 0;\n const moveVector = options.horizontal\n ? [-(pos - posOffset), 0] : [0, -(pos - posOffset)];\n const moveCoord = moveVector.map(coord => `${Math.round(coord)}px`).join(\", \");\n\n this.cameraElement.style[transform] = state.translate.has3d\n ? `translate3d(${moveCoord}, 0px)`\n : `translate(${moveCoord})`;\n }\n\n public stopCamera = (axesEvent: any): void => {\n if (axesEvent && axesEvent.setTo) {\n axesEvent.setTo({ flick: this.state.position }, 0);\n }\n\n this.stateMachine.transitTo(STATE_TYPE.IDLE);\n }\n\n public unCacheBbox(): void {\n const state = this.state;\n const options = this.options;\n\n state.cachedBbox = null;\n this.visiblePanels = [];\n\n const viewportElement = this.viewportElement;\n if (!options.horizontal) {\n // Don't preserve previous width for adaptive resizing\n viewportElement.style.width = \"\";\n } else {\n viewportElement.style.height = \"\";\n }\n state.isAdaptiveCached = false;\n this.panelBboxes = {};\n }\n\n public resize(): void {\n this.updateSize();\n this.updateOriginalPanelPositions();\n this.updateAdaptiveSize();\n this.updateScrollArea();\n this.updateClonePanels();\n this.updateVisiblePanelPositions();\n this.updateCameraPosition();\n this.updatePlugins();\n }\n\n // Find nearest anchor from current hanger position\n public findNearestPanel(): Panel | undefined {\n const state = this.state;\n const panelManager = this.panelManager;\n const hangerPosition = this.getHangerPosition();\n\n if (this.isOutOfBound()) {\n const position = state.position;\n\n return position <= state.scrollArea.prev\n ? panelManager.firstPanel()\n : panelManager.lastPanel();\n }\n\n return this.findNearestPanelAt(hangerPosition);\n }\n\n public findNearestPanelAt(position: number): Panel | undefined {\n const panelManager = this.panelManager;\n\n const allPanels = panelManager.allPanels();\n let minimumDistance = Infinity;\n let nearestPanel: Panel | undefined;\n\n for (const panel of allPanels) {\n if (!panel) {\n continue;\n }\n const prevPosition = panel.getPosition();\n const nextPosition = prevPosition + panel.getSize();\n\n // Use shortest distance from panel's range\n const distance = isBetween(position, prevPosition, nextPosition)\n ? 0\n : Math.min(\n Math.abs(prevPosition - position),\n Math.abs(nextPosition - position),\n );\n\n if (distance > minimumDistance) {\n break;\n } else if (distance === minimumDistance) {\n const minimumAnchorDistance = Math.abs(position - nearestPanel!.getAnchorPosition());\n const anchorDistance = Math.abs(position - panel.getAnchorPosition());\n\n if (anchorDistance > minimumAnchorDistance) {\n break;\n }\n }\n\n minimumDistance = distance;\n nearestPanel = panel;\n }\n\n return nearestPanel;\n }\n\n public findNearestIdenticalPanel(panel: Panel): Panel {\n let nearest = panel;\n let shortestDistance = Infinity;\n const hangerPosition = this.getHangerPosition();\n\n const identicals = panel.getIdenticalPanels();\n identicals.forEach(identical => {\n const anchorPosition = identical.getAnchorPosition();\n const distance = Math.abs(anchorPosition - hangerPosition);\n\n if (distance < shortestDistance) {\n nearest = identical;\n shortestDistance = distance;\n }\n });\n\n return nearest;\n }\n\n // Find shortest camera position that distance is minimum\n public findShortestPositionToPanel(panel: Panel): number {\n const state = this.state;\n const options = this.options;\n const anchorPosition = panel.getAnchorPosition();\n const hangerPosition = this.getHangerPosition();\n const distance = Math.abs(hangerPosition - anchorPosition);\n const scrollAreaSize = state.scrollArea.next - state.scrollArea.prev;\n\n if (!options.circular) {\n const position = anchorPosition - state.relativeHangerPosition;\n return this.canSetBoundMode()\n ? clamp(position, state.scrollArea.prev, state.scrollArea.next)\n : position;\n } else {\n // If going out of viewport border is more efficient way of moving, choose that position\n return distance <= scrollAreaSize - distance\n ? anchorPosition - state.relativeHangerPosition\n : anchorPosition > hangerPosition\n // PREV TO NEXT\n ? anchorPosition - state.relativeHangerPosition - scrollAreaSize\n // NEXT TO PREV\n : anchorPosition - state.relativeHangerPosition + scrollAreaSize;\n }\n }\n\n public findEstimatedPosition(panel: Panel): number {\n const scrollArea = this.getScrollArea();\n\n let estimatedPosition = panel.getAnchorPosition() - this.getRelativeHangerPosition();\n estimatedPosition = this.canSetBoundMode()\n ? clamp(estimatedPosition, scrollArea.prev, scrollArea.next)\n : estimatedPosition;\n\n return estimatedPosition;\n }\n\n public addVisiblePanel(panel: Panel): void {\n if (this.getVisibleIndexOf(panel) < 0) {\n this.visiblePanels.push(panel);\n }\n }\n\n public enable(): void {\n if (!this.panInput) {\n this.createPanInput();\n }\n }\n\n public disable(): void {\n if (this.panInput) {\n this.panInput.destroy();\n this.panInput = null;\n\n // Refresh Axes instance\n this.axes.destroy();\n this.setAxesInstance();\n this.updateScrollArea();\n this.updateAxesPosition(this.state.position);\n\n this.stateMachine.transitTo(STATE_TYPE.IDLE);\n }\n }\n\n public insert(index: number, element: ElementLike | ElementLike[]): FlickingPanel[] {\n const lastIndex = this.panelManager.getLastIndex();\n\n // Index should not below 0\n if (index < 0 || index > lastIndex) {\n return [];\n }\n\n const state = this.state;\n const options = this.options;\n const parsedElements = parseElement(element);\n\n const panels = parsedElements\n .map((el, idx) => new Panel(el, index + idx, this))\n .slice(0, lastIndex - index + 1);\n\n if (panels.length <= 0) {\n return [];\n }\n\n const pushedIndex = this.panelManager.insert(index, panels);\n\n // ...then calc bbox for all panels\n this.resizePanels(panels);\n\n if (!this.currentPanel) {\n this.currentPanel = panels[0];\n this.nearestPanel = panels[0];\n\n const newCenterPanel = panels[0];\n const newPanelPosition = this.findEstimatedPosition(newCenterPanel);\n state.position = newPanelPosition;\n this.updateAxesPosition(newPanelPosition);\n state.panelMaintainRatio = (newCenterPanel.getRelativeAnchorPosition() + options.gap / 2) / (newCenterPanel.getSize() + options.gap);\n }\n\n // Update checked indexes in infinite mode\n this.updateCheckedIndexes({ min: index, max: index });\n state.checkedIndexes.forEach((indexes, idx) => {\n const [min, max] = indexes;\n if (index < min) {\n // Push checked index\n state.checkedIndexes.splice(idx, 1, [min + pushedIndex, max + pushedIndex]);\n }\n });\n\n this.resize();\n\n return panels;\n }\n\n public replace(index: number, element: ElementLike | ElementLike[]): FlickingPanel[] {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const lastIndex = panelManager.getLastIndex();\n\n // Index should not below 0\n if (index < 0 || index > lastIndex) {\n return [];\n }\n\n const parsedElements = parseElement(element);\n const panels = parsedElements\n .map((el, idx) => new Panel(el, index + idx, this))\n .slice(0, lastIndex - index + 1);\n\n if (panels.length <= 0) {\n return [];\n }\n\n const replacedPanels = panelManager.replace(index, panels);\n\n replacedPanels.forEach(panel => {\n const visibleIndex = this.getVisibleIndexOf(panel);\n if (visibleIndex > -1) {\n this.visiblePanels.splice(visibleIndex, 1);\n }\n });\n\n // ...then calc bbox for all panels\n this.resizePanels(panels);\n\n const currentPanel = this.currentPanel;\n const wasEmpty = !currentPanel;\n if (wasEmpty) {\n this.currentPanel = panels[0];\n this.nearestPanel = panels[0];\n\n const newCenterPanel = panels[0];\n const newPanelPosition = this.findEstimatedPosition(newCenterPanel);\n state.position = newPanelPosition;\n this.updateAxesPosition(newPanelPosition);\n state.panelMaintainRatio = (newCenterPanel.getRelativeAnchorPosition() + options.gap / 2) / (newCenterPanel.getSize() + options.gap);\n } else if (isBetween(currentPanel!.getIndex(), index, index + panels.length - 1)) {\n // Current panel is replaced\n this.currentPanel = panelManager.get(currentPanel!.getIndex());\n }\n\n // Update checked indexes in infinite mode\n this.updateCheckedIndexes({ min: index, max: index + panels.length - 1 });\n\n this.resize();\n\n return panels;\n }\n\n public remove(index: number, deleteCount: number = 1): FlickingPanel[] {\n const state = this.state;\n // Index should not below 0\n index = Math.max(index, 0);\n\n const panelManager = this.panelManager;\n const currentIndex = this.getCurrentIndex();\n\n const removedPanels = panelManager.remove(index, deleteCount);\n if (isBetween(currentIndex, index, index + deleteCount - 1)) {\n // Current panel is removed\n // Use panel at removing index - 1 as new current panel if it exists\n const newCurrentIndex = Math.max(index - 1, panelManager.getRange().min);\n this.currentPanel = panelManager.get(newCurrentIndex);\n }\n\n // Update checked indexes in infinite mode\n if (deleteCount > 0) {\n // Check whether removing index will affect checked indexes\n // Suppose index 0 is empty and removed index 1, then checked index 0 should be deleted and vice versa.\n this.updateCheckedIndexes({ min: index - 1, max: index + deleteCount });\n // Uncache visible panels to refresh panels\n this.visiblePanels = [];\n }\n\n if (panelManager.getPanelCount() <= 0) {\n this.currentPanel = undefined;\n this.nearestPanel = undefined;\n }\n\n this.resize();\n\n const scrollArea = state.scrollArea;\n if (state.position < scrollArea.prev || state.position > scrollArea.next) {\n const newPosition = circulate(state.position, scrollArea.prev, scrollArea.next, false);\n this.moveCamera(newPosition);\n this.updateAxesPosition(newPosition);\n }\n\n return removedPanels;\n }\n\n public updateAdaptiveSize(): void {\n const state = this.state;\n const options = this.options;\n const horizontal = options.horizontal;\n const currentPanel = this.getCurrentPanel();\n\n if (!currentPanel) {\n return;\n }\n\n const shouldApplyAdaptive = options.adaptive || !state.isAdaptiveCached;\n const viewportStyle = this.viewportElement.style;\n if (shouldApplyAdaptive) {\n let sizeToApply: number;\n if (options.adaptive) {\n const panelBbox = currentPanel.getBbox();\n\n sizeToApply = horizontal ? panelBbox.height : panelBbox.width;\n } else {\n // Find minimum height of panels to maximum panel size\n const maximumPanelSize = this.panelManager.originalPanels().reduce((maximum, panel) => {\n const panelBbox = panel.getBbox();\n return Math.max(maximum, horizontal ? panelBbox.height : panelBbox.width);\n }, 0);\n\n sizeToApply = maximumPanelSize;\n }\n\n if (!state.isAdaptiveCached) {\n const viewportBbox = this.updateBbox();\n sizeToApply = Math.max(sizeToApply, horizontal ? viewportBbox.height : viewportBbox.width);\n state.isAdaptiveCached = true;\n }\n\n const viewportSize = `${sizeToApply}px`;\n if (horizontal) {\n viewportStyle.height = viewportSize;\n state.cachedBbox!.height = sizeToApply;\n } else {\n viewportStyle.width = viewportSize;\n state.cachedBbox!.width = sizeToApply;\n }\n }\n }\n\n // Update camera position after resizing\n public updateCameraPosition(): void {\n const state = this.state;\n const currentPanel = this.getCurrentPanel();\n const cameraPosition = this.getCameraPosition();\n const currentState = this.stateMachine.getState();\n const isFreeScroll = this.moveType.is(MOVE_TYPE.FREE_SCROLL);\n const relativeHangerPosition = this.getRelativeHangerPosition();\n const halfGap = this.options.gap / 2;\n\n if (currentState.holding || currentState.playing) {\n this.updateVisiblePanels();\n return;\n }\n\n let newPosition: number;\n if (isFreeScroll) {\n const positionBounded = this.canSetBoundMode() && (cameraPosition === state.scrollArea.prev || cameraPosition === state.scrollArea.next);\n const nearestPanel = this.getNearestPanel();\n\n // Preserve camera position if it is bound to scroll area limit\n newPosition = positionBounded || !nearestPanel\n ? cameraPosition\n : nearestPanel.getPosition() - halfGap + (nearestPanel.getSize() + 2 * halfGap) * state.panelMaintainRatio - relativeHangerPosition;\n } else {\n newPosition = currentPanel\n ? currentPanel.getAnchorPosition() - relativeHangerPosition\n : cameraPosition;\n }\n\n if (this.canSetBoundMode()) {\n newPosition = clamp(newPosition, state.scrollArea.prev, state.scrollArea.next);\n }\n\n // Pause & resume axes to prevent axes's \"change\" event triggered\n // This should be done before moveCamera, as moveCamera can trigger needPanel\n this.updateAxesPosition(newPosition);\n\n this.moveCamera(newPosition);\n }\n\n public updateBbox(): BoundingBox {\n const state = this.state;\n const options = this.options;\n const viewportElement = this.viewportElement;\n\n if (!state.cachedBbox) {\n state.cachedBbox = getBbox(viewportElement, options.useOffset);\n }\n\n return state.cachedBbox!;\n }\n\n public updatePlugins(): void {\n // update for resize\n this.plugins.forEach(plugin => {\n plugin.update && plugin.update(this.flicking);\n });\n }\n\n public destroy(option: Partial<DestroyOption>): void {\n const state = this.state;\n const wrapper = this.flicking.getElement();\n const viewportElement = this.viewportElement;\n const cameraElement = this.cameraElement;\n const originalPanels = this.panelManager.originalPanels();\n\n this.removePlugins(this.plugins);\n if (!option.preserveUI) {\n restoreStyle(viewportElement, state.originalViewportStyle);\n restoreStyle(cameraElement, state.originalCameraStyle);\n\n if (!state.isCameraGiven && !this.options.renderExternal) {\n const topmostElement = state.isViewportGiven\n ? viewportElement\n : wrapper;\n const deletingElement = state.isViewportGiven\n ? cameraElement\n : viewportElement;\n\n originalPanels.forEach(panel => {\n topmostElement.appendChild(panel.getElement());\n });\n\n topmostElement.removeChild(deletingElement);\n }\n }\n\n this.axes.destroy();\n this.panInput?.destroy();\n\n originalPanels.forEach(panel => { panel.destroy(option); });\n\n // release resources\n for (const x in this) {\n (this as any)[x] = null;\n }\n }\n\n public restore(status: FlickingStatus): void {\n const panels = status.panels;\n const defaultIndex = this.options.defaultIndex;\n const cameraElement = this.cameraElement;\n const panelManager = this.panelManager;\n\n // Restore index\n cameraElement.innerHTML = panels.map(panel => panel.html).join(\"\");\n\n // Create panels first\n this.refreshPanels();\n const createdPanels = panelManager.originalPanels();\n\n // ...then order it by its index\n const orderedPanels: Panel[] = [];\n panels.forEach((panel, idx) => {\n const createdPanel = createdPanels[idx];\n createdPanel.setIndex(panel.index);\n createdPanel.setPosition(panel.position);\n orderedPanels[panel.index] = createdPanel;\n });\n panelManager.replacePanels(orderedPanels, []);\n panelManager.setCloneCount(0); // No clones at this point\n\n const panelCount = panelManager.getPanelCount();\n if (panelCount > 0) {\n this.currentPanel = panelManager.get(status.index)\n || panelManager.get(defaultIndex)\n || panelManager.firstPanel();\n } else {\n this.currentPanel = undefined;\n }\n this.visiblePanels = orderedPanels.filter(panel => Boolean(panel));\n\n this.resize();\n\n this.axes.setTo({ flick: status.position }, 0);\n this.moveCamera(status.position);\n }\n\n public calcVisiblePanels(): Panel[] {\n const allPanels = this.panelManager.allPanels();\n if (this.options.renderOnlyVisible) {\n const cameraPos = this.getCameraPosition();\n const viewportSize = this.getSize();\n const basePanel = this.nearestPanel!;\n\n const getNextPanel = (panel: Panel) => {\n const nextPanel = panel.nextSibling;\n\n if (nextPanel && nextPanel.getPosition() >= panel.getPosition()) {\n return nextPanel;\n } else {\n return null;\n }\n };\n\n const getPrevPanel = (panel: Panel) => {\n const prevPanel = panel.prevSibling;\n\n if (prevPanel && prevPanel.getPosition() <= panel.getPosition()) {\n return prevPanel;\n } else {\n return null;\n }\n };\n\n const isOutOfBoundNext = (panel: Panel) => panel.getPosition() >= cameraPos + viewportSize;\n const isOutOfBoundPrev = (panel: Panel) => panel.getPosition() + panel.getSize() <= cameraPos;\n\n const getVisiblePanels = (\n panel: Panel,\n getNext: (panel: Panel) => Panel | null,\n isOutOfViewport: (panel: Panel) => boolean,\n ): Panel[] => {\n const visiblePanels: Panel[] = [];\n\n let lastPanel = panel;\n while (true) {\n const nextPanel = getNext(lastPanel);\n if (!nextPanel || isOutOfViewport(nextPanel)) {\n break;\n }\n visiblePanels.push(nextPanel);\n lastPanel = nextPanel;\n }\n return visiblePanels;\n };\n\n const panelCount = this.panelManager.getPanelCount();\n const getAbsIndex = (panel: Panel) => panel.getIndex() + (panel.getCloneIndex() + 1) * panelCount;\n const nextPanels = getVisiblePanels(basePanel, getNextPanel, isOutOfBoundNext);\n const prevPanels = getVisiblePanels(basePanel, getPrevPanel, isOutOfBoundPrev);\n\n return [basePanel, ...nextPanels, ...prevPanels].sort((panel1, panel2) => getAbsIndex(panel1) - getAbsIndex(panel2));\n } else {\n return allPanels.filter(panel => {\n const outsetProgress = panel.getOutsetProgress();\n\n return outsetProgress > -1 && outsetProgress < 1;\n });\n }\n }\n\n public getCurrentPanel(): Panel | undefined {\n return this.currentPanel;\n }\n\n public getCurrentIndex(): number {\n const currentPanel = this.currentPanel;\n\n return currentPanel\n ? currentPanel.getIndex()\n : -1;\n }\n\n public getNearestPanel(): Panel | undefined {\n return this.nearestPanel;\n }\n\n // Get progress from nearest panel\n public getCurrentProgress(): number {\n const currentState = this.stateMachine.getState();\n let nearestPanel = currentState.playing || currentState.holding\n ? this.nearestPanel\n : this.currentPanel;\n\n const panelManager = this.panelManager;\n if (!nearestPanel) {\n // There're no panels\n return NaN;\n }\n const { prev: prevRange, next: nextRange } = this.getScrollArea();\n const cameraPosition = this.getCameraPosition();\n const isOutOfBound = this.isOutOfBound();\n let prevPanel = nearestPanel.prevSibling;\n let nextPanel = nearestPanel.nextSibling;\n let hangerPosition = this.getHangerPosition();\n let nearestAnchorPos = nearestPanel.getAnchorPosition();\n\n if (\n isOutOfBound\n && prevPanel\n && nextPanel\n && cameraPosition < nextRange\n // On the basis of anchor, prevPanel is nearestPanel.\n && (hangerPosition - prevPanel.getAnchorPosition() < nearestAnchorPos - hangerPosition)\n ) {\n nearestPanel = prevPanel;\n nextPanel = nearestPanel.nextSibling;\n prevPanel = nearestPanel.prevSibling;\n nearestAnchorPos = nearestPanel.getAnchorPosition();\n }\n const nearestIndex = nearestPanel.getIndex() + (nearestPanel.getCloneIndex() + 1) * panelManager.getPanelCount();\n const nearestSize = nearestPanel.getSize();\n\n if (isOutOfBound) {\n const relativeHangerPosition = this.getRelativeHangerPosition();\n\n if (nearestAnchorPos > nextRange + relativeHangerPosition) {\n // next bounce area: hangerPosition - relativeHangerPosition - nextRange\n hangerPosition = nearestAnchorPos + hangerPosition - relativeHangerPosition - nextRange;\n } else if (nearestAnchorPos < prevRange + relativeHangerPosition) {\n // prev bounce area: hangerPosition - relativeHangerPosition - prevRange\n hangerPosition = nearestAnchorPos + hangerPosition - relativeHangerPosition - prevRange;\n }\n }\n const hangerIsNextToNearestPanel = hangerPosition >= nearestAnchorPos;\n const gap = this.options.gap;\n\n let basePosition = nearestAnchorPos;\n let targetPosition = nearestAnchorPos;\n if (hangerIsNextToNearestPanel) {\n targetPosition = nextPanel\n ? nextPanel.getAnchorPosition()\n : nearestAnchorPos + nearestSize + gap;\n } else {\n basePosition = prevPanel\n ? prevPanel.getAnchorPosition()\n : nearestAnchorPos - nearestSize - gap;\n }\n\n const progressBetween = (hangerPosition - basePosition) / (targetPosition - basePosition);\n const startIndex = hangerIsNextToNearestPanel\n ? nearestIndex\n : prevPanel\n ? prevPanel.getIndex()\n : nearestIndex - 1;\n\n return startIndex + progressBetween;\n }\n\n // Update axes flick position without triggering event\n public updateAxesPosition(position: number) {\n const axes = this.axes;\n axes.off();\n axes.setTo({\n flick: position,\n }, 0);\n axes.on(this.axesHandlers);\n }\n\n public getSize(): number {\n return this.state.size;\n }\n\n public getScrollArea(): { prev: number, next: number } {\n return this.state.scrollArea;\n }\n\n public isOutOfBound(): boolean {\n const state = this.state;\n const options = this.options;\n const scrollArea = state.scrollArea;\n\n return !options.circular\n && options.bound\n && (state.position <= scrollArea.prev || state.position >= scrollArea.next);\n }\n\n public canSetBoundMode(): boolean {\n const options = this.options;\n\n return options.bound && !options.circular;\n }\n\n public getViewportElement(): HTMLElement {\n return this.viewportElement;\n }\n\n public getCameraElement(): HTMLElement {\n return this.cameraElement;\n }\n\n public getScrollAreaSize(): number {\n const scrollArea = this.state.scrollArea;\n\n return scrollArea.next - scrollArea.prev;\n }\n\n public getRelativeHangerPosition(): number {\n return this.state.relativeHangerPosition;\n }\n\n public getHangerPosition(): number {\n return this.state.position + this.state.relativeHangerPosition;\n }\n\n public getCameraPosition(): number {\n return this.state.position;\n }\n\n public getPositionOffset(): number {\n return this.state.positionOffset;\n }\n\n public getCheckedIndexes(): Array<[number, number]> {\n return this.state.checkedIndexes;\n }\n\n public getVisiblePanels(): Panel[] {\n return this.visiblePanels;\n }\n\n public setCurrentPanel(panel: Panel | undefined): void {\n this.currentPanel = panel;\n }\n\n public setLastIndex(index: number): void {\n const currentPanel = this.currentPanel;\n const panelManager = this.panelManager;\n\n panelManager.setLastIndex(index);\n if (currentPanel && currentPanel.getIndex() > index) {\n this.currentPanel = panelManager.lastPanel();\n }\n\n this.resize();\n }\n\n public setVisiblePanels(panels: Panel[]): void {\n this.visiblePanels = panels;\n }\n\n public connectAxesHandler(handlers: { [key: string]: (event: { [key: string]: any; }) => any }): void {\n const axes = this.axes;\n\n this.axesHandlers = handlers;\n axes.on(handlers);\n }\n\n public addPlugins(plugins: Plugin | Plugin[]) {\n const newPlugins = ([] as Plugin[]).concat(plugins);\n\n newPlugins.forEach(plugin => {\n plugin.init(this.flicking);\n });\n\n this.plugins = this.plugins.concat(newPlugins);\n return this;\n }\n\n public removePlugins(plugins: Plugin | Plugin[]) {\n const currentPlugins = this.plugins;\n const removedPlugins = ([] as Plugin[]).concat(plugins);\n\n removedPlugins.forEach(plugin => {\n const index = currentPlugins.indexOf(plugin);\n\n if (index > -1) {\n currentPlugins.splice(index, 1);\n }\n\n plugin.destroy(this.flicking);\n });\n return this;\n }\n\n public updateCheckedIndexes(changedRange: { min: number, max: number }): void {\n const state = this.state;\n\n let removed = 0;\n state.checkedIndexes.concat().forEach((indexes, idx) => {\n const [min, max] = indexes;\n // Can fill part of indexes in range\n if (changedRange.min <= max && changedRange.max >= min) {\n // Remove checked index from list\n state.checkedIndexes.splice(idx - removed, 1);\n removed++;\n }\n });\n }\n\n public appendUncachedPanelElements(panels: Panel[]): void {\n const options = this.options;\n const fragment = document.createDocumentFragment();\n\n if (options.isEqualSize) {\n const prevVisiblePanels = this.visiblePanels;\n const equalSizeClasses = options.isEqualSize as string[]; // for readability\n const cached: { [className: string]: boolean } = {};\n\n this.visiblePanels = [];\n\n Object.keys(this.panelBboxes).forEach(className => {\n cached[className] = true;\n });\n\n panels.forEach(panel => {\n const overlappedClass = panel.getOverlappedClass(equalSizeClasses);\n if (overlappedClass && !cached[overlappedClass]) {\n if (!options.renderExternal) {\n fragment.appendChild(panel.getElement());\n }\n this.visiblePanels.push(panel);\n cached[overlappedClass] = true;\n } else if (!overlappedClass) {\n if (!options.renderExternal) {\n fragment.appendChild(panel.getElement());\n }\n this.visiblePanels.push(panel);\n }\n });\n prevVisiblePanels.forEach(panel => {\n this.addVisiblePanel(panel);\n });\n } else {\n if (!options.renderExternal) {\n panels.forEach(panel => fragment.appendChild(panel.getElement()));\n }\n this.visiblePanels = panels.filter(panel => Boolean(panel));\n }\n\n if (!options.renderExternal) {\n this.cameraElement.appendChild(fragment);\n }\n }\n\n private updateClonePanels() {\n const panelManager = this.panelManager;\n\n // Clone panels in circular mode\n if (this.options.circular && panelManager.getPanelCount() > 0) {\n this.clonePanels();\n this.updateClonedPanelPositions();\n }\n panelManager.chainAllPanels();\n }\n\n private getVisibleIndexOf(panel: Panel): number {\n return findIndex(this.visiblePanels, visiblePanel => visiblePanel === panel);\n }\n\n private build(): void {\n this.setElements();\n this.applyCSSValue();\n this.setMoveType();\n this.setAxesInstance();\n this.createPanInput();\n this.refreshPanels();\n this.setDefaultPanel();\n this.resize();\n this.moveToDefaultPanel();\n }\n\n private setElements(): void {\n const state = this.state;\n const options = this.options;\n const wrapper = this.flicking.getElement();\n const classPrefix = options.classPrefix;\n\n const viewportCandidate = wrapper.children[0] as HTMLElement;\n const hasViewportElement = viewportCandidate && hasClass(viewportCandidate, `${classPrefix}-viewport`);\n\n const viewportElement = hasViewportElement\n ? viewportCandidate\n : document.createElement(\"div\");\n\n const cameraCandidate = hasViewportElement\n ? viewportElement.children[0] as HTMLElement\n : wrapper.children[0] as HTMLElement;\n const hasCameraElement = cameraCandidate && hasClass(cameraCandidate, `${classPrefix}-camera`);\n\n const cameraElement = hasCameraElement\n ? cameraCandidate\n : document.createElement(\"div\");\n\n if (!hasCameraElement) {\n cameraElement.className = `${classPrefix}-camera`;\n\n const panelElements = hasViewportElement\n ? viewportElement.children\n : wrapper.children;\n\n // Make all panels to be a child of camera element\n // wrapper <- viewport <- camera <- panels[1...n]\n toArray(panelElements).forEach(child => {\n cameraElement.appendChild(child);\n });\n } else {\n state.originalCameraStyle = {\n className: cameraElement.getAttribute(\"class\"),\n style: cameraElement.getAttribute(\"style\"),\n };\n }\n\n if (!hasViewportElement) {\n viewportElement.className = `${classPrefix}-viewport`;\n\n // Add viewport element to wrapper\n wrapper.appendChild(viewportElement);\n } else {\n state.originalViewportStyle = {\n className: viewportElement.getAttribute(\"class\"),\n style: viewportElement.getAttribute(\"style\"),\n };\n }\n\n if (!hasCameraElement || !hasViewportElement) {\n viewportElement.appendChild(cameraElement);\n }\n\n this.viewportElement = viewportElement;\n this.cameraElement = cameraElement;\n state.isViewportGiven = hasViewportElement;\n state.isCameraGiven = hasCameraElement;\n }\n\n private applyCSSValue(): void {\n const options = this.options;\n const viewportElement = this.viewportElement;\n const cameraElement = this.cameraElement;\n const viewportStyle = this.viewportElement.style;\n\n // Set default css values for each element\n applyCSS(viewportElement, DEFAULT_VIEWPORT_CSS);\n applyCSS(cameraElement, DEFAULT_CAMERA_CSS);\n\n viewportElement.style.zIndex = `${options.zIndex}`;\n if (options.horizontal) {\n viewportStyle.minHeight = \"100%\";\n viewportStyle.width = \"100%\";\n } else {\n viewportStyle.minWidth = \"100%\";\n viewportStyle.height = \"100%\";\n }\n if (options.overflow) {\n viewportStyle.overflow = \"visible\";\n }\n\n this.panelManager = new PanelManager(this.cameraElement, options);\n }\n\n private setMoveType(): void {\n const moveType = this.options.moveType as MoveTypeObjectOption;\n\n switch (moveType.type) {\n case MOVE_TYPE.SNAP:\n this.moveType = new Snap(moveType.count);\n break;\n case MOVE_TYPE.FREE_SCROLL:\n this.moveType = new FreeScroll();\n break;\n default:\n throw new Error(\"moveType is not correct!\");\n }\n }\n\n private setAxesInstance(): void {\n const state = this.state;\n const options = this.options;\n\n const scrollArea = state.scrollArea;\n\n this.axes = new Axes({\n flick: {\n range: [scrollArea.prev, scrollArea.next],\n circular: options.circular,\n bounce: [0, 0], // will be updated in resize()\n },\n }, {\n easing: options.panelEffect,\n deceleration: options.deceleration,\n interruptable: true,\n });\n }\n\n private refreshPanels(): void {\n const panelManager = this.panelManager;\n // Panel elements were attached to camera element by Flicking class\n const panelElements = this.cameraElement.children;\n\n // Initialize panels\n const panels = toArray(panelElements).map(\n (el: HTMLElement, idx: number) => new Panel(el, idx, this),\n );\n\n panelManager.replacePanels(panels, []);\n this.visiblePanels = panels.filter(panel => Boolean(panel));\n }\n\n private setDefaultPanel(): void {\n const options = this.options;\n const panelManager = this.panelManager;\n const indexRange = this.panelManager.getRange();\n const index = clamp(options.defaultIndex, indexRange.min, indexRange.max);\n\n this.currentPanel = panelManager.get(index);\n }\n\n private clonePanels() {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n\n const gap = options.gap;\n const viewportSize = state.size;\n const firstPanel = panelManager.firstPanel();\n const lastPanel = panelManager.lastPanel()!;\n\n // There're no panels exist\n if (!firstPanel) {\n return;\n }\n\n // For each panels, clone itself while last panel's position + size is below viewport size\n const panels = panelManager.originalPanels();\n const reversedPanels = panels.concat().reverse();\n\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition() + gap;\n const relativeAnchorPosition = firstPanel.getRelativeAnchorPosition();\n const relativeHangerPosition = this.getRelativeHangerPosition();\n\n const areaPrev = (relativeHangerPosition - relativeAnchorPosition) % sumOriginalPanelSize;\n let sizeSum = 0;\n let panelAtLeftBoundary!: Panel;\n for (const panel of reversedPanels) {\n if (!panel) {\n continue;\n }\n sizeSum += panel.getSize() + gap;\n if (sizeSum >= areaPrev) {\n panelAtLeftBoundary = panel;\n break;\n }\n }\n\n const areaNext = (viewportSize - relativeHangerPosition + relativeAnchorPosition) % sumOriginalPanelSize;\n sizeSum = 0;\n let panelAtRightBoundary!: Panel;\n for (const panel of panels) {\n if (!panel) {\n continue;\n }\n sizeSum += panel.getSize() + gap;\n if (sizeSum >= areaNext) {\n panelAtRightBoundary = panel;\n break;\n }\n }\n\n // Need one more set of clones on prev area of original panel 0\n const needCloneOnPrev = panelAtLeftBoundary.getIndex() !== 0\n && panelAtLeftBoundary.getIndex() <= panelAtRightBoundary.getIndex();\n\n // Visible count of panel 0 on first screen\n const panel0OnFirstscreen = Math.ceil((relativeHangerPosition + firstPanel.getSize() - relativeAnchorPosition) / sumOriginalPanelSize)\n + Math.ceil((viewportSize - relativeHangerPosition + relativeAnchorPosition) / sumOriginalPanelSize)\n - 1; // duplication\n\n const cloneCount = panel0OnFirstscreen\n + (needCloneOnPrev ? 1 : 0);\n const prevCloneCount = panelManager.getCloneCount();\n\n panelManager.setCloneCount(cloneCount);\n if (options.renderExternal) {\n return;\n }\n\n if (cloneCount > prevCloneCount) {\n // should clone more\n for (let cloneIndex = prevCloneCount; cloneIndex < cloneCount; cloneIndex++) {\n const clones = panels.map(origPanel => origPanel.clone(cloneIndex));\n const fragment = document.createDocumentFragment();\n clones.forEach(panel => fragment.appendChild(panel.getElement()));\n\n this.cameraElement.appendChild(fragment);\n this.visiblePanels.push(...clones.filter(clone => Boolean(clone)));\n panelManager.insertClones(cloneIndex, 0, clones);\n }\n } else if (cloneCount < prevCloneCount) {\n // should remove some\n panelManager.removeClonesAfter(cloneCount);\n }\n }\n\n private moveToDefaultPanel(): void {\n const state = this.state;\n const panelManager = this.panelManager;\n const options = this.options;\n const indexRange = this.panelManager.getRange();\n\n const defaultIndex = clamp(options.defaultIndex, indexRange.min, indexRange.max);\n const defaultPanel = panelManager.get(defaultIndex);\n\n let defaultPosition = 0;\n if (defaultPanel) {\n defaultPosition = defaultPanel.getAnchorPosition() - state.relativeHangerPosition;\n defaultPosition = this.canSetBoundMode()\n ? clamp(defaultPosition, state.scrollArea.prev, state.scrollArea.next)\n : defaultPosition;\n }\n\n this.moveCamera(defaultPosition);\n this.axes.setTo({ flick: defaultPosition }, 0);\n }\n\n private updateSize(): void {\n const state = this.state;\n const options = this.options;\n const panels = this.panelManager.originalPanels()\n .filter(panel => Boolean(panel));\n const bbox = this.updateBbox();\n\n const prevSize = state.size;\n // Update size & hanger position\n state.size = options.horizontal\n ? bbox.width\n : bbox.height;\n\n if (prevSize !== state.size) {\n state.relativeHangerPosition = parseArithmeticExpression(options.hanger, state.size);\n state.infiniteThreshold = parseArithmeticExpression(options.infiniteThreshold, state.size);\n }\n\n if (panels.length <= 0) {\n return;\n }\n\n this.resizePanels(panels);\n }\n\n private updateOriginalPanelPositions(): void {\n const gap = this.options.gap;\n const panelManager = this.panelManager;\n\n const firstPanel = panelManager.firstPanel();\n const panels = panelManager.originalPanels();\n\n if (!firstPanel) {\n return;\n }\n\n const currentPanel = this.currentPanel!;\n const nearestPanel = this.nearestPanel;\n const currentState = this.stateMachine.getState();\n const scrollArea = this.state.scrollArea;\n\n // Update panel position && fit to wrapper\n let nextPanelPos = firstPanel.getPosition();\n let maintainingPanel: Panel = firstPanel;\n if (nearestPanel) {\n // We should maintain nearestPanel's position\n const looped = !isBetween(currentState.lastPosition + currentState.delta, scrollArea.prev, scrollArea.next);\n\n maintainingPanel = looped\n ? currentPanel\n : nearestPanel;\n } else if (firstPanel.getIndex() > 0) {\n maintainingPanel = currentPanel;\n }\n\n const panelsBeforeMaintainPanel = panels.slice(0, maintainingPanel.getIndex() + (maintainingPanel.getCloneIndex() + 1) * panels.length);\n const accumulatedSize = panelsBeforeMaintainPanel.reduce((total, panel) => {\n return total + panel.getSize() + gap;\n }, 0);\n\n nextPanelPos = maintainingPanel.getPosition() - accumulatedSize;\n\n panels.forEach(panel => {\n const newPosition = nextPanelPos;\n const panelSize = panel.getSize();\n\n panel.setPosition(newPosition);\n nextPanelPos += panelSize + gap;\n });\n\n if (!this.options.renderOnlyVisible) {\n panels.forEach(panel => panel.setPositionCSS());\n }\n }\n\n private updateClonedPanelPositions(): void {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const clonedPanels = panelManager.clonedPanels()\n .reduce((allClones, clones) => [...allClones, ...clones], [])\n .filter(panel => Boolean(panel));\n\n const scrollArea = state.scrollArea;\n\n const firstPanel = panelManager.firstPanel();\n const lastPanel = panelManager.lastPanel()!;\n\n if (!firstPanel) {\n return;\n }\n\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition() + options.gap;\n\n // Locate all cloned panels linearly first\n for (const panel of clonedPanels) {\n const origPanel = panel.getOriginalPanel();\n const cloneIndex = panel.getCloneIndex();\n const cloneBasePos = sumOriginalPanelSize * (cloneIndex + 1);\n const clonedPanelPos = cloneBasePos + origPanel.getPosition();\n\n panel.setPosition(clonedPanelPos);\n }\n\n let lastReplacePosition = firstPanel.getPosition();\n // reverse() pollutes original array, so copy it with concat()\n for (const panel of clonedPanels.concat().reverse()) {\n const panelSize = panel.getSize();\n const replacePosition = lastReplacePosition - panelSize - options.gap;\n\n if (replacePosition + panelSize <= scrollArea.prev) {\n // Replace is not meaningful, as it won't be seen in current scroll area\n break;\n }\n\n panel.setPosition(replacePosition);\n lastReplacePosition = replacePosition;\n }\n\n if (!this.options.renderOnlyVisible) {\n clonedPanels.forEach(panel => {\n panel.setPositionCSS();\n });\n }\n }\n\n private updateVisiblePanelPositions(): void {\n if (this.options.renderOnlyVisible) {\n this.visiblePanels.forEach(panel => {\n panel.setPositionCSS(this.state.positionOffset);\n });\n }\n }\n\n private updateScrollArea(): void {\n const state = this.state;\n const panelManager = this.panelManager;\n const options = this.options;\n const axes = this.axes;\n\n // Set viewport scrollable area\n const firstPanel = panelManager.firstPanel();\n const lastPanel = panelManager.lastPanel() as Panel;\n const relativeHangerPosition = state.relativeHangerPosition;\n\n if (!firstPanel) {\n state.scrollArea = {\n prev: 0,\n next: 0,\n };\n } else if (this.canSetBoundMode()) {\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition();\n\n if (sumOriginalPanelSize >= state.size) {\n state.scrollArea = {\n prev: firstPanel.getPosition(),\n next: lastPanel.getPosition() + lastPanel.getSize() - state.size,\n };\n } else {\n // Find anchor position of set of the combined panels\n const relAnchorPosOfCombined = parseArithmeticExpression(options.anchor, sumOriginalPanelSize);\n const anchorPos = firstPanel.getPosition() + clamp(\n relAnchorPosOfCombined,\n sumOriginalPanelSize - (state.size - relativeHangerPosition),\n relativeHangerPosition,\n );\n\n state.scrollArea = {\n prev: anchorPos - relativeHangerPosition,\n next: anchorPos - relativeHangerPosition,\n };\n }\n } else if (options.circular) {\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition() + options.gap;\n\n // Maximum scroll extends to first clone sequence's first panel\n state.scrollArea = {\n prev: firstPanel.getAnchorPosition() - relativeHangerPosition,\n next: sumOriginalPanelSize + firstPanel.getAnchorPosition() - relativeHangerPosition,\n };\n } else {\n state.scrollArea = {\n prev: firstPanel.getAnchorPosition() - relativeHangerPosition,\n next: lastPanel.getAnchorPosition() - relativeHangerPosition,\n };\n }\n\n const viewportSize = state.size;\n const bounce = options.bounce;\n\n let parsedBounce: number[];\n if (isArray(bounce)) {\n parsedBounce = (bounce as string[]).map(val => parseArithmeticExpression(val, viewportSize, DEFAULT_OPTIONS.bounce as number));\n } else {\n const parsedVal = parseArithmeticExpression(bounce as number | string, viewportSize, DEFAULT_OPTIONS.bounce as number);\n parsedBounce = [parsedVal, parsedVal];\n }\n\n // Update axes range and bounce\n const flick = axes.axis.flick;\n flick.range = [state.scrollArea.prev, state.scrollArea.next];\n flick.bounce = parsedBounce;\n }\n\n private checkNeedPanel(axesEvent?: any): void {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const currentPanel = this.currentPanel;\n const nearestPanel = this.nearestPanel;\n const currentState = this.stateMachine.getState();\n\n if (!options.infinite) {\n return;\n }\n\n const gap = options.gap;\n const infiniteThreshold = state.infiniteThreshold;\n const maxLastIndex = panelManager.getLastIndex();\n\n if (maxLastIndex < 0) {\n return;\n }\n\n if (!currentPanel || !nearestPanel) {\n // There're no panels\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: null,\n direction: null,\n indexRange: {\n min: 0,\n max: maxLastIndex,\n length: maxLastIndex + 1,\n },\n });\n return;\n }\n\n const originalNearestPosition = nearestPanel.getPosition();\n\n // Check next direction\n let checkingPanel: Panel | null = !currentState.holding && !currentState.playing\n ? currentPanel\n : nearestPanel;\n\n while (checkingPanel) {\n const currentIndex = checkingPanel.getIndex();\n const nextSibling = checkingPanel.nextSibling;\n const lastPanel = panelManager.lastPanel()!;\n const atLastPanel = currentIndex === lastPanel.getIndex();\n const nextIndex = !atLastPanel && nextSibling\n ? nextSibling.getIndex()\n : maxLastIndex + 1;\n const currentNearestPosition = nearestPanel.getPosition();\n const panelRight = checkingPanel.getPosition() + checkingPanel.getSize() - (currentNearestPosition - originalNearestPosition);\n const cameraNext = state.position + state.size;\n\n // There're empty panels between\n const emptyPanelExistsBetween = (nextIndex - currentIndex > 1);\n // Expected prev panel's left position is smaller than camera position\n const overThreshold = panelRight + gap - infiniteThreshold <= cameraNext;\n\n if (emptyPanelExistsBetween && overThreshold) {\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.NEXT,\n indexRange: {\n min: currentIndex + 1,\n max: nextIndex - 1,\n length: nextIndex - currentIndex - 1,\n },\n });\n }\n\n // Trigger needPanel in circular & at max panel index\n if (options.circular && currentIndex === maxLastIndex && overThreshold) {\n const firstPanel = panelManager.firstPanel();\n const firstIndex = firstPanel\n ? firstPanel.getIndex()\n : -1;\n\n if (firstIndex > 0) {\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.NEXT,\n indexRange: {\n min: 0,\n max: firstIndex - 1,\n length: firstIndex,\n },\n });\n }\n }\n\n // Check whether panels are changed\n const lastPanelAfterNeed = panelManager.lastPanel()!;\n const atLastPanelAfterNeed = lastPanelAfterNeed && currentIndex === lastPanelAfterNeed.getIndex();\n\n if (atLastPanelAfterNeed || !overThreshold) {\n break;\n }\n\n checkingPanel = checkingPanel.nextSibling;\n }\n\n // Check prev direction\n checkingPanel = nearestPanel;\n while (checkingPanel) {\n const cameraPrev = state.position;\n const checkingIndex = checkingPanel.getIndex();\n const prevSibling = checkingPanel.prevSibling;\n const firstPanel = panelManager.firstPanel()!;\n const atFirstPanel = checkingIndex === firstPanel.getIndex();\n const prevIndex = !atFirstPanel && prevSibling\n ? prevSibling.getIndex()\n : -1;\n const currentNearestPosition = nearestPanel.getPosition();\n const panelLeft = checkingPanel.getPosition() - (currentNearestPosition - originalNearestPosition);\n\n // There're empty panels between\n const emptyPanelExistsBetween = checkingIndex - prevIndex > 1;\n // Expected prev panel's right position is smaller than camera position\n const overThreshold = panelLeft - gap + infiniteThreshold >= cameraPrev;\n if (emptyPanelExistsBetween && overThreshold) {\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.PREV,\n indexRange: {\n min: prevIndex + 1,\n max: checkingIndex - 1,\n length: checkingIndex - prevIndex - 1,\n },\n });\n }\n\n // Trigger needPanel in circular & at panel 0\n if (options.circular && checkingIndex === 0 && overThreshold) {\n const lastPanel = panelManager.lastPanel();\n\n if (lastPanel && lastPanel.getIndex() < maxLastIndex) {\n const lastIndex = lastPanel.getIndex();\n\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.PREV,\n indexRange: {\n min: lastIndex + 1,\n max: maxLastIndex,\n length: maxLastIndex - lastIndex,\n },\n });\n }\n }\n\n // Check whether panels were changed\n const firstPanelAfterNeed = panelManager.firstPanel();\n const atFirstPanelAfterNeed = firstPanelAfterNeed && checkingIndex === firstPanelAfterNeed.getIndex();\n\n // Looped in circular mode\n if (atFirstPanelAfterNeed || !overThreshold) {\n break;\n }\n\n checkingPanel = checkingPanel.prevSibling;\n }\n }\n\n private triggerNeedPanel(params: {\n axesEvent: any;\n siblingPanel: Panel | null,\n direction: FlickingEvent[\"direction\"];\n indexRange: NeedPanelEvent[\"range\"];\n }): void {\n const { axesEvent, siblingPanel, direction, indexRange } = params;\n const options = this.options;\n const checkedIndexes = this.state.checkedIndexes;\n const alreadyTriggered = checkedIndexes.some(([min, max]) => min === indexRange.min || max === indexRange.max);\n const hasHandler = this.flicking.hasOn(EVENTS.NEED_PANEL);\n\n if (alreadyTriggered || !hasHandler) {\n return;\n }\n\n // Should done before triggering event, as we can directly add panels by event callback\n checkedIndexes.push([indexRange.min, indexRange.max]);\n\n const index = siblingPanel\n ? siblingPanel.getIndex()\n : 0;\n const isTrusted = axesEvent\n ? axesEvent.isTrusted\n : false;\n\n this.triggerEvent(\n EVENTS.NEED_PANEL,\n axesEvent,\n isTrusted,\n {\n index,\n panel: siblingPanel,\n direction,\n range: indexRange,\n fill: (element: ElementLike | ElementLike[]) => {\n const panelManager = this.panelManager;\n if (!siblingPanel) {\n return this.insert(panelManager.getRange().max + 1, element);\n }\n\n const parsedElements = parseElement(element);\n // Slice elements to fit size equal to empty spaces\n const elements = direction === DIRECTION.NEXT\n ? parsedElements.slice(0, indexRange.length)\n : parsedElements.slice(-indexRange.length);\n\n if (direction === DIRECTION.NEXT) {\n if (options.circular && index === panelManager.getLastIndex()) {\n // needPanel event is triggered on last index, insert at index 0\n return this.insert(0, elements);\n } else {\n return siblingPanel.insertAfter(elements);\n }\n } else if (direction === DIRECTION.PREV) {\n if (options.circular && index === 0) {\n // needPanel event is triggered on first index(0), insert at the last index\n return this.insert(indexRange.max - elements.length + 1, elements);\n } else {\n return siblingPanel.insertBefore(elements);\n }\n } else {\n // direction is null when there're no panels exist\n return this.insert(0, elements);\n }\n },\n } as Partial<NeedPanelEvent>,\n );\n }\n\n private updateVisiblePanels() {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const currentState = this.stateMachine.getState();\n const cameraElement = this.cameraElement;\n const { renderExternal, renderOnlyVisible } = options;\n if (!renderOnlyVisible) {\n return;\n }\n\n if (!this.nearestPanel) {\n this.visiblePanels = [];\n while (cameraElement.firstChild) {\n cameraElement.removeChild(cameraElement.firstChild);\n }\n return;\n }\n\n const prevVisiblePanels = this.visiblePanels;\n const newVisiblePanels = this.calcVisiblePanels();\n\n const { addedPanels, removedPanels } = this.checkVisiblePanelChange(prevVisiblePanels, newVisiblePanels);\n\n if (addedPanels.length <= 0 && removedPanels.length <= 0) {\n // Visible panels not changed\n return;\n }\n\n if (currentState.holding) {\n newVisiblePanels.push(...removedPanels);\n } else {\n const firstVisiblePanelPos = newVisiblePanels[0].getPosition();\n state.positionOffset = firstVisiblePanelPos;\n }\n\n newVisiblePanels.forEach(panel => {\n panel.setPositionCSS(state.positionOffset);\n });\n\n if (!renderExternal) {\n if (!currentState.holding) {\n removedPanels.forEach(panel => {\n const panelElement = panel.getElement();\n panelElement.parentNode && cameraElement.removeChild(panelElement);\n });\n }\n\n const fragment = document.createDocumentFragment();\n addedPanels.forEach(panel => {\n fragment.appendChild(panel.getElement());\n });\n\n cameraElement.appendChild(fragment);\n }\n\n const firstVisiblePanel = newVisiblePanels[0];\n const lastVisiblePanel = newVisiblePanels[newVisiblePanels.length - 1];\n const getAbsIndex = (panel: Panel) => panel.getIndex() + (panel.getCloneIndex() + 1) * panelManager.getPanelCount();\n\n const newVisibleRange = {\n min: getAbsIndex(firstVisiblePanel),\n max: getAbsIndex(lastVisiblePanel),\n };\n this.visiblePanels = newVisiblePanels;\n this.flicking.trigger(EVENTS.VISIBLE_CHANGE, {\n type: EVENTS.VISIBLE_CHANGE,\n range: newVisibleRange,\n });\n }\n\n private checkVisiblePanelChange(prevVisiblePanels: Panel[], newVisiblePanels: Panel[]) {\n const prevRefCount = prevVisiblePanels.map(() => 0);\n const newRefCount = newVisiblePanels.map(() => 0);\n\n prevVisiblePanels.forEach((prevPanel, prevIndex) => {\n newVisiblePanels.forEach((newPanel, newIndex) => {\n if (prevPanel === newPanel) {\n prevRefCount[prevIndex]++;\n newRefCount[newIndex]++;\n }\n });\n });\n\n const removedPanels = prevRefCount.reduce((removed: Panel[], count, index) => {\n return count === 0\n ? [...removed, prevVisiblePanels[index]]\n : removed;\n }, []);\n const addedPanels = newRefCount.reduce((added: Panel[], count, index) => {\n return count === 0\n ? [...added, newVisiblePanels[index]]\n : added;\n }, []);\n\n return { removedPanels, addedPanels };\n }\n\n private resizePanels(panels: Panel[]): void {\n const options = this.options;\n const panelBboxes = this.panelBboxes;\n\n if (options.isEqualSize === true) {\n if (!panelBboxes.default) {\n const defaultPanel = panels[0];\n panelBboxes.default = defaultPanel.getBbox();\n }\n\n const defaultBbox = panelBboxes.default;\n\n panels.forEach(panel => {\n panel.resize(defaultBbox);\n });\n return;\n } else if (options.isEqualSize) {\n const equalSizeClasses = options.isEqualSize;\n\n panels.forEach(panel => {\n const overlappedClass = panel.getOverlappedClass(equalSizeClasses);\n if (overlappedClass) {\n panel.resize(panelBboxes[overlappedClass]);\n panelBboxes[overlappedClass] = panel.getBbox();\n } else {\n panel.resize();\n }\n });\n return;\n }\n panels.forEach(panel => {\n panel.resize();\n });\n }\n\n private createPanInput() {\n const options = this.options;\n\n this.panInput = new PanInput(this.viewportElement, {\n inputType: options.inputType,\n thresholdAngle: options.thresholdAngle,\n iOSEdgeSwipeThreshold: options.iOSEdgeSwipeThreshold,\n scale: options.horizontal ? [-1, 0] : [0, -1],\n releaseOnScroll: true,\n });\n\n this.axes.connect(options.horizontal ? [\"flick\", \"\"] : [\"\", \"flick\"], this.panInput);\n }\n}\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Flicking from \"../Flicking\";\n\nclass AutoResizer {\n private flicking: Flicking;\n private enabled: boolean;\n private resizeObserver: ResizeObserver | null;\n\n private skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n return;\n }\n this.onResize();\n });\n })();\n\n public constructor(flicking: Flicking) {\n this.flicking = flicking;\n this.enabled = false;\n this.resizeObserver = null;\n }\n\n public enable(): this {\n const flicking = this.flicking;\n\n if (this.enabled) {\n this.disable();\n }\n\n if (flicking.options.useResizeObserver && !!window.ResizeObserver) {\n const flickingEl = flicking.getElement();\n const viewportSizeNot0 = flickingEl.clientWidth !== 0 || flickingEl.clientHeight !== 0;\n\n const resizeObserver = viewportSizeNot0\n ? new ResizeObserver(this.skipFirstResize)\n : new ResizeObserver(this.onResize);\n\n resizeObserver.observe(flickingEl);\n\n this.resizeObserver = resizeObserver;\n } else {\n window.addEventListener(\"resize\", this.onResize);\n }\n\n this.enabled = true;\n\n return this;\n }\n\n public disable(): this {\n if (!this.enabled) {\n return this;\n }\n\n const resizeObserver = this.resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this.resizeObserver = null;\n } else {\n window.removeEventListener(\"resize\", this.onResize);\n }\n\n this.enabled = false;\n\n return this;\n }\n\n private onResize = () => {\n this.flicking.resize();\n }\n}\n\nexport default AutoResizer;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Component from \"@egjs/component\";\nimport ImReady from \"@egjs/imready\";\nimport { DiffResult } from \"@egjs/list-differ\";\nimport Viewport from \"./components/Viewport\";\nimport Panel from \"./components/Panel\";\nimport AutoResizer from \"./components/AutoResizer\";\n\nimport { merge, getProgress, parseElement, isString, counter, findIndex } from \"./utils\";\nimport { DEFAULT_OPTIONS, EVENTS, DIRECTION, AXES_EVENTS, STATE_TYPE, DEFAULT_MOVE_TYPE_OPTIONS } from \"./consts\";\nimport {\n FlickingOptions,\n FlickingEvent,\n Direction,\n EventType,\n FlickingPanel,\n TriggerCallback,\n FlickingContext,\n FlickingStatus,\n Plugin,\n ElementLike,\n DestroyOption,\n BeforeSyncResult,\n SyncResult,\n ChangeEvent,\n SelectEvent,\n NeedPanelEvent,\n VisibleChangeEvent,\n ContentErrorEvent,\n MoveTypeStringOption,\n ValueOf,\n} from \"./types\";\n\n/**\n * @memberof eg\n * @extends eg.Component\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\" , \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"4.X+\"}\n * @requires {@link https://github.com/naver/egjs-component|eg.Component}\n * @requires {@link https://github.com/naver/egjs-axes|eg.Axes}\n * @see Easing Functions Cheat Sheet {@link http://easings.net/} <ko>이징 함수 Cheat Sheet {@link http://easings.net/}</ko>\n */\nclass Flicking extends Component<{\n holdStart: FlickingEvent;\n holdEnd: FlickingEvent;\n moveStart: FlickingEvent;\n move: FlickingEvent;\n moveEnd: FlickingEvent;\n change: ChangeEvent;\n restore: FlickingEvent;\n select: SelectEvent;\n needPanel: NeedPanelEvent;\n visibleChange: VisibleChangeEvent;\n contentError: ContentErrorEvent;\n}> {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @example\n * eg.Flicking.VERSION; // ex) 3.0.0\n * @memberof eg.Flicking\n */\n public static VERSION: string = \"#__VERSION__#\";\n /**\n * Direction constant - \"PREV\" or \"NEXT\"\n * @ko 방향 상수 - \"PREV\" 또는 \"NEXT\"\n * @type {object}\n * @property {\"PREV\"} PREV - Prev direction from current hanger position.<br/>It's `left(←️)` direction when `horizontal: true`.<br/>Or, `up(↑️)` direction when `horizontal: false`.<ko>현재 행어를 기준으로 이전 방향.<br/>`horizontal: true`일 경우 `왼쪽(←️)` 방향.<br/>`horizontal: false`일 경우 `위쪽(↑️)`방향이다.</ko>\n * @property {\"NEXT\"} NEXT - Next direction from current hanger position.<br/>It's `right(→)` direction when `horizontal: true`.<br/>Or, `down(↓️)` direction when `horizontal: false`.<ko>현재 행어를 기준으로 다음 방향.<br/>`horizontal: true`일 경우 `오른쪽(→)` 방향.<br/>`horizontal: false`일 경우 `아래쪽(↓️)`방향이다.</ko>\n * @example\n * eg.Flicking.DIRECTION.PREV; // \"PREV\"\n * eg.Flicking.DIRECTION.NEXT; // \"NEXT\"\n */\n public static DIRECTION: Direction = DIRECTION;\n\n /**\n * Event type object with event name strings.\n * @ko 이벤트 이름 문자열들을 담은 객체\n * @type {object}\n * @property {\"holdStart\"} HOLD_START - holdStart event<ko>holdStart 이벤트</ko>\n * @property {\"holdEnd\"} HOLD_END - holdEnd event<ko>holdEnd 이벤트</ko>\n * @property {\"moveStart\"} MOVE_START - moveStart event<ko>moveStart 이벤트</ko>\n * @property {\"move\"} MOVE - move event<ko>move 이벤트</ko>\n * @property {\"moveEnd\"} MOVE_END - moveEnd event<ko>moveEnd 이벤트</ko>\n * @property {\"change\"} CHANGE - change event<ko>change 이벤트</ko>\n * @property {\"restore\"} RESTORE - restore event<ko>restore 이벤트</ko>\n * @property {\"select\"} SELECT - select event<ko>select 이벤트</ko>\n * @property {\"needPanel\"} NEED_PANEL - needPanel event<ko>needPanel 이벤트</ko>\n * @example\n * eg.Flicking.EVENTS.MOVE_START; // \"MOVE_START\"\n */\n public static EVENTS: EventType = EVENTS;\n\n public options: FlickingOptions;\n\n private wrapper: HTMLElement;\n private viewport: Viewport;\n private autoResizer: AutoResizer;\n private contentsReadyChecker: ImReady | null = null;\n\n private eventContext: FlickingContext;\n private isPanelChangedAtBeforeSync: boolean = false;\n\n /**\n * @param element A base element for the eg.Flicking module. When specifying a value as a `string` type, you must specify a css selector string to select the element.<ko>eg.Flicking 모듈을 사용할 기준 요소. `string`타입으로 값 지정시 요소를 선택하기 위한 css 선택자 문자열을 지정해야 한다.</ko>\n * @param options An option object of the eg.Flicking module<ko>eg.Flicking 모듈의 옵션 객체</ko>\n * @param {string} [options.classPrefix=\"eg-flick\"] A prefix of class names will be added for the panels, viewport, and camera.<ko>패널들과 뷰포트, 카메라에 추가될 클래스 이름의 접두사.</ko>\n * @param {number} [options.deceleration=0.0075] Deceleration value for panel movement animation for animation triggered by manual user input. A higher value means a shorter running time.<ko>사용자의 동작으로 가속도가 적용된 패널 이동 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아진다.</ko>\n * @param {boolean} [options.horizontal=true] The direction of panel movement. (true: horizontal, false: vertical)<ko>패널 이동 방향. (true: 가로방향, false: 세로방향)</ko>\n * @param {boolean} [options.circular=false] Enables circular mode, which connects first/last panel for continuous scrolling.<ko>순환 모드를 활성화한다. 순환 모드에서는 양 끝의 패널이 서로 연결되어 끊김없는 스크롤이 가능하다.</ko>\n * @param {boolean} [options.infinite=false] Enables infinite mode, which can automatically trigger needPanel until reaching the last panel's index reaches the lastIndex.<ko>무한 모드를 활성화한다. 무한 모드에서는 needPanel 이벤트를 자동으로 트리거한다. 해당 동작은 마지막 패널의 인덱스가 lastIndex와 일치할때까지 일어난다.</ko>\n * @param {number} [options.infiniteThreshold=0] A Threshold from viewport edge before triggering `needPanel` event in infinite mode.<ko>무한 모드에서 `needPanel`이벤트가 발생하기 위한 뷰포트 끝으로부터의 최대 거리.</ko>\n * @param {number} [options.lastIndex=Infinity] Maximum panel index that Flicking can set. Flicking won't trigger `needPanel` when the event's panel index is greater than it.<br/>Also, if the last panel's index reached a given index, you can't add more panels.<ko>Flicking이 설정 가능한 패널의 최대 인덱스. `needPanel` 이벤트에 지정된 인덱스가 최대 패널의 개수보다 같거나 커야 하는 경우에 이벤트를 트리거하지 않게 한다.<br>또한, 마지막 패널의 인덱스가 주어진 인덱스와 동일할 경우, 새로운 패널을 더 이상 추가할 수 없다.</ko>\n * @param {number} [options.threshold=40] Movement threshold to change panel(unit: pixel). It should be dragged above the threshold to change the current panel.<ko>패널 변경을 위한 이동 임계값 (단위: 픽셀). 주어진 값 이상으로 스크롤해야만 패널 변경이 가능하다.</ko>\n * @param {number} [options.duration=100] Duration of the panel movement animation. (unit: ms)<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @param {function} [options.panelEffect=x => 1 - Math.pow(1 - x, 3)] An easing function applied to the panel movement animation. Default value is `easeOutCubic`.<ko>패널 이동 애니메이션에 적용할 easing함수. 기본값은 `easeOutCubic`이다.</ko>\n * @param {number} [options.defaultIndex=0] Index of the panel to set as default when initializing. A zero-based integer.<ko>초기화시 지정할 디폴트 패널의 인덱스로, 0부터 시작하는 정수.</ko>\n * @param {string[]} [options.inputType=[\"touch,\"mouse\"]] Types of input devices to enable.({@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption Reference})<ko>활성화할 입력 장치 종류. ({@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption 참고})</ko>\n * @param {number} [options.thresholdAngle=45] The threshold angle value(0 ~ 90).<br>If the input angle from click/touched position is above or below this value in horizontal and vertical mode each, scrolling won't happen.<ko>스크롤 동작을 막기 위한 임계각(0 ~ 90).<br>클릭/터치한 지점으로부터 계산된 사용자 입력의 각도가 horizontal/vertical 모드에서 각각 크거나 작으면, 스크롤 동작이 이루어지지 않는다.</ko>\n * @param {number|string|number[]|string[]} [options.bounce=[10,10]] The size value of the bounce area. Only can be enabled when `circular=false`.<br>You can set different bounce value for prev/next direction by using array.<br>`number` for px value, and `string` for px, and % value relative to viewport size.(ex - 0, \"10px\", \"20%\")<ko>바운스 영역의 크기값. `circular=false`인 경우에만 사용할 수 있다.<br>배열을 통해 prev/next 방향에 대해 서로 다른 바운스 값을 지정 가능하다.<br>`number`를 통해 px값을, `stirng`을 통해 px 혹은 뷰포트 크기 대비 %값을 사용할 수 있다.(ex - 0, \"10px\", \"20%\")</ko>\n * @param {boolean} [options.autoResize=false] Whether the `resize` method should be called automatically after a window resize event.<ko>window의 `resize` 이벤트 이후 자동으로 resize()메소드를 호출할지의 여부.</ko>\n * @param {boolean} [options.adaptive=false] Whether the height(horizontal)/width(vertical) of the viewport element reflects the height/width value of the panel after completing the movement.<ko>목적 패널로 이동한 후 그 패널의 높이(horizontal)/너비(vertical)값을 뷰포트 요소의 높이/너비값에 반영할지 여부.</ko>\n * @param {number|\"\"} [options.zIndex=2000] z-index value for viewport element.<ko>뷰포트 엘리먼트의 z-index 값.</ko>\n * @param {boolean} [options.bound=false] Prevent the view from going out of the first/last panel. Only can be enabled when `circular=false`.<ko>뷰가 첫번째와 마지막 패널 밖으로 나가는 것을 막아준다. `circular=false`인 경우에만 사용할 수 있다.</ko>\n * @param {boolean} [options.overflow=false] Disables CSS property `overflow: hidden` in viewport if `true`.<ko>`true`로 설정시 뷰포트에 `overflow: hidden` 속성을 해제한다.</ko>\n * @param {string} [options.hanger=\"50%\"] The reference position of the hanger in the viewport, which hangs panel anchors should be stopped at.<br>It should be provided in px or % value of viewport size.<br>You can combinate those values with plus/minus sign.<br>ex) \"50\", \"100px\", \"0%\", \"25% + 100px\"<ko>뷰포트 내부의 행어의 위치. 패널의 앵커들이 뷰포트 내에서 멈추는 지점에 해당한다.<br>px값이나, 뷰포트의 크기 대비 %값을 사용할 수 있고, 이를 + 혹은 - 기호로 연계하여 사용할 수도 있다.<br>예) \"50\", \"100px\", \"0%\", \"25% + 100px\"</ko>\n * @param {string} [options.anchor=\"50%\"] The reference position of the anchor in panels, which can be hanged by viewport hanger.<br>It should be provided in px or % value of panel size.<br>You can combinate those values with plus/minus sign.<br>ex) \"50\", \"100px\", \"0%\", \"25% + 100px\"<ko>패널 내부의 앵커의 위치. 뷰포트의 행어와 연계하여 패널이 화면 내에서 멈추는 지점을 설정할 수 있다.<br>px값이나, 패널의 크기 대비 %값을 사용할 수 있고, 이를 + 혹은 - 기호로 연계하여 사용할 수도 있다.<br>예) \"50\", \"100px\", \"0%\", \"25% + 100px\"</ko>\n * @param {number} [options.gap=0] Space value between panels. Should be given in number.(px)<ko>패널간에 부여할 간격의 크기를 나타내는 숫자.(px)</ko>\n * @param {eg.Flicking.MoveTypeOption} [options.moveType=\"snap\"] Movement style by user input. (ex: snap, freeScroll)<ko>사용자 입력에 의한 이동 방식.(ex: snap, freeScroll)</ko>\n * @param {boolean} [options.useOffset=false] Whether to use `offsetWidth`/`offsetHeight` instead of `getBoundingClientRect` for panel/viewport size calculation.<br/>You can use this option to calculate the original panel size when CSS transform is applied to viewport or panel.<br/>⚠️ If panel size is not fixed integer value, there can be a 1px gap between panels.<ko>패널과 뷰포트의 크기를 계산할 때 `offsetWidth`/`offsetHeight`를 `getBoundingClientRect` 대신 사용할지 여부.<br/>패널이나 뷰포트에 CSS transform이 설정되어 있을 때 원래 패널 크기를 계산하려면 옵션을 활성화한다.<br/>⚠️ 패널의 크기가 정수로 고정되어있지 않다면 패널 사이에 1px의 공간이 생길 수 있다.</ko>\n * @param {boolean} [options.renderOnlyVisible=false] Whether to render visible panels only. This can dramatically increase performance when there're many panels.<ko>보이는 패널만 렌더링할지 여부를 설정한다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있다.</ko>\n * @param {boolean|string[]} [options.isEqualSize=false] This option indicates whether all panels have the same size(true) of first panel, or it can hold a list of class names that determines panel size.<br/>Enabling this option can increase performance while recalculating panel size.<ko>모든 패널의 크기가 동일한지(true), 혹은 패널 크기를 결정하는 패널 클래스들의 리스트.<br/>이 옵션을 설정하면 패널 크기 재설정시에 성능을 높일 수 있다.</ko>\n * @param {boolean} [options.isConstantSize=false] Whether all panels have a constant size that won't be changed after resize. Enabling this option can increase performance while recalculating panel size.<ko>모든 패널의 크기가 불변인지의 여부. 이 옵션을 'true'로 설정하면 패널 크기 재설정시에 성능을 높일 수 있다.</ko>\n * @param {boolean} [options.renderExternal=false] Whether to use external rendering. It will delegate DOM manipulation and can synchronize the rendered state by calling `sync()` method. You can use this option to use in frameworks like React, Vue, Angular, which has its states and rendering methods.<ko>외부 렌더링을 사용할 지의 여부. 이 옵션을 사용시 렌더링을 외부에 위임할 수 있고, `sync()`를 호출하여 그 상태를 동기화할 수 있다. 이 옵션을 사용하여, React, Vue, Angular 등 자체적인 상태와 렌더링 방법을 갖는 프레임워크에 대응할 수 있다.</ko>\n * @param {boolean} [options.resizeOnContentsReady=false] Whether to resize the Flicking after the image/video elements inside viewport are ready.<br/>Use this property to prevent wrong Flicking layout caused by dynamic image / video sizes.<ko>Flicking 내부의 이미지 / 비디오 엘리먼트들이 전부 로드되었을 때 Flicking의 크기를 재계산하기 위한 옵션.<br/>이미지 / 비디오 크기가 고정 크기가 아닐 경우 사용하여 레이아웃이 잘못되는 것을 방지할 수 있다.</ko>\n * @param {boolean} [options.useResizeObserver=true] Whether to listen {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}'s event instead of Window's {@link https://developer.mozilla.org/ko/docs/Web/API/Window/resize_event resize} event when using the `autoResize` option<ko>autoResize 옵션 사용시 {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}의 이벤트를 Window객체의 {@link https://developer.mozilla.org/ko/docs/Web/API/Window/resize_event resize} 이벤트 대신 수신할지 여부를 설정합니다</ko>\n * @param {boolean} [options.collectStatistics=true] Whether to collect statistics on how you are using `Flicking`. These statistical data do not contain any personal information and are used only as a basis for the development of a user-friendly product.<ko>어떻게 `Flicking`을 사용하고 있는지에 대한 통계 수집 여부를 나타낸다. 이 통계자료는 개인정보를 포함하고 있지 않으며 오직 사용자 친화적인 제품으로 발전시키기 위한 근거자료로서 활용한다.</ko>\n */\n constructor(\n element: string | HTMLElement,\n options: Partial<FlickingOptions> = {},\n ) {\n super();\n\n // Set flicking wrapper user provided\n let wrapper: HTMLElement | null;\n if (isString(element)) {\n wrapper = document.querySelector(element);\n if (!wrapper) {\n throw new Error(\"Base element doesn't exist.\");\n }\n } else if (element.nodeName && element.nodeType === 1) {\n wrapper = element;\n } else {\n throw new Error(\"Element should be provided in string or HTMLElement.\");\n }\n\n this.wrapper = wrapper;\n // Override default options\n this.options = merge({}, DEFAULT_OPTIONS, options) as FlickingOptions;\n // Override moveType option\n const currentOptions = this.options;\n const moveType = currentOptions.moveType as MoveTypeStringOption;\n\n if (moveType in DEFAULT_MOVE_TYPE_OPTIONS) {\n currentOptions.moveType = DEFAULT_MOVE_TYPE_OPTIONS[moveType as keyof typeof DEFAULT_MOVE_TYPE_OPTIONS];\n }\n\n // Make viewport instance with panel container element\n this.viewport = new Viewport(this, this.options, this.triggerEvent);\n this.autoResizer = new AutoResizer(this);\n\n this.listenInput();\n this.listenResize();\n }\n\n /**\n * Move to the previous panel if it exists.\n * @ko 이전 패널이 존재시 해당 패널로 이동한다.\n * @param [duration=options.duration] Duration of the panel movement animation.(unit: ms)<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public prev(duration?: number): this {\n const currentPanel = this.getCurrentPanel();\n const currentState = this.viewport.stateMachine.getState();\n\n if (currentPanel && currentState.type === STATE_TYPE.IDLE) {\n const prevPanel = currentPanel.prev();\n if (prevPanel) {\n prevPanel.focus(duration);\n }\n }\n\n return this;\n }\n\n /**\n * Move to the next panel if it exists.\n * @ko 다음 패널이 존재시 해당 패널로 이동한다.\n * @param [duration=options.duration] Duration of the panel movement animation(unit: ms).<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public next(duration?: number): this {\n const currentPanel = this.getCurrentPanel();\n const currentState = this.viewport.stateMachine.getState();\n\n if (currentPanel && currentState.type === STATE_TYPE.IDLE) {\n const nextPanel = currentPanel.next();\n if (nextPanel) {\n nextPanel.focus(duration);\n }\n }\n\n return this;\n }\n\n /**\n * Move to the panel of given index.\n * @ko 주어진 인덱스에 해당하는 패널로 이동한다.\n * @param index The index number of the panel to move.<ko>이동할 패널의 인덱스 번호.</ko>\n * @param duration [duration=options.duration] Duration of the panel movement.(unit: ms)<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public moveTo(index: number, duration?: number): this {\n const viewport = this.viewport;\n const panel = viewport.panelManager.get(index);\n const state = viewport.stateMachine.getState();\n\n if (!panel || state.type !== STATE_TYPE.IDLE) {\n return this;\n }\n\n const anchorPosition = panel.getAnchorPosition();\n const hangerPosition = viewport.getHangerPosition();\n\n let targetPanel = panel;\n if (this.options.circular) {\n const scrollAreaSize = viewport.getScrollAreaSize();\n // Check all three possible locations, find the nearest position among them.\n const possiblePositions = [\n anchorPosition - scrollAreaSize,\n anchorPosition,\n anchorPosition + scrollAreaSize,\n ];\n const nearestPosition = possiblePositions.reduce((nearest, current) => {\n return (Math.abs(current - hangerPosition) < Math.abs(nearest - hangerPosition))\n ? current\n : nearest;\n }, Infinity) - panel.getRelativeAnchorPosition();\n\n const identicals = panel.getIdenticalPanels();\n const offset = nearestPosition - anchorPosition;\n if (offset > 0) {\n // First cloned panel is nearest\n targetPanel = identicals[1];\n } else if (offset < 0) {\n // Last cloned panel is nearest\n targetPanel = identicals[identicals.length - 1];\n }\n\n targetPanel = targetPanel.clone(targetPanel.getCloneIndex(), true);\n targetPanel.setPosition(nearestPosition);\n }\n const currentIndex = this.getIndex();\n\n if (hangerPosition === targetPanel.getAnchorPosition() && currentIndex === index) {\n return this;\n }\n\n const eventType = panel.getIndex() === viewport.getCurrentIndex()\n ? \"\"\n : EVENTS.CHANGE;\n\n viewport.moveTo(\n targetPanel,\n viewport.findEstimatedPosition(targetPanel),\n eventType,\n null,\n duration,\n );\n return this;\n }\n\n /**\n * Return index of the current panel. `-1` if no panel exists.\n * @ko 현재 패널의 인덱스 번호를 반환한다. 패널이 하나도 없을 경우 `-1`을 반환한다.\n * @return Current panel's index, zero-based integer.<ko>현재 패널의 인덱스 번호. 0부터 시작하는 정수.</ko>\n */\n public getIndex(): number {\n return this.viewport.getCurrentIndex();\n }\n\n /**\n * Return the wrapper element user provided in constructor.\n * @ko 사용자가 생성자에서 제공한 래퍼 엘리먼트를 반환한다.\n * @return Wrapper element user provided.<ko>사용자가 제공한 래퍼 엘리먼트.</ko>\n */\n public getElement(): HTMLElement {\n return this.wrapper;\n }\n\n /**\n * Return the viewport element's size.\n * @ko 뷰포트 엘리먼트의 크기를 반환한다.\n * @return Width if horizontal: true, height if horizontal: false\n */\n public getSize(): number {\n return this.viewport.getSize();\n }\n\n /**\n * Return current panel. `null` if no panel exists.\n * @ko 현재 패널을 반환한다. 패널이 하나도 없을 경우 `null`을 반환한다.\n * @return Current panel.<ko>현재 패널.</ko>\n */\n public getCurrentPanel(): FlickingPanel | null {\n const viewport = this.viewport;\n const panel = viewport.getCurrentPanel();\n return panel\n ? panel\n : null;\n }\n\n /**\n * Return the panel of given index. `null` if it doesn't exists.\n * @ko 주어진 인덱스에 해당하는 패널을 반환한다. 해당 패널이 존재하지 않을 시 `null`이다.\n * @return Panel of given index.<ko>주어진 인덱스에 해당하는 패널.</ko>\n */\n public getPanel(index: number): FlickingPanel | null {\n const viewport = this.viewport;\n const panel = viewport.panelManager.get(index);\n return panel\n ? panel\n : null;\n }\n\n /**\n * Return all panels.\n * @ko 모든 패널들을 반환한다.\n * @param - Should include cloned panels or not.<ko>복사된 패널들을 포함할지의 여부.</ko>\n * @return All panels.<ko>모든 패널들.</ko>\n */\n public getAllPanels(includeClone?: boolean): FlickingPanel[] {\n const viewport = this.viewport;\n const panelManager = viewport.panelManager;\n const panels = includeClone\n ? panelManager.allPanels()\n : panelManager.originalPanels();\n\n return panels\n .filter(panel => !!panel);\n }\n\n /**\n * Return the panels currently shown in viewport area.\n * @ko 현재 뷰포트 영역에서 보여지고 있는 패널들을 반환한다.\n * @return Panels currently shown in viewport area.<ko>현재 뷰포트 영역에 보여지는 패널들</ko>\n */\n public getVisiblePanels(): FlickingPanel[] {\n return this.viewport.calcVisiblePanels();\n }\n\n /**\n * Return length of original panels.\n * @ko 원본 패널의 개수를 반환한다.\n * @return Length of original panels.<ko>원본 패널의 개수</ko>\n */\n public getPanelCount(): number {\n return this.viewport.panelManager.getPanelCount();\n }\n\n /**\n * Return how many groups of clones are created.\n * @ko 몇 개의 클론 그룹이 생성되었는지를 반환한다.\n * @return Length of cloned panel groups.<ko>클론된 패널 그룹의 개수</ko>\n */\n public getCloneCount(): number {\n return this.viewport.panelManager.getCloneCount();\n }\n\n /**\n * Get maximum panel index for `infinite` mode.\n * @ko `infinite` 모드에서 적용되는 추가 가능한 패널의 최대 인덱스 값을 반환한다.\n * @see {@link eg.Flicking.FlickingOptions}\n * @return Maximum index of panel that can be added.<ko>최대 추가 가능한 패널의 인덱스.</ko>\n */\n public getLastIndex(): number {\n return this.viewport.panelManager.getLastIndex();\n }\n\n /**\n * Set maximum panel index for `infinite' mode.<br>[needPanel]{@link eg.Flicking#events:needPanel} won't be triggered anymore when last panel's index reaches it.<br>Also, you can't add more panels after it.\n * @ko `infinite` 모드에서 적용되는 패널의 최대 인덱스를 설정한다.<br>마지막 패널의 인덱스가 설정한 값에 도달할 경우 더 이상 [needPanel]{@link eg.Flicking#events:needPanel} 이벤트가 발생되지 않는다.<br>또한, 설정한 인덱스 이후로 새로운 패널을 추가할 수 없다.\n * @param - Maximum panel index.\n * @see {@link eg.Flicking.FlickingOptions}\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public setLastIndex(index: number): this {\n this.viewport.setLastIndex(index);\n\n return this;\n }\n\n /**\n * Return panel movement animation.\n * @ko 현재 패널 이동 애니메이션이 진행 중인지를 반환한다.\n * @return Is animating or not.<ko>애니메이션 진행 여부.</ko>\n */\n public isPlaying(): boolean {\n return this.viewport.stateMachine.getState().playing;\n }\n\n /**\n * Unblock input devices.\n * @ko 막았던 입력 장치로부터의 입력을 푼다.\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public enableInput(): this {\n this.viewport.enable();\n\n return this;\n }\n\n /**\n * Block input devices.\n * @ko 입력 장치로부터의 입력을 막는다.\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public disableInput(): this {\n this.viewport.disable();\n\n return this;\n }\n\n /**\n * Get current flicking status. You can restore current state by giving returned value to [setStatus()]{@link eg.Flicking#setStatus}.\n * @ko 현재 상태 값을 반환한다. 반환받은 값을 [setStatus()]{@link eg.Flicking#setStatus} 메소드의 인자로 지정하면 현재 상태를 복원할 수 있다.\n * @return An object with current status value information.<ko>현재 상태값 정보를 가진 객체.</ko>\n */\n public getStatus(): FlickingStatus {\n const viewport = this.viewport;\n\n const panels = viewport.panelManager.originalPanels()\n .filter(panel => !!panel)\n .map(panel => {\n return {\n html: panel.getElement().outerHTML,\n index: panel.getIndex(),\n position: panel.getPosition(),\n };\n });\n\n return {\n index: viewport.getCurrentIndex(),\n panels,\n position: viewport.getCameraPosition(),\n };\n }\n\n /**\n * Restore to the state of the `status`.\n * @ko `status`의 상태로 복원한다.\n * @param status Status value to be restored. You can specify the return value of the [getStatus()]{@link eg.Flicking#getStatus} method.<ko>복원할 상태 값. [getStatus()]{@link eg.Flicking#getStatus}메서드의 반환값을 지정하면 된다.</ko>\n */\n public setStatus(status: FlickingStatus): void {\n this.viewport.restore(status);\n }\n\n /**\n * Add plugins that can have different effects on Flicking.\n * @ko 플리킹에 다양한 효과를 부여할 수 있는 플러그인을 추가한다.\n * @param - The plugin(s) to add.<ko>추가할 플러그인(들).</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public addPlugins(plugins: Plugin | Plugin[]) {\n this.viewport.addPlugins(plugins);\n return this;\n }\n\n /**\n * Remove plugins from Flicking.\n * @ko 플리킹으로부터 플러그인들을 제거한다.\n * @param - The plugin(s) to remove.<ko>제거 플러그인(들).</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public removePlugins(plugins: Plugin | Plugin[]) {\n this.viewport.removePlugins(plugins);\n return this;\n }\n\n /**\n * Return the reference element and all its children to the state they were in before the instance was created. Remove all attached event handlers. Specify `null` for all attributes of the instance (including inherited attributes).\n * @ko 기준 요소와 그 하위 패널들을 인스턴스 생성전의 상태로 되돌린다. 부착된 모든 이벤트 핸들러를 탈거한다. 인스턴스의 모든 속성(상속받은 속성포함)에 `null`을 지정한다.\n * @example\n * const flick = new eg.Flicking(\"#flick\");\n * flick.destroy();\n * console.log(flick.moveTo); // null\n */\n public destroy(option: Partial<DestroyOption> = {}): void {\n this.off();\n\n this.autoResizer.disable();\n this.viewport.destroy(option);\n this.contentsReadyChecker?.destroy();\n\n // release resources\n for (const x in this) {\n (this as any)[x] = null;\n }\n }\n\n /**\n * Update panels to current state.\n * @ko 패널들을 현재 상태에 맞춰 갱신한다.\n * @method\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public resize = (): this => {\n const viewport = this.viewport;\n const options = this.options;\n const wrapper = this.getElement();\n\n const allPanels = viewport.panelManager.allPanels();\n if (!options.isConstantSize) {\n allPanels\n .filter(panel => !!panel)\n .forEach(panel => panel.unCacheBbox());\n }\n\n const shouldResetElements = options.renderOnlyVisible\n && !options.isConstantSize\n && options.isEqualSize !== true;\n\n // Temporarily set parent's height to prevent scroll (#333)\n const parent = wrapper.parentElement!;\n const origStyle = parent.style.height;\n parent.style.height = `${parent.offsetHeight}px`;\n\n viewport.unCacheBbox();\n // This should be done before adding panels, to lower performance issue\n viewport.updateBbox();\n\n if (shouldResetElements) {\n viewport.appendUncachedPanelElements(allPanels as Panel[]);\n }\n\n viewport.resize();\n parent.style.height = origStyle;\n\n return this;\n }\n\n /**\n * Add new panels at the beginning of panels.\n * @ko 제일 앞에 새로운 패널을 추가한다.\n * @param element - Either HTMLElement, HTML string, or array of them.<br>It can be also HTML string of multiple elements with same depth.<ko>HTMLElement 혹은 HTML 문자열, 혹은 그것들의 배열도 가능하다.<br>또한, 같은 depth의 여러 개의 엘리먼트에 해당하는 HTML 문자열도 가능하다.</ko>\n * @return Array of appended panels.<ko>추가된 패널들의 배열</ko>\n * @example\n * // Suppose there were no panels at initialization\n * const flicking = new eg.Flicking(\"#flick\");\n * flicking.replace(3, document.createElement(\"div\")); // Add new panel at index 3\n * flicking.prepend(\"\\<div\\>Panel\\</div\\>\"); // Prepended at index 2\n * flicking.prepend([\"\\<div\\>Panel\\</div\\>\", document.createElement(\"div\")]); // Prepended at index 0, 1\n * flicking.prepend(\"\\<div\\>Panel\\</div\\>\"); // Prepended at index 0, pushing every panels behind it.\n */\n public prepend(element: ElementLike | ElementLike[]): FlickingPanel[] {\n const viewport = this.viewport;\n const parsedElements = parseElement(element);\n\n const insertingIndex = Math.max(viewport.panelManager.getRange().min - parsedElements.length, 0);\n const prependedPanels = viewport.insert(insertingIndex, parsedElements);\n\n this.checkContentsReady(prependedPanels);\n\n return prependedPanels;\n }\n\n /**\n * Add new panels at the end of panels.\n * @ko 제일 끝에 새로운 패널을 추가한다.\n * @param element - Either HTMLElement, HTML string, or array of them.<br>It can be also HTML string of multiple elements with same depth.<ko>HTMLElement 혹은 HTML 문자열, 혹은 그것들의 배열도 가능하다.<br>또한, 같은 depth의 여러 개의 엘리먼트에 해당하는 HTML 문자열도 가능하다.</ko>\n * @return Array of appended panels.<ko>추가된 패널들의 배열</ko>\n * @example\n * // Suppose there were no panels at initialization\n * const flicking = new eg.Flicking(\"#flick\");\n * flicking.append(document.createElement(\"div\")); // Appended at index 0\n * flicking.append(\"\\<div\\>Panel\\</div\\>\"); // Appended at index 1\n * flicking.append([\"\\<div\\>Panel\\</div\\>\", document.createElement(\"div\")]); // Appended at index 2, 3\n * // Even this is possible\n * flicking.append(\"\\<div\\>Panel 1\\</div\\>\\<div\\>Panel 2\\</div\\>\"); // Appended at index 4, 5\n */\n public append(element: ElementLike | ElementLike[]): FlickingPanel[] {\n const viewport = this.viewport;\n const appendedPanels = viewport.insert(viewport.panelManager.getRange().max + 1, element);\n\n this.checkContentsReady(appendedPanels);\n\n return appendedPanels;\n }\n\n /**\n * Replace existing panels with new panels from given index. If target index is empty, add new panel at target index.\n * @ko 주어진 인덱스로부터의 패널들을 새로운 패널들로 교체한다. 인덱스에 해당하는 자리가 비어있다면, 새로운 패널을 해당 자리에 집어넣는다.\n * @param index - Start index to replace new panels.<ko>새로운 패널들로 교체할 시작 인덱스</ko>\n * @param element - Either HTMLElement, HTML string, or array of them.<br>It can be also HTML string of multiple elements with same depth.<ko>HTMLElement 혹은 HTML 문자열, 혹은 그것들의 배열도 가능하다.<br>또한, 같은 depth의 여러 개의 엘리먼트에 해당하는 HTML 문자열도 가능하다.</ko>\n * @return Array of created panels by replace.<ko>교체되어 새롭게 추가된 패널들의 배열</ko>\n * @example\n * // Suppose there were no panels at initialization\n * const flicking = new eg.Flicking(\"#flick\");\n *\n * // This will add new panel at index 3,\n * // Index 0, 1, 2 is empty at this moment.\n * // [empty, empty, empty, PANEL]\n * flicking.replace(3, document.createElement(\"div\"));\n *\n * // As index 2 was empty, this will also add new panel at index 2.\n * // [empty, empty, PANEL, PANEL]\n * flicking.replace(2, \"\\<div\\>Panel\\</div\\>\");\n *\n * // Index 3 was not empty, so it will replace previous one.\n * // It will also add new panels at index 4 and 5.\n * // before - [empty, empty, PANEL, PANEL]\n * // after - [empty, empty, PANEL, NEW_PANEL, NEW_PANEL, NEW_PANEL]\n * flicking.replace(3, [\"\\<div\\>Panel\\</div\\>\", \"\\<div\\>Panel\\</div\\>\", \"\\<div\\>Panel\\</div\\>\"])\n */\n public replace(index: number, element: ElementLike | ElementLike[]): FlickingPanel[] {\n const replacedPanels = this.viewport.replace(index, element);\n\n this.checkContentsReady(replacedPanels);\n\n return replacedPanels;\n }\n\n /**\n * Remove panel at target index. This will decrease index of panels behind it.\n * @ko `index`에 해당하는 자리의 패널을 제거한다. 수행시 `index` 이후의 패널들의 인덱스가 감소된다.\n * @param index - Index of panel to remove.<ko>제거할 패널의 인덱스</ko>\n * @param {number} [deleteCount=1] - Number of panels to remove from index.<ko>`index` 이후로 제거할 패널의 개수.</ko>\n * @return Array of removed panels<ko>제거된 패널들의 배열</ko>\n */\n public remove(index: number, deleteCount: number = 1): FlickingPanel[] {\n return this.viewport.remove(index, deleteCount);\n }\n\n /**\n * Get indexes to render. Should be used with `renderOnlyVisible` option.\n * `beforeSync` should be called before this method for a correct result.\n * @private\n * @ko 렌더링이 필요한 인덱스들을 반환한다. `renderOnlyVisible` 옵션과 함께 사용해야 한다. 정확한 결과를 위해선 `beforeSync`를 이전에 호출해야만 합니다.\n * @param - Info object of how panel infos are changed.<ko>패널 정보들의 변경 정보를 담는 오브젝트.</ko>\n * @return Array of indexes to render.<ko>렌더링할 인덱스의 배열</ko>\n */\n public getRenderingIndexes(diffResult: DiffResult<any>): number[] {\n const viewport = this.viewport;\n const visiblePanels = viewport.getVisiblePanels();\n const maintained = diffResult.maintained.reduce((values: {[key: number]: number}, [before, after]) => {\n values[after] = before;\n return values;\n }, {});\n\n const panelCount = diffResult.list.length;\n const added = diffResult.added;\n const getPanelAbsIndex = (panel: Panel) => {\n return panel.getIndex() + (panel.getCloneIndex() + 1) * panelCount;\n };\n\n const visibleIndexes = visiblePanels.map(panel => getPanelAbsIndex(panel))\n .filter(val => maintained[val % panelCount] != null);\n\n const renderingPanels = [...visibleIndexes, ...added];\n const allPanels = viewport.panelManager.allPanels();\n\n viewport.setVisiblePanels(renderingPanels.map(index => allPanels[index]));\n\n return renderingPanels;\n }\n\n /**\n * Synchronize info of panels instance with info given by external rendering.\n * @ko 외부 렌더링 방식에 의해 입력받은 패널의 정보와 현재 플리킹이 갖는 패널 정보를 동기화한다.\n * @private\n * @param - Info object of how panel infos are changed.<ko>패널 정보들의 변경 정보를 담는 오브젝트.</ko>\n * @param - Whether called from sync method <ko> sync 메소드로부터 호출됐는지 여부 </ko>\n */\n public beforeSync(diffInfo: BeforeSyncResult) {\n const { maintained, added, changed, removed } = diffInfo;\n const viewport = this.viewport;\n const panelManager = viewport.panelManager;\n const isCircular = this.options.circular;\n const currentPanel = viewport.getCurrentPanel();\n const cloneCount = panelManager.getCloneCount();\n const prevClonedPanels = panelManager.clonedPanels();\n\n // Update visible panels\n const newVisiblePanels = viewport.getVisiblePanels()\n .filter(panel => findIndex(removed, index => {\n return index === panel.getIndex();\n }) < 0);\n viewport.setVisiblePanels(newVisiblePanels);\n\n // Did not changed at all\n if (\n added.length <= 0\n && removed.length <= 0\n && changed.length <= 0\n && cloneCount === prevClonedPanels.length\n ) {\n return this;\n }\n const prevOriginalPanels = panelManager.originalPanels();\n const newPanels: Panel[] = [];\n const newClones: Panel[][] = counter(cloneCount).map(() => []);\n\n maintained.forEach(([beforeIdx, afterIdx]) => {\n newPanels[afterIdx] = prevOriginalPanels[beforeIdx];\n newPanels[afterIdx].setIndex(afterIdx);\n });\n\n added.forEach(addIndex => {\n newPanels[addIndex] = new Panel(null, addIndex, this.viewport);\n });\n\n if (isCircular) {\n counter(cloneCount).forEach(groupIndex => {\n const prevCloneGroup = prevClonedPanels[groupIndex];\n const newCloneGroup = newClones[groupIndex];\n\n maintained.forEach(([beforeIdx, afterIdx]) => {\n newCloneGroup[afterIdx] = prevCloneGroup\n ? prevCloneGroup[beforeIdx]\n : newPanels[afterIdx].clone(groupIndex, false);\n\n newCloneGroup[afterIdx].setIndex(afterIdx);\n });\n\n added.forEach(addIndex => {\n const newPanel = newPanels[addIndex];\n\n newCloneGroup[addIndex] = newPanel.clone(groupIndex, false);\n });\n });\n }\n\n added.forEach(index => { viewport.updateCheckedIndexes({ min: index, max: index }); });\n removed.forEach(index => { viewport.updateCheckedIndexes({ min: index - 1, max: index + 1 }); });\n\n const checkedIndexes = viewport.getCheckedIndexes();\n checkedIndexes.forEach(([min, max], idx) => {\n // Push checked indexes backward\n const pushedIndex = added.filter(index => index < min && panelManager.has(index)).length\n - removed.filter(index => index < min).length;\n checkedIndexes.splice(idx, 1, [min + pushedIndex, max + pushedIndex]);\n });\n\n // Only effective only when there are least one panel which have changed its index\n if (changed.length > 0) {\n // Removed checked index by changed ones after pushing\n maintained.forEach(([, next]) => { viewport.updateCheckedIndexes({ min: next, max: next }); });\n }\n panelManager.replacePanels(newPanels, newClones);\n\n const currentPanelIndex = currentPanel?.getIndex() ?? -1;\n const currentPanelIsRemoved = findIndex(removed, index => index === currentPanelIndex) >= 0;\n\n if ((!currentPanel || currentPanelIsRemoved) && newPanels.length > 0) {\n viewport.setCurrentPanel(newPanels[0]);\n } else if (newPanels.length <= 0) {\n viewport.setCurrentPanel(undefined);\n }\n\n this.isPanelChangedAtBeforeSync = true;\n }\n\n /**\n * Synchronize info of panels with DOM info given by external rendering.\n * @ko 외부 렌더링 방식에 의해 입력받은 DOM의 정보와 현재 플리킹이 갖는 패널 정보를 동기화 한다.\n * @private\n * @param - Info object of how panel elements are changed.<ko>패널의 DOM 요소들의 변경 정보를 담는 오브젝트.</ko>\n */\n public sync(diffInfo: SyncResult): this {\n const { list, maintained, added, changed, removed } = diffInfo;\n\n // Did not changed at all\n if (added.length <= 0 && removed.length <= 0 && changed.length <= 0) {\n return this;\n }\n const viewport = this.viewport;\n const { renderOnlyVisible, circular } = this.options;\n const panelManager = viewport.panelManager;\n\n if (!renderOnlyVisible) {\n const indexRange = panelManager.getRange();\n let beforeDiffInfo: BeforeSyncResult = diffInfo;\n\n if (circular) {\n const prevOriginalPanelCount = indexRange.max;\n const originalPanelCount = (list.length / (panelManager.getCloneCount() + 1)) >> 0;\n const originalAdded = added.filter(index => index < originalPanelCount);\n const originalRemoved = removed.filter(index => index <= prevOriginalPanelCount);\n const originalMaintained = maintained.filter(([beforeIdx]) => beforeIdx <= prevOriginalPanelCount);\n const originalChanged = changed.filter(([beforeIdx]) => beforeIdx <= prevOriginalPanelCount);\n\n beforeDiffInfo = {\n added: originalAdded,\n maintained: originalMaintained,\n removed: originalRemoved,\n changed: originalChanged,\n };\n }\n this.beforeSync(beforeDiffInfo);\n }\n\n const visiblePanels = renderOnlyVisible\n ? viewport.getVisiblePanels()\n : this.getAllPanels(true);\n\n added.forEach(addedIndex => {\n const addedElement = list[addedIndex];\n const beforePanel = visiblePanels[addedIndex] as Panel;\n\n beforePanel.setElement(addedElement);\n // As it can be 0\n beforePanel.unCacheBbox();\n });\n if (this.isPanelChangedAtBeforeSync) {\n // Reset visible panels\n viewport.setVisiblePanels([]);\n this.isPanelChangedAtBeforeSync = false;\n }\n viewport.resize();\n\n return this;\n }\n\n private listenInput(): void {\n const flicking = this;\n const viewport = flicking.viewport;\n const stateMachine = viewport.stateMachine;\n\n // Set event context\n flicking.eventContext = {\n flicking,\n viewport: flicking.viewport,\n transitTo: stateMachine.transitTo,\n triggerEvent: flicking.triggerEvent,\n moveCamera: flicking.moveCamera,\n stopCamera: viewport.stopCamera,\n };\n\n const handlers = {};\n for (const key in AXES_EVENTS) {\n const eventType = AXES_EVENTS[key];\n\n handlers[eventType] = (e: any) => stateMachine.fire(eventType, e, flicking.eventContext);\n }\n\n // Connect Axes instance with PanInput\n flicking.viewport.connectAxesHandler(handlers);\n }\n\n private listenResize(): void {\n const options = this.options;\n\n if (options.autoResize) {\n this.autoResizer.enable();\n }\n\n if (options.resizeOnContentsReady) {\n const contentsReadyChecker = new ImReady();\n\n contentsReadyChecker.on(\"preReady\", () => {\n this.resize();\n });\n contentsReadyChecker.on(\"readyElement\", e => {\n if (e.hasLoading && e.isPreReadyOver) {\n this.resize();\n }\n });\n contentsReadyChecker.on(\"error\", e => {\n this.trigger(EVENTS.CONTENT_ERROR, {\n type: EVENTS.CONTENT_ERROR,\n element: e.element,\n });\n });\n contentsReadyChecker.check([this.wrapper]);\n\n this.contentsReadyChecker = contentsReadyChecker;\n }\n }\n\n private triggerEvent = <T extends FlickingEvent>(\n eventName: ValueOf<Omit<EventType, \"VISIBLE_CHANGE\">>, // visibleChange event has no common event definition from other events\n axesEvent: any,\n isTrusted: boolean,\n params: Partial<T> = {},\n ): TriggerCallback => {\n const viewport = this.viewport;\n\n let canceled: boolean = true;\n\n // Ignore events before viewport is initialized\n if (viewport) {\n const state = viewport.stateMachine.getState();\n const { prev, next } = viewport.getScrollArea();\n const pos = viewport.getCameraPosition();\n let progress = getProgress(pos, [prev, prev, next]);\n\n if (this.options.circular) {\n progress %= 1;\n }\n canceled = !super.trigger(eventName, merge({\n type: eventName,\n index: this.getIndex(),\n panel: this.getCurrentPanel(),\n direction: state.direction,\n holding: state.holding,\n progress,\n axesEvent,\n isTrusted,\n }, params) as FlickingEvent);\n }\n\n return {\n onSuccess(callback: () => void): TriggerCallback {\n if (!canceled) {\n callback();\n }\n return this;\n },\n onStopped(callback: () => void): TriggerCallback {\n if (canceled) {\n callback();\n }\n return this;\n },\n } as TriggerCallback;\n }\n\n // Return result of \"move\" event triggered\n private moveCamera = (axesEvent: any): TriggerCallback => {\n const viewport = this.viewport;\n const state = viewport.stateMachine.getState();\n const options = this.options;\n\n const pos = axesEvent.pos.flick;\n const previousPosition = viewport.getCameraPosition();\n\n if (axesEvent.isTrusted && state.holding) {\n const inputOffset = options.horizontal\n ? axesEvent.inputEvent.offsetX\n : axesEvent.inputEvent.offsetY;\n\n const isNextDirection = inputOffset < 0;\n\n let cameraChange = pos - previousPosition;\n const looped = isNextDirection === (pos < previousPosition);\n if (options.circular && looped) {\n // Reached at max/min range of axes\n const scrollAreaSize = viewport.getScrollAreaSize();\n cameraChange = (cameraChange > 0 ? -1 : 1) * (scrollAreaSize - Math.abs(cameraChange));\n }\n\n const currentDirection = cameraChange === 0\n ? state.direction\n : cameraChange > 0\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n state.direction = currentDirection;\n }\n state.delta += axesEvent.delta.flick;\n\n viewport.moveCamera(pos, axesEvent);\n return this.triggerEvent(EVENTS.MOVE, axesEvent, axesEvent.isTrusted)\n .onStopped(() => {\n // Undo camera movement\n viewport.moveCamera(previousPosition, axesEvent);\n });\n }\n\n private checkContentsReady(panels: FlickingPanel[]) {\n this.contentsReadyChecker?.check(panels.map(panel => panel.getElement()));\n }\n}\n\nexport default Flicking;\n","import Flicking from \"./Flicking\";\nimport { withFlickingMethods } from \"./utils\";\nimport { DEFAULT_OPTIONS, MOVE_TYPE } from \"./consts\";\n\n(Flicking as any).withFlickingMethods = withFlickingMethods;\n(Flicking as any).DEFAULT_OPTIONS = DEFAULT_OPTIONS;\n(Flicking as any).MOVE_TYPE = MOVE_TYPE;\nexport default Flicking;\n"],"names":["MOVE_TYPE","SNAP","FREE_SCROLL","DEFAULT_MOVE_TYPE_OPTIONS","snap","type","count","freeScroll","isBrowser","document","DEFAULT_OPTIONS","classPrefix","deceleration","horizontal","circular","infinite","infiniteThreshold","lastIndex","Infinity","threshold","duration","panelEffect","x","Math","pow","defaultIndex","inputType","thresholdAngle","bounce","autoResize","adaptive","zIndex","bound","overflow","hanger","anchor","gap","moveType","useOffset","isEqualSize","isConstantSize","renderOnlyVisible","renderExternal","resizeOnContentsReady","iOSEdgeSwipeThreshold","collectStatistics","useResizeObserver","DEFAULT_VIEWPORT_CSS","position","DEFAULT_CAMERA_CSS","width","height","willChange","DEFAULT_PANEL_CSS","EVENTS","HOLD_START","HOLD_END","MOVE_START","MOVE","MOVE_END","CHANGE","RESTORE","SELECT","NEED_PANEL","VISIBLE_CHANGE","CONTENT_ERROR","AXES_EVENTS","HOLD","RELEASE","ANIMATION_END","FINISH","STATE_TYPE","DIRECTION","PREV","NEXT","FLICKING_METHODS","prev","next","moveTo","getIndex","getAllPanels","getCurrentPanel","getElement","getSize","getPanel","getPanelCount","getStatus","getVisiblePanels","enableInput","disableInput","destroy","resize","setStatus","isPlaying","checkTranslateSupport","transforms","webkitTransform","msTransform","MozTransform","OTransform","transform","name","has3d","prefixedTransform","supportedStyle","documentElement","style","transformName","Error","el","createElement","insertBefore","styleVal","window","getComputedStyle","getPropertyValue","parentElement","removeChild","transformInfo","length","TRANSFORM","merge","target","_i","srcs","forEach","source","Object","keys","key","value","parseElement","element","Array","isArray","elements","isString","tempDiv","innerHTML","push","toArray","children","firstChild","hasClass","className","classList","contains","split","indexOf","applyCSS","cssObj","property","clamp","val","min","max","isBetween","iterable","slice","call","parseArithmeticExpression","cssValue","base","defaultVal","defaultValue","cssRegex","idx","calculatedValue","matchResult","exec","sign","unit","parsedValue","parseFloat","getProgress","pos","range","center","findIndex","callback","i","counter","counterArray","circulate","indexed","size","restoreStyle","originalStyle","setAttribute","removeAttribute","getBbox","y","offsetWidth","offsetHeight","clientRect","getBoundingClientRect","left","top","index","viewport","prevSibling","nextSibling","clonedPanels","state","relativeAnchorPosition","isClone","isVirtual","cloneIndex","cachedBbox","setElement","givenBbox","this","options","bbox","prevSize","panel","cloneState","panelCount","panelManager","scrollAreaSize","getScrollAreaSize","floor","getPosition","getCurrentProgress","outsetRange","getRelativeHangerPosition","getRelativeAnchorPosition","getCameraPosition","panelSize","relativePanelPosition","rightRelativePanelPosition","visibleSize","currentPanel","getHangerPosition","getAnchorPosition","eventType","findEstimatedPosition","updateFunction","shouldResize","identicalPanels","getIdenticalPanels","eachPanel","unCacheBbox","addVisiblePanel","currentIndex","currentPosition","prevPanelIndex","prevPanelPosition","prevPanelSize","hasEmptyPanelBetween","notYetMinPanel","newPosition","prevPanel","clone","getCloneIndex","setPosition","getLastIndex","nextPanelIndex","nextPanelPosition","notYetMaxPanel","nextPanel","parsedElements","firstPanel","targetIndex","insert","remove","option","preserveUI","wasVisible","cameraElement","Boolean","parentNode","getCameraElement","appendChild","classes","classes_1","original","getClonedPanels","offset","elementStyle","currentElementStyle","styleToApply","cloneElement","clonedPanel","Panel","cloneNode","clonedState","removeClonedPanelsAfter","start","removingPanels","splice","removeElement","currentElement","getAttribute","add","replace","panels","clones","cloneCount","reduce","allClones","newPanels","newClones","filter","lastPanel","possibleLastPanel","shouldRender","isCircular","findFirstPanelFrom","siblingElement","insertNewPanels","panelCount_1","pushedIndex","emptyPanelCount","panelsAfterIndex","removedPanels","newLastIndex","concat","reverse","setIndex","updateIndex","addNewClones","cloneSet","replacedPanels","wasNonEmptyCount","deleteCount","deletedPanels","nonEmptyIndexFromLast","allPanels","allPanelsCount","insertTarget_1","newClones_1","allPanels_1","_a","originalPanels","getCloneCount","lastPanelClones","nextSiblingClones","cloneNextSibling","lastPanelSibling","cloneSiblingElement","nextElementSibling","map","_this","this_1","insertClones","insertingIndex","fragment_1","createDocumentFragment","prevState","delta","direction","targetPanel","lastPosition","nextState","e","context","__extends","flicking","triggerEvent","transitTo","moveCamera","onSuccess","onStopped","onChange","State","inputEvent","offsetX","offsetY","flick","setTo","srcEvent","cancelable","releaseEvent","clickedPanel","cameraPosition","clickedElement","touch","changedTouches","elementFromPoint","clientX","clientY","findPanelOf","clickedPanelPosition","stopCamera","absDelta","abs","velocity","velocityX","velocityY","inputDelta","deltaX","deltaY","isNextDirection","swipeDistance","swipeAngle","atan","PI","belowAngleThreshold","overThreshold","moveTypeContext","axesEvent","interruptDestInfo","findPanelWhenInterrupted","destPos","nearestPanel","getNearestPanel","stop","destInfo","findTargetPanel","findRestorePanel","scrollArea","getScrollArea","loopCount","originalTargetPosition","newCloneIndex","newTargetPosition","newTargetPanel","setCurrentPanel","isTrusted","updateAdaptiveSize","updateCameraPosition","updateAxesPosition","IdleState","nextStateType","currentState","HoldingState","DraggingState","AnimatingState","DisabledState","onExit","onEnter","onHold","onRelease","onAnimationEnd","onFinish","_super","ctx","snapCount","eventDelta","minimumDistanceToChange","calcBrinkOfChange","nearestIsCurrent","shouldMoveWhenBounceIs0","canSetBoundMode","shouldMoveToAdjacent","isOutOfBound","findSnappedPanel","findAdjacentPanel","halfGap","estimatedHangerPos","panelToMove","cycleIndex","passedPanelCount","originalPanel","getOriginalPanel","panelPosition","siblingPanel","panelIndex","siblingIndex","originalPosition","defaultDuration","getCurrentIndex","get","hangerPosition","firstClonedPanel","basePanel","basePosition","adjacentPanel","targetRelativeAnchorPosition","estimatedPosition","findRestorePanelInCircularMode","lapped","findNearestPanelAt","stateMachine","getState","currentPanelPosition","lastHangerPosition","Snap","panelMaintainRatio","relativeHangerPosition","positionOffset","translate","checkedIndexes","isAdaptiveCached","isViewportGiven","isCameraGiven","originalViewportStyle","originalCameraStyle","StateMachine","visiblePanels","panelBboxes","build","eventResult","axes","findNearestPanel","originalNearestPosition","checkNeedPanel","updateVisiblePanels","posOffset","moveCoord","coord","round","join","viewportElement","updateSize","updateOriginalPanelPositions","updateScrollArea","updateClonePanels","updateVisiblePanelPositions","updatePlugins","minimumDistance","prevPosition","nextPosition","distance","nearest","shortestDistance","identical","anchorPosition","getVisibleIndexOf","panInput","createPanInput","setAxesInstance","resizePanels","newCenterPanel","newPanelPosition","updateCheckedIndexes","indexes","visibleIndex","newCurrentIndex","getRange","undefined","viewportStyle","sizeToApply","viewportSize","shouldApplyAdaptive","panelBbox","maximum","viewportBbox","updateBbox","isFreeScroll","is","holding","playing","positionBounded","plugins","plugin","update","topmostElement_1","deletingElement","wrapper","removePlugins","status","html","refreshPanels","createdPanels","orderedPanels","createdPanel","replacePanels","setCloneCount","cameraPos_1","viewportSize_1","getNext","isOutOfViewport","getAbsIndex_1","__spreadArrays","sort","panel1","panel2","outsetProgress","getOutsetProgress","NaN","prevRange","nextRange","nearestAnchorPos","nearestIndex","nearestSize","hangerIsNextToNearestPanel","targetPosition","progressBetween","off","on","axesHandlers","setLastIndex","handlers","newPlugins","init","currentPlugins","changedRange","removed","prevVisiblePanels","equalSizeClasses_1","cached_1","fragment","overlappedClass","getOverlappedClass","clonePanels","updateClonedPanelPositions","chainAllPanels","visiblePanel","setElements","applyCSSValue","setMoveType","setDefaultPanel","moveToDefaultPanel","viewportCandidate","hasViewportElement","cameraCandidate","hasCameraElement","child","minHeight","minWidth","PanelManager","FreeScroll","Axes","easing","interruptable","indexRange","panelAtLeftBoundary","reversedPanels","sumOriginalPanelSize","areaPrev","sizeSum","reversedPanels_1","panelAtRightBoundary","areaNext","panels_1","needCloneOnPrev","ceil","prevCloneCount","origPanel","removeClonesAfter","defaultPanel","defaultPosition","accumulatedSize","nextPanelPos","maintainingPanel","total","setPositionCSS","clonedPanels_1","clonedPanelPos","lastReplacePosition","_b","replacePosition","relAnchorPosOfCombined","anchorPos","parsedBounce","arr","constructor","parsedVal","axis","maxLastIndex","checkingPanel","nextIndex","currentNearestPosition","triggerNeedPanel","firstIndex","lastPanelAfterNeed","cameraPrev","checkingIndex","prevIndex","firstPanelAfterNeed","params","alreadyTriggered","some","hasHandler","hasOn","fill","insertAfter","newVisiblePanels","calcVisiblePanels","checkVisiblePanelChange","addedPanels","firstVisiblePanelPos","panelElement","firstVisiblePanel","lastVisiblePanel","newVisibleRange","getAbsIndex","trigger","prevRefCount","newRefCount","newPanel","newIndex","added","equalSizeClasses_2","defaultBbox_1","default","PanInput","scale","releaseOnScroll","connect","isFirstResize","onResize","enabled","resizeObserver","flickingEl","disable","ResizeObserver","clientWidth","clientHeight","skipFirstResize","observe","addEventListener","disconnect","removeEventListener","shouldResetElements","parent","origStyle","appendUncachedPanelElements","eventName","progress","canceled","looped","currentDirection","previousPosition","inputOffset","cameraChange","querySelector","nodeName","nodeType","currentOptions","Viewport","autoResizer","AutoResizer","listenInput","listenResize","focus","nearestPosition","current","identicals","includeClone","enable","outerHTML","restore","addPlugins","contentsReadyChecker","prependedPanels","checkContentsReady","appendedPanels","diffResult","maintained","values","before","list","renderingPanels","setVisiblePanels","diffInfo","changed","prevClonedPanels","prevOriginalPanels","beforeIdx","afterIdx","addIndex","groupIndex","prevCloneGroup","newCloneGroup","getCheckedIndexes","has","currentPanelIndex","currentPanelIsRemoved","isPanelChangedAtBeforeSync","prevOriginalPanelCount_1","originalPanelCount_1","beforeDiffInfo","originalAdded","originalRemoved","beforeSync","addedIndex","addedElement","beforePanel","eventContext","fire","connectAxesHandler","ImReady","hasLoading","isPreReadyOver","check","Flicking","Component","withFlickingMethods","prototype","flickingName","args","result"],"mappings":"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"}
1
+ {"version":3,"file":"flicking.pkgd.min.js","sources":["../src/consts.ts","../src/utils.ts","../src/components/Panel.ts","../src/components/PanelManager.ts","../src/states/State.ts","../src/states/IdleState.ts","../src/states/HoldingState.ts","../src/states/DraggingState.ts","../src/states/AnimatingState.ts","../src/states/DisabledState.ts","../src/components/StateMachine.ts","../src/moves/Snap.ts","../src/moves/MoveType.ts","../src/moves/FreeScroll.ts","../src/components/Viewport.ts","../src/components/AutoResizer.ts","../src/Flicking.ts","../src/index.umd.ts"],"sourcesContent":["/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { FlickingOptions, EventType, Direction, AxesEventType, StateType, MoveTypeSnapOption, MoveTypeFreeScrollOption, FlickingMethodsKeys } from \"./types\";\n\nexport const MOVE_TYPE: {\n SNAP: \"snap\";\n FREE_SCROLL: \"freeScroll\";\n} = {\n SNAP: \"snap\",\n FREE_SCROLL: \"freeScroll\",\n};\n\nexport const DEFAULT_MOVE_TYPE_OPTIONS: {\n snap: MoveTypeSnapOption,\n freeScroll: MoveTypeFreeScrollOption,\n} = {\n snap: {\n type: \"snap\",\n count: 1,\n },\n freeScroll: {\n type: \"freeScroll\",\n },\n};\nexport const isBrowser = typeof document !== \"undefined\";\n\n/**\n * Default options for creating Flicking.\n * @ko 플리킹을 만들 때 사용하는 기본 옵션들\n * @private\n * @memberof eg.Flicking\n */\nexport const DEFAULT_OPTIONS: Readonly<FlickingOptions> = {\n classPrefix: \"eg-flick\",\n deceleration: 0.0075,\n horizontal: true,\n circular: false,\n infinite: false,\n infiniteThreshold: 0,\n lastIndex: Infinity,\n threshold: 40,\n duration: 100,\n panelEffect: x => 1 - Math.pow(1 - x, 3),\n defaultIndex: 0,\n inputType: [\"touch\", \"mouse\"],\n thresholdAngle: 45,\n bounce: 10,\n autoResize: false,\n adaptive: false,\n zIndex: 2000,\n bound: false,\n overflow: false,\n hanger: \"50%\",\n anchor: \"50%\",\n gap: 0,\n moveType: DEFAULT_MOVE_TYPE_OPTIONS.snap,\n useOffset: false,\n isEqualSize: false,\n isConstantSize: false,\n renderOnlyVisible: false,\n renderExternal: false,\n resizeOnContentsReady: false,\n iOSEdgeSwipeThreshold: 30,\n collectStatistics: true,\n useResizeObserver: true,\n};\n\nexport const DEFAULT_VIEWPORT_CSS = {\n position: \"relative\",\n zIndex: DEFAULT_OPTIONS.zIndex,\n overflow: \"hidden\",\n};\n\nexport const DEFAULT_CAMERA_CSS = {\n width: \"100%\",\n height: \"100%\",\n willChange: \"transform\",\n};\n\nexport const DEFAULT_PANEL_CSS = {\n position: \"absolute\",\n};\n\nexport const EVENTS: EventType = {\n HOLD_START: \"holdStart\",\n HOLD_END: \"holdEnd\",\n MOVE_START: \"moveStart\",\n MOVE: \"move\",\n MOVE_END: \"moveEnd\",\n CHANGE: \"change\",\n RESTORE: \"restore\",\n SELECT: \"select\",\n NEED_PANEL: \"needPanel\",\n VISIBLE_CHANGE: \"visibleChange\",\n CONTENT_ERROR: \"contentError\",\n};\n\nexport const AXES_EVENTS: AxesEventType = {\n HOLD: \"hold\",\n CHANGE: \"change\",\n RELEASE: \"release\",\n ANIMATION_END: \"animationEnd\",\n FINISH: \"finish\",\n};\n\nexport const STATE_TYPE: StateType = {\n IDLE: 0,\n HOLDING: 1,\n DRAGGING: 2,\n ANIMATING: 3,\n DISABLED: 4,\n};\n\nexport const DIRECTION: Direction = {\n PREV: \"PREV\",\n NEXT: \"NEXT\",\n};\nexport const FLICKING_METHODS: {[key in FlickingMethodsKeys]: true} = {\n prev: true,\n next: true,\n moveTo: true,\n getIndex: true,\n getAllPanels: true,\n getCurrentPanel: true,\n getElement: true,\n getSize: true,\n getPanel: true,\n getPanelCount: true,\n getStatus: true,\n getVisiblePanels: true,\n enableInput: true,\n disableInput: true,\n destroy: true,\n resize: true,\n setStatus: true,\n isPlaying: true,\n};\n\n// Check whether browser supports transform: translate3d\n// https://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support\nexport let checkTranslateSupport = () => {\n const transforms = {\n webkitTransform: \"-webkit-transform\",\n msTransform: \"-ms-transform\",\n MozTransform: \"-moz-transform\",\n OTransform: \"-o-transform\",\n transform: \"transform\",\n };\n\n if (!isBrowser) {\n return {\n name: transforms.transform,\n has3d: true,\n };\n }\n const supportedStyle = document.documentElement.style;\n let transformName = \"\";\n for (const prefixedTransform in transforms) {\n if (prefixedTransform in supportedStyle) {\n transformName = prefixedTransform;\n }\n }\n\n if (!transformName) {\n throw new Error(\"Browser doesn't support CSS3 2D Transforms.\");\n }\n\n const el = document.createElement(\"div\");\n\n document.documentElement.insertBefore(el, null);\n\n el.style[transformName] = \"translate3d(1px, 1px, 1px)\";\n const styleVal = window.getComputedStyle(el).getPropertyValue(transforms[transformName]);\n\n el.parentElement!.removeChild(el);\n\n const transformInfo = {\n name: transformName,\n has3d: styleVal.length > 0 && styleVal !== \"none\",\n };\n\n checkTranslateSupport = () => transformInfo;\n\n return transformInfo;\n};\n\nexport const TRANSFORM = checkTranslateSupport();\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { ElementLike, OriginalStyle, BoundingBox } from \"./types\";\nimport Flicking from \"./Flicking\";\nimport { FLICKING_METHODS } from \"./consts\";\n\nexport function merge(target: object, ...srcs: object[]): object {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n target[key] = value;\n });\n });\n\n return target;\n}\n\nexport function parseElement(element: ElementLike | ElementLike[]): HTMLElement[] {\n if (!Array.isArray(element)) {\n element = [element];\n }\n\n const elements: HTMLElement[] = [];\n element.forEach(el => {\n if (isString(el)) {\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = el;\n\n elements.push(...toArray(tempDiv.children) as HTMLElement[]);\n while (tempDiv.firstChild) {\n tempDiv.removeChild(tempDiv.firstChild);\n }\n } else {\n elements.push(el as HTMLElement);\n }\n });\n\n return elements;\n}\n\nexport function isString(value: any): value is string {\n return typeof value === \"string\";\n}\n\n// Get class list of element as string array\nexport function classList(element: HTMLElement): string[] {\n return element.classList\n ? toArray(element.classList)\n : element.className.split(\" \");\n}\n\n// Add class to specified element\nexport function addClass(element: HTMLElement, className: string): void {\n if (element.classList) {\n element.classList.add(className);\n } else {\n if (!hasClass(element, className)) {\n element.className = (`${element.className} ${className}`).replace(/\\s{2,}/g, \" \");\n }\n }\n}\n\nexport function hasClass(element: HTMLElement, className: string): boolean {\n if (element.classList) {\n return element.classList.contains(className);\n } else {\n return (element.className.split(\" \").indexOf(className) >= 0);\n }\n}\n\nexport function applyCSS(element: HTMLElement, cssObj: object): void {\n Object.keys(cssObj).forEach(property => {\n element.style[property] = cssObj[property];\n });\n}\n\nexport function clamp(val: number, min: number, max: number) {\n return Math.max(Math.min(val, max), min);\n}\n\n// Min: inclusive, Max: exclusive\nexport function isBetween(val: number, min: number, max: number) {\n return val >= min && val <= max;\n}\n\nexport interface ArrayLike<T> {\n length: number;\n [index: number]: T;\n}\n\nexport function toArray<T>(iterable: ArrayLike<T>): T[] {\n return [].slice.call(iterable);\n}\n\nexport function isArray(arr: any): boolean {\n return arr && arr.constructor === Array;\n}\n\nexport function parseArithmeticExpression(cssValue: number | string, base: number, defaultVal?: number): number {\n // Set base / 2 to default value, if it's undefined\n const defaultValue = defaultVal != null ? defaultVal : base / 2;\n const cssRegex = /(?:(\\+|\\-)\\s*)?(\\d+(?:\\.\\d+)?(%|px)?)/g;\n\n if (typeof cssValue === \"number\") {\n return clamp(cssValue, 0, base);\n }\n\n let idx = 0;\n let calculatedValue = 0;\n let matchResult = cssRegex.exec(cssValue);\n while (matchResult != null) {\n let sign = matchResult[1];\n const value = matchResult[2];\n const unit = matchResult[3];\n\n let parsedValue = parseFloat(value);\n\n if (idx <= 0) {\n sign = sign || \"+\";\n }\n\n // Return default value for values not in good form\n if (!sign) {\n return defaultValue;\n }\n\n if (unit === \"%\") {\n parsedValue = (parsedValue / 100) * base;\n }\n\n calculatedValue += sign === \"+\"\n ? parsedValue\n : -parsedValue;\n\n // Match next occurrence\n ++idx;\n matchResult = cssRegex.exec(cssValue);\n }\n\n // None-matched\n if (idx === 0) {\n return defaultValue;\n }\n\n // Clamp between 0 ~ base\n return clamp(calculatedValue, 0, base);\n}\n\nexport function getProgress(pos: number, range: number[]) {\n // start, anchor, end\n // -1 , 0 , 1\n const [min, center, max] = range;\n\n if (pos > center && (max - center)) {\n // 0 ~ 1\n return (pos - center) / (max - center);\n } else if (pos < center && (center - min)) {\n // -1 ~ 0\n return (pos - center) / (center - min);\n } else if (pos !== center && max - min) {\n return (pos - min) / (max - min);\n }\n return 0;\n}\n\nexport function findIndex<T>(iterable: T[], callback: (el: T) => boolean): number {\n for (let i = 0; i < iterable.length; i += 1) {\n const element = iterable[i];\n if (element != null && callback(element)) {\n return i;\n }\n }\n\n return -1;\n}\n\n// return [0, 1, ...., max - 1]\nexport function counter(max: number): number[] {\n const counterArray: number[] = [];\n for (let i = 0; i < max; i += 1) {\n counterArray[i] = i;\n }\n return counterArray;\n}\n\n// Circulate number between range [min, max]\n/*\n * \"indexed\" means min and max is not same, so if it's true \"min - 1\" should be max\n * While if it's false, \"min - 1\" should be \"max - 1\"\n * use `indexed: true` when it should be used for circulating integers like index\n * or `indexed: false` when it should be used for something like positions.\n */\nexport function circulate(value: number, min: number, max: number, indexed: boolean): number {\n const size = indexed\n ? max - min + 1\n : max - min;\n if (value < min) {\n const offset = indexed\n ? (min - value - 1) % size\n : (min - value) % size;\n value = max - offset;\n } else if (value > max) {\n const offset = indexed\n ? (value - max - 1) % size\n : (value - max) % size;\n value = min + offset;\n }\n\n return value;\n}\n\nexport function restoreStyle(element: HTMLElement, originalStyle: OriginalStyle): void {\n originalStyle.className\n ? element.setAttribute(\"class\", originalStyle.className)\n : element.removeAttribute(\"class\");\n originalStyle.style\n ? element.setAttribute(\"style\", originalStyle.style)\n : element.removeAttribute(\"style\");\n}\n\n/**\n * Decorator that makes the method of flicking available in the framework.\n * @ko 프레임워크에서 플리킹의 메소드를 사용할 수 있게 하는 데코레이터.\n * @memberof eg.Flicking\n * @private\n * @example\n * ```js\n * import Flicking, { withFlickingMethods } from \"@egjs/flicking\";\n *\n * class Flicking extends React.Component<Partial<FlickingProps & FlickingOptions>> {\n * &#64;withFlickingMethods\n * private flicking: Flicking;\n * }\n * ```\n */\nexport function withFlickingMethods(prototype: any, flickingName: string) {\n Object.keys(FLICKING_METHODS).forEach((name: keyof Flicking) => {\n if (prototype[name]) {\n return;\n }\n prototype[name] = function(...args) {\n const result = this[flickingName][name](...args);\n\n // fix `this` type to return your own `flicking` instance to the instance using the decorator.\n if (result === this[flickingName]) {\n return this;\n } else {\n return result;\n }\n };\n });\n}\n\nexport function getBbox(element: HTMLElement, useOffset: boolean) {\n let bbox: BoundingBox;\n if (useOffset) {\n bbox = {\n x: 0,\n y: 0,\n width: element.offsetWidth,\n height: element.offsetHeight,\n };\n } else {\n const clientRect = element.getBoundingClientRect();\n bbox = {\n x: clientRect.left,\n y: clientRect.top,\n width: clientRect.width,\n height: clientRect.height,\n };\n }\n return bbox;\n}\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Viewport from \"./Viewport\";\nimport { OriginalStyle, FlickingPanel, ElementLike, DestroyOption, BoundingBox } from \"../types\";\nimport { DEFAULT_PANEL_CSS, EVENTS } from \"../consts\";\nimport { addClass, applyCSS, parseArithmeticExpression, parseElement, getProgress, restoreStyle, hasClass, getBbox } from \"../utils\";\n\nclass Panel implements FlickingPanel {\n public viewport: Viewport;\n public prevSibling: Panel | null;\n public nextSibling: Panel | null;\n\n protected state: {\n index: number;\n position: number;\n relativeAnchorPosition: number;\n size: number;\n isClone: boolean;\n isVirtual: boolean;\n // Index of cloned panel, zero-based integer(original: -1, cloned: [0, 1, 2, ...])\n // if cloneIndex is 0, that means it's first cloned panel of original panel\n cloneIndex: number;\n originalStyle: OriginalStyle;\n cachedBbox: BoundingBox | null;\n };\n private element: HTMLElement;\n private original?: Panel;\n private clonedPanels: Panel[];\n\n public constructor(\n element?: HTMLElement | null,\n index?: number,\n viewport?: Viewport,\n ) {\n this.viewport = viewport!;\n this.prevSibling = null;\n this.nextSibling = null;\n this.clonedPanels = [];\n\n this.state = {\n index: index!,\n position: 0,\n relativeAnchorPosition: 0,\n size: 0,\n isClone: false,\n isVirtual: false,\n cloneIndex: -1,\n originalStyle: {\n className: \"\",\n style: \"\",\n },\n cachedBbox: null,\n };\n this.setElement(element);\n }\n\n public resize(givenBbox?: BoundingBox): void {\n const state = this.state;\n const options = this.viewport.options;\n const bbox = givenBbox\n ? givenBbox\n : this.getBbox();\n this.state.cachedBbox = bbox;\n const prevSize = state.size;\n\n state.size = options.horizontal\n ? bbox.width\n : bbox.height;\n\n if (prevSize !== state.size) {\n state.relativeAnchorPosition = parseArithmeticExpression(options.anchor, state.size);\n }\n\n if (!state.isClone) {\n this.clonedPanels.forEach(panel => {\n const cloneState = panel.state;\n\n cloneState.size = state.size;\n cloneState.cachedBbox = state.cachedBbox;\n cloneState.relativeAnchorPosition = state.relativeAnchorPosition;\n });\n }\n }\n\n public unCacheBbox(): void {\n this.state.cachedBbox = null;\n }\n\n public getProgress() {\n const viewport = this.viewport;\n const options = viewport.options;\n const panelCount = viewport.panelManager.getPanelCount();\n const scrollAreaSize = viewport.getScrollAreaSize();\n\n const relativeIndex = (options.circular ? Math.floor(this.getPosition() / scrollAreaSize) * panelCount : 0) + this.getIndex();\n const progress = relativeIndex - viewport.getCurrentProgress();\n\n return progress;\n }\n\n public getOutsetProgress() {\n const viewport = this.viewport;\n const outsetRange = [\n -this.getSize(),\n viewport.getRelativeHangerPosition() - this.getRelativeAnchorPosition(),\n viewport.getSize(),\n ];\n const relativePanelPosition = this.getPosition() - viewport.getCameraPosition();\n const outsetProgress = getProgress(relativePanelPosition, outsetRange);\n\n return outsetProgress;\n }\n\n public getVisibleRatio() {\n const viewport = this.viewport;\n const panelSize = this.getSize();\n const relativePanelPosition = this.getPosition() - viewport.getCameraPosition();\n const rightRelativePanelPosition = relativePanelPosition + panelSize;\n\n const visibleSize = Math.min(viewport.getSize(), rightRelativePanelPosition) - Math.max(relativePanelPosition, 0);\n const visibleRatio = visibleSize >= 0\n ? visibleSize / panelSize\n : 0;\n\n return visibleRatio;\n }\n\n public focus(duration?: number): void {\n const viewport = this.viewport;\n const currentPanel = viewport.getCurrentPanel();\n const hangerPosition = viewport.getHangerPosition();\n const anchorPosition = this.getAnchorPosition();\n if (hangerPosition === anchorPosition || !currentPanel) {\n return;\n }\n\n const currentPosition = currentPanel.getPosition();\n const eventType = currentPosition === this.getPosition()\n ? \"\"\n : EVENTS.CHANGE;\n\n viewport.moveTo(this, viewport.findEstimatedPosition(this), eventType, null, duration);\n }\n\n public update(updateFunction: ((element: HTMLElement) => any) | null = null, shouldResize: boolean = true): void {\n const identicalPanels = this.getIdenticalPanels();\n\n if (updateFunction) {\n identicalPanels.forEach(eachPanel => {\n updateFunction(eachPanel.getElement());\n });\n }\n\n if (shouldResize) {\n identicalPanels.forEach(eachPanel => {\n eachPanel.unCacheBbox();\n });\n this.viewport.addVisiblePanel(this);\n this.viewport.resize();\n }\n }\n\n public prev(): FlickingPanel | null {\n const viewport = this.viewport;\n const options = viewport.options;\n const prevSibling = this.prevSibling;\n\n if (!prevSibling) {\n return null;\n }\n\n const currentIndex = this.getIndex();\n const currentPosition = this.getPosition();\n const prevPanelIndex = prevSibling.getIndex();\n const prevPanelPosition = prevSibling.getPosition();\n const prevPanelSize = prevSibling.getSize();\n\n const hasEmptyPanelBetween = currentIndex - prevPanelIndex > 1;\n const notYetMinPanel = options.infinite\n && currentIndex > 0\n && prevPanelIndex > currentIndex;\n\n if (hasEmptyPanelBetween || notYetMinPanel) {\n // Empty panel exists between\n return null;\n }\n\n const newPosition = currentPosition - prevPanelSize - options.gap;\n\n let prevPanel = prevSibling;\n if (prevPanelPosition !== newPosition) {\n prevPanel = prevSibling.clone(prevSibling.getCloneIndex(), true);\n prevPanel.setPosition(newPosition);\n }\n\n return prevPanel;\n }\n\n public next(): FlickingPanel | null {\n const viewport = this.viewport;\n const options = viewport.options;\n const nextSibling = this.nextSibling;\n const lastIndex = viewport.panelManager.getLastIndex();\n\n if (!nextSibling) {\n return null;\n }\n\n const currentIndex = this.getIndex();\n const currentPosition = this.getPosition();\n const nextPanelIndex = nextSibling.getIndex();\n const nextPanelPosition = nextSibling.getPosition();\n\n const hasEmptyPanelBetween = nextPanelIndex - currentIndex > 1;\n const notYetMaxPanel = options.infinite\n && currentIndex < lastIndex\n && nextPanelIndex < currentIndex;\n\n if (hasEmptyPanelBetween || notYetMaxPanel) {\n return null;\n }\n\n const newPosition = currentPosition + this.getSize() + options.gap;\n\n let nextPanel = nextSibling;\n if (nextPanelPosition !== newPosition) {\n nextPanel = nextSibling.clone(nextSibling.getCloneIndex(), true);\n nextPanel.setPosition(newPosition);\n }\n\n return nextPanel;\n }\n\n public insertBefore(element: ElementLike | ElementLike[]): FlickingPanel[] {\n const viewport = this.viewport;\n const parsedElements = parseElement(element);\n const firstPanel = viewport.panelManager.firstPanel()!;\n const prevSibling = this.prevSibling;\n // Finding correct inserting index\n // While it should insert removing empty spaces,\n // It also should have to be bigger than prevSibling' s index\n const targetIndex = prevSibling && firstPanel.getIndex() !== this.getIndex()\n ? Math.max(prevSibling.getIndex() + 1, this.getIndex() - parsedElements.length)\n : Math.max(this.getIndex() - parsedElements.length, 0);\n\n return viewport.insert(targetIndex, parsedElements);\n }\n\n public insertAfter(element: ElementLike | ElementLike[]): FlickingPanel[] {\n return this.viewport.insert(this.getIndex() + 1, element);\n }\n\n public remove(): FlickingPanel {\n this.viewport.remove(this.getIndex());\n\n return this;\n }\n\n public destroy(option: Partial<DestroyOption>): void {\n if (!option.preserveUI) {\n const originalStyle = this.state.originalStyle;\n\n restoreStyle(this.element, originalStyle);\n }\n\n // release resources\n for (const x in this) {\n (this as any)[x] = null;\n }\n }\n\n public getElement(): HTMLElement {\n return this.element;\n }\n\n public getAnchorPosition(): number {\n return this.state.position + this.state.relativeAnchorPosition;\n }\n\n public getRelativeAnchorPosition(): number {\n return this.state.relativeAnchorPosition;\n }\n\n public getIndex(): number {\n return this.state.index;\n }\n\n public getPosition(): number {\n return this.state.position;\n }\n\n public getSize(): number {\n return this.state.size;\n }\n\n public getBbox(): BoundingBox {\n const state = this.state;\n const viewport = this.viewport;\n const element = this.element;\n const options = viewport.options;\n\n if (!element) {\n state.cachedBbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n } else if (!state.cachedBbox) {\n const wasVisible = Boolean(element.parentNode);\n const cameraElement = viewport.getCameraElement();\n if (!wasVisible) {\n cameraElement.appendChild(element);\n viewport.addVisiblePanel(this);\n }\n state.cachedBbox = getBbox(element, options.useOffset);\n\n if (!wasVisible && viewport.options.renderExternal) {\n cameraElement.removeChild(element);\n }\n }\n return state.cachedBbox!;\n }\n\n public isClone(): boolean {\n return this.state.isClone;\n }\n\n public getOverlappedClass(classes: string[]): string | undefined {\n const element = this.element;\n\n for (const className of classes) {\n if (hasClass(element, className)) {\n return className;\n }\n }\n }\n\n public getCloneIndex(): number {\n return this.state.cloneIndex;\n }\n\n public getClonedPanels(): Panel[] {\n const state = this.state;\n\n return state.isClone\n ? this.original!.getClonedPanels()\n : this.clonedPanels;\n }\n\n public getIdenticalPanels(): Panel[] {\n const state = this.state;\n\n return state.isClone\n ? this.original!.getIdenticalPanels()\n : [this, ...this.clonedPanels];\n }\n\n public getOriginalPanel(): Panel {\n return this.state.isClone\n ? this.original!\n : this;\n }\n\n public setIndex(index: number): void {\n const state = this.state;\n\n state.index = index;\n this.clonedPanels.forEach(panel => panel.state.index = index);\n }\n\n public setPosition(pos: number): this {\n this.state.position = pos;\n\n return this;\n }\n\n public setPositionCSS(offset: number = 0): void {\n if (!this.element) {\n return;\n }\n const state = this.state;\n const pos = state.position;\n const options = this.viewport.options;\n const elementStyle = this.element.style;\n const currentElementStyle = options.horizontal\n ? elementStyle.left\n : elementStyle.top;\n const styleToApply = `${pos - offset}px`;\n\n if (!state.isVirtual && currentElementStyle !== styleToApply) {\n options.horizontal\n ? elementStyle.left = styleToApply\n : elementStyle.top = styleToApply;\n }\n }\n\n public clone(cloneIndex: number, isVirtual: boolean = false, element?: HTMLElement | null): Panel {\n const state = this.state;\n const viewport = this.viewport;\n let cloneElement = element;\n\n if (!cloneElement && this.element) {\n cloneElement = isVirtual ? this.element : this.element.cloneNode(true) as HTMLElement;\n }\n const clonedPanel = new Panel(cloneElement, state.index, viewport);\n const clonedState = clonedPanel.state;\n\n clonedPanel.original = state.isClone\n ? this.original\n : this;\n clonedState.isClone = true;\n clonedState.isVirtual = isVirtual;\n clonedState.cloneIndex = cloneIndex;\n // Inherit some state values\n clonedState.size = state.size;\n clonedState.relativeAnchorPosition = state.relativeAnchorPosition;\n clonedState.originalStyle = state.originalStyle;\n clonedState.cachedBbox = state.cachedBbox;\n\n if (!isVirtual) {\n this.clonedPanels.push(clonedPanel);\n } else {\n clonedPanel.prevSibling = this.prevSibling;\n clonedPanel.nextSibling = this.nextSibling;\n }\n\n return clonedPanel;\n }\n\n public removeElement(): void {\n if (!this.viewport.options.renderExternal) {\n const element = this.element;\n element.parentNode && element.parentNode.removeChild(element);\n }\n\n // Do the same thing for clones\n if (!this.state.isClone) {\n this.removeClonedPanelsAfter(0);\n }\n }\n\n public removeClonedPanelsAfter(start: number): void {\n const options = this.viewport.options;\n const removingPanels = this.clonedPanels.splice(start);\n\n if (!options.renderExternal) {\n removingPanels.forEach(panel => {\n panel.removeElement();\n });\n }\n }\n\n public setElement(element?: HTMLElement | null): void {\n if (!element) {\n return;\n }\n const currentElement = this.element;\n if (element !== currentElement) {\n const options = this.viewport.options;\n\n if (currentElement) {\n if (options.horizontal) {\n element.style.left = currentElement.style.left;\n } else {\n element.style.top = currentElement.style.top;\n }\n } else {\n const originalStyle = this.state.originalStyle;\n\n originalStyle.className = element.getAttribute(\"class\");\n originalStyle.style = element.getAttribute(\"style\");\n }\n\n this.element = element;\n\n if (options.classPrefix) {\n addClass(element, `${options.classPrefix}-panel`);\n }\n\n // Update size info after applying panel css\n applyCSS(this.element, DEFAULT_PANEL_CSS);\n }\n }\n}\n\nexport default Panel;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Panel from \"./Panel\";\nimport { FlickingOptions } from \"../types\";\nimport { findIndex, counter } from \"../utils\";\n\nclass PanelManager {\n private cameraElement: HTMLElement;\n private options: FlickingOptions;\n private panels: Panel[];\n private clones: Panel[][];\n // index range of existing panels\n private range: {\n min: number;\n max: number;\n };\n private length: number;\n private lastIndex: number;\n private cloneCount: number;\n\n constructor(\n cameraElement: HTMLElement,\n options: FlickingOptions,\n ) {\n this.cameraElement = cameraElement;\n this.panels = [];\n this.clones = [];\n this.range = {\n min: -1,\n max: -1,\n };\n this.length = 0;\n this.cloneCount = 0;\n this.options = options;\n this.lastIndex = options.lastIndex;\n }\n\n public firstPanel(): Panel | undefined {\n return this.panels[this.range.min];\n }\n\n public lastPanel(): Panel | undefined {\n return this.panels[this.range.max];\n }\n\n public allPanels(): ReadonlyArray<Panel> {\n return [\n ...this.panels,\n ...this.clones.reduce((allClones, clones) => [...allClones, ...clones], []),\n ];\n }\n\n public originalPanels(): ReadonlyArray<Panel> {\n return this.panels;\n }\n\n public clonedPanels(): ReadonlyArray<Panel[]> {\n return this.clones;\n }\n\n public replacePanels(newPanels: Panel[], newClones: Panel[][]): void {\n this.panels = newPanels;\n this.clones = newClones;\n\n this.range = {\n min: findIndex(newPanels, panel => Boolean(panel)),\n max: newPanels.length - 1,\n };\n this.length = newPanels.filter(panel => Boolean(panel)).length;\n }\n\n public has(index: number): boolean {\n return !!this.panels[index];\n }\n\n public get(index: number): Panel | undefined {\n return this.panels[index];\n }\n\n public getPanelCount(): number {\n return this.length;\n }\n\n public getLastIndex(): number {\n return this.lastIndex;\n }\n\n public getRange(): Readonly<{ min: number, max: number }> {\n return this.range;\n }\n\n public getCloneCount(): number {\n return this.cloneCount;\n }\n\n public setLastIndex(lastIndex: number): void {\n this.lastIndex = lastIndex;\n\n const firstPanel = this.firstPanel();\n const lastPanel = this.lastPanel();\n\n if (!firstPanel || !lastPanel) {\n return; // no meaning of updating range & length\n }\n\n // Remove panels above new last index\n const range = this.range;\n if (lastPanel.getIndex() > lastIndex) {\n const removingPanels = this.panels.splice(lastIndex + 1);\n this.length -= removingPanels.length;\n\n const firstRemovedPanel = removingPanels.filter(panel => !!panel)[0];\n const possibleLastPanel = firstRemovedPanel.prevSibling;\n if (possibleLastPanel) {\n range.max = possibleLastPanel.getIndex();\n } else {\n range.min = -1;\n range.max = -1;\n }\n\n if (this.shouldRender()) {\n removingPanels.forEach(panel => panel.removeElement());\n }\n }\n }\n\n public setCloneCount(cloneCount: number): void {\n this.cloneCount = cloneCount;\n }\n\n // Insert at index\n // Returns pushed elements from index, inserting at 'empty' position doesn't push elements behind it\n public insert(index: number, newPanels: Panel[]): number {\n const panels = this.panels;\n const range = this.range;\n const isCircular = this.options.circular;\n const lastIndex = this.lastIndex;\n\n // Find first panel that index is greater than inserting index\n const nextSibling = this.findFirstPanelFrom(index);\n\n // if it's null, element will be inserted at last position\n // https://developer.mozilla.org/ko/docs/Web/API/Node/insertBefore#Syntax\n const firstPanel = this.firstPanel();\n const siblingElement = nextSibling\n ? nextSibling.getElement()\n : isCircular && firstPanel\n ? firstPanel.getClonedPanels()[0].getElement()\n : null;\n\n // Insert panels before sibling element\n this.insertNewPanels(newPanels, siblingElement);\n\n let pushedIndex = newPanels.length;\n // Like when setting index 50 while visible panels are 0, 1, 2\n if (index > range.max) {\n newPanels.forEach((panel, offset) => {\n panels[index + offset] = panel;\n });\n } else {\n const panelsAfterIndex = panels.slice(index, index + newPanels.length);\n // Find empty from beginning\n let emptyPanelCount = findIndex(panelsAfterIndex, panel => !!panel);\n if (emptyPanelCount < 0) {\n // All empty\n emptyPanelCount = panelsAfterIndex.length;\n }\n pushedIndex = newPanels.length - emptyPanelCount;\n\n // Insert removing empty panels\n panels.splice(index, emptyPanelCount, ...newPanels);\n\n // Remove panels after last index\n if (panels.length > lastIndex + 1) {\n const removedPanels = panels.splice(lastIndex + 1)\n .filter(panel => Boolean(panel));\n this.length -= removedPanels.length;\n\n // Find first\n const newLastIndex = lastIndex - findIndex(this.panels.concat().reverse(), panel => !!panel);\n\n // Can be filled with empty after newLastIndex\n this.panels.splice(newLastIndex + 1);\n this.range.max = newLastIndex;\n\n if (this.shouldRender()) {\n removedPanels.forEach(panel => panel.removeElement());\n }\n }\n }\n\n // Update index of previous panels\n if (pushedIndex > 0) {\n panels.slice(index + newPanels.length).forEach(panel => {\n panel.setIndex(panel.getIndex() + pushedIndex);\n });\n }\n\n // Update state\n this.length += newPanels.length;\n this.updateIndex(index);\n\n if (isCircular) {\n this.addNewClones(index, newPanels, newPanels.length - pushedIndex, nextSibling);\n const clones = this.clones;\n const panelCount = this.panels.length;\n if (clones[0] && clones[0].length > lastIndex + 1) {\n clones.forEach(cloneSet => {\n cloneSet.splice(panelCount);\n });\n }\n }\n\n return pushedIndex;\n }\n\n public replace(index: number, newPanels: Panel[]): Panel[] {\n const panels = this.panels;\n const range = this.range;\n const options = this.options;\n const isCircular = options.circular;\n\n // Find first panel that index is greater than inserting index\n const nextSibling = this.findFirstPanelFrom(index + newPanels.length);\n\n // if it's null, element will be inserted at last position\n // https://developer.mozilla.org/ko/docs/Web/API/Node/insertBefore#Syntax\n const firstPanel = this.firstPanel();\n const siblingElement = nextSibling\n ? nextSibling.getElement()\n : isCircular && firstPanel\n ? firstPanel.getClonedPanels()[0].getElement()\n : null;\n\n // Insert panels before sibling element\n this.insertNewPanels(newPanels, siblingElement);\n\n if (index > range.max) {\n // Temporarily insert null at index to use splice()\n (panels[index] as any) = null;\n }\n const replacedPanels = panels.splice(index, newPanels.length, ...newPanels);\n const wasNonEmptyCount = replacedPanels.filter(panel => Boolean(panel)).length;\n\n // Suppose inserting [1, 2, 3] at 0 position when there were [empty, 1]\n // So length should be increased by 3(inserting panels) - 1(non-empty panels)\n this.length += newPanels.length - wasNonEmptyCount;\n this.updateIndex(index);\n\n if (isCircular) {\n this.addNewClones(index, newPanels, newPanels.length, nextSibling);\n }\n\n if (this.shouldRender()) {\n replacedPanels.forEach(panel => panel && panel.removeElement());\n }\n\n return replacedPanels;\n }\n\n public remove(index: number, deleteCount: number = 1): Panel[] {\n const isCircular = this.options.circular;\n const panels = this.panels;\n const clones = this.clones;\n // Delete count should be equal or larger than 0\n deleteCount = Math.max(deleteCount, 0);\n\n const deletedPanels = panels\n .splice(index, deleteCount)\n .filter(panel => !!panel);\n\n if (this.shouldRender()) {\n deletedPanels.forEach(panel => panel.removeElement());\n }\n\n if (isCircular) {\n clones.forEach(cloneSet => {\n cloneSet.splice(index, deleteCount);\n });\n }\n\n // Update indexes\n panels\n .slice(index)\n .forEach(panel => {\n panel.setIndex(panel.getIndex() - deleteCount);\n });\n\n // Check last panel is empty\n let lastIndex = panels.length - 1;\n if (!panels[lastIndex]) {\n const reversedPanels = panels.concat().reverse();\n const nonEmptyIndexFromLast = findIndex(reversedPanels, panel => !!panel);\n lastIndex = nonEmptyIndexFromLast < 0\n ? -1 // All empty\n : lastIndex - nonEmptyIndexFromLast;\n\n // Remove all empty panels from last\n panels.splice(lastIndex + 1);\n if (isCircular) {\n clones.forEach(cloneSet => {\n cloneSet.splice(lastIndex + 1);\n });\n }\n }\n\n // Update range & length\n this.range = {\n min: findIndex(panels, panel => !!panel),\n max: lastIndex,\n };\n this.length -= deletedPanels.length;\n\n if (this.length <= 0) {\n // Reset clones\n this.clones = [];\n this.cloneCount = 0;\n }\n\n return deletedPanels;\n }\n\n public chainAllPanels() {\n const allPanels = this.allPanels().filter(panel => !!panel);\n const allPanelsCount = allPanels.length;\n\n if (allPanelsCount <= 1) {\n return;\n }\n\n allPanels.slice(1, allPanels.length - 1).forEach((panel, idx) => {\n const prevPanel = allPanels[idx];\n const nextPanel = allPanels[idx + 2];\n\n panel.prevSibling = prevPanel;\n panel.nextSibling = nextPanel;\n });\n\n const firstPanel = allPanels[0];\n const lastPanel = allPanels[allPanelsCount - 1];\n\n firstPanel.prevSibling = null;\n firstPanel.nextSibling = allPanels[1];\n lastPanel.prevSibling = allPanels[allPanelsCount - 2];\n lastPanel.nextSibling = null;\n\n if (this.options.circular) {\n firstPanel.prevSibling = lastPanel;\n lastPanel.nextSibling = firstPanel;\n }\n }\n\n public insertClones(cloneIndex: number, index: number, clonedPanels: Panel[], deleteCount: number = 0): void {\n const clones = this.clones;\n const lastIndex = this.lastIndex;\n\n if (!clones[cloneIndex]) {\n const newClones: Panel[] = [];\n clonedPanels.forEach((panel, offset) => {\n newClones[index + offset] = panel;\n });\n\n clones[cloneIndex] = newClones;\n } else {\n const insertTarget = clones[cloneIndex];\n\n if (index >= insertTarget.length) {\n clonedPanels.forEach((panel, offset) => {\n insertTarget[index + offset] = panel;\n });\n } else {\n insertTarget.splice(index, deleteCount, ...clonedPanels);\n // Remove panels after last index\n if (clonedPanels.length > lastIndex + 1) {\n clonedPanels.splice(lastIndex + 1);\n }\n }\n }\n }\n\n // clones are operating in set\n public removeClonesAfter(cloneIndex: number): void {\n const panels = this.panels;\n\n panels.forEach(panel => {\n panel.removeClonedPanelsAfter(cloneIndex);\n });\n this.clones.splice(cloneIndex);\n }\n\n public findPanelOf(element: HTMLElement): Panel | undefined {\n const allPanels = this.allPanels();\n for (const panel of allPanels) {\n if (!panel) {\n continue;\n }\n const panelElement = panel.getElement();\n if (panelElement.contains(element)) {\n return panel;\n }\n }\n }\n\n public findFirstPanelFrom(index: number): Panel | undefined {\n for (const panel of this.panels.slice(index)) {\n if (panel && panel.getIndex() >= index && panel.getElement().parentNode) {\n return panel;\n }\n }\n }\n\n private addNewClones(index: number, originalPanels: Panel[], deleteCount: number, nextSibling: Panel | undefined) {\n const cameraElement = this.cameraElement;\n const cloneCount = this.getCloneCount();\n const lastPanel = this.lastPanel();\n const lastPanelClones: Panel[] = lastPanel\n ? lastPanel.getClonedPanels()\n : [];\n const nextSiblingClones: Panel[] = nextSibling\n ? nextSibling.getClonedPanels()\n : [];\n\n for (const cloneIndex of counter(cloneCount)) {\n const cloneNextSibling = nextSiblingClones[cloneIndex];\n const lastPanelSibling = lastPanelClones[cloneIndex];\n\n const cloneSiblingElement = cloneNextSibling\n ? cloneNextSibling.getElement()\n : lastPanelSibling\n ? lastPanelSibling.getElement().nextElementSibling\n : null;\n\n const newClones = originalPanels.map(panel => {\n const clone = panel.clone(cloneIndex);\n\n if (this.shouldRender()) {\n cameraElement.insertBefore(clone.getElement(), cloneSiblingElement);\n }\n\n return clone;\n });\n\n this.insertClones(cloneIndex, index, newClones, deleteCount);\n }\n }\n\n private updateIndex(insertingIndex: number) {\n const panels = this.panels;\n const range = this.range;\n\n const newLastIndex = panels.length - 1;\n if (newLastIndex > range.max) {\n range.max = newLastIndex;\n }\n if (insertingIndex < range.min || range.min < 0) {\n range.min = insertingIndex;\n }\n }\n\n private insertNewPanels(newPanels: Panel[], siblingElement: HTMLElement | null) {\n if (this.shouldRender()) {\n const fragment = document.createDocumentFragment();\n newPanels.forEach(panel => fragment.appendChild(panel.getElement()));\n this.cameraElement.insertBefore(fragment, siblingElement);\n }\n }\n\n private shouldRender(): boolean {\n const options = this.options;\n\n return !options.renderExternal && !options.renderOnlyVisible;\n }\n}\n\nexport default PanelManager;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnAnimationEnd, OnChange, OnFinish, OnHold, OnRelease } from \"@egjs/axes\";\nimport Panel from \"../components/Panel\";\nimport { ValueOf, Direction, StateType, FlickingContext } from \"../types\";\n\nabstract class State {\n public delta: number = 0;\n public direction: ValueOf<Direction> | null = null;\n public targetPanel: Panel | null = null;\n public lastPosition: number = 0;\n public abstract readonly type: ValueOf<StateType>;\n public abstract readonly holding: boolean;\n public abstract readonly playing: boolean;\n\n public onEnter(prevState: State): void {\n this.delta = prevState.delta;\n this.direction = prevState.direction;\n this.targetPanel = prevState.targetPanel;\n this.lastPosition = prevState.lastPosition;\n }\n\n public onExit(nextState: State): void {\n // DO NOTHING\n }\n\n public onHold(e: OnHold, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onChange(e: OnChange, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onRelease(e: OnRelease, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onAnimationEnd(e: OnAnimationEnd, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onFinish(e: OnFinish, context: FlickingContext): void {\n // DO NOTHING\n }\n}\n\nexport default State;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnHold, OnChange } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { EVENTS, STATE_TYPE } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass IdleState extends State {\n public readonly type = STATE_TYPE.IDLE;\n public readonly holding = false;\n public readonly playing = false;\n\n public onEnter() {\n this.direction = null;\n this.targetPanel = null;\n this.delta = 0;\n this.lastPosition = 0;\n }\n\n public onHold(e: OnHold, { flicking, viewport, triggerEvent, transitTo }: FlickingContext): void {\n // Shouldn't do any action until any panels on flicking area\n if (flicking.getPanelCount() <= 0) {\n if (viewport.options.infinite) {\n viewport.moveCamera(viewport.getCameraPosition(), e);\n }\n transitTo(STATE_TYPE.DISABLED);\n return;\n }\n\n this.lastPosition = viewport.getCameraPosition();\n triggerEvent(EVENTS.HOLD_START, e, true)\n .onSuccess(() => {\n transitTo(STATE_TYPE.HOLDING);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n // By methods call\n public onChange(e: OnChange, context: FlickingContext): void {\n const { triggerEvent, transitTo } = context;\n\n triggerEvent(EVENTS.MOVE_START, e, false)\n .onSuccess(() => {\n // Trigger AnimatingState's onChange, to trigger \"move\" event immediately\n transitTo(STATE_TYPE.ANIMATING)\n .onChange(e, context);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n}\n\nexport default IdleState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnChange, OnRelease, OnFinish } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { STATE_TYPE, EVENTS, DIRECTION } from \"../consts\";\nimport { FlickingContext, SelectEvent } from \"../types\";\n\nclass HoldingState extends State {\n public readonly type = STATE_TYPE.HOLDING;\n public readonly holding = true;\n public readonly playing = true;\n\n private releaseEvent: any = null;\n\n public onChange(e: OnChange, context: FlickingContext): void {\n const { flicking, triggerEvent, transitTo } = context;\n\n const offset = flicking.options.horizontal\n ? e.inputEvent.offsetX\n : e.inputEvent.offsetY;\n this.direction = offset < 0\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n triggerEvent(EVENTS.MOVE_START, e, true)\n .onSuccess(() => {\n // Trigger DraggingState's onChange, to trigger \"move\" event immediately\n transitTo(STATE_TYPE.DRAGGING)\n .onChange(e, context);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onRelease(e: OnRelease, context: FlickingContext): void {\n const { viewport, triggerEvent, transitTo } = context;\n\n triggerEvent(EVENTS.HOLD_END, e, true);\n\n if (e.delta.flick !== 0) {\n // Sometimes \"release\" event on axes triggered before \"change\" event\n // Especially if user flicked panel fast in really short amount of time\n // if delta is not zero, that means above case happened.\n\n // Event flow should be HOLD_START -> MOVE_START -> MOVE -> HOLD_END\n // At least one move event should be included between holdStart and holdEnd\n e.setTo({ flick: viewport.getCameraPosition() }, 0);\n transitTo(STATE_TYPE.IDLE);\n return;\n }\n\n if (!e.inputEvent.srcEvent.cancelable) {\n // Released by scrolling\n return;\n }\n\n // Can't handle select event here,\n // As \"finish\" axes event happens\n this.releaseEvent = e;\n }\n\n public onFinish(e: OnFinish, { viewport, triggerEvent, transitTo }: FlickingContext): void {\n // Should transite to IDLE state before select event\n // As user expects hold is already finished\n transitTo(STATE_TYPE.IDLE);\n\n if (!this.releaseEvent) {\n return;\n }\n\n // Handle release event here\n // To prevent finish event called twice\n const releaseEvent = this.releaseEvent;\n\n // Static click\n const srcEvent = releaseEvent.inputEvent.srcEvent;\n\n let clickedElement: HTMLElement;\n if (srcEvent.type === \"touchend\") {\n const touchEvent = srcEvent as TouchEvent;\n const touch = touchEvent.changedTouches[0];\n clickedElement = document.elementFromPoint(touch.clientX, touch.clientY) as HTMLElement;\n } else {\n clickedElement = srcEvent.target;\n }\n const clickedPanel = viewport.panelManager.findPanelOf(clickedElement);\n const cameraPosition = viewport.getCameraPosition();\n\n if (clickedPanel) {\n const clickedPanelPosition = clickedPanel.getPosition();\n const direction = clickedPanelPosition > cameraPosition\n ? DIRECTION.NEXT\n : clickedPanelPosition < cameraPosition\n ? DIRECTION.PREV\n : null;\n\n // Don't provide axes event, to use axes instance instead\n triggerEvent<SelectEvent>(EVENTS.SELECT, releaseEvent, true, {\n direction, // Direction to the clicked panel\n index: clickedPanel.getIndex(),\n panel: clickedPanel,\n element: clickedElement,\n });\n }\n }\n}\n\nexport default HoldingState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnChange, OnRelease } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { STATE_TYPE, EVENTS } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass DraggingState extends State {\n public readonly type = STATE_TYPE.DRAGGING;\n public readonly holding = true;\n public readonly playing = true;\n\n public onChange(e: OnChange, { moveCamera, transitTo }: FlickingContext): void {\n if (!e.delta.flick) {\n return;\n }\n\n moveCamera(e)\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onRelease(e: OnRelease, context: FlickingContext): void {\n const { flicking, viewport, triggerEvent, transitTo, stopCamera } = context;\n\n const delta = this.delta;\n const absDelta = Math.abs(delta);\n const options = flicking.options;\n const horizontal = options.horizontal;\n const moveType = viewport.moveType;\n const inputEvent = e.inputEvent;\n\n const velocity = horizontal\n ? inputEvent.velocityX\n : inputEvent.velocityY;\n const inputDelta = horizontal\n ? inputEvent.deltaX\n : inputEvent.deltaY;\n const isNextDirection = Math.abs(velocity) > 1\n ? velocity < 0\n : absDelta > 0\n ? delta > 0\n : inputDelta < 0;\n\n const swipeDistance = viewport.options.bound\n ? Math.max(absDelta, Math.abs(inputDelta))\n : absDelta;\n const swipeAngle = inputEvent.deltaX\n ? Math.abs(180 * Math.atan(inputEvent.deltaY / inputEvent.deltaX) / Math.PI)\n : 90;\n const belowAngleThreshold = horizontal\n ? swipeAngle <= options.thresholdAngle\n : swipeAngle > options.thresholdAngle;\n const overThreshold = swipeDistance >= options.threshold\n && belowAngleThreshold;\n\n const moveTypeContext = {\n viewport,\n axesEvent: e,\n state: this,\n swipeDistance,\n isNextDirection,\n };\n\n // Update last position to cope with Axes's animating behavior\n // Axes uses start position when animation start\n triggerEvent(EVENTS.HOLD_END, e, true);\n\n const targetPanel = this.targetPanel;\n if (!overThreshold && targetPanel) {\n // Interrupted while animating\n const interruptDestInfo = moveType.findPanelWhenInterrupted(moveTypeContext);\n\n viewport.moveTo(\n interruptDestInfo.panel,\n interruptDestInfo.destPos,\n interruptDestInfo.eventType,\n e,\n interruptDestInfo.duration,\n );\n transitTo(STATE_TYPE.ANIMATING);\n return;\n }\n\n const currentPanel = viewport.getCurrentPanel();\n const nearestPanel = viewport.getNearestPanel();\n\n if (!currentPanel || !nearestPanel) {\n // There're no panels\n (e as any).stop();\n transitTo(STATE_TYPE.IDLE);\n return;\n }\n\n const destInfo = overThreshold\n ? moveType.findTargetPanel(moveTypeContext)\n : moveType.findRestorePanel(moveTypeContext);\n\n viewport.moveTo(\n destInfo.panel,\n destInfo.destPos,\n destInfo.eventType,\n e,\n destInfo.duration,\n ).onSuccess(() => {\n transitTo(STATE_TYPE.ANIMATING);\n }).onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n stopCamera(e);\n });\n }\n}\n\nexport default DraggingState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnChange, OnFinish, OnHold } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { STATE_TYPE, EVENTS } from \"../consts\";\nimport { FlickingContext } from \"../types\";\nimport { circulate } from \"../utils\";\n\nclass AnimatingState extends State {\n public readonly type = STATE_TYPE.ANIMATING;\n public readonly holding = false;\n public readonly playing = true;\n\n public onHold(e: OnHold, { viewport, triggerEvent, transitTo }: FlickingContext): void {\n const options = viewport.options;\n const scrollArea = viewport.getScrollArea();\n const scrollAreaSize = viewport.getScrollAreaSize();\n const loopCount = Math.floor((this.lastPosition + this.delta - scrollArea.prev) / scrollAreaSize);\n\n const targetPanel = this.targetPanel;\n if (options.circular && loopCount !== 0 && targetPanel) {\n const cloneCount = viewport.panelManager.getCloneCount();\n const originalTargetPosition = targetPanel.getPosition();\n\n // cloneIndex is from -1 to cloneCount - 1\n const newCloneIndex = circulate(targetPanel.getCloneIndex() - loopCount, -1, cloneCount - 1, true);\n const newTargetPosition = originalTargetPosition - loopCount * scrollAreaSize;\n const newTargetPanel = targetPanel.getIdenticalPanels()[newCloneIndex + 1].clone(newCloneIndex, true);\n\n // Set new target panel considering looped count\n newTargetPanel.setPosition(newTargetPosition);\n this.targetPanel = newTargetPanel;\n }\n\n // Reset last position and delta\n this.delta = 0;\n this.lastPosition = viewport.getCameraPosition();\n\n // Update current panel as current nearest panel\n viewport.setCurrentPanel(viewport.getNearestPanel()!);\n triggerEvent(EVENTS.HOLD_START, e, true)\n .onSuccess(() => {\n transitTo(STATE_TYPE.DRAGGING);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onChange(e: OnChange, { moveCamera, transitTo }: FlickingContext): void {\n if (!e.delta.flick) {\n return;\n }\n\n moveCamera(e)\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onFinish(e: OnFinish, { flicking, viewport, triggerEvent, transitTo }: FlickingContext) {\n const isTrusted = e && e.isTrusted;\n\n viewport.options.bound\n ? viewport.setCurrentPanel(this.targetPanel!)\n : viewport.setCurrentPanel(viewport.getNearestPanel()!);\n\n if (flicking.options.adaptive) {\n viewport.updateAdaptiveSize();\n }\n\n transitTo(STATE_TYPE.IDLE);\n viewport.updateCameraPosition();\n triggerEvent(EVENTS.MOVE_END, e, isTrusted, {\n direction: this.direction,\n });\n }\n}\n\nexport default AnimatingState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport type { OnAnimationEnd, OnChange, OnRelease } from \"@egjs/axes\";\nimport State from \"./State\";\nimport { STATE_TYPE } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass DisabledState extends State {\n public readonly type = STATE_TYPE.DISABLED;\n public readonly holding = false;\n public readonly playing = true;\n\n public onAnimationEnd(e: OnAnimationEnd, { transitTo }: FlickingContext): void {\n transitTo(STATE_TYPE.IDLE);\n }\n\n public onChange(e: OnChange, { viewport, transitTo }: FlickingContext): void {\n // Can stop Axes's change event\n e.stop();\n\n // Should update axes position as it's already changed at this moment\n viewport.updateAxesPosition(viewport.getCameraPosition());\n transitTo(STATE_TYPE.IDLE);\n }\n\n public onRelease(e: OnRelease, { transitTo }: FlickingContext): void {\n // This is needed when stopped hold start event\n if (e.delta.flick === 0) {\n transitTo(STATE_TYPE.IDLE);\n }\n }\n}\n\nexport default DisabledState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport State from \"../states/State\";\nimport { AxesEventType, ValueOf, FlickingContext, StateType } from \"../types\";\nimport { AXES_EVENTS, STATE_TYPE } from \"../consts\";\nimport IdleState from \"../states/IdleState\";\nimport HoldingState from \"../states/HoldingState\";\nimport DraggingState from \"../states/DraggingState\";\nimport AnimatingState from \"../states/AnimatingState\";\nimport DisabledState from \"../states/DisabledState\";\n\nclass StateMachine {\n private state: State = new IdleState();\n\n public fire(eventType: ValueOf<AxesEventType>, e: any, context: FlickingContext) {\n const currentState = this.state;\n switch (eventType) {\n case AXES_EVENTS.HOLD:\n currentState.onHold(e, context);\n break;\n case AXES_EVENTS.CHANGE:\n currentState.onChange(e, context);\n break;\n case AXES_EVENTS.RELEASE:\n currentState.onRelease(e, context);\n break;\n case AXES_EVENTS.ANIMATION_END:\n currentState.onAnimationEnd(e, context);\n break;\n case AXES_EVENTS.FINISH:\n currentState.onFinish(e, context);\n break;\n }\n }\n\n public getState(): State {\n return this.state;\n }\n\n public transitTo = (nextStateType: ValueOf<StateType>): State => {\n const currentState = this.state;\n\n if (currentState.type !== nextStateType) {\n let nextState: State;\n\n switch (nextStateType) {\n case STATE_TYPE.IDLE:\n nextState = new IdleState();\n break;\n case STATE_TYPE.HOLDING:\n nextState = new HoldingState();\n break;\n case STATE_TYPE.DRAGGING:\n nextState = new DraggingState();\n break;\n case STATE_TYPE.ANIMATING:\n nextState = new AnimatingState();\n break;\n case STATE_TYPE.DISABLED:\n nextState = new DisabledState();\n break;\n }\n\n currentState.onExit(nextState!);\n nextState!.onEnter(currentState);\n\n this.state = nextState!;\n }\n return this.state;\n }\n}\n\nexport default StateMachine;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport MoveType from \"./MoveType\";\nimport { MOVE_TYPE, EVENTS } from \"../consts\";\nimport { MoveTypeContext, DestinationInfo } from \"../types\";\nimport { clamp } from \"../utils\";\n\nclass Snap extends MoveType {\n protected readonly type: string = MOVE_TYPE.SNAP;\n protected count: number;\n\n constructor(count: number) {\n super();\n this.count = count;\n }\n\n public findTargetPanel(ctx: MoveTypeContext): DestinationInfo {\n const { viewport, axesEvent, swipeDistance } = ctx;\n const snapCount = this.count;\n const eventDelta = Math.abs(axesEvent.delta.flick);\n const currentPanel = viewport.getCurrentPanel()!;\n const nearestPanel = viewport.getNearestPanel()!;\n const minimumDistanceToChange = this.calcBrinkOfChange(ctx);\n const nearestIsCurrent = nearestPanel.getIndex() === currentPanel.getIndex();\n\n // This can happen when bounce is 0\n const shouldMoveWhenBounceIs0 = viewport.canSetBoundMode() && nearestIsCurrent;\n const shouldMoveToAdjacent = !viewport.isOutOfBound()\n && (swipeDistance <= minimumDistanceToChange || shouldMoveWhenBounceIs0);\n\n if (snapCount > 1 && eventDelta > minimumDistanceToChange) {\n return this.findSnappedPanel(ctx);\n } else if (shouldMoveToAdjacent) {\n return this.findAdjacentPanel(ctx);\n } else {\n return {\n panel: nearestPanel,\n duration: viewport.options.duration,\n destPos: viewport.findEstimatedPosition(nearestPanel),\n // As swipeDistance holds mouse/touch position change regardless of bounce option value\n // swipDistance > minimumDistanceToChange can happen in bounce area\n // Second condition is for handling that.\n eventType: (swipeDistance <= minimumDistanceToChange)\n || (viewport.isOutOfBound() && nearestIsCurrent)\n ? EVENTS.RESTORE\n : EVENTS.CHANGE,\n };\n }\n }\n\n protected findSnappedPanel(ctx: MoveTypeContext): DestinationInfo {\n const { axesEvent, viewport, state, isNextDirection } = ctx;\n\n const eventDelta = Math.abs(axesEvent.delta.flick);\n const minimumDistanceToChange = this.calcBrinkOfChange(ctx);\n const snapCount = this.count;\n const options = viewport.options;\n const scrollAreaSize = viewport.getScrollAreaSize();\n const halfGap = options.gap / 2;\n const estimatedHangerPos = axesEvent.destPos.flick + viewport.getRelativeHangerPosition();\n\n let panelToMove = viewport.getNearestPanel()!;\n let cycleIndex = panelToMove.getCloneIndex() + 1; // 0(original) or 1(clone)\n let passedPanelCount = 0;\n\n while (passedPanelCount < snapCount) {\n // Since panelToMove holds also cloned panels, we should use original panel's position\n const originalPanel = panelToMove.getOriginalPanel();\n const panelPosition = originalPanel.getPosition() + cycleIndex * scrollAreaSize;\n const panelSize = originalPanel.getSize();\n\n const panelNextPosition = panelPosition + panelSize + halfGap;\n const panelPrevPosition = panelPosition - halfGap;\n\n // Current panelToMove contains destPos\n if (\n (isNextDirection && panelNextPosition > estimatedHangerPos)\n || (!isNextDirection && panelPrevPosition < estimatedHangerPos)\n ) {\n break;\n }\n\n const siblingPanel = isNextDirection\n ? panelToMove.nextSibling\n : panelToMove.prevSibling;\n if (!siblingPanel) {\n break;\n }\n\n const panelIndex = panelToMove.getIndex();\n const siblingIndex = siblingPanel.getIndex();\n if ((isNextDirection && siblingIndex <= panelIndex)\n || (!isNextDirection && siblingIndex >= panelIndex)\n ) {\n cycleIndex = isNextDirection\n ? cycleIndex + 1\n : cycleIndex - 1;\n }\n panelToMove = siblingPanel;\n passedPanelCount += 1;\n }\n\n const originalPosition = panelToMove.getOriginalPanel().getPosition();\n\n if (cycleIndex !== 0) {\n panelToMove = panelToMove.clone(panelToMove.getCloneIndex(), true);\n panelToMove.setPosition(originalPosition + cycleIndex * scrollAreaSize);\n }\n\n const defaultDuration = viewport.options.duration;\n const duration = clamp(axesEvent.duration, defaultDuration, defaultDuration * passedPanelCount);\n\n return {\n panel: panelToMove,\n destPos: viewport.findEstimatedPosition(panelToMove),\n duration,\n eventType: Math.max(eventDelta, state.delta) > minimumDistanceToChange\n ? EVENTS.CHANGE\n : EVENTS.RESTORE,\n };\n }\n\n private findAdjacentPanel(ctx: MoveTypeContext): DestinationInfo {\n const { viewport, isNextDirection } = ctx;\n\n const options = viewport.options;\n const currentIndex = viewport.getCurrentIndex();\n const currentPanel = viewport.panelManager.get(currentIndex)!;\n const hangerPosition = viewport.getHangerPosition();\n const scrollArea = viewport.getScrollArea();\n\n const firstClonedPanel = currentPanel.getIdenticalPanels()[1];\n const lapped = options.circular\n && (Math.abs(currentPanel.getAnchorPosition() - hangerPosition)\n > Math.abs(firstClonedPanel.getAnchorPosition() - hangerPosition));\n\n // If lapped in circular mode, use first cloned panel as base panel\n const basePanel = lapped\n ? firstClonedPanel\n : currentPanel;\n const basePosition = basePanel.getPosition();\n\n const adjacentPanel = isNextDirection\n ? basePanel.nextSibling\n : basePanel.prevSibling;\n\n const eventType = adjacentPanel\n ? EVENTS.CHANGE\n : EVENTS.RESTORE;\n const panelToMove = adjacentPanel\n ? adjacentPanel\n : basePanel;\n const targetRelativeAnchorPosition = panelToMove.getRelativeAnchorPosition();\n\n const estimatedPanelPosition = options.circular\n ? isNextDirection\n ? basePosition + basePanel.getSize() + targetRelativeAnchorPosition + options.gap\n : basePosition - (panelToMove.getSize() - targetRelativeAnchorPosition) - options.gap\n : panelToMove.getAnchorPosition();\n const estimatedPosition = estimatedPanelPosition - viewport.getRelativeHangerPosition();\n const destPos = viewport.canSetBoundMode()\n ? clamp(estimatedPosition, scrollArea.prev, scrollArea.next)\n : estimatedPosition;\n\n return {\n panel: panelToMove,\n destPos,\n duration: options.duration,\n eventType,\n };\n }\n}\n\nexport default Snap;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { MoveTypeStringOption, MoveTypeContext, DestinationInfo } from \"../types\";\nimport Panel from \"../components/Panel\";\nimport { EVENTS } from \"../consts\";\n\nabstract class MoveType {\n protected readonly abstract type: string;\n\n public abstract findTargetPanel(ctx: MoveTypeContext): DestinationInfo;\n\n public is(type: MoveTypeStringOption): boolean {\n return type === this.type;\n }\n\n public findRestorePanel(ctx: MoveTypeContext): DestinationInfo {\n const viewport = ctx.viewport;\n const options = viewport.options;\n\n const panel = options.circular\n ? this.findRestorePanelInCircularMode(ctx)\n : viewport.getCurrentPanel()!;\n\n return {\n panel,\n destPos: viewport.findEstimatedPosition(panel),\n duration: options.duration,\n eventType: EVENTS.RESTORE,\n };\n }\n\n public findPanelWhenInterrupted(ctx: MoveTypeContext): DestinationInfo {\n const { state, viewport } = ctx;\n const targetPanel = state.targetPanel!;\n\n return {\n panel: targetPanel,\n destPos: viewport.findEstimatedPosition(targetPanel),\n duration: viewport.options.duration,\n eventType: \"\",\n };\n }\n\n // Calculate minimum distance to \"change\" panel\n protected calcBrinkOfChange(ctx: MoveTypeContext): number {\n const { viewport, isNextDirection } = ctx;\n\n const options = viewport.options;\n const currentPanel = viewport.getCurrentPanel()!;\n const halfGap = options.gap / 2;\n\n const relativeAnchorPosition = currentPanel.getRelativeAnchorPosition();\n\n // Minimum distance needed to decide prev/next panel as nearest\n /*\n * | Prev | Next |\n * |--------|--------------|\n * [][ |<-Anchor ][] <- Panel + Half-Gap\n */\n let minimumDistanceToChange = isNextDirection\n ? currentPanel.getSize() - relativeAnchorPosition + halfGap\n : relativeAnchorPosition + halfGap;\n\n minimumDistanceToChange = Math.max(minimumDistanceToChange, options.threshold);\n\n return minimumDistanceToChange;\n }\n\n private findRestorePanelInCircularMode(ctx: MoveTypeContext): Panel {\n const viewport = ctx.viewport;\n const originalPanel = viewport.getCurrentPanel()!.getOriginalPanel();\n const hangerPosition = viewport.getHangerPosition();\n\n const firstClonedPanel = originalPanel.getIdenticalPanels()[1];\n const lapped = Math.abs(originalPanel.getAnchorPosition() - hangerPosition)\n > Math.abs(firstClonedPanel.getAnchorPosition() - hangerPosition);\n\n return (!ctx.isNextDirection && lapped)\n ? firstClonedPanel\n : originalPanel;\n }\n}\n\nexport default MoveType;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Snap from \"./Snap\";\nimport { MOVE_TYPE, EVENTS } from \"../consts\";\nimport { MoveTypeContext, DestinationInfo } from \"../types\";\nimport { circulate, clamp } from \"../utils\";\n\nclass FreeScroll extends Snap {\n protected readonly type: string = MOVE_TYPE.FREE_SCROLL;\n\n constructor() {\n // Set snap count to Infinity\n super(Infinity);\n }\n\n public findTargetPanel(ctx: MoveTypeContext): DestinationInfo {\n const { axesEvent, state, viewport } = ctx;\n const destPos = axesEvent.destPos.flick;\n const minimumDistanceToChange = this.calcBrinkOfChange(ctx);\n const scrollArea = viewport.getScrollArea();\n const currentPanel = viewport.getCurrentPanel()!;\n const options = viewport.options;\n\n const delta = Math.abs(axesEvent.delta.flick + state.delta);\n if (delta > minimumDistanceToChange) {\n const destInfo = super.findSnappedPanel(ctx);\n\n destInfo.duration = axesEvent.duration;\n destInfo.destPos = destPos;\n destInfo.eventType = !options.circular && destInfo.panel === currentPanel\n ? \"\"\n : EVENTS.CHANGE;\n\n return destInfo;\n } else {\n let estimatedPosition = options.circular\n ? circulate(destPos, scrollArea.prev, scrollArea.next, false)\n : destPos;\n estimatedPosition = clamp(estimatedPosition, scrollArea.prev, scrollArea.next);\n estimatedPosition += viewport.getRelativeHangerPosition();\n\n const estimatedPanel = viewport.findNearestPanelAt(estimatedPosition)!;\n\n return {\n panel: estimatedPanel,\n destPos,\n duration: axesEvent.duration,\n eventType: \"\",\n };\n }\n }\n\n public findRestorePanel(ctx: MoveTypeContext): DestinationInfo {\n return this.findTargetPanel(ctx);\n }\n\n public findPanelWhenInterrupted(ctx: MoveTypeContext): DestinationInfo {\n const { viewport } = ctx;\n\n return {\n panel: viewport.getNearestPanel()!,\n destPos: viewport.getCameraPosition(),\n duration: 0,\n eventType: \"\",\n };\n }\n\n protected calcBrinkOfChange(ctx: MoveTypeContext): number {\n const { viewport, isNextDirection } = ctx;\n\n const options = viewport.options;\n const currentPanel = viewport.getCurrentPanel()!;\n const halfGap = options.gap / 2;\n\n const lastPosition = viewport.stateMachine.getState().lastPosition;\n const currentPanelPosition = currentPanel.getPosition();\n\n // As camera can stop anywhere in free scroll mode,\n // minimumDistanceToChange should be calculated differently.\n // Ref #191(https://github.com/naver/egjs-flicking/issues/191)\n const lastHangerPosition = lastPosition + viewport.getRelativeHangerPosition();\n\n const scrollAreaSize = viewport.getScrollAreaSize();\n let minimumDistanceToChange = isNextDirection\n ? currentPanelPosition + currentPanel.getSize() - lastHangerPosition + halfGap\n : lastHangerPosition - currentPanelPosition + halfGap;\n minimumDistanceToChange = Math.abs(minimumDistanceToChange % scrollAreaSize);\n\n return Math.min(minimumDistanceToChange, scrollAreaSize - minimumDistanceToChange);\n }\n}\n\nexport default FreeScroll;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport Flicking from \"../Flicking\";\nimport Panel from \"./Panel\";\nimport PanelManager from \"./PanelManager\";\nimport StateMachine from \"./StateMachine\";\nimport MoveType from \"../moves/MoveType\";\nimport { FlickingOptions, FlickingPanel, FlickingStatus, ElementLike, EventType, TriggerCallback, NeedPanelEvent, FlickingEvent, MoveTypeObjectOption, OriginalStyle, Plugin, DestroyOption, BoundingBox } from \"../types\";\nimport { DEFAULT_VIEWPORT_CSS, DEFAULT_CAMERA_CSS, TRANSFORM, DEFAULT_OPTIONS, EVENTS, DIRECTION, STATE_TYPE, MOVE_TYPE } from \"../consts\";\nimport { clamp, applyCSS, toArray, parseArithmeticExpression, isBetween, isArray, parseElement, hasClass, restoreStyle, circulate, findIndex, getBbox } from \"../utils\";\nimport Snap from \"../moves/Snap\";\nimport FreeScroll from \"../moves/FreeScroll\";\n\nexport default class Viewport {\n public options: FlickingOptions;\n public stateMachine: StateMachine;\n public panelManager: PanelManager;\n public moveType: MoveType;\n\n private flicking: Flicking;\n private axes: Axes;\n private panInput: PanInput | null;\n\n private viewportElement: HTMLElement;\n private cameraElement: HTMLElement;\n\n private triggerEvent: Flicking[\"triggerEvent\"];\n private axesHandlers: { [key: string]: any };\n\n private currentPanel: Panel | undefined;\n private nearestPanel: Panel | undefined;\n private visiblePanels: Panel[];\n\n private plugins: Plugin[] = [];\n private panelBboxes: { [className: string]: BoundingBox };\n private state: {\n size: number;\n position: number;\n panelMaintainRatio: number;\n relativeHangerPosition: number;\n positionOffset: number;\n scrollArea: {\n prev: number;\n next: number;\n };\n translate: {\n name: string,\n has3d: boolean,\n };\n infiniteThreshold: number;\n checkedIndexes: Array<[number, number]>;\n isAdaptiveCached: boolean;\n isViewportGiven: boolean;\n isCameraGiven: boolean;\n originalViewportStyle: OriginalStyle;\n originalCameraStyle: OriginalStyle;\n cachedBbox: BoundingBox | null;\n };\n\n constructor(\n flicking: Flicking,\n options: FlickingOptions,\n triggerEvent: Flicking[\"triggerEvent\"],\n ) {\n this.flicking = flicking;\n this.triggerEvent = triggerEvent;\n\n this.state = {\n size: 0,\n position: 0,\n panelMaintainRatio: 0,\n relativeHangerPosition: 0,\n positionOffset: 0,\n scrollArea: {\n prev: 0,\n next: 0,\n },\n translate: TRANSFORM,\n infiniteThreshold: 0,\n checkedIndexes: [],\n isAdaptiveCached: false,\n isViewportGiven: false,\n isCameraGiven: false,\n originalViewportStyle: {\n className: null,\n style: null,\n },\n originalCameraStyle: {\n className: null,\n style: null,\n },\n cachedBbox: null,\n };\n this.options = options;\n this.stateMachine = new StateMachine();\n this.visiblePanels = [];\n this.panelBboxes = {};\n\n this.build();\n }\n\n public moveTo(\n panel: Panel,\n destPos: number,\n eventType: EventType[\"CHANGE\"] | EventType[\"RESTORE\"] | \"\",\n axesEvent: any,\n duration: number = this.options.duration,\n ): TriggerCallback {\n const state = this.state;\n const currentState = this.stateMachine.getState();\n const currentPosition = state.position;\n\n const isTrusted = axesEvent\n ? axesEvent.isTrusted\n : false;\n const direction = destPos === currentPosition\n ? null\n : destPos > currentPosition\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n let eventResult: TriggerCallback;\n if (eventType === EVENTS.CHANGE) {\n eventResult = this.triggerEvent(EVENTS.CHANGE, axesEvent, isTrusted, {\n index: panel.getIndex(),\n panel,\n direction,\n });\n } else if (eventType === EVENTS.RESTORE) {\n eventResult = this.triggerEvent(EVENTS.RESTORE, axesEvent, isTrusted);\n } else {\n eventResult = {\n onSuccess(callback: () => void): TriggerCallback {\n callback();\n return this;\n },\n onStopped(): TriggerCallback {\n return this;\n },\n };\n }\n\n eventResult.onSuccess(() => {\n currentState.delta = 0;\n currentState.lastPosition = this.getCameraPosition();\n currentState.targetPanel = panel;\n currentState.direction = destPos === currentPosition\n ? null\n : destPos > currentPosition\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n if (destPos === currentPosition) {\n // no move\n this.nearestPanel = panel;\n this.currentPanel = panel;\n }\n\n if (axesEvent && axesEvent.setTo) {\n // freeScroll only occurs in release events\n axesEvent.setTo({ flick: destPos }, duration);\n } else {\n this.axes.setTo({ flick: destPos }, duration);\n }\n });\n\n return eventResult;\n }\n\n public moveCamera(pos: number, axesEvent?: any): void {\n const state = this.state;\n const options = this.options;\n const transform = state.translate.name;\n const scrollArea = state.scrollArea;\n\n // Update position & nearestPanel\n if (options.circular && !isBetween(pos, scrollArea.prev, scrollArea.next)) {\n pos = circulate(pos, scrollArea.prev, scrollArea.next, false);\n }\n state.position = pos;\n this.nearestPanel = this.findNearestPanel();\n const nearestPanel = this.nearestPanel;\n const originalNearestPosition = nearestPanel\n ? nearestPanel.getPosition()\n : 0;\n\n // From 0(panel position) to 1(panel position + panel size)\n // When it's on gap area value will be (val > 1 || val < 0)\n if (nearestPanel) {\n const hangerPosition = this.getHangerPosition();\n const panelPosition = nearestPanel.getPosition();\n const panelSize = nearestPanel.getSize();\n const halfGap = options.gap / 2;\n\n // As panel's range is from panel position - half gap ~ panel pos + panel size + half gap\n state.panelMaintainRatio = (hangerPosition - panelPosition + halfGap) / (panelSize + 2 * halfGap);\n } else {\n state.panelMaintainRatio = 0;\n }\n\n this.checkNeedPanel(axesEvent);\n\n // Possibly modified after need panel, if it's looped\n const modifiedNearestPosition = nearestPanel\n ? nearestPanel.getPosition()\n : 0;\n\n pos += (modifiedNearestPosition - originalNearestPosition);\n state.position = pos;\n\n this.updateVisiblePanels();\n\n // Offset is needed to fix camera layer size in visible-only rendering mode\n const posOffset = options.renderOnlyVisible\n ? state.positionOffset\n : 0;\n const moveVector = options.horizontal\n ? [-(pos - posOffset), 0] : [0, -(pos - posOffset)];\n const moveCoord = moveVector.map(coord => `${Math.round(coord)}px`).join(\", \");\n\n this.cameraElement.style[transform] = state.translate.has3d\n ? `translate3d(${moveCoord}, 0px)`\n : `translate(${moveCoord})`;\n }\n\n public stopCamera = (axesEvent: any): void => {\n if (axesEvent && axesEvent.setTo) {\n axesEvent.setTo({ flick: this.state.position }, 0);\n }\n\n this.stateMachine.transitTo(STATE_TYPE.IDLE);\n }\n\n public unCacheBbox(): void {\n const state = this.state;\n const options = this.options;\n\n state.cachedBbox = null;\n this.visiblePanels = [];\n\n const viewportElement = this.viewportElement;\n if (!options.horizontal) {\n // Don't preserve previous width for adaptive resizing\n viewportElement.style.width = \"\";\n } else {\n viewportElement.style.height = \"\";\n }\n state.isAdaptiveCached = false;\n this.panelBboxes = {};\n }\n\n public resize(): void {\n this.updateSize();\n this.updateOriginalPanelPositions();\n this.updateAdaptiveSize();\n this.updateScrollArea();\n this.updateClonePanels();\n this.updateVisiblePanelPositions();\n this.updateCameraPosition();\n this.updatePlugins();\n }\n\n // Find nearest anchor from current hanger position\n public findNearestPanel(): Panel | undefined {\n const state = this.state;\n const panelManager = this.panelManager;\n const hangerPosition = this.getHangerPosition();\n\n if (this.isOutOfBound()) {\n const position = state.position;\n\n return position <= state.scrollArea.prev\n ? panelManager.firstPanel()\n : panelManager.lastPanel();\n }\n\n return this.findNearestPanelAt(hangerPosition);\n }\n\n public findNearestPanelAt(position: number): Panel | undefined {\n const panelManager = this.panelManager;\n\n const allPanels = panelManager.allPanels();\n let minimumDistance = Infinity;\n let nearestPanel: Panel | undefined;\n\n for (const panel of allPanels) {\n if (!panel) {\n continue;\n }\n const prevPosition = panel.getPosition();\n const nextPosition = prevPosition + panel.getSize();\n\n // Use shortest distance from panel's range\n const distance = isBetween(position, prevPosition, nextPosition)\n ? 0\n : Math.min(\n Math.abs(prevPosition - position),\n Math.abs(nextPosition - position),\n );\n\n if (distance > minimumDistance) {\n break;\n } else if (distance === minimumDistance) {\n const minimumAnchorDistance = Math.abs(position - nearestPanel!.getAnchorPosition());\n const anchorDistance = Math.abs(position - panel.getAnchorPosition());\n\n if (anchorDistance > minimumAnchorDistance) {\n break;\n }\n }\n\n minimumDistance = distance;\n nearestPanel = panel;\n }\n\n return nearestPanel;\n }\n\n public findNearestIdenticalPanel(panel: Panel): Panel {\n let nearest = panel;\n let shortestDistance = Infinity;\n const hangerPosition = this.getHangerPosition();\n\n const identicals = panel.getIdenticalPanels();\n identicals.forEach(identical => {\n const anchorPosition = identical.getAnchorPosition();\n const distance = Math.abs(anchorPosition - hangerPosition);\n\n if (distance < shortestDistance) {\n nearest = identical;\n shortestDistance = distance;\n }\n });\n\n return nearest;\n }\n\n // Find shortest camera position that distance is minimum\n public findShortestPositionToPanel(panel: Panel): number {\n const state = this.state;\n const options = this.options;\n const anchorPosition = panel.getAnchorPosition();\n const hangerPosition = this.getHangerPosition();\n const distance = Math.abs(hangerPosition - anchorPosition);\n const scrollAreaSize = state.scrollArea.next - state.scrollArea.prev;\n\n if (!options.circular) {\n const position = anchorPosition - state.relativeHangerPosition;\n return this.canSetBoundMode()\n ? clamp(position, state.scrollArea.prev, state.scrollArea.next)\n : position;\n } else {\n // If going out of viewport border is more efficient way of moving, choose that position\n return distance <= scrollAreaSize - distance\n ? anchorPosition - state.relativeHangerPosition\n : anchorPosition > hangerPosition\n // PREV TO NEXT\n ? anchorPosition - state.relativeHangerPosition - scrollAreaSize\n // NEXT TO PREV\n : anchorPosition - state.relativeHangerPosition + scrollAreaSize;\n }\n }\n\n public findEstimatedPosition(panel: Panel): number {\n const scrollArea = this.getScrollArea();\n\n let estimatedPosition = panel.getAnchorPosition() - this.getRelativeHangerPosition();\n estimatedPosition = this.canSetBoundMode()\n ? clamp(estimatedPosition, scrollArea.prev, scrollArea.next)\n : estimatedPosition;\n\n return estimatedPosition;\n }\n\n public addVisiblePanel(panel: Panel): void {\n if (this.getVisibleIndexOf(panel) < 0) {\n this.visiblePanels.push(panel);\n }\n }\n\n public enable(): void {\n if (!this.panInput) {\n this.createPanInput();\n }\n }\n\n public disable(): void {\n if (this.panInput) {\n this.panInput.destroy();\n this.panInput = null;\n\n // Refresh Axes instance\n this.axes.destroy();\n this.setAxesInstance();\n this.updateScrollArea();\n this.updateAxesPosition(this.state.position);\n\n this.stateMachine.transitTo(STATE_TYPE.IDLE);\n }\n }\n\n public insert(index: number, element: ElementLike | ElementLike[]): FlickingPanel[] {\n const lastIndex = this.panelManager.getLastIndex();\n\n // Index should not below 0\n if (index < 0 || index > lastIndex) {\n return [];\n }\n\n const state = this.state;\n const options = this.options;\n const parsedElements = parseElement(element);\n\n const panels = parsedElements\n .map((el, idx) => new Panel(el, index + idx, this))\n .slice(0, lastIndex - index + 1);\n\n if (panels.length <= 0) {\n return [];\n }\n\n const pushedIndex = this.panelManager.insert(index, panels);\n\n // ...then calc bbox for all panels\n this.resizePanels(panels);\n\n if (!this.currentPanel) {\n this.currentPanel = panels[0];\n this.nearestPanel = panels[0];\n\n const newCenterPanel = panels[0];\n const newPanelPosition = this.findEstimatedPosition(newCenterPanel);\n state.position = newPanelPosition;\n this.updateAxesPosition(newPanelPosition);\n state.panelMaintainRatio = (newCenterPanel.getRelativeAnchorPosition() + options.gap / 2) / (newCenterPanel.getSize() + options.gap);\n }\n\n // Update checked indexes in infinite mode\n this.updateCheckedIndexes({ min: index, max: index });\n state.checkedIndexes.forEach((indexes, idx) => {\n const [min, max] = indexes;\n if (index < min) {\n // Push checked index\n state.checkedIndexes.splice(idx, 1, [min + pushedIndex, max + pushedIndex]);\n }\n });\n\n this.resize();\n\n return panels;\n }\n\n public replace(index: number, element: ElementLike | ElementLike[]): FlickingPanel[] {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const lastIndex = panelManager.getLastIndex();\n\n // Index should not below 0\n if (index < 0 || index > lastIndex) {\n return [];\n }\n\n const parsedElements = parseElement(element);\n const panels = parsedElements\n .map((el, idx) => new Panel(el, index + idx, this))\n .slice(0, lastIndex - index + 1);\n\n if (panels.length <= 0) {\n return [];\n }\n\n const replacedPanels = panelManager.replace(index, panels);\n\n replacedPanels.forEach(panel => {\n const visibleIndex = this.getVisibleIndexOf(panel);\n if (visibleIndex > -1) {\n this.visiblePanels.splice(visibleIndex, 1);\n }\n });\n\n // ...then calc bbox for all panels\n this.resizePanels(panels);\n\n const currentPanel = this.currentPanel;\n const wasEmpty = !currentPanel;\n if (wasEmpty) {\n this.currentPanel = panels[0];\n this.nearestPanel = panels[0];\n\n const newCenterPanel = panels[0];\n const newPanelPosition = this.findEstimatedPosition(newCenterPanel);\n state.position = newPanelPosition;\n this.updateAxesPosition(newPanelPosition);\n state.panelMaintainRatio = (newCenterPanel.getRelativeAnchorPosition() + options.gap / 2) / (newCenterPanel.getSize() + options.gap);\n } else if (isBetween(currentPanel!.getIndex(), index, index + panels.length - 1)) {\n // Current panel is replaced\n this.currentPanel = panelManager.get(currentPanel!.getIndex());\n }\n\n // Update checked indexes in infinite mode\n this.updateCheckedIndexes({ min: index, max: index + panels.length - 1 });\n\n this.resize();\n\n return panels;\n }\n\n public remove(index: number, deleteCount: number = 1): FlickingPanel[] {\n const state = this.state;\n // Index should not below 0\n index = Math.max(index, 0);\n\n const panelManager = this.panelManager;\n const currentIndex = this.getCurrentIndex();\n\n const removedPanels = panelManager.remove(index, deleteCount);\n if (isBetween(currentIndex, index, index + deleteCount - 1)) {\n // Current panel is removed\n // Use panel at removing index - 1 as new current panel if it exists\n const newCurrentIndex = Math.max(index - 1, panelManager.getRange().min);\n this.currentPanel = panelManager.get(newCurrentIndex);\n }\n\n // Update checked indexes in infinite mode\n if (deleteCount > 0) {\n // Check whether removing index will affect checked indexes\n // Suppose index 0 is empty and removed index 1, then checked index 0 should be deleted and vice versa.\n this.updateCheckedIndexes({ min: index - 1, max: index + deleteCount });\n // Uncache visible panels to refresh panels\n this.visiblePanels = [];\n }\n\n if (panelManager.getPanelCount() <= 0) {\n this.currentPanel = undefined;\n this.nearestPanel = undefined;\n }\n\n this.resize();\n\n const scrollArea = state.scrollArea;\n if (state.position < scrollArea.prev || state.position > scrollArea.next) {\n const newPosition = circulate(state.position, scrollArea.prev, scrollArea.next, false);\n this.moveCamera(newPosition);\n this.updateAxesPosition(newPosition);\n }\n\n return removedPanels;\n }\n\n public updateAdaptiveSize(): void {\n const state = this.state;\n const options = this.options;\n const horizontal = options.horizontal;\n const currentPanel = this.getCurrentPanel();\n\n if (!currentPanel) {\n return;\n }\n\n const shouldApplyAdaptive = options.adaptive || !state.isAdaptiveCached;\n const viewportStyle = this.viewportElement.style;\n if (shouldApplyAdaptive) {\n let sizeToApply: number;\n if (options.adaptive) {\n const panelBbox = currentPanel.getBbox();\n\n sizeToApply = horizontal ? panelBbox.height : panelBbox.width;\n } else {\n // Find minimum height of panels to maximum panel size\n const maximumPanelSize = this.panelManager.originalPanels().reduce((maximum, panel) => {\n const panelBbox = panel.getBbox();\n return Math.max(maximum, horizontal ? panelBbox.height : panelBbox.width);\n }, 0);\n\n sizeToApply = maximumPanelSize;\n }\n\n if (!state.isAdaptiveCached) {\n const viewportBbox = this.updateBbox();\n sizeToApply = Math.max(sizeToApply, horizontal ? viewportBbox.height : viewportBbox.width);\n state.isAdaptiveCached = true;\n }\n\n const viewportSize = `${sizeToApply}px`;\n if (horizontal) {\n viewportStyle.height = viewportSize;\n state.cachedBbox!.height = sizeToApply;\n } else {\n viewportStyle.width = viewportSize;\n state.cachedBbox!.width = sizeToApply;\n }\n }\n }\n\n // Update camera position after resizing\n public updateCameraPosition(): void {\n const state = this.state;\n const currentPanel = this.getCurrentPanel();\n const cameraPosition = this.getCameraPosition();\n const currentState = this.stateMachine.getState();\n const isFreeScroll = this.moveType.is(MOVE_TYPE.FREE_SCROLL);\n const relativeHangerPosition = this.getRelativeHangerPosition();\n const halfGap = this.options.gap / 2;\n\n if (currentState.holding || currentState.playing) {\n this.updateVisiblePanels();\n return;\n }\n\n let newPosition: number;\n if (isFreeScroll) {\n const positionBounded = this.canSetBoundMode() && (cameraPosition === state.scrollArea.prev || cameraPosition === state.scrollArea.next);\n const nearestPanel = this.getNearestPanel();\n\n // Preserve camera position if it is bound to scroll area limit\n newPosition = positionBounded || !nearestPanel\n ? cameraPosition\n : nearestPanel.getPosition() - halfGap + (nearestPanel.getSize() + 2 * halfGap) * state.panelMaintainRatio - relativeHangerPosition;\n } else {\n newPosition = currentPanel\n ? currentPanel.getAnchorPosition() - relativeHangerPosition\n : cameraPosition;\n }\n\n if (this.canSetBoundMode()) {\n newPosition = clamp(newPosition, state.scrollArea.prev, state.scrollArea.next);\n }\n\n // Pause & resume axes to prevent axes's \"change\" event triggered\n // This should be done before moveCamera, as moveCamera can trigger needPanel\n this.updateAxesPosition(newPosition);\n\n this.moveCamera(newPosition);\n }\n\n public updateBbox(): BoundingBox {\n const state = this.state;\n const options = this.options;\n const viewportElement = this.viewportElement;\n\n if (!state.cachedBbox) {\n state.cachedBbox = getBbox(viewportElement, options.useOffset);\n }\n\n return state.cachedBbox!;\n }\n\n public updatePlugins(): void {\n // update for resize\n this.plugins.forEach(plugin => {\n plugin.update && plugin.update(this.flicking);\n });\n }\n\n public destroy(option: Partial<DestroyOption>): void {\n const state = this.state;\n const wrapper = this.flicking.getElement();\n const viewportElement = this.viewportElement;\n const cameraElement = this.cameraElement;\n const originalPanels = this.panelManager.originalPanels();\n\n this.removePlugins(this.plugins);\n if (!option.preserveUI) {\n restoreStyle(viewportElement, state.originalViewportStyle);\n restoreStyle(cameraElement, state.originalCameraStyle);\n\n if (!state.isCameraGiven && !this.options.renderExternal) {\n const topmostElement = state.isViewportGiven\n ? viewportElement\n : wrapper;\n const deletingElement = state.isViewportGiven\n ? cameraElement\n : viewportElement;\n\n originalPanels.forEach(panel => {\n topmostElement.appendChild(panel.getElement());\n });\n\n topmostElement.removeChild(deletingElement);\n }\n }\n\n this.axes.destroy();\n this.panInput?.destroy();\n\n originalPanels.forEach(panel => { panel.destroy(option); });\n\n // release resources\n for (const x in this) {\n (this as any)[x] = null;\n }\n }\n\n public restore(status: FlickingStatus): void {\n const panels = status.panels;\n const defaultIndex = this.options.defaultIndex;\n const cameraElement = this.cameraElement;\n const panelManager = this.panelManager;\n\n // Restore index\n cameraElement.innerHTML = panels.map(panel => panel.html).join(\"\");\n\n // Create panels first\n this.refreshPanels();\n const createdPanels = panelManager.originalPanels();\n\n // ...then order it by its index\n const orderedPanels: Panel[] = [];\n panels.forEach((panel, idx) => {\n const createdPanel = createdPanels[idx];\n createdPanel.setIndex(panel.index);\n createdPanel.setPosition(panel.position);\n orderedPanels[panel.index] = createdPanel;\n });\n panelManager.replacePanels(orderedPanels, []);\n panelManager.setCloneCount(0); // No clones at this point\n\n const panelCount = panelManager.getPanelCount();\n if (panelCount > 0) {\n this.currentPanel = panelManager.get(status.index)\n || panelManager.get(defaultIndex)\n || panelManager.firstPanel();\n } else {\n this.currentPanel = undefined;\n }\n this.visiblePanels = orderedPanels.filter(panel => Boolean(panel));\n\n this.resize();\n\n this.axes.setTo({ flick: status.position }, 0);\n this.moveCamera(status.position);\n }\n\n public calcVisiblePanels(): Panel[] {\n const allPanels = this.panelManager.allPanels();\n if (this.options.renderOnlyVisible) {\n const cameraPos = this.getCameraPosition();\n const viewportSize = this.getSize();\n const basePanel = this.nearestPanel!;\n\n const getNextPanel = (panel: Panel) => {\n const nextPanel = panel.nextSibling;\n\n if (nextPanel && nextPanel.getPosition() >= panel.getPosition()) {\n return nextPanel;\n } else {\n return null;\n }\n };\n\n const getPrevPanel = (panel: Panel) => {\n const prevPanel = panel.prevSibling;\n\n if (prevPanel && prevPanel.getPosition() <= panel.getPosition()) {\n return prevPanel;\n } else {\n return null;\n }\n };\n\n const isOutOfBoundNext = (panel: Panel) => panel.getPosition() >= cameraPos + viewportSize;\n const isOutOfBoundPrev = (panel: Panel) => panel.getPosition() + panel.getSize() <= cameraPos;\n\n const getVisiblePanels = (\n panel: Panel,\n getNext: (panel: Panel) => Panel | null,\n isOutOfViewport: (panel: Panel) => boolean,\n ): Panel[] => {\n const visiblePanels: Panel[] = [];\n\n let lastPanel = panel;\n while (true) {\n const nextPanel = getNext(lastPanel);\n if (!nextPanel || isOutOfViewport(nextPanel)) {\n break;\n }\n visiblePanels.push(nextPanel);\n lastPanel = nextPanel;\n }\n return visiblePanels;\n };\n\n const panelCount = this.panelManager.getPanelCount();\n const getAbsIndex = (panel: Panel) => panel.getIndex() + (panel.getCloneIndex() + 1) * panelCount;\n const nextPanels = getVisiblePanels(basePanel, getNextPanel, isOutOfBoundNext);\n const prevPanels = getVisiblePanels(basePanel, getPrevPanel, isOutOfBoundPrev);\n\n return [basePanel, ...nextPanels, ...prevPanels].sort((panel1, panel2) => getAbsIndex(panel1) - getAbsIndex(panel2));\n } else {\n return allPanels.filter(panel => {\n const outsetProgress = panel.getOutsetProgress();\n\n return outsetProgress > -1 && outsetProgress < 1;\n });\n }\n }\n\n public getCurrentPanel(): Panel | undefined {\n return this.currentPanel;\n }\n\n public getCurrentIndex(): number {\n const currentPanel = this.currentPanel;\n\n return currentPanel\n ? currentPanel.getIndex()\n : -1;\n }\n\n public getNearestPanel(): Panel | undefined {\n return this.nearestPanel;\n }\n\n // Get progress from nearest panel\n public getCurrentProgress(): number {\n const currentState = this.stateMachine.getState();\n let nearestPanel = currentState.playing || currentState.holding\n ? this.nearestPanel\n : this.currentPanel;\n\n const panelManager = this.panelManager;\n if (!nearestPanel) {\n // There're no panels\n return NaN;\n }\n const { prev: prevRange, next: nextRange } = this.getScrollArea();\n const cameraPosition = this.getCameraPosition();\n const isOutOfBound = this.isOutOfBound();\n let prevPanel = nearestPanel.prevSibling;\n let nextPanel = nearestPanel.nextSibling;\n let hangerPosition = this.getHangerPosition();\n let nearestAnchorPos = nearestPanel.getAnchorPosition();\n\n if (\n isOutOfBound\n && prevPanel\n && nextPanel\n && cameraPosition < nextRange\n // On the basis of anchor, prevPanel is nearestPanel.\n && (hangerPosition - prevPanel.getAnchorPosition() < nearestAnchorPos - hangerPosition)\n ) {\n nearestPanel = prevPanel;\n nextPanel = nearestPanel.nextSibling;\n prevPanel = nearestPanel.prevSibling;\n nearestAnchorPos = nearestPanel.getAnchorPosition();\n }\n const nearestIndex = nearestPanel.getIndex() + (nearestPanel.getCloneIndex() + 1) * panelManager.getPanelCount();\n const nearestSize = nearestPanel.getSize();\n\n if (isOutOfBound) {\n const relativeHangerPosition = this.getRelativeHangerPosition();\n\n if (nearestAnchorPos > nextRange + relativeHangerPosition) {\n // next bounce area: hangerPosition - relativeHangerPosition - nextRange\n hangerPosition = nearestAnchorPos + hangerPosition - relativeHangerPosition - nextRange;\n } else if (nearestAnchorPos < prevRange + relativeHangerPosition) {\n // prev bounce area: hangerPosition - relativeHangerPosition - prevRange\n hangerPosition = nearestAnchorPos + hangerPosition - relativeHangerPosition - prevRange;\n }\n }\n const hangerIsNextToNearestPanel = hangerPosition >= nearestAnchorPos;\n const gap = this.options.gap;\n\n let basePosition = nearestAnchorPos;\n let targetPosition = nearestAnchorPos;\n if (hangerIsNextToNearestPanel) {\n targetPosition = nextPanel\n ? nextPanel.getAnchorPosition()\n : nearestAnchorPos + nearestSize + gap;\n } else {\n basePosition = prevPanel\n ? prevPanel.getAnchorPosition()\n : nearestAnchorPos - nearestSize - gap;\n }\n\n const progressBetween = (hangerPosition - basePosition) / (targetPosition - basePosition);\n const startIndex = hangerIsNextToNearestPanel\n ? nearestIndex\n : prevPanel\n ? prevPanel.getIndex()\n : nearestIndex - 1;\n\n return startIndex + progressBetween;\n }\n\n // Update axes flick position without triggering event\n public updateAxesPosition(position: number) {\n const axes = this.axes;\n axes.off();\n axes.setTo({\n flick: position,\n }, 0);\n axes.on(this.axesHandlers);\n }\n\n public getSize(): number {\n return this.state.size;\n }\n\n public getScrollArea(): { prev: number, next: number } {\n return this.state.scrollArea;\n }\n\n public isOutOfBound(): boolean {\n const state = this.state;\n const options = this.options;\n const scrollArea = state.scrollArea;\n\n return !options.circular\n && options.bound\n && (state.position <= scrollArea.prev || state.position >= scrollArea.next);\n }\n\n public canSetBoundMode(): boolean {\n const options = this.options;\n\n return options.bound && !options.circular;\n }\n\n public getViewportElement(): HTMLElement {\n return this.viewportElement;\n }\n\n public getCameraElement(): HTMLElement {\n return this.cameraElement;\n }\n\n public getScrollAreaSize(): number {\n const scrollArea = this.state.scrollArea;\n\n return scrollArea.next - scrollArea.prev;\n }\n\n public getRelativeHangerPosition(): number {\n return this.state.relativeHangerPosition;\n }\n\n public getHangerPosition(): number {\n return this.state.position + this.state.relativeHangerPosition;\n }\n\n public getCameraPosition(): number {\n return this.state.position;\n }\n\n public getPositionOffset(): number {\n return this.state.positionOffset;\n }\n\n public getCheckedIndexes(): Array<[number, number]> {\n return this.state.checkedIndexes;\n }\n\n public getVisiblePanels(): Panel[] {\n return this.visiblePanels;\n }\n\n public setCurrentPanel(panel: Panel | undefined): void {\n this.currentPanel = panel;\n }\n\n public setLastIndex(index: number): void {\n const currentPanel = this.currentPanel;\n const panelManager = this.panelManager;\n\n panelManager.setLastIndex(index);\n if (currentPanel && currentPanel.getIndex() > index) {\n this.currentPanel = panelManager.lastPanel();\n }\n\n this.resize();\n }\n\n public setVisiblePanels(panels: Panel[]): void {\n this.visiblePanels = panels;\n }\n\n public connectAxesHandler(handlers: { [key: string]: (event: { [key: string]: any; }) => any }): void {\n const axes = this.axes;\n\n this.axesHandlers = handlers;\n axes.on(handlers);\n }\n\n public addPlugins(plugins: Plugin | Plugin[]) {\n const newPlugins = ([] as Plugin[]).concat(plugins);\n\n newPlugins.forEach(plugin => {\n plugin.init(this.flicking);\n });\n\n this.plugins = this.plugins.concat(newPlugins);\n return this;\n }\n\n public removePlugins(plugins: Plugin | Plugin[]) {\n const currentPlugins = this.plugins;\n const removedPlugins = ([] as Plugin[]).concat(plugins);\n\n removedPlugins.forEach(plugin => {\n const index = currentPlugins.indexOf(plugin);\n\n if (index > -1) {\n currentPlugins.splice(index, 1);\n }\n\n plugin.destroy(this.flicking);\n });\n return this;\n }\n\n public updateCheckedIndexes(changedRange: { min: number, max: number }): void {\n const state = this.state;\n\n let removed = 0;\n state.checkedIndexes.concat().forEach((indexes, idx) => {\n const [min, max] = indexes;\n // Can fill part of indexes in range\n if (changedRange.min <= max && changedRange.max >= min) {\n // Remove checked index from list\n state.checkedIndexes.splice(idx - removed, 1);\n removed++;\n }\n });\n }\n\n public appendUncachedPanelElements(panels: Panel[]): void {\n const options = this.options;\n const fragment = document.createDocumentFragment();\n\n if (options.isEqualSize) {\n const prevVisiblePanels = this.visiblePanels;\n const equalSizeClasses = options.isEqualSize as string[]; // for readability\n const cached: { [className: string]: boolean } = {};\n\n this.visiblePanels = [];\n\n Object.keys(this.panelBboxes).forEach(className => {\n cached[className] = true;\n });\n\n panels.forEach(panel => {\n const overlappedClass = panel.getOverlappedClass(equalSizeClasses);\n if (overlappedClass && !cached[overlappedClass]) {\n if (!options.renderExternal) {\n fragment.appendChild(panel.getElement());\n }\n this.visiblePanels.push(panel);\n cached[overlappedClass] = true;\n } else if (!overlappedClass) {\n if (!options.renderExternal) {\n fragment.appendChild(panel.getElement());\n }\n this.visiblePanels.push(panel);\n }\n });\n prevVisiblePanels.forEach(panel => {\n this.addVisiblePanel(panel);\n });\n } else {\n if (!options.renderExternal) {\n panels.forEach(panel => fragment.appendChild(panel.getElement()));\n }\n this.visiblePanels = panels.filter(panel => Boolean(panel));\n }\n\n if (!options.renderExternal) {\n this.cameraElement.appendChild(fragment);\n }\n }\n\n private updateClonePanels() {\n const panelManager = this.panelManager;\n\n // Clone panels in circular mode\n if (this.options.circular && panelManager.getPanelCount() > 0) {\n this.clonePanels();\n this.updateClonedPanelPositions();\n }\n panelManager.chainAllPanels();\n }\n\n private getVisibleIndexOf(panel: Panel): number {\n return findIndex(this.visiblePanels, visiblePanel => visiblePanel === panel);\n }\n\n private build(): void {\n this.setElements();\n this.applyCSSValue();\n this.setMoveType();\n this.setAxesInstance();\n this.createPanInput();\n this.refreshPanels();\n this.setDefaultPanel();\n this.resize();\n this.moveToDefaultPanel();\n }\n\n private setElements(): void {\n const state = this.state;\n const options = this.options;\n const wrapper = this.flicking.getElement();\n const classPrefix = options.classPrefix;\n\n const viewportCandidate = wrapper.children[0] as HTMLElement;\n const hasViewportElement = viewportCandidate && hasClass(viewportCandidate, `${classPrefix}-viewport`);\n\n const viewportElement = hasViewportElement\n ? viewportCandidate\n : document.createElement(\"div\");\n\n const cameraCandidate = hasViewportElement\n ? viewportElement.children[0] as HTMLElement\n : wrapper.children[0] as HTMLElement;\n const hasCameraElement = cameraCandidate && hasClass(cameraCandidate, `${classPrefix}-camera`);\n\n const cameraElement = hasCameraElement\n ? cameraCandidate\n : document.createElement(\"div\");\n\n if (!hasCameraElement) {\n cameraElement.className = `${classPrefix}-camera`;\n\n const panelElements = hasViewportElement\n ? viewportElement.children\n : wrapper.children;\n\n // Make all panels to be a child of camera element\n // wrapper <- viewport <- camera <- panels[1...n]\n toArray(panelElements).forEach(child => {\n cameraElement.appendChild(child);\n });\n } else {\n state.originalCameraStyle = {\n className: cameraElement.getAttribute(\"class\"),\n style: cameraElement.getAttribute(\"style\"),\n };\n }\n\n if (!hasViewportElement) {\n viewportElement.className = `${classPrefix}-viewport`;\n\n // Add viewport element to wrapper\n wrapper.appendChild(viewportElement);\n } else {\n state.originalViewportStyle = {\n className: viewportElement.getAttribute(\"class\"),\n style: viewportElement.getAttribute(\"style\"),\n };\n }\n\n if (!hasCameraElement || !hasViewportElement) {\n viewportElement.appendChild(cameraElement);\n }\n\n this.viewportElement = viewportElement;\n this.cameraElement = cameraElement;\n state.isViewportGiven = hasViewportElement;\n state.isCameraGiven = hasCameraElement;\n }\n\n private applyCSSValue(): void {\n const options = this.options;\n const viewportElement = this.viewportElement;\n const cameraElement = this.cameraElement;\n const viewportStyle = this.viewportElement.style;\n\n // Set default css values for each element\n applyCSS(viewportElement, DEFAULT_VIEWPORT_CSS);\n applyCSS(cameraElement, DEFAULT_CAMERA_CSS);\n\n viewportElement.style.zIndex = `${options.zIndex}`;\n if (options.horizontal) {\n viewportStyle.minHeight = \"100%\";\n viewportStyle.width = \"100%\";\n } else {\n viewportStyle.minWidth = \"100%\";\n viewportStyle.height = \"100%\";\n }\n if (options.overflow) {\n viewportStyle.overflow = \"visible\";\n }\n\n this.panelManager = new PanelManager(this.cameraElement, options);\n }\n\n private setMoveType(): void {\n const moveType = this.options.moveType as MoveTypeObjectOption;\n\n switch (moveType.type) {\n case MOVE_TYPE.SNAP:\n this.moveType = new Snap(moveType.count);\n break;\n case MOVE_TYPE.FREE_SCROLL:\n this.moveType = new FreeScroll();\n break;\n default:\n throw new Error(\"moveType is not correct!\");\n }\n }\n\n private setAxesInstance(): void {\n const state = this.state;\n const options = this.options;\n\n const scrollArea = state.scrollArea;\n\n this.axes = new Axes({\n flick: {\n range: [scrollArea.prev, scrollArea.next],\n circular: options.circular,\n bounce: [0, 0], // will be updated in resize()\n },\n }, {\n easing: options.panelEffect,\n deceleration: options.deceleration,\n interruptable: true,\n });\n }\n\n private refreshPanels(): void {\n const panelManager = this.panelManager;\n // Panel elements were attached to camera element by Flicking class\n const panelElements = this.cameraElement.children;\n\n // Initialize panels\n const panels = toArray(panelElements).map(\n (el: HTMLElement, idx: number) => new Panel(el, idx, this),\n );\n\n panelManager.replacePanels(panels, []);\n this.visiblePanels = panels.filter(panel => Boolean(panel));\n }\n\n private setDefaultPanel(): void {\n const options = this.options;\n const panelManager = this.panelManager;\n const indexRange = this.panelManager.getRange();\n const index = clamp(options.defaultIndex, indexRange.min, indexRange.max);\n\n this.currentPanel = panelManager.get(index);\n }\n\n private clonePanels() {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n\n const gap = options.gap;\n const viewportSize = state.size;\n const firstPanel = panelManager.firstPanel();\n const lastPanel = panelManager.lastPanel()!;\n\n // There're no panels exist\n if (!firstPanel) {\n return;\n }\n\n // For each panels, clone itself while last panel's position + size is below viewport size\n const panels = panelManager.originalPanels();\n const reversedPanels = panels.concat().reverse();\n\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition() + gap;\n const relativeAnchorPosition = firstPanel.getRelativeAnchorPosition();\n const relativeHangerPosition = this.getRelativeHangerPosition();\n\n const areaPrev = (relativeHangerPosition - relativeAnchorPosition) % sumOriginalPanelSize;\n let sizeSum = 0;\n let panelAtLeftBoundary: Panel | null = null;\n for (const panel of reversedPanels) {\n if (!panel) {\n continue;\n }\n sizeSum += panel.getSize() + gap;\n if (sizeSum >= areaPrev) {\n panelAtLeftBoundary = panel;\n break;\n }\n }\n\n const areaNext = (viewportSize - relativeHangerPosition + relativeAnchorPosition) % sumOriginalPanelSize;\n sizeSum = 0;\n let panelAtRightBoundary: Panel | null = null;\n for (const panel of panels) {\n if (!panel) {\n continue;\n }\n sizeSum += panel.getSize() + gap;\n if (sizeSum >= areaNext) {\n panelAtRightBoundary = panel;\n break;\n }\n }\n\n // Need one more set of clones on prev area of original panel 0\n const needCloneOnPrev = (panelAtLeftBoundary && panelAtRightBoundary)\n && panelAtLeftBoundary.getIndex() !== 0\n && panelAtLeftBoundary.getIndex() <= panelAtRightBoundary.getIndex();\n\n // Visible count of panel 0 on first screen\n const panel0OnFirstscreen = Math.ceil((relativeHangerPosition + firstPanel.getSize() - relativeAnchorPosition) / sumOriginalPanelSize)\n + Math.ceil((viewportSize - relativeHangerPosition + relativeAnchorPosition) / sumOriginalPanelSize)\n - 1; // duplication\n\n const cloneCount = panel0OnFirstscreen\n + (needCloneOnPrev ? 1 : 0);\n const prevCloneCount = panelManager.getCloneCount();\n\n panelManager.setCloneCount(cloneCount);\n if (options.renderExternal) {\n return;\n }\n\n if (cloneCount > prevCloneCount) {\n // should clone more\n for (let cloneIndex = prevCloneCount; cloneIndex < cloneCount; cloneIndex++) {\n const clones = panels.map(origPanel => origPanel.clone(cloneIndex));\n const fragment = document.createDocumentFragment();\n clones.forEach(panel => fragment.appendChild(panel.getElement()));\n\n this.cameraElement.appendChild(fragment);\n this.visiblePanels.push(...clones.filter(clone => Boolean(clone)));\n panelManager.insertClones(cloneIndex, 0, clones);\n }\n } else if (cloneCount < prevCloneCount) {\n // should remove some\n panelManager.removeClonesAfter(cloneCount);\n }\n }\n\n private moveToDefaultPanel(): void {\n const state = this.state;\n const panelManager = this.panelManager;\n const options = this.options;\n const indexRange = this.panelManager.getRange();\n\n const defaultIndex = clamp(options.defaultIndex, indexRange.min, indexRange.max);\n const defaultPanel = panelManager.get(defaultIndex);\n\n let defaultPosition = 0;\n if (defaultPanel) {\n defaultPosition = defaultPanel.getAnchorPosition() - state.relativeHangerPosition;\n defaultPosition = this.canSetBoundMode()\n ? clamp(defaultPosition, state.scrollArea.prev, state.scrollArea.next)\n : defaultPosition;\n }\n\n this.moveCamera(defaultPosition);\n this.axes.setTo({ flick: defaultPosition }, 0);\n }\n\n private updateSize(): void {\n const state = this.state;\n const options = this.options;\n const panels = this.panelManager.originalPanels()\n .filter(panel => Boolean(panel));\n const bbox = this.updateBbox();\n\n const prevSize = state.size;\n // Update size & hanger position\n state.size = options.horizontal\n ? bbox.width\n : bbox.height;\n\n if (prevSize !== state.size) {\n state.relativeHangerPosition = parseArithmeticExpression(options.hanger, state.size);\n state.infiniteThreshold = parseArithmeticExpression(options.infiniteThreshold, state.size);\n }\n\n if (panels.length <= 0) {\n return;\n }\n\n this.resizePanels(panels);\n }\n\n private updateOriginalPanelPositions(): void {\n const gap = this.options.gap;\n const panelManager = this.panelManager;\n\n const firstPanel = panelManager.firstPanel();\n const panels = panelManager.originalPanels();\n\n if (!firstPanel) {\n return;\n }\n\n const currentPanel = this.currentPanel!;\n const nearestPanel = this.nearestPanel;\n const currentState = this.stateMachine.getState();\n const scrollArea = this.state.scrollArea;\n\n // Update panel position && fit to wrapper\n let nextPanelPos = firstPanel.getPosition();\n let maintainingPanel: Panel = firstPanel;\n if (nearestPanel) {\n // We should maintain nearestPanel's position\n const looped = !isBetween(currentState.lastPosition + currentState.delta, scrollArea.prev, scrollArea.next);\n\n maintainingPanel = looped\n ? currentPanel\n : nearestPanel;\n } else if (firstPanel.getIndex() > 0) {\n maintainingPanel = currentPanel;\n }\n\n const panelsBeforeMaintainPanel = panels.slice(0, maintainingPanel.getIndex() + (maintainingPanel.getCloneIndex() + 1) * panels.length);\n const accumulatedSize = panelsBeforeMaintainPanel.reduce((total, panel) => {\n return total + panel.getSize() + gap;\n }, 0);\n\n nextPanelPos = maintainingPanel.getPosition() - accumulatedSize;\n\n panels.forEach(panel => {\n const newPosition = nextPanelPos;\n const panelSize = panel.getSize();\n\n panel.setPosition(newPosition);\n nextPanelPos += panelSize + gap;\n });\n\n if (!this.options.renderOnlyVisible) {\n panels.forEach(panel => panel.setPositionCSS());\n }\n }\n\n private updateClonedPanelPositions(): void {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const clonedPanels = panelManager.clonedPanels()\n .reduce((allClones, clones) => [...allClones, ...clones], [])\n .filter(panel => Boolean(panel));\n\n const scrollArea = state.scrollArea;\n\n const firstPanel = panelManager.firstPanel();\n const lastPanel = panelManager.lastPanel()!;\n\n if (!firstPanel) {\n return;\n }\n\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition() + options.gap;\n\n // Locate all cloned panels linearly first\n for (const panel of clonedPanels) {\n const origPanel = panel.getOriginalPanel();\n const cloneIndex = panel.getCloneIndex();\n const cloneBasePos = sumOriginalPanelSize * (cloneIndex + 1);\n const clonedPanelPos = cloneBasePos + origPanel.getPosition();\n\n panel.setPosition(clonedPanelPos);\n }\n\n let lastReplacePosition = firstPanel.getPosition();\n // reverse() pollutes original array, so copy it with concat()\n for (const panel of clonedPanels.concat().reverse()) {\n const panelSize = panel.getSize();\n const replacePosition = lastReplacePosition - panelSize - options.gap;\n\n if (replacePosition + panelSize <= scrollArea.prev) {\n // Replace is not meaningful, as it won't be seen in current scroll area\n break;\n }\n\n panel.setPosition(replacePosition);\n lastReplacePosition = replacePosition;\n }\n\n if (!this.options.renderOnlyVisible) {\n clonedPanels.forEach(panel => {\n panel.setPositionCSS();\n });\n }\n }\n\n private updateVisiblePanelPositions(): void {\n if (this.options.renderOnlyVisible) {\n this.visiblePanels.forEach(panel => {\n panel.setPositionCSS(this.state.positionOffset);\n });\n }\n }\n\n private updateScrollArea(): void {\n const state = this.state;\n const panelManager = this.panelManager;\n const options = this.options;\n const axes = this.axes;\n\n // Set viewport scrollable area\n const firstPanel = panelManager.firstPanel();\n const lastPanel = panelManager.lastPanel() as Panel;\n const relativeHangerPosition = state.relativeHangerPosition;\n\n if (!firstPanel) {\n state.scrollArea = {\n prev: 0,\n next: 0,\n };\n } else if (this.canSetBoundMode()) {\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition();\n\n if (sumOriginalPanelSize >= state.size) {\n state.scrollArea = {\n prev: firstPanel.getPosition(),\n next: lastPanel.getPosition() + lastPanel.getSize() - state.size,\n };\n } else {\n // Find anchor position of set of the combined panels\n const relAnchorPosOfCombined = parseArithmeticExpression(options.anchor, sumOriginalPanelSize);\n const anchorPos = firstPanel.getPosition() + clamp(\n relAnchorPosOfCombined,\n sumOriginalPanelSize - (state.size - relativeHangerPosition),\n relativeHangerPosition,\n );\n\n state.scrollArea = {\n prev: anchorPos - relativeHangerPosition,\n next: anchorPos - relativeHangerPosition,\n };\n }\n } else if (options.circular) {\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition() + options.gap;\n\n // Maximum scroll extends to first clone sequence's first panel\n state.scrollArea = {\n prev: firstPanel.getAnchorPosition() - relativeHangerPosition,\n next: sumOriginalPanelSize + firstPanel.getAnchorPosition() - relativeHangerPosition,\n };\n } else {\n state.scrollArea = {\n prev: firstPanel.getAnchorPosition() - relativeHangerPosition,\n next: lastPanel.getAnchorPosition() - relativeHangerPosition,\n };\n }\n\n const viewportSize = state.size;\n const bounce = options.bounce;\n\n let parsedBounce: number[];\n if (isArray(bounce)) {\n parsedBounce = (bounce as string[]).map(val => parseArithmeticExpression(val, viewportSize, DEFAULT_OPTIONS.bounce as number));\n } else {\n const parsedVal = parseArithmeticExpression(bounce as number | string, viewportSize, DEFAULT_OPTIONS.bounce as number);\n parsedBounce = [parsedVal, parsedVal];\n }\n\n // Update axes range and bounce\n const flick = axes.axis.flick;\n flick.range = [state.scrollArea.prev, state.scrollArea.next];\n flick.bounce = parsedBounce;\n }\n\n private checkNeedPanel(axesEvent?: any): void {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const currentPanel = this.currentPanel;\n const nearestPanel = this.nearestPanel;\n const currentState = this.stateMachine.getState();\n\n if (!options.infinite) {\n return;\n }\n\n const gap = options.gap;\n const infiniteThreshold = state.infiniteThreshold;\n const maxLastIndex = panelManager.getLastIndex();\n\n if (maxLastIndex < 0) {\n return;\n }\n\n if (!currentPanel || !nearestPanel) {\n // There're no panels\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: null,\n direction: null,\n indexRange: {\n min: 0,\n max: maxLastIndex,\n length: maxLastIndex + 1,\n },\n });\n return;\n }\n\n const originalNearestPosition = nearestPanel.getPosition();\n\n // Check next direction\n let checkingPanel: Panel | null = !currentState.holding && !currentState.playing\n ? currentPanel\n : nearestPanel;\n\n while (checkingPanel) {\n const currentIndex = checkingPanel.getIndex();\n const nextSibling = checkingPanel.nextSibling;\n const lastPanel = panelManager.lastPanel()!;\n const atLastPanel = currentIndex === lastPanel.getIndex();\n const nextIndex = !atLastPanel && nextSibling\n ? nextSibling.getIndex()\n : maxLastIndex + 1;\n const currentNearestPosition = nearestPanel.getPosition();\n const panelRight = checkingPanel.getPosition() + checkingPanel.getSize() - (currentNearestPosition - originalNearestPosition);\n const cameraNext = state.position + state.size;\n\n // There're empty panels between\n const emptyPanelExistsBetween = (nextIndex - currentIndex > 1);\n // Expected prev panel's left position is smaller than camera position\n const overThreshold = panelRight + gap - infiniteThreshold <= cameraNext;\n\n if (emptyPanelExistsBetween && overThreshold) {\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.NEXT,\n indexRange: {\n min: currentIndex + 1,\n max: nextIndex - 1,\n length: nextIndex - currentIndex - 1,\n },\n });\n }\n\n // Trigger needPanel in circular & at max panel index\n if (options.circular && currentIndex === maxLastIndex && overThreshold) {\n const firstPanel = panelManager.firstPanel();\n const firstIndex = firstPanel\n ? firstPanel.getIndex()\n : -1;\n\n if (firstIndex > 0) {\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.NEXT,\n indexRange: {\n min: 0,\n max: firstIndex - 1,\n length: firstIndex,\n },\n });\n }\n }\n\n // Check whether panels are changed\n const lastPanelAfterNeed = panelManager.lastPanel()!;\n const atLastPanelAfterNeed = lastPanelAfterNeed && currentIndex === lastPanelAfterNeed.getIndex();\n\n if (atLastPanelAfterNeed || !overThreshold) {\n break;\n }\n\n checkingPanel = checkingPanel.nextSibling;\n }\n\n // Check prev direction\n checkingPanel = nearestPanel;\n while (checkingPanel) {\n const cameraPrev = state.position;\n const checkingIndex = checkingPanel.getIndex();\n const prevSibling = checkingPanel.prevSibling;\n const firstPanel = panelManager.firstPanel()!;\n const atFirstPanel = checkingIndex === firstPanel.getIndex();\n const prevIndex = !atFirstPanel && prevSibling\n ? prevSibling.getIndex()\n : -1;\n const currentNearestPosition = nearestPanel.getPosition();\n const panelLeft = checkingPanel.getPosition() - (currentNearestPosition - originalNearestPosition);\n\n // There're empty panels between\n const emptyPanelExistsBetween = checkingIndex - prevIndex > 1;\n // Expected prev panel's right position is smaller than camera position\n const overThreshold = panelLeft - gap + infiniteThreshold >= cameraPrev;\n if (emptyPanelExistsBetween && overThreshold) {\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.PREV,\n indexRange: {\n min: prevIndex + 1,\n max: checkingIndex - 1,\n length: checkingIndex - prevIndex - 1,\n },\n });\n }\n\n // Trigger needPanel in circular & at panel 0\n if (options.circular && checkingIndex === 0 && overThreshold) {\n const lastPanel = panelManager.lastPanel();\n\n if (lastPanel && lastPanel.getIndex() < maxLastIndex) {\n const lastIndex = lastPanel.getIndex();\n\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.PREV,\n indexRange: {\n min: lastIndex + 1,\n max: maxLastIndex,\n length: maxLastIndex - lastIndex,\n },\n });\n }\n }\n\n // Check whether panels were changed\n const firstPanelAfterNeed = panelManager.firstPanel();\n const atFirstPanelAfterNeed = firstPanelAfterNeed && checkingIndex === firstPanelAfterNeed.getIndex();\n\n // Looped in circular mode\n if (atFirstPanelAfterNeed || !overThreshold) {\n break;\n }\n\n checkingPanel = checkingPanel.prevSibling;\n }\n }\n\n private triggerNeedPanel(params: {\n axesEvent: any;\n siblingPanel: Panel | null,\n direction: FlickingEvent[\"direction\"];\n indexRange: NeedPanelEvent[\"range\"];\n }): void {\n const { axesEvent, siblingPanel, direction, indexRange } = params;\n const options = this.options;\n const checkedIndexes = this.state.checkedIndexes;\n const alreadyTriggered = checkedIndexes.some(([min, max]) => min === indexRange.min || max === indexRange.max);\n const hasHandler = this.flicking.hasOn(EVENTS.NEED_PANEL);\n\n if (alreadyTriggered || !hasHandler) {\n return;\n }\n\n // Should done before triggering event, as we can directly add panels by event callback\n checkedIndexes.push([indexRange.min, indexRange.max]);\n\n const index = siblingPanel\n ? siblingPanel.getIndex()\n : 0;\n const isTrusted = axesEvent\n ? axesEvent.isTrusted\n : false;\n\n this.triggerEvent(\n EVENTS.NEED_PANEL,\n axesEvent,\n isTrusted,\n {\n index,\n panel: siblingPanel,\n direction,\n range: indexRange,\n fill: (element: ElementLike | ElementLike[]) => {\n const panelManager = this.panelManager;\n if (!siblingPanel) {\n return this.insert(panelManager.getRange().max + 1, element);\n }\n\n const parsedElements = parseElement(element);\n // Slice elements to fit size equal to empty spaces\n const elements = direction === DIRECTION.NEXT\n ? parsedElements.slice(0, indexRange.length)\n : parsedElements.slice(-indexRange.length);\n\n if (direction === DIRECTION.NEXT) {\n if (options.circular && index === panelManager.getLastIndex()) {\n // needPanel event is triggered on last index, insert at index 0\n return this.insert(0, elements);\n } else {\n return siblingPanel.insertAfter(elements);\n }\n } else if (direction === DIRECTION.PREV) {\n if (options.circular && index === 0) {\n // needPanel event is triggered on first index(0), insert at the last index\n return this.insert(indexRange.max - elements.length + 1, elements);\n } else {\n return siblingPanel.insertBefore(elements);\n }\n } else {\n // direction is null when there're no panels exist\n return this.insert(0, elements);\n }\n },\n } as Partial<NeedPanelEvent>,\n );\n }\n\n private updateVisiblePanels() {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const currentState = this.stateMachine.getState();\n const cameraElement = this.cameraElement;\n const { renderExternal, renderOnlyVisible } = options;\n if (!renderOnlyVisible) {\n return;\n }\n\n if (!this.nearestPanel) {\n this.visiblePanels = [];\n while (cameraElement.firstChild) {\n cameraElement.removeChild(cameraElement.firstChild);\n }\n return;\n }\n\n const prevVisiblePanels = this.visiblePanels;\n const newVisiblePanels = this.calcVisiblePanels();\n\n const { addedPanels, removedPanels } = this.checkVisiblePanelChange(prevVisiblePanels, newVisiblePanels);\n\n if (addedPanels.length <= 0 && removedPanels.length <= 0) {\n // Visible panels not changed\n return;\n }\n\n if (currentState.holding) {\n newVisiblePanels.push(...removedPanels);\n } else {\n const firstVisiblePanelPos = newVisiblePanels[0].getPosition();\n state.positionOffset = firstVisiblePanelPos;\n }\n\n newVisiblePanels.forEach(panel => {\n panel.setPositionCSS(state.positionOffset);\n });\n\n if (!renderExternal) {\n if (!currentState.holding) {\n removedPanels.forEach(panel => {\n const panelElement = panel.getElement();\n panelElement.parentNode && cameraElement.removeChild(panelElement);\n });\n }\n\n const fragment = document.createDocumentFragment();\n addedPanels.forEach(panel => {\n fragment.appendChild(panel.getElement());\n });\n\n cameraElement.appendChild(fragment);\n }\n\n const firstVisiblePanel = newVisiblePanels[0];\n const lastVisiblePanel = newVisiblePanels[newVisiblePanels.length - 1];\n const getAbsIndex = (panel: Panel) => panel.getIndex() + (panel.getCloneIndex() + 1) * panelManager.getPanelCount();\n\n const newVisibleRange = {\n min: getAbsIndex(firstVisiblePanel),\n max: getAbsIndex(lastVisiblePanel),\n };\n this.visiblePanels = newVisiblePanels;\n this.flicking.trigger(EVENTS.VISIBLE_CHANGE, {\n type: EVENTS.VISIBLE_CHANGE,\n range: newVisibleRange,\n });\n }\n\n private checkVisiblePanelChange(prevVisiblePanels: Panel[], newVisiblePanels: Panel[]) {\n const prevRefCount = prevVisiblePanels.map(() => 0);\n const newRefCount = newVisiblePanels.map(() => 0);\n\n prevVisiblePanels.forEach((prevPanel, prevIndex) => {\n newVisiblePanels.forEach((newPanel, newIndex) => {\n if (prevPanel === newPanel) {\n prevRefCount[prevIndex]++;\n newRefCount[newIndex]++;\n }\n });\n });\n\n const removedPanels = prevRefCount.reduce((removed: Panel[], count, index) => {\n return count === 0\n ? [...removed, prevVisiblePanels[index]]\n : removed;\n }, []);\n const addedPanels = newRefCount.reduce((added: Panel[], count, index) => {\n return count === 0\n ? [...added, newVisiblePanels[index]]\n : added;\n }, []);\n\n return { removedPanels, addedPanels };\n }\n\n private resizePanels(panels: Panel[]): void {\n const options = this.options;\n const panelBboxes = this.panelBboxes;\n\n if (options.isEqualSize === true) {\n if (!panelBboxes.default) {\n const defaultPanel = panels[0];\n panelBboxes.default = defaultPanel.getBbox();\n }\n\n const defaultBbox = panelBboxes.default;\n\n panels.forEach(panel => {\n panel.resize(defaultBbox);\n });\n return;\n } else if (options.isEqualSize) {\n const equalSizeClasses = options.isEqualSize;\n\n panels.forEach(panel => {\n const overlappedClass = panel.getOverlappedClass(equalSizeClasses);\n if (overlappedClass) {\n panel.resize(panelBboxes[overlappedClass]);\n panelBboxes[overlappedClass] = panel.getBbox();\n } else {\n panel.resize();\n }\n });\n return;\n }\n panels.forEach(panel => {\n panel.resize();\n });\n }\n\n private createPanInput() {\n const options = this.options;\n\n this.panInput = new PanInput(this.viewportElement, {\n inputType: options.inputType,\n thresholdAngle: options.thresholdAngle,\n iOSEdgeSwipeThreshold: options.iOSEdgeSwipeThreshold,\n scale: options.horizontal ? [-1, 0] : [0, -1],\n releaseOnScroll: true,\n });\n\n this.axes.connect(options.horizontal ? [\"flick\", \"\"] : [\"\", \"flick\"], this.panInput);\n }\n}\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Flicking from \"../Flicking\";\n\nclass AutoResizer {\n private flicking: Flicking;\n private enabled: boolean;\n private resizeObserver: ResizeObserver | null;\n\n private skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n return;\n }\n this.onResize();\n });\n })();\n\n public constructor(flicking: Flicking) {\n this.flicking = flicking;\n this.enabled = false;\n this.resizeObserver = null;\n }\n\n public enable(): this {\n const flicking = this.flicking;\n\n if (this.enabled) {\n this.disable();\n }\n\n if (flicking.options.useResizeObserver && !!window.ResizeObserver) {\n const flickingEl = flicking.getElement();\n const viewportSizeNot0 = flickingEl.clientWidth !== 0 || flickingEl.clientHeight !== 0;\n\n const resizeObserver = viewportSizeNot0\n ? new ResizeObserver(this.skipFirstResize)\n : new ResizeObserver(this.onResize);\n\n resizeObserver.observe(flickingEl);\n\n this.resizeObserver = resizeObserver;\n } else {\n window.addEventListener(\"resize\", this.onResize);\n }\n\n this.enabled = true;\n\n return this;\n }\n\n public disable(): this {\n if (!this.enabled) {\n return this;\n }\n\n const resizeObserver = this.resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this.resizeObserver = null;\n } else {\n window.removeEventListener(\"resize\", this.onResize);\n }\n\n this.enabled = false;\n\n return this;\n }\n\n private onResize = () => {\n this.flicking.resize();\n }\n}\n\nexport default AutoResizer;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Component from \"@egjs/component\";\nimport ImReady from \"@egjs/imready\";\nimport { DiffResult } from \"@egjs/list-differ\";\nimport Viewport from \"./components/Viewport\";\nimport Panel from \"./components/Panel\";\nimport AutoResizer from \"./components/AutoResizer\";\n\nimport { merge, getProgress, parseElement, isString, counter, findIndex } from \"./utils\";\nimport { DEFAULT_OPTIONS, EVENTS, DIRECTION, AXES_EVENTS, STATE_TYPE, DEFAULT_MOVE_TYPE_OPTIONS } from \"./consts\";\nimport {\n FlickingOptions,\n FlickingEvent,\n Direction,\n EventType,\n FlickingPanel,\n TriggerCallback,\n FlickingContext,\n FlickingStatus,\n Plugin,\n ElementLike,\n DestroyOption,\n BeforeSyncResult,\n SyncResult,\n ChangeEvent,\n SelectEvent,\n NeedPanelEvent,\n VisibleChangeEvent,\n ContentErrorEvent,\n MoveTypeStringOption,\n ValueOf,\n} from \"./types\";\n\n/**\n * @memberof eg\n * @extends eg.Component\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\" , \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"4.X+\"}\n * @requires {@link https://github.com/naver/egjs-component|eg.Component}\n * @requires {@link https://github.com/naver/egjs-axes|eg.Axes}\n * @see Easing Functions Cheat Sheet {@link http://easings.net/} <ko>이징 함수 Cheat Sheet {@link http://easings.net/}</ko>\n */\nclass Flicking extends Component<{\n holdStart: FlickingEvent;\n holdEnd: FlickingEvent;\n moveStart: FlickingEvent;\n move: FlickingEvent;\n moveEnd: FlickingEvent;\n change: ChangeEvent;\n restore: FlickingEvent;\n select: SelectEvent;\n needPanel: NeedPanelEvent;\n visibleChange: VisibleChangeEvent;\n contentError: ContentErrorEvent;\n}> {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @example\n * eg.Flicking.VERSION; // ex) 3.0.0\n * @memberof eg.Flicking\n */\n public static VERSION: string = \"#__VERSION__#\";\n /**\n * Direction constant - \"PREV\" or \"NEXT\"\n * @ko 방향 상수 - \"PREV\" 또는 \"NEXT\"\n * @type {object}\n * @property {\"PREV\"} PREV - Prev direction from current hanger position.<br/>It's `left(←️)` direction when `horizontal: true`.<br/>Or, `up(↑️)` direction when `horizontal: false`.<ko>현재 행어를 기준으로 이전 방향.<br/>`horizontal: true`일 경우 `왼쪽(←️)` 방향.<br/>`horizontal: false`일 경우 `위쪽(↑️)`방향이다.</ko>\n * @property {\"NEXT\"} NEXT - Next direction from current hanger position.<br/>It's `right(→)` direction when `horizontal: true`.<br/>Or, `down(↓️)` direction when `horizontal: false`.<ko>현재 행어를 기준으로 다음 방향.<br/>`horizontal: true`일 경우 `오른쪽(→)` 방향.<br/>`horizontal: false`일 경우 `아래쪽(↓️)`방향이다.</ko>\n * @example\n * eg.Flicking.DIRECTION.PREV; // \"PREV\"\n * eg.Flicking.DIRECTION.NEXT; // \"NEXT\"\n */\n public static DIRECTION: Direction = DIRECTION;\n\n /**\n * Event type object with event name strings.\n * @ko 이벤트 이름 문자열들을 담은 객체\n * @type {object}\n * @property {\"holdStart\"} HOLD_START - holdStart event<ko>holdStart 이벤트</ko>\n * @property {\"holdEnd\"} HOLD_END - holdEnd event<ko>holdEnd 이벤트</ko>\n * @property {\"moveStart\"} MOVE_START - moveStart event<ko>moveStart 이벤트</ko>\n * @property {\"move\"} MOVE - move event<ko>move 이벤트</ko>\n * @property {\"moveEnd\"} MOVE_END - moveEnd event<ko>moveEnd 이벤트</ko>\n * @property {\"change\"} CHANGE - change event<ko>change 이벤트</ko>\n * @property {\"restore\"} RESTORE - restore event<ko>restore 이벤트</ko>\n * @property {\"select\"} SELECT - select event<ko>select 이벤트</ko>\n * @property {\"needPanel\"} NEED_PANEL - needPanel event<ko>needPanel 이벤트</ko>\n * @example\n * eg.Flicking.EVENTS.MOVE_START; // \"MOVE_START\"\n */\n public static EVENTS: EventType = EVENTS;\n\n public options: FlickingOptions;\n\n private wrapper: HTMLElement;\n private viewport: Viewport;\n private autoResizer: AutoResizer;\n private contentsReadyChecker: ImReady | null = null;\n\n private eventContext: FlickingContext;\n private isPanelChangedAtBeforeSync: boolean = false;\n\n /**\n * @param element A base element for the eg.Flicking module. When specifying a value as a `string` type, you must specify a css selector string to select the element.<ko>eg.Flicking 모듈을 사용할 기준 요소. `string`타입으로 값 지정시 요소를 선택하기 위한 css 선택자 문자열을 지정해야 한다.</ko>\n * @param options An option object of the eg.Flicking module<ko>eg.Flicking 모듈의 옵션 객체</ko>\n * @param {string} [options.classPrefix=\"eg-flick\"] A prefix of class names will be added for the panels, viewport, and camera.<ko>패널들과 뷰포트, 카메라에 추가될 클래스 이름의 접두사.</ko>\n * @param {number} [options.deceleration=0.0075] Deceleration value for panel movement animation for animation triggered by manual user input. A higher value means a shorter running time.<ko>사용자의 동작으로 가속도가 적용된 패널 이동 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아진다.</ko>\n * @param {boolean} [options.horizontal=true] The direction of panel movement. (true: horizontal, false: vertical)<ko>패널 이동 방향. (true: 가로방향, false: 세로방향)</ko>\n * @param {boolean} [options.circular=false] Enables circular mode, which connects first/last panel for continuous scrolling.<ko>순환 모드를 활성화한다. 순환 모드에서는 양 끝의 패널이 서로 연결되어 끊김없는 스크롤이 가능하다.</ko>\n * @param {boolean} [options.infinite=false] Enables infinite mode, which can automatically trigger needPanel until reaching the last panel's index reaches the lastIndex.<ko>무한 모드를 활성화한다. 무한 모드에서는 needPanel 이벤트를 자동으로 트리거한다. 해당 동작은 마지막 패널의 인덱스가 lastIndex와 일치할때까지 일어난다.</ko>\n * @param {number} [options.infiniteThreshold=0] A Threshold from viewport edge before triggering `needPanel` event in infinite mode.<ko>무한 모드에서 `needPanel`이벤트가 발생하기 위한 뷰포트 끝으로부터의 최대 거리.</ko>\n * @param {number} [options.lastIndex=Infinity] Maximum panel index that Flicking can set. Flicking won't trigger `needPanel` when the event's panel index is greater than it.<br/>Also, if the last panel's index reached a given index, you can't add more panels.<ko>Flicking이 설정 가능한 패널의 최대 인덱스. `needPanel` 이벤트에 지정된 인덱스가 최대 패널의 개수보다 같거나 커야 하는 경우에 이벤트를 트리거하지 않게 한다.<br>또한, 마지막 패널의 인덱스가 주어진 인덱스와 동일할 경우, 새로운 패널을 더 이상 추가할 수 없다.</ko>\n * @param {number} [options.threshold=40] Movement threshold to change panel(unit: pixel). It should be dragged above the threshold to change the current panel.<ko>패널 변경을 위한 이동 임계값 (단위: 픽셀). 주어진 값 이상으로 스크롤해야만 패널 변경이 가능하다.</ko>\n * @param {number} [options.duration=100] Duration of the panel movement animation. (unit: ms)<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @param {function} [options.panelEffect=x => 1 - Math.pow(1 - x, 3)] An easing function applied to the panel movement animation. Default value is `easeOutCubic`.<ko>패널 이동 애니메이션에 적용할 easing함수. 기본값은 `easeOutCubic`이다.</ko>\n * @param {number} [options.defaultIndex=0] Index of the panel to set as default when initializing. A zero-based integer.<ko>초기화시 지정할 디폴트 패널의 인덱스로, 0부터 시작하는 정수.</ko>\n * @param {string[]} [options.inputType=[\"touch,\"mouse\"]] Types of input devices to enable.({@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption Reference})<ko>활성화할 입력 장치 종류. ({@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption 참고})</ko>\n * @param {number} [options.thresholdAngle=45] The threshold angle value(0 ~ 90).<br>If the input angle from click/touched position is above or below this value in horizontal and vertical mode each, scrolling won't happen.<ko>스크롤 동작을 막기 위한 임계각(0 ~ 90).<br>클릭/터치한 지점으로부터 계산된 사용자 입력의 각도가 horizontal/vertical 모드에서 각각 크거나 작으면, 스크롤 동작이 이루어지지 않는다.</ko>\n * @param {number|string|number[]|string[]} [options.bounce=[10,10]] The size value of the bounce area. Only can be enabled when `circular=false`.<br>You can set different bounce value for prev/next direction by using array.<br>`number` for px value, and `string` for px, and % value relative to viewport size.(ex - 0, \"10px\", \"20%\")<ko>바운스 영역의 크기값. `circular=false`인 경우에만 사용할 수 있다.<br>배열을 통해 prev/next 방향에 대해 서로 다른 바운스 값을 지정 가능하다.<br>`number`를 통해 px값을, `stirng`을 통해 px 혹은 뷰포트 크기 대비 %값을 사용할 수 있다.(ex - 0, \"10px\", \"20%\")</ko>\n * @param {boolean} [options.autoResize=false] Whether the `resize` method should be called automatically after a window resize event.<ko>window의 `resize` 이벤트 이후 자동으로 resize()메소드를 호출할지의 여부.</ko>\n * @param {boolean} [options.adaptive=false] Whether the height(horizontal)/width(vertical) of the viewport element reflects the height/width value of the panel after completing the movement.<ko>목적 패널로 이동한 후 그 패널의 높이(horizontal)/너비(vertical)값을 뷰포트 요소의 높이/너비값에 반영할지 여부.</ko>\n * @param {number|\"\"} [options.zIndex=2000] z-index value for viewport element.<ko>뷰포트 엘리먼트의 z-index 값.</ko>\n * @param {boolean} [options.bound=false] Prevent the view from going out of the first/last panel. Only can be enabled when `circular=false`.<ko>뷰가 첫번째와 마지막 패널 밖으로 나가는 것을 막아준다. `circular=false`인 경우에만 사용할 수 있다.</ko>\n * @param {boolean} [options.overflow=false] Disables CSS property `overflow: hidden` in viewport if `true`.<ko>`true`로 설정시 뷰포트에 `overflow: hidden` 속성을 해제한다.</ko>\n * @param {string} [options.hanger=\"50%\"] The reference position of the hanger in the viewport, which hangs panel anchors should be stopped at.<br>It should be provided in px or % value of viewport size.<br>You can combinate those values with plus/minus sign.<br>ex) \"50\", \"100px\", \"0%\", \"25% + 100px\"<ko>뷰포트 내부의 행어의 위치. 패널의 앵커들이 뷰포트 내에서 멈추는 지점에 해당한다.<br>px값이나, 뷰포트의 크기 대비 %값을 사용할 수 있고, 이를 + 혹은 - 기호로 연계하여 사용할 수도 있다.<br>예) \"50\", \"100px\", \"0%\", \"25% + 100px\"</ko>\n * @param {string} [options.anchor=\"50%\"] The reference position of the anchor in panels, which can be hanged by viewport hanger.<br>It should be provided in px or % value of panel size.<br>You can combinate those values with plus/minus sign.<br>ex) \"50\", \"100px\", \"0%\", \"25% + 100px\"<ko>패널 내부의 앵커의 위치. 뷰포트의 행어와 연계하여 패널이 화면 내에서 멈추는 지점을 설정할 수 있다.<br>px값이나, 패널의 크기 대비 %값을 사용할 수 있고, 이를 + 혹은 - 기호로 연계하여 사용할 수도 있다.<br>예) \"50\", \"100px\", \"0%\", \"25% + 100px\"</ko>\n * @param {number} [options.gap=0] Space value between panels. Should be given in number.(px)<ko>패널간에 부여할 간격의 크기를 나타내는 숫자.(px)</ko>\n * @param {eg.Flicking.MoveTypeOption} [options.moveType=\"snap\"] Movement style by user input. (ex: snap, freeScroll)<ko>사용자 입력에 의한 이동 방식.(ex: snap, freeScroll)</ko>\n * @param {boolean} [options.useOffset=false] Whether to use `offsetWidth`/`offsetHeight` instead of `getBoundingClientRect` for panel/viewport size calculation.<br/>You can use this option to calculate the original panel size when CSS transform is applied to viewport or panel.<br/>⚠️ If panel size is not fixed integer value, there can be a 1px gap between panels.<ko>패널과 뷰포트의 크기를 계산할 때 `offsetWidth`/`offsetHeight`를 `getBoundingClientRect` 대신 사용할지 여부.<br/>패널이나 뷰포트에 CSS transform이 설정되어 있을 때 원래 패널 크기를 계산하려면 옵션을 활성화한다.<br/>⚠️ 패널의 크기가 정수로 고정되어있지 않다면 패널 사이에 1px의 공간이 생길 수 있다.</ko>\n * @param {boolean} [options.renderOnlyVisible=false] Whether to render visible panels only. This can dramatically increase performance when there're many panels.<ko>보이는 패널만 렌더링할지 여부를 설정한다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있다.</ko>\n * @param {boolean|string[]} [options.isEqualSize=false] This option indicates whether all panels have the same size(true) of first panel, or it can hold a list of class names that determines panel size.<br/>Enabling this option can increase performance while recalculating panel size.<ko>모든 패널의 크기가 동일한지(true), 혹은 패널 크기를 결정하는 패널 클래스들의 리스트.<br/>이 옵션을 설정하면 패널 크기 재설정시에 성능을 높일 수 있다.</ko>\n * @param {boolean} [options.isConstantSize=false] Whether all panels have a constant size that won't be changed after resize. Enabling this option can increase performance while recalculating panel size.<ko>모든 패널의 크기가 불변인지의 여부. 이 옵션을 'true'로 설정하면 패널 크기 재설정시에 성능을 높일 수 있다.</ko>\n * @param {boolean} [options.renderExternal=false] Whether to use external rendering. It will delegate DOM manipulation and can synchronize the rendered state by calling `sync()` method. You can use this option to use in frameworks like React, Vue, Angular, which has its states and rendering methods.<ko>외부 렌더링을 사용할 지의 여부. 이 옵션을 사용시 렌더링을 외부에 위임할 수 있고, `sync()`를 호출하여 그 상태를 동기화할 수 있다. 이 옵션을 사용하여, React, Vue, Angular 등 자체적인 상태와 렌더링 방법을 갖는 프레임워크에 대응할 수 있다.</ko>\n * @param {boolean} [options.resizeOnContentsReady=false] Whether to resize the Flicking after the image/video elements inside viewport are ready.<br/>Use this property to prevent wrong Flicking layout caused by dynamic image / video sizes.<ko>Flicking 내부의 이미지 / 비디오 엘리먼트들이 전부 로드되었을 때 Flicking의 크기를 재계산하기 위한 옵션.<br/>이미지 / 비디오 크기가 고정 크기가 아닐 경우 사용하여 레이아웃이 잘못되는 것을 방지할 수 있다.</ko>\n * @param {boolean} [options.useResizeObserver=true] Whether to listen {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}'s event instead of Window's {@link https://developer.mozilla.org/ko/docs/Web/API/Window/resize_event resize} event when using the `autoResize` option<ko>autoResize 옵션 사용시 {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}의 이벤트를 Window객체의 {@link https://developer.mozilla.org/ko/docs/Web/API/Window/resize_event resize} 이벤트 대신 수신할지 여부를 설정합니다</ko>\n * @param {boolean} [options.collectStatistics=true] Whether to collect statistics on how you are using `Flicking`. These statistical data do not contain any personal information and are used only as a basis for the development of a user-friendly product.<ko>어떻게 `Flicking`을 사용하고 있는지에 대한 통계 수집 여부를 나타낸다. 이 통계자료는 개인정보를 포함하고 있지 않으며 오직 사용자 친화적인 제품으로 발전시키기 위한 근거자료로서 활용한다.</ko>\n */\n constructor(\n element: string | HTMLElement,\n options: Partial<FlickingOptions> = {},\n ) {\n super();\n\n // Set flicking wrapper user provided\n let wrapper: HTMLElement | null;\n if (isString(element)) {\n wrapper = document.querySelector(element);\n if (!wrapper) {\n throw new Error(\"Base element doesn't exist.\");\n }\n } else if (element.nodeName && element.nodeType === 1) {\n wrapper = element;\n } else {\n throw new Error(\"Element should be provided in string or HTMLElement.\");\n }\n\n this.wrapper = wrapper;\n // Override default options\n this.options = merge({}, DEFAULT_OPTIONS, options) as FlickingOptions;\n // Override moveType option\n const currentOptions = this.options;\n const moveType = currentOptions.moveType as MoveTypeStringOption;\n\n if (moveType in DEFAULT_MOVE_TYPE_OPTIONS) {\n currentOptions.moveType = DEFAULT_MOVE_TYPE_OPTIONS[moveType as keyof typeof DEFAULT_MOVE_TYPE_OPTIONS];\n }\n\n // Make viewport instance with panel container element\n this.viewport = new Viewport(this, this.options, this.triggerEvent);\n this.autoResizer = new AutoResizer(this);\n\n this.listenInput();\n this.listenResize();\n }\n\n /**\n * Move to the previous panel if it exists.\n * @ko 이전 패널이 존재시 해당 패널로 이동한다.\n * @param [duration=options.duration] Duration of the panel movement animation.(unit: ms)<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public prev(duration?: number): this {\n const currentPanel = this.getCurrentPanel();\n const currentState = this.viewport.stateMachine.getState();\n\n if (currentPanel && currentState.type === STATE_TYPE.IDLE) {\n const prevPanel = currentPanel.prev();\n if (prevPanel) {\n prevPanel.focus(duration);\n }\n }\n\n return this;\n }\n\n /**\n * Move to the next panel if it exists.\n * @ko 다음 패널이 존재시 해당 패널로 이동한다.\n * @param [duration=options.duration] Duration of the panel movement animation(unit: ms).<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public next(duration?: number): this {\n const currentPanel = this.getCurrentPanel();\n const currentState = this.viewport.stateMachine.getState();\n\n if (currentPanel && currentState.type === STATE_TYPE.IDLE) {\n const nextPanel = currentPanel.next();\n if (nextPanel) {\n nextPanel.focus(duration);\n }\n }\n\n return this;\n }\n\n /**\n * Move to the panel of given index.\n * @ko 주어진 인덱스에 해당하는 패널로 이동한다.\n * @param index The index number of the panel to move.<ko>이동할 패널의 인덱스 번호.</ko>\n * @param duration [duration=options.duration] Duration of the panel movement.(unit: ms)<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public moveTo(index: number, duration?: number): this {\n const viewport = this.viewport;\n const panel = viewport.panelManager.get(index);\n const state = viewport.stateMachine.getState();\n\n if (!panel || state.type !== STATE_TYPE.IDLE) {\n return this;\n }\n\n const anchorPosition = panel.getAnchorPosition();\n const hangerPosition = viewport.getHangerPosition();\n\n let targetPanel = panel;\n if (this.options.circular) {\n const scrollAreaSize = viewport.getScrollAreaSize();\n // Check all three possible locations, find the nearest position among them.\n const possiblePositions = [\n anchorPosition - scrollAreaSize,\n anchorPosition,\n anchorPosition + scrollAreaSize,\n ];\n const nearestPosition = possiblePositions.reduce((nearest, current) => {\n return (Math.abs(current - hangerPosition) < Math.abs(nearest - hangerPosition))\n ? current\n : nearest;\n }, Infinity) - panel.getRelativeAnchorPosition();\n\n const identicals = panel.getIdenticalPanels();\n const offset = nearestPosition - anchorPosition;\n if (offset > 0) {\n // First cloned panel is nearest\n targetPanel = identicals[1];\n } else if (offset < 0) {\n // Last cloned panel is nearest\n targetPanel = identicals[identicals.length - 1];\n }\n\n targetPanel = targetPanel.clone(targetPanel.getCloneIndex(), true);\n targetPanel.setPosition(nearestPosition);\n }\n const currentIndex = this.getIndex();\n\n if (hangerPosition === targetPanel.getAnchorPosition() && currentIndex === index) {\n return this;\n }\n\n const eventType = panel.getIndex() === viewport.getCurrentIndex()\n ? \"\"\n : EVENTS.CHANGE;\n\n viewport.moveTo(\n targetPanel,\n viewport.findEstimatedPosition(targetPanel),\n eventType,\n null,\n duration,\n );\n return this;\n }\n\n /**\n * Return index of the current panel. `-1` if no panel exists.\n * @ko 현재 패널의 인덱스 번호를 반환한다. 패널이 하나도 없을 경우 `-1`을 반환한다.\n * @return Current panel's index, zero-based integer.<ko>현재 패널의 인덱스 번호. 0부터 시작하는 정수.</ko>\n */\n public getIndex(): number {\n return this.viewport.getCurrentIndex();\n }\n\n /**\n * Return the wrapper element user provided in constructor.\n * @ko 사용자가 생성자에서 제공한 래퍼 엘리먼트를 반환한다.\n * @return Wrapper element user provided.<ko>사용자가 제공한 래퍼 엘리먼트.</ko>\n */\n public getElement(): HTMLElement {\n return this.wrapper;\n }\n\n /**\n * Return the viewport element's size.\n * @ko 뷰포트 엘리먼트의 크기를 반환한다.\n * @return Width if horizontal: true, height if horizontal: false\n */\n public getSize(): number {\n return this.viewport.getSize();\n }\n\n /**\n * Return current panel. `null` if no panel exists.\n * @ko 현재 패널을 반환한다. 패널이 하나도 없을 경우 `null`을 반환한다.\n * @return Current panel.<ko>현재 패널.</ko>\n */\n public getCurrentPanel(): FlickingPanel | null {\n const viewport = this.viewport;\n const panel = viewport.getCurrentPanel();\n return panel\n ? panel\n : null;\n }\n\n /**\n * Return the panel of given index. `null` if it doesn't exists.\n * @ko 주어진 인덱스에 해당하는 패널을 반환한다. 해당 패널이 존재하지 않을 시 `null`이다.\n * @return Panel of given index.<ko>주어진 인덱스에 해당하는 패널.</ko>\n */\n public getPanel(index: number): FlickingPanel | null {\n const viewport = this.viewport;\n const panel = viewport.panelManager.get(index);\n return panel\n ? panel\n : null;\n }\n\n /**\n * Return all panels.\n * @ko 모든 패널들을 반환한다.\n * @param - Should include cloned panels or not.<ko>복사된 패널들을 포함할지의 여부.</ko>\n * @return All panels.<ko>모든 패널들.</ko>\n */\n public getAllPanels(includeClone?: boolean): FlickingPanel[] {\n const viewport = this.viewport;\n const panelManager = viewport.panelManager;\n const panels = includeClone\n ? panelManager.allPanels()\n : panelManager.originalPanels();\n\n return panels\n .filter(panel => !!panel);\n }\n\n /**\n * Return the panels currently shown in viewport area.\n * @ko 현재 뷰포트 영역에서 보여지고 있는 패널들을 반환한다.\n * @return Panels currently shown in viewport area.<ko>현재 뷰포트 영역에 보여지는 패널들</ko>\n */\n public getVisiblePanels(): FlickingPanel[] {\n return this.viewport.calcVisiblePanels();\n }\n\n /**\n * Return length of original panels.\n * @ko 원본 패널의 개수를 반환한다.\n * @return Length of original panels.<ko>원본 패널의 개수</ko>\n */\n public getPanelCount(): number {\n return this.viewport.panelManager.getPanelCount();\n }\n\n /**\n * Return how many groups of clones are created.\n * @ko 몇 개의 클론 그룹이 생성되었는지를 반환한다.\n * @return Length of cloned panel groups.<ko>클론된 패널 그룹의 개수</ko>\n */\n public getCloneCount(): number {\n return this.viewport.panelManager.getCloneCount();\n }\n\n /**\n * Get maximum panel index for `infinite` mode.\n * @ko `infinite` 모드에서 적용되는 추가 가능한 패널의 최대 인덱스 값을 반환한다.\n * @see {@link eg.Flicking.FlickingOptions}\n * @return Maximum index of panel that can be added.<ko>최대 추가 가능한 패널의 인덱스.</ko>\n */\n public getLastIndex(): number {\n return this.viewport.panelManager.getLastIndex();\n }\n\n /**\n * Set maximum panel index for `infinite' mode.<br>[needPanel]{@link eg.Flicking#events:needPanel} won't be triggered anymore when last panel's index reaches it.<br>Also, you can't add more panels after it.\n * @ko `infinite` 모드에서 적용되는 패널의 최대 인덱스를 설정한다.<br>마지막 패널의 인덱스가 설정한 값에 도달할 경우 더 이상 [needPanel]{@link eg.Flicking#events:needPanel} 이벤트가 발생되지 않는다.<br>또한, 설정한 인덱스 이후로 새로운 패널을 추가할 수 없다.\n * @param - Maximum panel index.\n * @see {@link eg.Flicking.FlickingOptions}\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public setLastIndex(index: number): this {\n this.viewport.setLastIndex(index);\n\n return this;\n }\n\n /**\n * Return panel movement animation.\n * @ko 현재 패널 이동 애니메이션이 진행 중인지를 반환한다.\n * @return Is animating or not.<ko>애니메이션 진행 여부.</ko>\n */\n public isPlaying(): boolean {\n return this.viewport.stateMachine.getState().playing;\n }\n\n /**\n * Unblock input devices.\n * @ko 막았던 입력 장치로부터의 입력을 푼다.\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public enableInput(): this {\n this.viewport.enable();\n\n return this;\n }\n\n /**\n * Block input devices.\n * @ko 입력 장치로부터의 입력을 막는다.\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public disableInput(): this {\n this.viewport.disable();\n\n return this;\n }\n\n /**\n * Get current flicking status. You can restore current state by giving returned value to [setStatus()]{@link eg.Flicking#setStatus}.\n * @ko 현재 상태 값을 반환한다. 반환받은 값을 [setStatus()]{@link eg.Flicking#setStatus} 메소드의 인자로 지정하면 현재 상태를 복원할 수 있다.\n * @return An object with current status value information.<ko>현재 상태값 정보를 가진 객체.</ko>\n */\n public getStatus(): FlickingStatus {\n const viewport = this.viewport;\n\n const panels = viewport.panelManager.originalPanels()\n .filter(panel => !!panel)\n .map(panel => {\n return {\n html: panel.getElement().outerHTML,\n index: panel.getIndex(),\n position: panel.getPosition(),\n };\n });\n\n return {\n index: viewport.getCurrentIndex(),\n panels,\n position: viewport.getCameraPosition(),\n };\n }\n\n /**\n * Restore to the state of the `status`.\n * @ko `status`의 상태로 복원한다.\n * @param status Status value to be restored. You can specify the return value of the [getStatus()]{@link eg.Flicking#getStatus} method.<ko>복원할 상태 값. [getStatus()]{@link eg.Flicking#getStatus}메서드의 반환값을 지정하면 된다.</ko>\n */\n public setStatus(status: FlickingStatus): void {\n this.viewport.restore(status);\n }\n\n /**\n * Add plugins that can have different effects on Flicking.\n * @ko 플리킹에 다양한 효과를 부여할 수 있는 플러그인을 추가한다.\n * @param - The plugin(s) to add.<ko>추가할 플러그인(들).</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public addPlugins(plugins: Plugin | Plugin[]) {\n this.viewport.addPlugins(plugins);\n return this;\n }\n\n /**\n * Remove plugins from Flicking.\n * @ko 플리킹으로부터 플러그인들을 제거한다.\n * @param - The plugin(s) to remove.<ko>제거 플러그인(들).</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public removePlugins(plugins: Plugin | Plugin[]) {\n this.viewport.removePlugins(plugins);\n return this;\n }\n\n /**\n * Return the reference element and all its children to the state they were in before the instance was created. Remove all attached event handlers. Specify `null` for all attributes of the instance (including inherited attributes).\n * @ko 기준 요소와 그 하위 패널들을 인스턴스 생성전의 상태로 되돌린다. 부착된 모든 이벤트 핸들러를 탈거한다. 인스턴스의 모든 속성(상속받은 속성포함)에 `null`을 지정한다.\n * @example\n * const flick = new eg.Flicking(\"#flick\");\n * flick.destroy();\n * console.log(flick.moveTo); // null\n */\n public destroy(option: Partial<DestroyOption> = {}): void {\n this.off();\n\n this.autoResizer.disable();\n this.viewport.destroy(option);\n this.contentsReadyChecker?.destroy();\n\n // release resources\n for (const x in this) {\n (this as any)[x] = null;\n }\n }\n\n /**\n * Update panels to current state.\n * @ko 패널들을 현재 상태에 맞춰 갱신한다.\n * @method\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public resize = (): this => {\n const viewport = this.viewport;\n const options = this.options;\n const wrapper = this.getElement();\n\n const allPanels = viewport.panelManager.allPanels();\n if (!options.isConstantSize) {\n allPanels\n .filter(panel => !!panel)\n .forEach(panel => panel.unCacheBbox());\n }\n\n const shouldResetElements = options.renderOnlyVisible\n && !options.isConstantSize\n && options.isEqualSize !== true;\n\n // Temporarily set parent's height to prevent scroll (#333)\n const parent = wrapper.parentElement!;\n const origStyle = parent.style.height;\n parent.style.height = `${parent.offsetHeight}px`;\n\n viewport.unCacheBbox();\n // This should be done before adding panels, to lower performance issue\n viewport.updateBbox();\n\n if (shouldResetElements) {\n viewport.appendUncachedPanelElements(allPanels as Panel[]);\n }\n\n viewport.resize();\n parent.style.height = origStyle;\n\n return this;\n }\n\n /**\n * Add new panels at the beginning of panels.\n * @ko 제일 앞에 새로운 패널을 추가한다.\n * @param element - Either HTMLElement, HTML string, or array of them.<br>It can be also HTML string of multiple elements with same depth.<ko>HTMLElement 혹은 HTML 문자열, 혹은 그것들의 배열도 가능하다.<br>또한, 같은 depth의 여러 개의 엘리먼트에 해당하는 HTML 문자열도 가능하다.</ko>\n * @return Array of appended panels.<ko>추가된 패널들의 배열</ko>\n * @example\n * // Suppose there were no panels at initialization\n * const flicking = new eg.Flicking(\"#flick\");\n * flicking.replace(3, document.createElement(\"div\")); // Add new panel at index 3\n * flicking.prepend(\"\\<div\\>Panel\\</div\\>\"); // Prepended at index 2\n * flicking.prepend([\"\\<div\\>Panel\\</div\\>\", document.createElement(\"div\")]); // Prepended at index 0, 1\n * flicking.prepend(\"\\<div\\>Panel\\</div\\>\"); // Prepended at index 0, pushing every panels behind it.\n */\n public prepend(element: ElementLike | ElementLike[]): FlickingPanel[] {\n const viewport = this.viewport;\n const parsedElements = parseElement(element);\n\n const insertingIndex = Math.max(viewport.panelManager.getRange().min - parsedElements.length, 0);\n const prependedPanels = viewport.insert(insertingIndex, parsedElements);\n\n this.checkContentsReady(prependedPanels);\n\n return prependedPanels;\n }\n\n /**\n * Add new panels at the end of panels.\n * @ko 제일 끝에 새로운 패널을 추가한다.\n * @param element - Either HTMLElement, HTML string, or array of them.<br>It can be also HTML string of multiple elements with same depth.<ko>HTMLElement 혹은 HTML 문자열, 혹은 그것들의 배열도 가능하다.<br>또한, 같은 depth의 여러 개의 엘리먼트에 해당하는 HTML 문자열도 가능하다.</ko>\n * @return Array of appended panels.<ko>추가된 패널들의 배열</ko>\n * @example\n * // Suppose there were no panels at initialization\n * const flicking = new eg.Flicking(\"#flick\");\n * flicking.append(document.createElement(\"div\")); // Appended at index 0\n * flicking.append(\"\\<div\\>Panel\\</div\\>\"); // Appended at index 1\n * flicking.append([\"\\<div\\>Panel\\</div\\>\", document.createElement(\"div\")]); // Appended at index 2, 3\n * // Even this is possible\n * flicking.append(\"\\<div\\>Panel 1\\</div\\>\\<div\\>Panel 2\\</div\\>\"); // Appended at index 4, 5\n */\n public append(element: ElementLike | ElementLike[]): FlickingPanel[] {\n const viewport = this.viewport;\n const appendedPanels = viewport.insert(viewport.panelManager.getRange().max + 1, element);\n\n this.checkContentsReady(appendedPanels);\n\n return appendedPanels;\n }\n\n /**\n * Replace existing panels with new panels from given index. If target index is empty, add new panel at target index.\n * @ko 주어진 인덱스로부터의 패널들을 새로운 패널들로 교체한다. 인덱스에 해당하는 자리가 비어있다면, 새로운 패널을 해당 자리에 집어넣는다.\n * @param index - Start index to replace new panels.<ko>새로운 패널들로 교체할 시작 인덱스</ko>\n * @param element - Either HTMLElement, HTML string, or array of them.<br>It can be also HTML string of multiple elements with same depth.<ko>HTMLElement 혹은 HTML 문자열, 혹은 그것들의 배열도 가능하다.<br>또한, 같은 depth의 여러 개의 엘리먼트에 해당하는 HTML 문자열도 가능하다.</ko>\n * @return Array of created panels by replace.<ko>교체되어 새롭게 추가된 패널들의 배열</ko>\n * @example\n * // Suppose there were no panels at initialization\n * const flicking = new eg.Flicking(\"#flick\");\n *\n * // This will add new panel at index 3,\n * // Index 0, 1, 2 is empty at this moment.\n * // [empty, empty, empty, PANEL]\n * flicking.replace(3, document.createElement(\"div\"));\n *\n * // As index 2 was empty, this will also add new panel at index 2.\n * // [empty, empty, PANEL, PANEL]\n * flicking.replace(2, \"\\<div\\>Panel\\</div\\>\");\n *\n * // Index 3 was not empty, so it will replace previous one.\n * // It will also add new panels at index 4 and 5.\n * // before - [empty, empty, PANEL, PANEL]\n * // after - [empty, empty, PANEL, NEW_PANEL, NEW_PANEL, NEW_PANEL]\n * flicking.replace(3, [\"\\<div\\>Panel\\</div\\>\", \"\\<div\\>Panel\\</div\\>\", \"\\<div\\>Panel\\</div\\>\"])\n */\n public replace(index: number, element: ElementLike | ElementLike[]): FlickingPanel[] {\n const replacedPanels = this.viewport.replace(index, element);\n\n this.checkContentsReady(replacedPanels);\n\n return replacedPanels;\n }\n\n /**\n * Remove panel at target index. This will decrease index of panels behind it.\n * @ko `index`에 해당하는 자리의 패널을 제거한다. 수행시 `index` 이후의 패널들의 인덱스가 감소된다.\n * @param index - Index of panel to remove.<ko>제거할 패널의 인덱스</ko>\n * @param {number} [deleteCount=1] - Number of panels to remove from index.<ko>`index` 이후로 제거할 패널의 개수.</ko>\n * @return Array of removed panels<ko>제거된 패널들의 배열</ko>\n */\n public remove(index: number, deleteCount: number = 1): FlickingPanel[] {\n return this.viewport.remove(index, deleteCount);\n }\n\n /**\n * Get indexes to render. Should be used with `renderOnlyVisible` option.\n * `beforeSync` should be called before this method for a correct result.\n * @private\n * @ko 렌더링이 필요한 인덱스들을 반환한다. `renderOnlyVisible` 옵션과 함께 사용해야 한다. 정확한 결과를 위해선 `beforeSync`를 이전에 호출해야만 합니다.\n * @param - Info object of how panel infos are changed.<ko>패널 정보들의 변경 정보를 담는 오브젝트.</ko>\n * @return Array of indexes to render.<ko>렌더링할 인덱스의 배열</ko>\n */\n public getRenderingIndexes(diffResult: DiffResult<any>): number[] {\n const viewport = this.viewport;\n const visiblePanels = viewport.getVisiblePanels();\n const maintained = diffResult.maintained.reduce((values: {[key: number]: number}, [before, after]) => {\n values[after] = before;\n return values;\n }, {});\n\n const panelCount = diffResult.list.length;\n const added = diffResult.added;\n const getPanelAbsIndex = (panel: Panel) => {\n return panel.getIndex() + (panel.getCloneIndex() + 1) * panelCount;\n };\n\n const visibleIndexes = visiblePanels.map(panel => getPanelAbsIndex(panel))\n .filter(val => maintained[val % panelCount] != null);\n\n const renderingPanels = [...visibleIndexes, ...added];\n const allPanels = viewport.panelManager.allPanels();\n\n viewport.setVisiblePanels(renderingPanels.map(index => allPanels[index]));\n\n return renderingPanels;\n }\n\n /**\n * Synchronize info of panels instance with info given by external rendering.\n * @ko 외부 렌더링 방식에 의해 입력받은 패널의 정보와 현재 플리킹이 갖는 패널 정보를 동기화한다.\n * @private\n * @param - Info object of how panel infos are changed.<ko>패널 정보들의 변경 정보를 담는 오브젝트.</ko>\n * @param - Whether called from sync method <ko> sync 메소드로부터 호출됐는지 여부 </ko>\n */\n public beforeSync(diffInfo: BeforeSyncResult) {\n const { maintained, added, changed, removed } = diffInfo;\n const viewport = this.viewport;\n const panelManager = viewport.panelManager;\n const isCircular = this.options.circular;\n const currentPanel = viewport.getCurrentPanel();\n const cloneCount = panelManager.getCloneCount();\n const prevClonedPanels = panelManager.clonedPanels();\n\n // Update visible panels\n const newVisiblePanels = viewport.getVisiblePanels()\n .filter(panel => findIndex(removed, index => {\n return index === panel.getIndex();\n }) < 0);\n viewport.setVisiblePanels(newVisiblePanels);\n\n // Did not changed at all\n if (\n added.length <= 0\n && removed.length <= 0\n && changed.length <= 0\n && cloneCount === prevClonedPanels.length\n ) {\n return this;\n }\n const prevOriginalPanels = panelManager.originalPanels();\n const newPanels: Panel[] = [];\n const newClones: Panel[][] = counter(cloneCount).map(() => []);\n\n maintained.forEach(([beforeIdx, afterIdx]) => {\n newPanels[afterIdx] = prevOriginalPanels[beforeIdx];\n newPanels[afterIdx].setIndex(afterIdx);\n });\n\n added.forEach(addIndex => {\n newPanels[addIndex] = new Panel(null, addIndex, this.viewport);\n });\n\n if (isCircular) {\n counter(cloneCount).forEach(groupIndex => {\n const prevCloneGroup = prevClonedPanels[groupIndex];\n const newCloneGroup = newClones[groupIndex];\n\n maintained.forEach(([beforeIdx, afterIdx]) => {\n newCloneGroup[afterIdx] = prevCloneGroup\n ? prevCloneGroup[beforeIdx]\n : newPanels[afterIdx].clone(groupIndex, false);\n\n newCloneGroup[afterIdx].setIndex(afterIdx);\n });\n\n added.forEach(addIndex => {\n const newPanel = newPanels[addIndex];\n\n newCloneGroup[addIndex] = newPanel.clone(groupIndex, false);\n });\n });\n }\n\n added.forEach(index => { viewport.updateCheckedIndexes({ min: index, max: index }); });\n removed.forEach(index => { viewport.updateCheckedIndexes({ min: index - 1, max: index + 1 }); });\n\n const checkedIndexes = viewport.getCheckedIndexes();\n checkedIndexes.forEach(([min, max], idx) => {\n // Push checked indexes backward\n const pushedIndex = added.filter(index => index < min && panelManager.has(index)).length\n - removed.filter(index => index < min).length;\n checkedIndexes.splice(idx, 1, [min + pushedIndex, max + pushedIndex]);\n });\n\n // Only effective only when there are least one panel which have changed its index\n if (changed.length > 0) {\n // Removed checked index by changed ones after pushing\n maintained.forEach(([, next]) => { viewport.updateCheckedIndexes({ min: next, max: next }); });\n }\n panelManager.replacePanels(newPanels, newClones);\n\n const currentPanelIndex = currentPanel?.getIndex() ?? -1;\n const currentPanelIsRemoved = findIndex(removed, index => index === currentPanelIndex) >= 0;\n\n if ((!currentPanel || currentPanelIsRemoved) && newPanels.length > 0) {\n viewport.setCurrentPanel(newPanels[0]);\n } else if (newPanels.length <= 0) {\n viewport.setCurrentPanel(undefined);\n }\n\n this.isPanelChangedAtBeforeSync = true;\n }\n\n /**\n * Synchronize info of panels with DOM info given by external rendering.\n * @ko 외부 렌더링 방식에 의해 입력받은 DOM의 정보와 현재 플리킹이 갖는 패널 정보를 동기화 한다.\n * @private\n * @param - Info object of how panel elements are changed.<ko>패널의 DOM 요소들의 변경 정보를 담는 오브젝트.</ko>\n */\n public sync(diffInfo: SyncResult): this {\n const { list, maintained, added, changed, removed } = diffInfo;\n\n // Did not changed at all\n if (added.length <= 0 && removed.length <= 0 && changed.length <= 0) {\n return this;\n }\n const viewport = this.viewport;\n const { renderOnlyVisible, circular } = this.options;\n const panelManager = viewport.panelManager;\n\n if (!renderOnlyVisible) {\n const indexRange = panelManager.getRange();\n let beforeDiffInfo: BeforeSyncResult = diffInfo;\n\n if (circular) {\n const prevOriginalPanelCount = indexRange.max;\n const originalPanelCount = (list.length / (panelManager.getCloneCount() + 1)) >> 0;\n const originalAdded = added.filter(index => index < originalPanelCount);\n const originalRemoved = removed.filter(index => index <= prevOriginalPanelCount);\n const originalMaintained = maintained.filter(([beforeIdx]) => beforeIdx <= prevOriginalPanelCount);\n const originalChanged = changed.filter(([beforeIdx]) => beforeIdx <= prevOriginalPanelCount);\n\n beforeDiffInfo = {\n added: originalAdded,\n maintained: originalMaintained,\n removed: originalRemoved,\n changed: originalChanged,\n };\n }\n this.beforeSync(beforeDiffInfo);\n }\n\n const visiblePanels = renderOnlyVisible\n ? viewport.getVisiblePanels()\n : this.getAllPanels(true);\n\n added.forEach(addedIndex => {\n const addedElement = list[addedIndex];\n const beforePanel = visiblePanels[addedIndex] as Panel;\n\n beforePanel.setElement(addedElement);\n // As it can be 0\n beforePanel.unCacheBbox();\n });\n if (this.isPanelChangedAtBeforeSync) {\n // Reset visible panels\n viewport.setVisiblePanels([]);\n this.isPanelChangedAtBeforeSync = false;\n }\n viewport.resize();\n\n return this;\n }\n\n private listenInput(): void {\n const flicking = this;\n const viewport = flicking.viewport;\n const stateMachine = viewport.stateMachine;\n\n // Set event context\n flicking.eventContext = {\n flicking,\n viewport: flicking.viewport,\n transitTo: stateMachine.transitTo,\n triggerEvent: flicking.triggerEvent,\n moveCamera: flicking.moveCamera,\n stopCamera: viewport.stopCamera,\n };\n\n const handlers = {};\n for (const key in AXES_EVENTS) {\n const eventType = AXES_EVENTS[key];\n\n handlers[eventType] = (e: any) => stateMachine.fire(eventType, e, flicking.eventContext);\n }\n\n // Connect Axes instance with PanInput\n flicking.viewport.connectAxesHandler(handlers);\n }\n\n private listenResize(): void {\n const options = this.options;\n\n if (options.autoResize) {\n this.autoResizer.enable();\n }\n\n if (options.resizeOnContentsReady) {\n const contentsReadyChecker = new ImReady();\n\n contentsReadyChecker.on(\"preReady\", () => {\n this.resize();\n });\n contentsReadyChecker.on(\"readyElement\", e => {\n if (e.hasLoading && e.isPreReadyOver) {\n this.resize();\n }\n });\n contentsReadyChecker.on(\"error\", e => {\n this.trigger(EVENTS.CONTENT_ERROR, {\n type: EVENTS.CONTENT_ERROR,\n element: e.element,\n });\n });\n contentsReadyChecker.check([this.wrapper]);\n\n this.contentsReadyChecker = contentsReadyChecker;\n }\n }\n\n private triggerEvent = <T extends FlickingEvent>(\n eventName: ValueOf<Omit<EventType, \"VISIBLE_CHANGE\">>, // visibleChange event has no common event definition from other events\n axesEvent: any,\n isTrusted: boolean,\n params: Partial<T> = {},\n ): TriggerCallback => {\n const viewport = this.viewport;\n\n let canceled: boolean = true;\n\n // Ignore events before viewport is initialized\n if (viewport) {\n const state = viewport.stateMachine.getState();\n const { prev, next } = viewport.getScrollArea();\n const pos = viewport.getCameraPosition();\n let progress = getProgress(pos, [prev, prev, next]);\n\n if (this.options.circular) {\n progress %= 1;\n }\n canceled = !super.trigger(eventName, merge({\n type: eventName,\n index: this.getIndex(),\n panel: this.getCurrentPanel(),\n direction: state.direction,\n holding: state.holding,\n progress,\n axesEvent,\n isTrusted,\n }, params) as FlickingEvent);\n }\n\n return {\n onSuccess(callback: () => void): TriggerCallback {\n if (!canceled) {\n callback();\n }\n return this;\n },\n onStopped(callback: () => void): TriggerCallback {\n if (canceled) {\n callback();\n }\n return this;\n },\n } as TriggerCallback;\n }\n\n // Return result of \"move\" event triggered\n private moveCamera = (axesEvent: any): TriggerCallback => {\n const viewport = this.viewport;\n const state = viewport.stateMachine.getState();\n const options = this.options;\n\n const pos = axesEvent.pos.flick;\n const previousPosition = viewport.getCameraPosition();\n\n if (axesEvent.isTrusted && state.holding) {\n const inputOffset = options.horizontal\n ? axesEvent.inputEvent.offsetX\n : axesEvent.inputEvent.offsetY;\n\n const isNextDirection = inputOffset < 0;\n\n let cameraChange = pos - previousPosition;\n const looped = isNextDirection === (pos < previousPosition);\n if (options.circular && looped) {\n // Reached at max/min range of axes\n const scrollAreaSize = viewport.getScrollAreaSize();\n cameraChange = (cameraChange > 0 ? -1 : 1) * (scrollAreaSize - Math.abs(cameraChange));\n }\n\n const currentDirection = cameraChange === 0\n ? state.direction\n : cameraChange > 0\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n state.direction = currentDirection;\n }\n state.delta += axesEvent.delta.flick;\n\n viewport.moveCamera(pos, axesEvent);\n return this.triggerEvent(EVENTS.MOVE, axesEvent, axesEvent.isTrusted)\n .onStopped(() => {\n // Undo camera movement\n viewport.moveCamera(previousPosition, axesEvent);\n });\n }\n\n private checkContentsReady(panels: FlickingPanel[]) {\n this.contentsReadyChecker?.check(panels.map(panel => panel.getElement()));\n }\n}\n\nexport default Flicking;\n","import Flicking from \"./Flicking\";\nimport { withFlickingMethods } from \"./utils\";\nimport { DEFAULT_OPTIONS, MOVE_TYPE } from \"./consts\";\n\n(Flicking as any).withFlickingMethods = withFlickingMethods;\n(Flicking as any).DEFAULT_OPTIONS = DEFAULT_OPTIONS;\n(Flicking as any).MOVE_TYPE = MOVE_TYPE;\nexport default Flicking;\n"],"names":["MOVE_TYPE","SNAP","FREE_SCROLL","DEFAULT_MOVE_TYPE_OPTIONS","snap","type","count","freeScroll","isBrowser","document","DEFAULT_OPTIONS","classPrefix","deceleration","horizontal","circular","infinite","infiniteThreshold","lastIndex","Infinity","threshold","duration","panelEffect","x","Math","pow","defaultIndex","inputType","thresholdAngle","bounce","autoResize","adaptive","zIndex","bound","overflow","hanger","anchor","gap","moveType","useOffset","isEqualSize","isConstantSize","renderOnlyVisible","renderExternal","resizeOnContentsReady","iOSEdgeSwipeThreshold","collectStatistics","useResizeObserver","DEFAULT_VIEWPORT_CSS","position","DEFAULT_CAMERA_CSS","width","height","willChange","DEFAULT_PANEL_CSS","EVENTS","HOLD_START","HOLD_END","MOVE_START","MOVE","MOVE_END","CHANGE","RESTORE","SELECT","NEED_PANEL","VISIBLE_CHANGE","CONTENT_ERROR","AXES_EVENTS","HOLD","RELEASE","ANIMATION_END","FINISH","STATE_TYPE","DIRECTION","PREV","NEXT","FLICKING_METHODS","prev","next","moveTo","getIndex","getAllPanels","getCurrentPanel","getElement","getSize","getPanel","getPanelCount","getStatus","getVisiblePanels","enableInput","disableInput","destroy","resize","setStatus","isPlaying","checkTranslateSupport","transforms","webkitTransform","msTransform","MozTransform","OTransform","transform","name","has3d","prefixedTransform","supportedStyle","documentElement","style","transformName","Error","el","createElement","insertBefore","styleVal","window","getComputedStyle","getPropertyValue","parentElement","removeChild","transformInfo","length","TRANSFORM","merge","target","_i","srcs","forEach","source","Object","keys","key","value","parseElement","element","Array","isArray","elements","isString","tempDiv","innerHTML","push","toArray","children","firstChild","hasClass","className","classList","contains","split","indexOf","applyCSS","cssObj","property","clamp","val","min","max","isBetween","iterable","slice","call","parseArithmeticExpression","cssValue","base","defaultVal","defaultValue","cssRegex","idx","calculatedValue","matchResult","exec","sign","unit","parsedValue","parseFloat","getProgress","pos","range","center","findIndex","callback","i","counter","counterArray","circulate","indexed","size","restoreStyle","originalStyle","setAttribute","removeAttribute","getBbox","y","offsetWidth","offsetHeight","clientRect","getBoundingClientRect","left","top","index","viewport","prevSibling","nextSibling","clonedPanels","state","relativeAnchorPosition","isClone","isVirtual","cloneIndex","cachedBbox","setElement","givenBbox","this","options","bbox","prevSize","panel","cloneState","panelCount","panelManager","scrollAreaSize","getScrollAreaSize","floor","getPosition","getCurrentProgress","outsetRange","getRelativeHangerPosition","getRelativeAnchorPosition","getCameraPosition","panelSize","relativePanelPosition","rightRelativePanelPosition","visibleSize","currentPanel","getHangerPosition","getAnchorPosition","eventType","findEstimatedPosition","updateFunction","shouldResize","identicalPanels","getIdenticalPanels","eachPanel","unCacheBbox","addVisiblePanel","currentIndex","currentPosition","prevPanelIndex","prevPanelPosition","prevPanelSize","hasEmptyPanelBetween","notYetMinPanel","newPosition","prevPanel","clone","getCloneIndex","setPosition","getLastIndex","nextPanelIndex","nextPanelPosition","notYetMaxPanel","nextPanel","parsedElements","firstPanel","targetIndex","insert","remove","option","preserveUI","wasVisible","cameraElement","Boolean","parentNode","getCameraElement","appendChild","classes","classes_1","original","getClonedPanels","offset","elementStyle","currentElementStyle","styleToApply","cloneElement","clonedPanel","Panel","cloneNode","clonedState","removeClonedPanelsAfter","start","removingPanels","splice","removeElement","currentElement","getAttribute","add","replace","panels","clones","cloneCount","reduce","allClones","newPanels","newClones","filter","lastPanel","possibleLastPanel","shouldRender","isCircular","findFirstPanelFrom","siblingElement","insertNewPanels","panelCount_1","pushedIndex","emptyPanelCount","panelsAfterIndex","removedPanels","newLastIndex","concat","reverse","setIndex","updateIndex","addNewClones","cloneSet","replacedPanels","wasNonEmptyCount","deleteCount","deletedPanels","nonEmptyIndexFromLast","allPanels","allPanelsCount","insertTarget_1","newClones_1","allPanels_1","_a","originalPanels","getCloneCount","lastPanelClones","nextSiblingClones","cloneNextSibling","lastPanelSibling","cloneSiblingElement","nextElementSibling","map","_this","this_1","insertClones","insertingIndex","fragment_1","createDocumentFragment","prevState","delta","direction","targetPanel","lastPosition","nextState","e","context","__extends","flicking","triggerEvent","transitTo","moveCamera","onSuccess","onStopped","onChange","State","inputEvent","offsetX","offsetY","flick","setTo","srcEvent","cancelable","releaseEvent","clickedPanel","cameraPosition","clickedElement","touch","changedTouches","elementFromPoint","clientX","clientY","findPanelOf","clickedPanelPosition","stopCamera","absDelta","abs","velocity","velocityX","velocityY","inputDelta","deltaX","deltaY","isNextDirection","swipeDistance","swipeAngle","atan","PI","belowAngleThreshold","overThreshold","moveTypeContext","axesEvent","interruptDestInfo","findPanelWhenInterrupted","destPos","nearestPanel","getNearestPanel","stop","destInfo","findTargetPanel","findRestorePanel","scrollArea","getScrollArea","loopCount","originalTargetPosition","newCloneIndex","newTargetPosition","newTargetPanel","setCurrentPanel","isTrusted","updateAdaptiveSize","updateCameraPosition","updateAxesPosition","IdleState","nextStateType","currentState","HoldingState","DraggingState","AnimatingState","DisabledState","onExit","onEnter","onHold","onRelease","onAnimationEnd","onFinish","_super","ctx","snapCount","eventDelta","minimumDistanceToChange","calcBrinkOfChange","nearestIsCurrent","shouldMoveWhenBounceIs0","canSetBoundMode","shouldMoveToAdjacent","isOutOfBound","findSnappedPanel","findAdjacentPanel","halfGap","estimatedHangerPos","panelToMove","cycleIndex","passedPanelCount","originalPanel","getOriginalPanel","panelPosition","siblingPanel","panelIndex","siblingIndex","originalPosition","defaultDuration","getCurrentIndex","get","hangerPosition","firstClonedPanel","basePanel","basePosition","adjacentPanel","targetRelativeAnchorPosition","estimatedPosition","findRestorePanelInCircularMode","lapped","findNearestPanelAt","stateMachine","getState","currentPanelPosition","lastHangerPosition","Snap","panelMaintainRatio","relativeHangerPosition","positionOffset","translate","checkedIndexes","isAdaptiveCached","isViewportGiven","isCameraGiven","originalViewportStyle","originalCameraStyle","StateMachine","visiblePanels","panelBboxes","build","eventResult","axes","findNearestPanel","originalNearestPosition","checkNeedPanel","updateVisiblePanels","posOffset","moveCoord","coord","round","join","viewportElement","updateSize","updateOriginalPanelPositions","updateScrollArea","updateClonePanels","updateVisiblePanelPositions","updatePlugins","minimumDistance","prevPosition","nextPosition","distance","nearest","shortestDistance","identical","anchorPosition","getVisibleIndexOf","panInput","createPanInput","setAxesInstance","resizePanels","newCenterPanel","newPanelPosition","updateCheckedIndexes","indexes","visibleIndex","newCurrentIndex","getRange","undefined","viewportStyle","sizeToApply","viewportSize","shouldApplyAdaptive","panelBbox","maximum","viewportBbox","updateBbox","isFreeScroll","is","holding","playing","positionBounded","plugins","plugin","update","topmostElement_1","deletingElement","wrapper","removePlugins","status","html","refreshPanels","createdPanels","orderedPanels","createdPanel","replacePanels","setCloneCount","cameraPos_1","viewportSize_1","getNext","isOutOfViewport","getAbsIndex_1","__spreadArrays","sort","panel1","panel2","outsetProgress","getOutsetProgress","NaN","prevRange","nextRange","nearestAnchorPos","nearestIndex","nearestSize","hangerIsNextToNearestPanel","targetPosition","progressBetween","off","on","axesHandlers","setLastIndex","handlers","newPlugins","init","currentPlugins","changedRange","removed","prevVisiblePanels","equalSizeClasses_1","cached_1","fragment","overlappedClass","getOverlappedClass","clonePanels","updateClonedPanelPositions","chainAllPanels","visiblePanel","setElements","applyCSSValue","setMoveType","setDefaultPanel","moveToDefaultPanel","viewportCandidate","hasViewportElement","cameraCandidate","hasCameraElement","child","minHeight","minWidth","PanelManager","FreeScroll","Axes","easing","interruptable","indexRange","reversedPanels","sumOriginalPanelSize","areaPrev","sizeSum","panelAtLeftBoundary","reversedPanels_1","areaNext","panelAtRightBoundary","panels_1","needCloneOnPrev","ceil","prevCloneCount","origPanel","removeClonesAfter","defaultPanel","defaultPosition","accumulatedSize","nextPanelPos","maintainingPanel","total","setPositionCSS","clonedPanels_1","clonedPanelPos","lastReplacePosition","_b","replacePosition","relAnchorPosOfCombined","anchorPos","parsedBounce","arr","constructor","parsedVal","axis","maxLastIndex","checkingPanel","nextIndex","currentNearestPosition","triggerNeedPanel","firstIndex","lastPanelAfterNeed","cameraPrev","checkingIndex","prevIndex","firstPanelAfterNeed","params","alreadyTriggered","some","hasHandler","hasOn","fill","insertAfter","newVisiblePanels","calcVisiblePanels","checkVisiblePanelChange","addedPanels","firstVisiblePanelPos","panelElement","firstVisiblePanel","lastVisiblePanel","newVisibleRange","getAbsIndex","trigger","prevRefCount","newRefCount","newPanel","newIndex","added","equalSizeClasses_2","defaultBbox_1","default","PanInput","scale","releaseOnScroll","connect","isFirstResize","onResize","enabled","resizeObserver","flickingEl","disable","ResizeObserver","clientWidth","clientHeight","skipFirstResize","observe","addEventListener","disconnect","removeEventListener","shouldResetElements","parent","origStyle","appendUncachedPanelElements","eventName","progress","canceled","looped","currentDirection","previousPosition","inputOffset","cameraChange","querySelector","nodeName","nodeType","currentOptions","Viewport","autoResizer","AutoResizer","listenInput","listenResize","focus","nearestPosition","current","identicals","includeClone","enable","outerHTML","restore","addPlugins","contentsReadyChecker","prependedPanels","checkContentsReady","appendedPanels","diffResult","maintained","values","before","list","renderingPanels","setVisiblePanels","diffInfo","changed","prevClonedPanels","prevOriginalPanels","beforeIdx","afterIdx","addIndex","groupIndex","prevCloneGroup","newCloneGroup","getCheckedIndexes","has","currentPanelIndex","currentPanelIsRemoved","isPanelChangedAtBeforeSync","prevOriginalPanelCount_1","originalPanelCount_1","beforeDiffInfo","originalAdded","originalRemoved","beforeSync","addedIndex","addedElement","beforePanel","eventContext","fire","connectAxesHandler","ImReady","hasLoading","isPreReadyOver","check","Flicking","Component","withFlickingMethods","prototype","flickingName","args","result"],"mappings":"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"}