UNPKG

310 kBSource Map (JSON)View Raw
1{"version":3,"file":"flicking.pkgd.min.js","sources":["../src/utils.ts","../src/const/error.ts","../src/const/external.ts","../src/core/FlickingError.ts","../src/core/Viewport.ts","../src/control/states/State.ts","../src/const/axes.ts","../src/control/states/IdleState.ts","../src/control/states/HoldingState.ts","../src/control/states/DraggingState.ts","../src/control/states/AnimatingState.ts","../src/control/states/DisabledState.ts","../src/control/StateMachine.ts","../src/control/AxesController.ts","../src/control/Control.ts","../src/core/AnchorPoint.ts","../src/control/SnapControl.ts","../src/control/FreeControl.ts","../src/control/StrictControl.ts","../src/camera/Camera.ts","../src/camera/LinearCamera.ts","../src/camera/CircularCamera.ts","../src/camera/BoundCamera.ts","../src/renderer/Renderer.ts","../src/core/panel/Panel.ts","../src/core/panel/ElementPanel.ts","../src/renderer/VanillaRenderer.ts","../src/renderer/ExternalRenderer.ts","../src/Flicking.ts","../src/core/panel/ExternalPanel.ts","../src/cfc/sync.ts","../src/cfc/getDefaultCameraTransform.ts","../src/cfc/withFlickingMethods.ts","../src/cfc/getRenderingPanels.ts","../src/index.umd.ts"],"sourcesContent":["/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Flicking, { FlickingOptions } from \"./Flicking\";\nimport FlickingError from \"./core/FlickingError\";\nimport * as ERROR from \"./const/error\";\nimport { ALIGN, DIRECTION } from \"./const/external\";\nimport { LiteralUnion, Merged, ValueOf } from \"./type/internal\";\nimport { ElementLike } from \"./type/external\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = <From extends object, To extends object>(target: From, ...sources: To[]): Merged<From, To> => {\n sources.forEach(source => {\n Object.keys(source).forEach(key => {\n target[key] = source[key] as unknown;\n });\n });\n\n return target as Merged<From, To>;\n};\n\nexport const getElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n if (!queryResult) {\n throw new FlickingError(ERROR.MESSAGE.ELEMENT_NOT_FOUND(el), ERROR.CODE.ELEMENT_NOT_FOUND);\n }\n targetEl = queryResult as HTMLElement;\n } else if (el && el.nodeType === Node.ELEMENT_NODE) {\n targetEl = el;\n }\n\n if (!targetEl) {\n throw new FlickingError(ERROR.MESSAGE.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODE.WRONG_TYPE);\n }\n\n return targetEl;\n};\n\nexport const checkExistence = (value: any, nameOnErrMsg: string) => {\n if (value == null) {\n throw new FlickingError(ERROR.MESSAGE.VAL_MUST_NOT_NULL(value, nameOnErrMsg), ERROR.CODE.VAL_MUST_NOT_NULL);\n }\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\nexport const getFlickingAttached = (val: Flicking | null, nameToThrowOnError: string): Flicking => {\n if (!val) {\n throw new FlickingError(ERROR.MESSAGE.NOT_ATTACHED_TO_FLICKING(nameToThrowOnError), ERROR.CODE.NOT_ATTACHED_TO_FLICKING);\n }\n\n return val;\n};\n\nexport const toArray = <T>(iterable: ArrayLike<T>): T[] => [].slice.call(iterable) as T[];\n\nexport const parseAlign = (align: LiteralUnion<ValueOf<typeof ALIGN>> | number, size: number): number => {\n let alignPoint: number | null;\n if (isString(align)) {\n switch (align) {\n case ALIGN.PREV:\n alignPoint = 0;\n break;\n case ALIGN.CENTER:\n alignPoint = 0.5 * size;\n break;\n case ALIGN.NEXT:\n alignPoint = size;\n break;\n default:\n alignPoint = parseArithmeticSize(align, size);\n if (alignPoint == null) {\n throw new FlickingError(ERROR.MESSAGE.WRONG_OPTION(\"align\", align), ERROR.CODE.WRONG_OPTION);\n }\n }\n } else {\n alignPoint = align as number;\n }\n\n return alignPoint;\n};\n\nexport const parseBounce = (bounce: FlickingOptions[\"bounce\"], size: number): number[] => {\n let parsedBounce: Array<number | null>;\n\n if (Array.isArray(bounce)) {\n parsedBounce = (bounce as string[]).map(val => parseArithmeticSize(val, size));\n } else {\n const parsedVal = parseArithmeticSize(bounce, size);\n\n parsedBounce = [parsedVal, parsedVal];\n }\n\n return parsedBounce.map(val => {\n if (val == null) {\n throw new FlickingError(ERROR.MESSAGE.WRONG_OPTION(\"bounce\", bounce), ERROR.CODE.WRONG_OPTION);\n }\n return val;\n });\n};\n\nexport const parseArithmeticSize = (cssValue: number | string, base: number): number | null => {\n const parsed = parseArithmeticExpression(cssValue);\n\n if (parsed == null) return null;\n\n return parsed.percentage * base + parsed.absolute;\n};\n\nexport const parseArithmeticExpression = (cssValue: number | string): { percentage: number; absolute: number } | null => {\n const cssRegex = /(?:(\\+|\\-)\\s*)?(\\d+(?:\\.\\d+)?(%|px)?)/g;\n\n if (typeof cssValue === \"number\") {\n return { percentage: 0, absolute: cssValue };\n }\n\n const parsed = {\n percentage: 0,\n absolute: 0\n };\n let idx = 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 const 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 null;\n }\n\n const signMultiplier = sign === \"+\" ? 1 : -1;\n\n if (unit === \"%\") {\n parsed.percentage += signMultiplier * (parsedValue / 100);\n } else {\n parsed.absolute += signMultiplier * parsedValue;\n }\n\n // Match next occurrence\n ++idx;\n matchResult = cssRegex.exec(cssValue);\n }\n\n // None-matched\n if (idx === 0) {\n return null;\n }\n\n return parsed;\n};\n\nexport const parseCSSSizeValue = (val: string | number): string => isString(val) ? val : `${val}px`;\n\nexport const getDirection = (start: number, end: number): ValueOf<typeof DIRECTION> => {\n if (start === end) return DIRECTION.NONE;\n return start < end ? DIRECTION.NEXT : DIRECTION.PREV;\n};\n\nexport const 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 if (el && el.nodeType === Node.ELEMENT_NODE) {\n elements.push(el);\n } else {\n throw new FlickingError(ERROR.MESSAGE.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODE.WRONG_TYPE);\n }\n });\n\n return elements;\n};\n\nexport const getMinusCompensatedIndex = (idx: number, max: number) => idx < 0 ? clamp(idx + max, 0, max) : clamp(idx, 0, max);\n\nexport const includes = <T>(array: T[], target: any): target is T => {\n for (const val of array) {\n if (val === target) return true;\n }\n return false;\n};\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\n\nexport const circulatePosition = (pos: number, min: number, max: number) => {\n const size = max - min;\n\n if (pos < min) {\n const offset = (min - pos) % size;\n pos = max - offset;\n } else if (pos > max) {\n const offset = (pos - max) % size;\n pos = min + offset;\n }\n\n return pos;\n};\n\nexport const find = <T>(array: T[], checker: (val: T) => boolean): T | null => {\n for (const val of array) {\n if (checker(val)) {\n return val;\n }\n }\n\n return null;\n};\n\nexport const findRight = <T>(array: T[], checker: (val: T) => boolean): T | null => {\n for (let idx = array.length - 1; idx >= 0; idx--) {\n const val = array[idx];\n if (checker(val)) {\n return val;\n }\n }\n\n return null;\n};\n\nexport const findIndex = <T>(array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getProgress = (pos: number, prev: number, next: number) => (pos - prev) / (next - prev);\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\nexport const getStyle = (el: HTMLElement): CSSStyleDeclaration => window.getComputedStyle(el) || (el as any).currentStyle as CSSStyleDeclaration;\n\nexport const isBetween = (val: number, min: number, max: number) => val >= min && val <= max;\n\nexport const circulateIndex = (index: number, max: number): number => {\n if (index >= max) {\n return index % max;\n } else if (index < 0) {\n return getMinusCompensatedIndex((index + 1) % max - 1, max);\n } else {\n return index;\n }\n};\n\nexport const setPrototypeOf = Object.setPrototypeOf || ((obj, proto) => {\n obj.__proto__ = proto;\n return obj;\n});\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/restrict-template-expressions */\n\n/**\n * Error codes of {@link FlickingError}. Below are the conditions where each error code occurs.\n * @ko {@link FlickingError}의 에러 코드. 아래는 각각의 에러 코드가 발생하는 조건입니다.\n * @name ERROR_CODE\n * @constant\n * @type object\n * @property {number} WRONG_TYPE Parameter type is wrong<ko>패러미터의 타입이 잘못되었을 경우</ko>\n * @property {number} ELEMENT_NOT_FOUND Element is not found inside page with the given CSS selector<ko>주어진 CSS selector로 페이지 내에서 해당 엘리먼트를 찾지 못했을 경우</ko>\n * @property {number} VAL_MUST_NOT_NULL Expected non-null value, but given `null` or `undefined`<ko>값을 기대했으나, `null`이나 `undefined`를 받은 경우</ko>\n * @property {number} NOT_ATTACHED_TO_FLICKING When Flicking's component is not initialized (i.e. {@link Flicking#init} is not called)<ko>Flicking 내부 컴포넌트가 초기화되지 않은 경우 ({@link Flicking#init}이 호출되지 않은 경우)</ko>\n * @property {number} WRONG_OPTION One of the options is wrong<ko>옵션들 중 잘못된 값이 있을 때</ko>\n * @property {number} INDEX_OUT_OF_RANGE When the given index is out of possible range<ko>인덱스가 주어진 범위를 벗어난 경우</ko>\n * @property {number} POSITION_NOT_REACHABLE When {@link Control#moveToPosition}'s position parameter is out of possible range.<ko>{@link Control#moveToPosition}의 `position` 패러미터가 도달 가능한 범위를 벗어난 경우</ko>\n * @property {number} TRANSFORM_NOT_SUPPORTED CSS `transform` property is not available(<=IE8) <ko>CSS `transform` 속성을 사용할 수 없는 경우(<=IE8)</ko>\n * @property {number} STOP_CALLED_BY_USER When the event's `stop()` is called by user.<ko>사용자에 의해 이벤트의 `stop()`이 호출된 경우</ko>\n * @property {number} ANIMATION_INTERRUPTED When the animation is interrupted by user.<ko>사용자에 의해 애니메이션이 중단된 경우</ko>\n * @property {number} ANIMATION_ALREADY_PLAYING When the animation is already playing.<ko>현재 애니메이션이 이미 진행중인 경우</ko>\n * @property {number} NOT_ALLOWED_IN_FRAMEWORK When the non-allowed method is called from frameworks (React, Angular, Vue...)\n * <ko>프레임워크(React, Angular, Vue ...)에서 사용 불가능한 메소드를 호출했을 경우</ko>\n * @property {number} NOT_INITIALIZED When the {@link Flicking#init} is not called before but is needed<ko>{@link Flicking#init}의 호출이 필요하나, 아직 호출되지 않았을 경우</ko>\n * @property {number} NO_ACTIVE When there're no active panel that flicking has selected. This may be due to the absence of any panels<ko>현재 Flicking이 선택한 패널이 없을 경우. 일반적으로 패널이 하나도 없는 경우에 발생할 수 있습니다</ko>\n */\nexport const CODE = {\n WRONG_TYPE: 0,\n ELEMENT_NOT_FOUND: 1,\n VAL_MUST_NOT_NULL: 2,\n NOT_ATTACHED_TO_FLICKING: 3,\n WRONG_OPTION: 4,\n INDEX_OUT_OF_RANGE: 5,\n POSITION_NOT_REACHABLE: 6,\n TRANSFORM_NOT_SUPPORTED: 7,\n STOP_CALLED_BY_USER: 8,\n ANIMATION_INTERRUPTED: 9,\n ANIMATION_ALREADY_PLAYING: 10,\n NOT_ALLOWED_IN_FRAMEWORK: 11,\n NOT_INITIALIZED: 12,\n NO_ACTIVE: 13\n} as const;\n\nexport const MESSAGE = {\n WRONG_TYPE: (wrongVal: any, correctTypes: string[]) => `${wrongVal}(${typeof wrongVal}) is not a ${correctTypes.map(type => `\"${type}\"`).join(\" or \")}.`,\n ELEMENT_NOT_FOUND: (selector: string) => `Element with selector \"${selector}\" not found.`,\n VAL_MUST_NOT_NULL: (val: any, name: string) => `${name} should be provided. Given: ${val}`,\n NOT_ATTACHED_TO_FLICKING: (name: string) => `${name} is not attached to the Flicking instance. \"init()\" should be called first.`,\n WRONG_OPTION: (optionName: string, val: any) => `Option \"${optionName}\" is not in correct format, given: ${val}`,\n INDEX_OUT_OF_RANGE: (val: number, min: number, max: number) => `Index \"${val}\" is out of range: should be between ${min} and ${max}.`,\n POSITION_NOT_REACHABLE: (position: number) => `Position \"${position}\" is not reachable.`,\n TRANSFORM_NOT_SUPPORTED: \"Browser does not support CSS transform.\",\n STOP_CALLED_BY_USER: \"Event stop() is called by user.\",\n ANIMATION_INTERRUPTED: \"Animation is interrupted by user input.\",\n ANIMATION_ALREADY_PLAYING: \"Animation is already playing.\",\n NOT_ALLOWED_IN_FRAMEWORK: \"This behavior is not allowed in the frameworks like React, Vue, or Angular.\",\n NOT_INITIALIZED: \"Flicking is not initialized yet, call init() first.\",\n NO_ACTIVE: \"There's no active panel that Flicking has selected. This may be due to the absence of any panels.\"\n} as const;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { CODE as ERROR_CODE } from \"./error\";\n\n/**\n * Event type object with event name strings of {@link Flicking}\n * @ko {@link Flicking}의 이벤트 이름 문자열들을 담은 객체\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 {\"willChange\"} WILL_CHANGE willChange event<ko>willChange 이벤트</ko>\n * @property {\"changed\"} CHANGED changed event<ko>changed 이벤트</ko>\n * @property {\"willRestore\"} WILL_RESTORE willRestore event<ko>willRestore 이벤트</ko>\n * @property {\"restored\"} RESTORED restored event<ko>restored 이벤트</ko>\n * @property {\"select\"} SELECT select event<ko>select 이벤트</ko>\n * @property {\"needPanel\"} NEED_PANEL needPanel event<ko>needPanel 이벤트</ko>\n * @property {\"panelChange\"} PANEL_CHANGE panelChange event<ko>panelChange 이벤트</ko>\n * @example\n * ```ts\n * import { EVENTS } from \"@egjs/flicking\";\n * EVENTS.MOVE_START; // \"moveStart\"\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n BEFORE_RESIZE: \"beforeResize\",\n AFTER_RESIZE: \"afterResize\",\n HOLD_START: \"holdStart\",\n HOLD_END: \"holdEnd\",\n MOVE_START: \"moveStart\",\n MOVE: \"move\",\n MOVE_END: \"moveEnd\",\n WILL_CHANGE: \"willChange\",\n CHANGED: \"changed\",\n WILL_RESTORE: \"willRestore\",\n RESTORED: \"restored\",\n SELECT: \"select\",\n NEED_PANEL: \"needPanel\",\n VISIBLE_CHANGE: \"visibleChange\",\n REACH_EDGE: \"reachEdge\",\n PANEL_CHANGE: \"panelChange\"\n} as const;\n\n/**\n * An object with all possible predefined literal string for the {@link Flicking#align align} option\n * @ko {@link Flicking#align align} 옵션에 사용되는 미리 정의된 리터럴 상수들을 담고 있는 객체\n * @type {object}\n * @property {\"prev\"} PREV left/top align<ko>좌/상 정렬</ko>\n * @property {\"center\"} CENTER center align<ko>중앙 정렬</ko>\n * @property {\"next\"} NEXT right/bottom align<ko>우/하 정렬</ko>\n */\nexport const ALIGN = {\n PREV: \"prev\",\n CENTER: \"center\",\n NEXT: \"next\"\n} as const;\n\n/**\n * An object of directions\n * @ko 방향을 나타내는 값들을 담고 있는 객체\n * @type {object}\n * @property {\"PREV\"} PREV \"left\" when {@link Flicking#horizontal horizontal} is true, and \"top\" when {@link Flicking#horizontal horizontal} is false\n * <ko>{@link Flicking#horizontal horizontal}가 `true`일 경우 왼쪽, {@link Flicking#horizontal horizontal}가 `false`일 경우 위쪽을 의미합니다</ko>\n * @property {\"NEXT\"} NEXT \"right\" when {@link Flicking#horizontal horizontal} is true, and \"bottom\" when {@link Flicking#horizontal horizontal} is false\n * <ko>{@link Flicking#horizontal horizontal}가 `true`일 경우 오른쪽, {@link Flicking#horizontal horizontal}가 `false`일 경우 아래쪽을 의미합니다</ko>\n * @property {null} NONE This value usually means it's the same position<ko>주로 제자리인 경우를 의미합니다</ko>\n */\nexport const DIRECTION = {\n PREV: \"PREV\",\n NEXT: \"NEXT\",\n NONE: null\n} as const;\n\n/**\n * An object with all possible {@link Flicking#moveType moveType}s\n * @ko Flicking이 제공하는 {@link Flicking#moveType moveType}들을 담고 있는 객체\n * @type {object}\n * @property {\"snap\"} SNAP Flicking's {@link Flicking#moveType moveType} that enables {@link SnapControl} as a Flicking's {@link Flicking#control control}\n * <ko>Flicking의 {@link Flicking#control control}을 {@link SnapControl}로 설정하게 하는 {@link Flicking#moveType moveType}</ko>\n * @property {\"freeScroll\"} FREE_SCROLL Flicking's {@link Flicking#moveType moveType} that enables {@link FreeControl} as a Flicking's {@link Flicking#control control}\n * <ko>Flicking의 {@link Flicking#control control}을 {@link FreeControl}로 설정하게 하는 {@link Flicking#moveType moveType}</ko>\n * @property {\"strict\"} STRICT Flicking's {@link Flicking#moveType moveType} that enables {@link StrictControl} as a Flicking's {@link Flicking#control control}\n * <ko>Flicking의 {@link Flicking#control control}을 {@link StrictControl}로 설정하게 하는 {@link Flicking#moveType moveType}</ko>\n */\nexport const MOVE_TYPE = {\n SNAP: \"snap\",\n FREE_SCROLL: \"freeScroll\",\n STRICT: \"strict\"\n} as const;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { setPrototypeOf } from \"../utils\";\n\n/**\n * Special type of known error that {@link Flicking} throws.\n * @ko Flicking 내부에서 알려진 오류 발생시 throw되는 에러\n * @property {number} code Error code<ko>에러 코드</ko>\n * @property {string} message Error message<ko>에러 메시지</ko>\n * @see {@link Constants.ERROR_CODE ERROR_CODE}\n * @example\n * ```ts\n * import Flicking, { FlickingError, ERROR_CODES } from \"@egjs/flicking\";\n * try {\n * const flicking = new Flicking(\".flicking-viewport\")\n * } catch (e) {\n * if (e instanceof FlickingError && e.code === ERROR_CODES.ELEMENT_NOT_FOUND) {\n * console.error(\"Element not found\")\n * }\n * }\n * ```\n */\nclass FlickingError extends Error {\n public code: number;\n\n /**\n * @param message Error message<ko>에러 메시지</ko>\n * @param code Error code<ko>에러 코드</ko>\n */\n public constructor(message: string, code: number) {\n super(message);\n\n setPrototypeOf(this, FlickingError.prototype);\n this.name = \"FlickingError\";\n this.code = code;\n }\n}\n\nexport default FlickingError;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { getStyle, isString } from \"../utils\";\n\n/**\n * A component that manages viewport size\n * @ko 뷰포트 크기 정보를 담당하는 컴포넌트\n */\nclass Viewport {\n private _el: HTMLElement;\n private _width: number;\n private _height: number;\n private _isBorderBoxSizing: boolean;\n private _padding: {\n left: number;\n right: number;\n top: number;\n bottom: number;\n };\n\n /**\n * A viewport(root) element\n * @ko 뷰포트(root) 엘리먼트\n * @type {HTMLElement}\n * @readonly\n */\n public get element() { return this._el; }\n\n /**\n * Viewport width, without paddings\n * @ko 뷰포트 너비\n * @type {number}\n * @readonly\n */\n public get width() { return this._width - this._padding.left - this._padding.right; }\n /**\n * Viewport height, without paddings\n * @ko 뷰포트 높이\n * @type {number}\n * @readonly\n */\n public get height() { return this._height - this._padding.top - this._padding.bottom; }\n /**\n * Viewport paddings\n * @ko 뷰포트 CSS padding 값\n * @type {object}\n * @property {number} left CSS `padding-left`\n * @property {number} right CSS `padding-right`\n * @property {number} top CSS `padding-top`\n * @property {number} bottom CSS `padding-bottom`\n * @readonly\n */\n public get padding() { return this._padding; }\n\n /**\n * @param el A viewport element<ko>뷰포트 엘리먼트</ko>\n */\n public constructor(el: HTMLElement) {\n this._el = el;\n this._width = 0;\n this._height = 0;\n this._padding = {\n left: 0,\n right: 0,\n top: 0,\n bottom: 0\n };\n this._isBorderBoxSizing = false;\n }\n\n /**\n * Change viewport's size.\n * This will change the actual size of `.flicking-viewport` element by changing its CSS width/height property\n * @ko 뷰포트 크기를 변경합니다.\n * `.flicking-viewport` 엘리먼트에 해당 크기의 CSS width/height를 적용합니다\n * @param {object} [size] New viewport size<ko>새 뷰포트 크기</ko>\n * @param {number|string} [size.width] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>\n * @param {number|string} [size.height] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>\n */\n public setSize({\n width,\n height\n }: Partial<{\n width: number | string;\n height: number | string;\n }>) {\n const el = this._el;\n const padding = this._padding;\n const isBorderBoxSizing = this._isBorderBoxSizing;\n\n if (width != null) {\n if (isString(width)) {\n el.style.width = width;\n } else {\n const newWidth = isBorderBoxSizing\n ? width + padding.left + padding.right\n : width;\n el.style.width = `${newWidth}px`;\n }\n }\n if (height != null) {\n if (isString(height)) {\n el.style.height = height;\n } else {\n const newHeight = isBorderBoxSizing\n ? height + padding.top + padding.bottom\n : height;\n el.style.height = `${newHeight}px`;\n }\n }\n this.resize();\n }\n\n /**\n * Update width/height to the current viewport element's size\n * @ko 현재 뷰포트 엘리먼트의 크기로 너비/높이를 업데이트합니다\n */\n public resize() {\n const el = this._el;\n const elStyle = getStyle(el);\n\n this._width = el.clientWidth;\n this._height = el.clientHeight;\n this._padding = {\n left: parseFloat(elStyle.paddingLeft),\n right: parseFloat(elStyle.paddingRight),\n top: parseFloat(elStyle.paddingTop),\n bottom: parseFloat(elStyle.paddingBottom)\n };\n this._isBorderBoxSizing = elStyle.boxSizing === \"border-box\";\n }\n}\n\nexport default Viewport;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { OnAnimationEnd, OnChange, OnFinish, OnHold, OnRelease } from \"@egjs/axes\";\nimport { ComponentEvent } from \"@egjs/component\";\n\nimport Flicking from \"../../Flicking\";\nimport Panel from \"../../core/panel/Panel\";\nimport { EVENTS } from \"../../const/external\";\nimport * as AXES from \"../../const/axes\";\nimport { circulatePosition, getDirection } from \"../../utils\";\n\nexport enum STATE_TYPE {\n IDLE,\n HOLDING,\n DRAGGING,\n ANIMATING,\n DISABLED\n}\n\n/**\n * A component that shows the current status of the user input or the animation\n * @ko 현재 사용자 입력 또는 애니메이션 상태를 나타내는 컴포넌트\n * @internal\n */\nabstract class State {\n /**\n * Whether user is clicking or touching\n * @ko 현재 사용자가 클릭/터치중인지 여부\n * @type {boolean}\n * @readonly\n */\n public abstract readonly holding: boolean;\n /**\n * Whether Flicking's animating\n * @ko 현재 애니메이션 동작 여부\n * @type {boolean}\n * @readonly\n */\n public abstract readonly animating: boolean;\n\n protected _delta: number = 0;\n protected _targetPanel: Panel | null = null;\n\n /**\n * A sum of delta values of change events from the last hold event of Axes\n * @ko 이전 hold이벤트부터 change에 의해 발생한 이동 delta값의 합산\n * @type {number}\n * @readonly\n */\n public get delta() { return this._delta; }\n\n /**\n * A panel to set as {@link Control#activePanel} after the animation is finished\n * @ko 애니메이션 종료시 {@link Control#activePanel}로 설정할 패널\n * @type {number}\n * @readonly\n */\n public get targetPanel() { return this._targetPanel; }\n\n public set targetPanel(val: Panel | null) { this._targetPanel = val; }\n\n /**\n * An callback which is called when state has changed to this state\n * @ko 현재 상태로 돌입했을때 호출되는 콜백 함수\n * @param {State} prevState An previous state<ko>이전 상태값</ko>\n * @return {void}\n */\n public onEnter(prevState: State): void {\n this._delta = prevState._delta;\n this._targetPanel = prevState._targetPanel;\n }\n\n /**\n * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} event\n * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} 이벤트 핸들러\n * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>\n * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>\n * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} event of Axes\n * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} 이벤트</ko>\n * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>\n * @return {void}\n */\n public onHold(ctx: {\n flicking: Flicking;\n axesEvent: OnHold;\n transitTo: (nextState: STATE_TYPE) => State;\n }): void {\n // DO NOTHING\n }\n\n /**\n * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} event\n * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} 이벤트 핸들러\n * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>\n * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>\n * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} event of Axes\n * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} 이벤트</ko>\n * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>\n * @return {void}\n */\n public onChange(ctx: {\n flicking: Flicking;\n axesEvent: OnChange;\n transitTo: (nextState: STATE_TYPE) => State;\n }): void {\n // DO NOTHING\n }\n\n /**\n * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event\n * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트 핸들러\n * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>\n * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>\n * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of Axes\n * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>\n * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>\n * @return {void}\n */\n public onRelease(ctx: {\n flicking: Flicking;\n axesEvent: OnRelease;\n transitTo: (nextState: STATE_TYPE) => State;\n }): void {\n // DO NOTHING\n }\n\n /**\n * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} event\n * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} 이벤트 핸들러\n * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>\n * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>\n * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} event of Axes\n * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} 이벤트</ko>\n * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>\n * @return {void}\n */\n public onAnimationEnd(ctx: {\n flicking: Flicking;\n axesEvent: OnAnimationEnd;\n transitTo: (nextState: STATE_TYPE) => State;\n }): void {\n // DO NOTHING\n }\n\n /**\n * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} event\n * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} 이벤트 핸들러\n * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>\n * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>\n * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} event of Axes<ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} 이벤트</ko>\n * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>\n * @return {void}\n */\n public onFinish(ctx: {\n flicking: Flicking;\n axesEvent: OnFinish;\n transitTo: (nextState: STATE_TYPE) => State;\n }): void {\n // DO NOTHING\n }\n\n protected _moveToChangedPosition(ctx: Parameters<State[\"onChange\"]>[0]): void {\n const { flicking, axesEvent, transitTo } = ctx;\n const delta = axesEvent.delta[AXES.POSITION_KEY];\n\n if (!delta) {\n return;\n }\n\n this._delta += delta;\n\n const camera = flicking.camera;\n const prevPosition = camera.position;\n const position = axesEvent.pos[AXES.POSITION_KEY];\n const newPosition = flicking.circularEnabled\n ? circulatePosition(position, camera.range.min, camera.range.max)\n : position;\n\n camera.lookAt(newPosition);\n\n const moveEvent = new ComponentEvent(EVENTS.MOVE, {\n isTrusted: axesEvent.isTrusted,\n holding: this.holding,\n direction: getDirection(0, axesEvent.delta[AXES.POSITION_KEY]),\n axesEvent\n });\n\n flicking.trigger(moveEvent);\n\n if (moveEvent.isCanceled()) {\n // Return to previous position\n camera.lookAt(prevPosition);\n transitTo(STATE_TYPE.DISABLED);\n }\n }\n}\n\nexport default State;\n","/**\n * All possible @egjs/axes event keys\n * @internal\n */\nexport const EVENT = {\n HOLD: \"hold\",\n CHANGE: \"change\",\n RELEASE: \"release\",\n ANIMATION_END: \"animationEnd\",\n FINISH: \"finish\"\n} as const;\n\n/**\n * An Axis key that Flicking uses\n * @internal\n */\nexport const POSITION_KEY = \"flick\";\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { ComponentEvent } from \"@egjs/component\";\n\nimport { EVENTS } from \"../../const/external\";\nimport { getDirection } from \"../../utils\";\n\nimport State, { STATE_TYPE } from \"./State\";\n\n/**\n * A default state when there's no user input and no animation's playing\n * @ko 사용자의 입력이 없고, 애니메이션이 동작하고있지 않은 기본 상태\n * @internal\n */\nclass IdleState extends State {\n /**\n * Whether user is clicking or touching\n * @ko 현재 사용자가 클릭/터치중인지 여부\n * @type {false}\n * @readonly\n */\n public readonly holding = false;\n /**\n * Whether Flicking's animating\n * @ko 현재 애니메이션 동작 여부\n * @type {false}\n * @readonly\n */\n public readonly animating = false;\n\n public onEnter() {\n this._delta = 0;\n this._targetPanel = null;\n }\n\n public onHold(ctx: Parameters<State[\"onHold\"]>[0]): void {\n // Shouldn't do any action until any panels on flicking area\n const { flicking, axesEvent, transitTo } = ctx;\n\n if (flicking.renderer.panelCount <= 0) {\n transitTo(STATE_TYPE.DISABLED);\n return;\n }\n\n const holdStartEvent = new ComponentEvent(EVENTS.HOLD_START, {\n axesEvent\n });\n\n flicking.trigger(holdStartEvent);\n\n if (holdStartEvent.isCanceled()) {\n transitTo(STATE_TYPE.DISABLED);\n } else {\n transitTo(STATE_TYPE.HOLDING);\n }\n }\n\n // By methods call\n public onChange(ctx: Parameters<State[\"onChange\"]>[0]): void {\n const { flicking, axesEvent, transitTo } = ctx;\n const controller = flicking.control.controller;\n const animatingContext = controller.animatingContext;\n\n const moveStartEvent = new ComponentEvent(EVENTS.MOVE_START, {\n isTrusted: axesEvent.isTrusted,\n holding: this.holding,\n direction: getDirection(animatingContext.start, animatingContext.end),\n axesEvent\n });\n flicking.trigger(moveStartEvent);\n\n if (moveStartEvent.isCanceled()) {\n transitTo(STATE_TYPE.DISABLED);\n } else {\n // Trigger AnimatingState's onChange, to trigger \"move\" event immediately\n transitTo(STATE_TYPE.ANIMATING).onChange(ctx);\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 { OnRelease } from \"@egjs/axes\";\nimport { ComponentEvent } from \"@egjs/component\";\n\nimport Panel from \"../../core/panel/Panel\";\nimport { EVENTS } from \"../../const/external\";\nimport { getDirection } from \"../../utils\";\n\nimport State, { STATE_TYPE } from \"./State\";\n\n/**\n * A state that activates when user's holding the Flicking area, but not moved a single pixel yet\n * @ko 사용자의 입력이 시작되었으나, 아직 움직이지는 않은 상태\n * @internal\n */\nclass HoldingState extends State {\n /**\n * Whether user is clicking or touching\n * @ko 현재 사용자가 클릭/터치중인지 여부\n * @type {true}\n * @readonly\n */\n public readonly holding = true;\n /**\n * Whether Flicking's animating\n * @ko 현재 애니메이션 동작 여부\n * @type {false}\n * @readonly\n */\n public readonly animating = false;\n\n private _releaseEvent: OnRelease | null = null;\n\n public onChange(ctx: Parameters<State[\"onChange\"]>[0]): void {\n const { flicking, axesEvent, transitTo } = ctx;\n\n const inputEvent = axesEvent.inputEvent as { offsetX: number; offsetY: number };\n\n const offset = flicking.horizontal\n ? inputEvent.offsetX\n : inputEvent.offsetY;\n\n const moveStartEvent = new ComponentEvent(EVENTS.MOVE_START, {\n isTrusted: axesEvent.isTrusted,\n holding: this.holding,\n direction: getDirection(0, -offset),\n axesEvent\n });\n flicking.trigger(moveStartEvent);\n\n if (moveStartEvent.isCanceled()) {\n transitTo(STATE_TYPE.DISABLED);\n } else {\n // Trigger DraggingState's onChange, to trigger \"move\" event immediately\n transitTo(STATE_TYPE.DRAGGING).onChange(ctx);\n }\n }\n\n public onRelease(ctx: Parameters<State[\"onRelease\"]>[0]): void {\n const { flicking, axesEvent, transitTo } = ctx;\n\n flicking.trigger(new ComponentEvent(EVENTS.HOLD_END, { axesEvent }));\n\n if (axesEvent.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 axesEvent.setTo({ flick: flicking.camera.position }, 0);\n transitTo(STATE_TYPE.IDLE);\n return;\n }\n\n // Can't handle select event here,\n // As \"finish\" axes event happens\n this._releaseEvent = axesEvent;\n }\n\n public onFinish(ctx: Parameters<State[\"onFinish\"]>[0]): void {\n const { flicking, transitTo } = ctx;\n\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 /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */\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 /* eslint-enable */\n\n const panels = flicking.renderer.panels;\n let clickedPanel: Panel | null = null;\n\n for (const panel of panels) {\n if (panel.contains(clickedElement)) {\n clickedPanel = panel;\n break;\n }\n }\n\n if (clickedPanel) {\n const cameraPosition = flicking.camera.position;\n const clickedPanelPosition = clickedPanel.position;\n\n flicking.trigger(new ComponentEvent(EVENTS.SELECT, {\n index: clickedPanel.index,\n panel: clickedPanel,\n // Direction to the clicked panel\n direction: getDirection(cameraPosition, clickedPanelPosition)\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 { ComponentEvent } from \"@egjs/component\";\n\nimport { EVENTS } from \"../../const/external\";\nimport * as AXES from \"../../const/axes\";\n\nimport State, { STATE_TYPE } from \"./State\";\n\n/**\n * A state that activates when user's dragging the Flicking area\n * @ko 사용자가 드래깅중인 상태\n * @internal\n */\nclass DraggingState extends State {\n /**\n * Whether user is clicking or touching\n * @ko 현재 사용자가 클릭/터치중인지 여부\n * @type {true}\n * @readonly\n */\n public readonly holding = true;\n /**\n * Whether Flicking's animating\n * @ko 현재 애니메이션 동작 여부\n * @type {true}\n * @readonly\n */\n public readonly animating = true;\n\n public onChange(ctx: Parameters<State[\"onChange\"]>[0]): void {\n this._moveToChangedPosition(ctx);\n }\n\n public onRelease(ctx: Parameters<State[\"onRelease\"]>[0]): void {\n const { flicking, axesEvent, transitTo } = ctx;\n\n // Update last position to cope with Axes's animating behavior\n // Axes uses start position when animation start\n flicking.trigger(new ComponentEvent(EVENTS.HOLD_END, {\n axesEvent\n }));\n\n if (flicking.renderer.panelCount <= 0) {\n // There're no panels\n transitTo(STATE_TYPE.IDLE);\n return;\n }\n\n transitTo(STATE_TYPE.ANIMATING);\n\n const control = flicking.control;\n const position = axesEvent.destPos[AXES.POSITION_KEY];\n const duration = Math.max(axesEvent.duration, flicking.duration);\n\n void control.moveToPosition(position, duration, axesEvent);\n }\n}\n\nexport default DraggingState;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { ComponentEvent } from \"@egjs/component\";\n\nimport { EVENTS } from \"../../const/external\";\nimport { getDirection } from \"../../utils\";\n\nimport State, { STATE_TYPE } from \"./State\";\n\n/**\n * A state that activates when Flicking's animating by user input or method call\n * @ko 사용자 입력이나 메소드 호출에 의해 Flicking의 애니메이션이 동작중인 상태\n * @internal\n */\nclass AnimatingState extends State {\n /**\n * Whether user is clicking or touching\n * @ko 현재 사용자가 클릭/터치중인지 여부\n * @type {false}\n * @readonly\n */\n public readonly holding = false;\n /**\n * Whether Flicking's animating\n * @ko 현재 애니메이션 동작 여부\n * @type {true}\n * @readonly\n */\n public readonly animating = true;\n\n public onHold(ctx: Parameters<State[\"onHold\"]>[0]): void {\n const { flicking, axesEvent, transitTo } = ctx;\n\n this._delta = 0;\n flicking.control.updateInput();\n\n const holdStartEvent = new ComponentEvent(EVENTS.HOLD_START, { axesEvent });\n flicking.trigger(holdStartEvent);\n\n if (holdStartEvent.isCanceled()) {\n transitTo(STATE_TYPE.DISABLED);\n } else {\n transitTo(STATE_TYPE.DRAGGING);\n }\n }\n\n public onChange(ctx: Parameters<State[\"onChange\"]>[0]): void {\n this._moveToChangedPosition(ctx);\n }\n\n public onFinish(ctx: Parameters<State[\"onFinish\"]>[0]) {\n const { flicking, axesEvent, transitTo } = ctx;\n\n const control = flicking.control;\n const controller = control.controller;\n const animatingContext = controller.animatingContext;\n\n transitTo(STATE_TYPE.IDLE);\n\n flicking.trigger(new ComponentEvent(EVENTS.MOVE_END, {\n isTrusted: axesEvent.isTrusted,\n direction: getDirection(animatingContext.start, animatingContext.end),\n axesEvent\n }));\n\n control.setActive(this._targetPanel!, control.activePanel, axesEvent.isTrusted);\n }\n}\n\nexport default AnimatingState;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport State, { STATE_TYPE } from \"./State\";\n\n/**\n * A state that activates when Flicking is stopped by event's `stop` method\n * @ko 이벤트의 `stop`호출에 의해 Flicking이 정지된 상태\n * @internal\n */\nclass DisabledState extends State {\n /**\n * Whether user is clicking or touching\n * @ko 현재 사용자가 클릭/터치중인지 여부\n * @type {false}\n * @readonly\n */\n public readonly holding = false;\n /**\n * Whether Flicking's animating\n * @ko 현재 애니메이션 동작 여부\n * @type {true}\n * @readonly\n */\n public readonly animating = true;\n\n public onAnimationEnd(ctx: Parameters<State[\"onAnimationEnd\"]>[0]): void {\n const { transitTo } = ctx;\n\n transitTo(STATE_TYPE.IDLE);\n }\n\n public onChange(ctx: Parameters<State[\"onChange\"]>[0]): void {\n const { axesEvent, transitTo } = ctx;\n\n // Can stop Axes's change event\n axesEvent.stop();\n\n transitTo(STATE_TYPE.IDLE);\n }\n\n public onRelease(ctx: Parameters<State[\"onRelease\"]>[0]): void {\n const { axesEvent, transitTo } = ctx;\n\n // This is needed when stopped hold start event\n if (axesEvent.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 */\nimport { AxesEvents } from \"@egjs/axes\";\n\nimport Flicking from \"../Flicking\";\nimport * as AXES from \"../const/axes\";\n\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\";\nimport State, { STATE_TYPE } from \"./states/State\";\n\n/**\n * @internal\n */\nclass StateMachine {\n private _state: State;\n\n public get state(): State { return this._state; }\n\n public constructor() {\n this._state = new IdleState();\n }\n\n public fire(eventType: keyof AxesEvents, externalCtx: {\n flicking: Flicking;\n axesEvent: any;\n }) {\n const currentState = this._state;\n const ctx = { ...externalCtx, transitTo: this.transitTo };\n\n switch (eventType) {\n case AXES.EVENT.HOLD:\n currentState.onHold(ctx);\n break;\n case AXES.EVENT.CHANGE:\n currentState.onChange(ctx);\n break;\n case AXES.EVENT.RELEASE:\n currentState.onRelease(ctx);\n break;\n case AXES.EVENT.ANIMATION_END:\n currentState.onAnimationEnd(ctx);\n break;\n case AXES.EVENT.FINISH:\n currentState.onFinish(ctx);\n break;\n }\n }\n\n public transitTo = (nextStateType: STATE_TYPE): State => {\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 nextState.onEnter(this._state);\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 */\nimport Axes, { PanInput, AxesEvents, OnRelease } from \"@egjs/axes\";\n\nimport Flicking from \"../Flicking\";\nimport FlickingError from \"../core/FlickingError\";\nimport * as AXES from \"../const/axes\";\nimport * as ERROR from \"../const/error\";\nimport { circulatePosition, getFlickingAttached, parseBounce } from \"../utils\";\nimport { ControlParams } from \"../type/external\";\n\nimport StateMachine from \"./StateMachine\";\n\n/**\n * A controller that handles the {@link https://naver.github.io/egjs-axes/ @egjs/axes} events\n * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 이벤트를 처리하는 컨트롤러 컴포넌트\n * @internal\n */\nclass AxesController {\n private _flicking: Flicking | null;\n private _axes: Axes | null;\n private _panInput: PanInput | null;\n private _stateMachine: StateMachine;\n\n private _animatingContext: { start: number; end: number; offset: number };\n private _dragged: boolean;\n\n /**\n * An {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance\n * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes}의 인스턴스\n * @type {Axes}\n * @see https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html\n * @readonly\n */\n public get axes() { return this._axes; }\n /**\n * @internal\n */\n public get stateMachine() { return this._stateMachine; }\n /**\n * A activated {@link State} that shows the current status of the user input or the animation\n * @ko 현재 활성화된 {@link State} 인스턴스로 사용자 입력 또는 애니메이션 상태를 나타냅니다\n * @type {State}\n */\n public get state() { return this._stateMachine.state; }\n /**\n * A context of the current animation playing\n * @ko 현재 재생중인 애니메이션 정보\n * @type {object}\n * @property {number} start A start position of the animation<ko>애니메이션 시작 지점</ko>\n * @property {number} end A end position of the animation<ko>애니메이션 끝 지점</ko>\n * @property {number} offset camera offset<ko>카메라 오프셋</ko>\n * @readonly\n */\n public get animatingContext() { return this._animatingContext; }\n /**\n * A current control parameters of the Axes instance\n * @ko 활성화된 현재 Axes 패러미터들\n * @type {ControlParams}\n */\n public get controlParams(): ControlParams {\n const axes = this._axes;\n\n if (!axes) {\n return {\n range: { min: 0, max: 0 },\n position: 0,\n circular: false\n };\n }\n\n const axis = axes.axis[AXES.POSITION_KEY];\n\n return {\n range: { min: axis.range![0], max: axis.range![1] },\n circular: (axis.circular as boolean[])[0],\n position: this.position\n };\n }\n\n /**\n * A Boolean indicating whether the user input is enabled\n * @ko 현재 사용자 입력이 활성화되었는지를 나타내는 값\n * @type {boolean}\n * @readonly\n */\n public get enabled() { return this._panInput?.isEnable() ?? false; }\n /**\n * Current position value in {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance\n * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} 인스턴스 내부의 현재 좌표 값\n * @type {number}\n * @readonly\n */\n public get position() { return this._axes?.get([AXES.POSITION_KEY])[AXES.POSITION_KEY] ?? 0; }\n /**\n * Current range value in {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance\n * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} 인스턴스 내부의 현재 이동 범위 값\n * @type {number[]}\n * @readonly\n */\n public get range() { return this._axes?.axis[AXES.POSITION_KEY].range ?? [0, 0]; }\n /**\n * Actual bounce size(px)\n * @ko 적용된 bounce 크기(px 단위)\n * @type {number[]}\n * @readonly\n */\n public get bounce() { return this._axes?.axis[AXES.POSITION_KEY].bounce as number[] | undefined; }\n\n /** */\n public constructor() {\n this._resetInternalValues();\n this._stateMachine = new StateMachine();\n }\n\n /**\n * Initialize AxesController\n * @ko AxesController를 초기화합니다\n * @param {Flicking} flicking An instance of Flicking\n * @chainable\n * @return {this}\n */\n public init(flicking: Flicking): this {\n this._flicking = flicking;\n\n this._axes = new Axes({\n [AXES.POSITION_KEY]: {\n range: [0, 0],\n circular: false,\n bounce: [0, 0]\n }\n }, {\n deceleration: flicking.deceleration,\n interruptable: flicking.interruptable,\n easing: flicking.easing\n });\n this._panInput = new PanInput(flicking.viewport.element, {\n inputType: flicking.inputType,\n iOSEdgeSwipeThreshold: flicking.iOSEdgeSwipeThreshold,\n scale: flicking.horizontal ? [-1, 0] : [0, -1],\n releaseOnScroll: true\n });\n\n const axes = this._axes;\n\n axes.connect(flicking.horizontal ? [AXES.POSITION_KEY, \"\"] : [\"\", AXES.POSITION_KEY], this._panInput);\n\n for (const key in AXES.EVENT) {\n const eventType = AXES.EVENT[key] as keyof AxesEvents;\n\n axes.on(eventType, (e: AxesEvents[typeof eventType]) => {\n this._stateMachine.fire(eventType, {\n flicking,\n axesEvent: e\n });\n });\n }\n\n return this;\n }\n\n /**\n * Destroy AxesController and return to initial state\n * @ko AxesController를 초기 상태로 되돌립니다\n * @return {void}\n */\n public destroy(): void {\n if (this._axes) {\n this.removePreventClickHandler();\n this._axes.destroy();\n }\n\n this._panInput?.destroy();\n\n this._resetInternalValues();\n }\n\n /**\n * Enable input from the user (mouse/touch)\n * @ko 사용자의 입력(마우스/터치)를 활성화합니다\n * @chainable\n * @return {this}\n */\n public enable(): this {\n this._panInput?.enable();\n\n return this;\n }\n\n /**\n * Disable input from the user (mouse/touch)\n * @ko 사용자의 입력(마우스/터치)를 막습니다\n * @chainable\n * @return {this}\n */\n public disable(): this {\n this._panInput?.disable();\n\n return this;\n }\n\n /**\n * Update {@link https://naver.github.io/egjs-axes/ @egjs/axes}'s state\n * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 상태를 갱신합니다\n * @chainable\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link AxesController#init init} is not called before\n * <ko>{@link AxesController#init init}이 이전에 호출되지 않은 경우</ko>\n * @return {this}\n */\n public update(controlParams: ControlParams): this {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n const axes = this._axes!;\n const axis = axes.axis[AXES.POSITION_KEY];\n\n axis.circular = [controlParams.circular, controlParams.circular];\n axis.range = [controlParams.range.min, controlParams.range.max];\n axis.bounce = parseBounce(flicking.bounce, camera.size);\n\n axes.axm.set({ [AXES.POSITION_KEY]: controlParams.position });\n\n return this;\n }\n\n /**\n * Attach a handler to the camera element to prevent click events during animation\n * @ko 카메라 엘리먼트에 애니메이션 도중에 클릭 이벤트를 방지하는 핸들러를 부착합니다\n * @return {this}\n */\n public addPreventClickHandler(): this {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const axes = this._axes!;\n const cameraEl = flicking.camera.element;\n\n axes.on(AXES.EVENT.HOLD, this._onAxesHold);\n axes.on(AXES.EVENT.CHANGE, this._onAxesChange);\n cameraEl.addEventListener(\"click\", this._preventClickWhenDragged, true);\n\n return this;\n }\n\n /**\n * Detach a handler to the camera element to prevent click events during animation\n * @ko 카메라 엘리먼트에 애니메이션 도중에 클릭 이벤트를 방지하는 핸들러를 탈착합니다\n * @return {this}\n */\n public removePreventClickHandler(): this {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const axes = this._axes!;\n const cameraEl = flicking.camera.element;\n\n axes.off(AXES.EVENT.HOLD, this._onAxesHold);\n axes.off(AXES.EVENT.CHANGE, this._onAxesChange);\n cameraEl.removeEventListener(\"click\", this._preventClickWhenDragged, true);\n\n return this;\n }\n\n /**\n * Run Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#setTo setTo} using the given position\n * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#setTo setTo} 메소드를 주어진 좌표를 이용하여 수행합니다\n * @param {number} position A position to move<ko>이동할 좌표</ko>\n * @param {number} duration Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>\n * @param {number} [axesEvent] If provided, it'll use its {@link https://naver#github#io/egjs-axes/release/latest/doc/eg#Axes#html#setTo setTo} method instead<ko>이 값이 주어졌을 경우, 해당 이벤트의 {@link https://naver#github#io/egjs-axes/release/latest/doc/eg#Axes#html#setTo setTo} 메소드를 대신해서 사용합니다.</ko>\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|\n * <ko>\n *\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|\n *\n * </ko>\n * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>\n */\n public animateTo(position: number, duration: number, axesEvent?: OnRelease): Promise<void> {\n const axes = this._axes;\n\n if (!axes) {\n return Promise.reject(new FlickingError(ERROR.MESSAGE.NOT_ATTACHED_TO_FLICKING(\"Control\"), ERROR.CODE.NOT_ATTACHED_TO_FLICKING));\n }\n\n const startPos = axes.get([AXES.POSITION_KEY])[AXES.POSITION_KEY];\n\n if (startPos === position) {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n\n flicking.camera.lookAt(position);\n return Promise.resolve();\n }\n\n this._animatingContext = {\n start: startPos,\n end: position,\n offset: 0\n };\n\n const animate = () => {\n const resetContext = () => {\n this._animatingContext = { start: 0, end: 0, offset: 0 };\n };\n\n axes.once(AXES.EVENT.FINISH, resetContext);\n\n if (axesEvent) {\n axesEvent.setTo({ [AXES.POSITION_KEY]: position }, duration);\n } else {\n axes.setTo({ [AXES.POSITION_KEY]: position }, duration);\n }\n };\n\n if (duration === 0) {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n\n animate();\n\n const newPos = flicking.circularEnabled\n ? circulatePosition(position, camera.range.min, camera.range.max)\n : position;\n\n axes.axm.set({ [AXES.POSITION_KEY]: newPos });\n\n return Promise.resolve();\n } else {\n return new Promise((resolve, reject) => {\n const animationFinishHandler = () => {\n axes.off(AXES.EVENT.HOLD, interruptionHandler);\n resolve();\n };\n\n const interruptionHandler = () => {\n axes.off(AXES.EVENT.FINISH, animationFinishHandler);\n reject(new FlickingError(ERROR.MESSAGE.ANIMATION_INTERRUPTED, ERROR.CODE.ANIMATION_INTERRUPTED));\n };\n\n axes.once(AXES.EVENT.FINISH, animationFinishHandler);\n axes.once(AXES.EVENT.HOLD, interruptionHandler);\n\n animate();\n });\n }\n }\n\n private _resetInternalValues() {\n this._flicking = null;\n this._axes = null;\n this._panInput = null;\n this._animatingContext = { start: 0, end: 0, offset: 0 };\n this._dragged = false;\n }\n\n private _onAxesHold = () => {\n this._dragged = false;\n };\n\n private _onAxesChange = () => {\n this._dragged = true;\n };\n\n private _preventClickWhenDragged = (e: MouseEvent) => {\n if (this._dragged) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n this._dragged = false;\n };\n}\n\nexport default AxesController;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { OnRelease } from \"@egjs/axes\";\nimport { ComponentEvent } from \"@egjs/component\";\n\nimport Flicking from \"../Flicking\";\nimport FlickingError from \"../core/FlickingError\";\nimport Panel from \"../core/panel/Panel\";\nimport AxesController from \"../control/AxesController\";\nimport { DIRECTION, EVENTS } from \"../const/external\";\nimport * as ERROR from \"../const/error\";\nimport { getDirection, getFlickingAttached } from \"../utils\";\nimport { ValueOf } from \"../type/internal\";\n\n/**\n * A component that manages inputs and animation of Flicking\n * @ko Flicking의 입력 장치 & 애니메이션을 담당하는 컴포넌트\n */\nabstract class Control {\n // Internal States\n protected _flicking: Flicking | null;\n protected _controller: AxesController;\n protected _activePanel: Panel | null;\n\n /**\n * A controller that handles the {@link https://naver.github.io/egjs-axes/ @egjs/axes} events\n * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 이벤트를 처리하는 컨트롤러 컴포넌트\n * @type {AxesController}\n * @readonly\n */\n public get controller() { return this._controller; }\n /**\n * Index number of the {@link Flicking#currentPanel currentPanel}\n * @ko {@link Flicking#currentPanel currentPanel}의 인덱스 번호\n * @type {number}\n * @default 0\n * @readonly\n */\n public get activeIndex() { return this._activePanel?.index ?? -1; }\n /**\n * An active panel\n * @ko 현재 선택된 패널\n * @type {Panel | null}\n * @readonly\n */\n public get activePanel() { return this._activePanel; }\n /**\n * Whether Flicking's animating\n * @ko 현재 애니메이션 동작 여부\n * @type {boolean}\n * @readonly\n */\n public get animating() { return this._controller.state.animating; }\n /**\n * Whether user is clicking or touching\n * @ko 현재 사용자가 클릭/터치중인지 여부\n * @type {boolean}\n * @readonly\n */\n public get holding() { return this._controller.state.holding; }\n\n /** */\n public constructor() {\n this._flicking = null;\n this._controller = new AxesController();\n this._activePanel = null;\n }\n\n /**\n * Move {@link Camera} to the given position\n * @ko {@link Camera}를 주어진 좌표로 이동합니다\n * @method\n * @abstract\n * @memberof Control\n * @instance\n * @name moveToPosition\n * @param {number} position The target position to move<ko>이동할 좌표</ko>\n * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>\n * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}\n * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>\n * @fires Flicking#moveStart\n * @fires Flicking#move\n * @fires Flicking#moveEnd\n * @fires Flicking#willChange\n * @fires Flicking#changed\n * @fires Flicking#willRestore\n * @fires Flicking#restored\n * @fires Flicking#needPanel\n * @fires Flicking#visibleChange\n * @fires Flicking#reachEdge\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|\n * <ko>\n *\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|\n *\n * </ko>\n * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>\n */\n public abstract moveToPosition(position: number, duration: number, axesEvent?: OnRelease): Promise<void>;\n\n /**\n * Initialize Control\n * @ko Control을 초기화합니다\n * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>\n * @chainable\n * @return {this}\n */\n public init(flicking: Flicking): this {\n this._flicking = flicking;\n this._controller.init(flicking);\n\n return this;\n }\n\n /**\n * Destroy Control and return to initial state\n * @ko Control을 초기 상태로 되돌립니다\n * @return {void}\n */\n public destroy(): void {\n this._controller.destroy();\n\n this._flicking = null;\n this._activePanel = null;\n }\n\n /**\n * Enable input from the user (mouse/touch)\n * @ko 사용자의 입력(마우스/터치)를 활성화합니다\n * @chainable\n * @return {this}\n */\n public enable(): this {\n this._controller.enable();\n\n return this;\n }\n\n /**\n * Disable input from the user (mouse/touch)\n * @ko 사용자의 입력(마우스/터치)를 막습니다\n * @chainable\n * @return {this}\n */\n public disable(): this {\n this._controller.disable();\n\n return this;\n }\n\n /**\n * Update position after resizing\n * @ko resize 이후에 position을 업데이트합니다\n * @param {number} progressInPanel Previous camera's progress in active panel before resize<ko>Resize 이전 현재 선택된 패널 내에서의 카메라 progress 값</ko>\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before\n * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>\n * @chainable\n * @return {Promise<void>}\n */\n public updatePosition(_progressInPanel: number): void { // eslint-disable-line @typescript-eslint/no-unused-vars\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n const activePanel = this._activePanel;\n\n if (activePanel) {\n camera.lookAt(camera.clampToReachablePosition(activePanel.position));\n }\n }\n\n /**\n * Update {@link Control#controller controller}'s state\n * @ko {@link Control#controller controller}의 내부 상태를 갱신합니다\n * @chainable\n * @return {this}\n */\n public updateInput(): this {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n\n this._controller.update(camera.controlParams);\n\n return this;\n }\n\n /**\n * Reset {@link Control#activePanel activePanel} to `null`\n * @ko {@link Control#activePanel activePanel}을 `null`로 초기화합니다\n * @chainable\n * @return {this}\n */\n public resetActive(): this {\n this._activePanel = null;\n\n return this;\n }\n\n /**\n * Move {@link Camera} to the given panel\n * @ko {@link Camera}를 해당 패널 위로 이동합니다\n * @param {Panel} panel The target panel to move<ko>이동할 패널</ko>\n * @param {object} options An options object<ko>옵션 오브젝트</ko>\n * @param {number} duration Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>\n * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}\n * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>\n * @param {DIRECTION} [direction=DIRECTION.NONE] Direction to move, only available in the {@link Flicking#circular circular} mode<ko>이동할 방향. {@link Flicking#circular circular} 옵션 활성화시에만 사용 가능합니다</ko>\n * @fires Flicking#moveStart\n * @fires Flicking#move\n * @fires Flicking#moveEnd\n * @fires Flicking#willChange\n * @fires Flicking#changed\n * @fires Flicking#willRestore\n * @fires Flicking#restored\n * @fires Flicking#needPanel\n * @fires Flicking#visibleChange\n * @fires Flicking#reachEdge\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|\n * <ko>\n *\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|\n *\n * </ko>\n * @return {Promise<void>} A Promise which will be resolved after reaching the target panel<ko>해당 패널 도달시에 resolve되는 Promise</ko>\n */\n public async moveToPanel(panel: Panel, {\n duration,\n direction = DIRECTION.NONE,\n axesEvent\n }: {\n duration: number;\n direction?: ValueOf<typeof DIRECTION>;\n axesEvent?: OnRelease;\n }) {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n\n let position = panel.position;\n const nearestAnchor = camera.findNearestAnchor(position);\n\n if (panel.removed || !nearestAnchor) {\n return Promise.reject(new FlickingError(ERROR.MESSAGE.POSITION_NOT_REACHABLE(panel.position), ERROR.CODE.POSITION_NOT_REACHABLE));\n }\n if (!camera.canReach(panel)) {\n // Override position & panel if that panel is not reachable\n position = nearestAnchor.position;\n panel = nearestAnchor.panel;\n } else if (flicking.circularEnabled) {\n // Circular mode is enabled, find nearest distance to panel\n const camPos = this._controller.position; // Actual position of the Axes\n const camRangeDiff = camera.rangeDiff;\n const possiblePositions = [position, position + camRangeDiff, position - camRangeDiff]\n .filter(pos => {\n if (direction === DIRECTION.NONE) return true;\n\n return direction === DIRECTION.PREV\n ? pos <= camPos\n : pos >= camPos;\n });\n\n position = possiblePositions.reduce((nearestPosition, pos) => {\n if (Math.abs(camPos - pos) < Math.abs(camPos - nearestPosition)) {\n return pos;\n } else {\n return nearestPosition;\n }\n }, Infinity);\n }\n\n this._triggerIndexChangeEvent(panel, panel.position, axesEvent);\n\n return this._animateToPosition({ position, duration, newActivePanel: panel, axesEvent });\n }\n\n /**\n * @internal\n */\n public setActive(newActivePanel: Panel, prevActivePanel: Panel | null, isTrusted: boolean) {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n\n this._activePanel = newActivePanel;\n\n flicking.camera.updateAdaptiveHeight();\n\n if (newActivePanel !== prevActivePanel) {\n flicking.trigger(new ComponentEvent(EVENTS.CHANGED, {\n index: newActivePanel.index,\n panel: newActivePanel,\n prevIndex: prevActivePanel?.index ?? -1,\n prevPanel: prevActivePanel,\n isTrusted,\n direction: prevActivePanel ? getDirection(prevActivePanel.position, newActivePanel.position) : DIRECTION.NONE\n }));\n } else {\n flicking.trigger(new ComponentEvent(EVENTS.RESTORED, {\n isTrusted\n }));\n }\n }\n\n protected _triggerIndexChangeEvent(panel: Panel, position: number, axesEvent?: OnRelease): void {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const triggeringEvent = panel !== this._activePanel ? EVENTS.WILL_CHANGE : EVENTS.WILL_RESTORE;\n const camera = flicking.camera;\n const activePanel = this._activePanel;\n\n const event = new ComponentEvent(triggeringEvent, {\n index: panel.index,\n panel,\n isTrusted: axesEvent?.isTrusted || false,\n direction: getDirection(activePanel?.position ?? camera.position, position)\n });\n flicking.trigger(event);\n\n if (event.isCanceled()) {\n throw new FlickingError(ERROR.MESSAGE.STOP_CALLED_BY_USER, ERROR.CODE.STOP_CALLED_BY_USER);\n }\n }\n\n protected async _animateToPosition({\n position,\n duration,\n newActivePanel,\n axesEvent\n }: {\n position: number;\n duration: number;\n newActivePanel: Panel;\n axesEvent?: OnRelease;\n }) {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const animate = () => this._controller.animateTo(position, duration, axesEvent);\n const state = this._controller.state;\n\n state.targetPanel = newActivePanel;\n\n if (duration <= 0) {\n return animate();\n } else {\n return animate().then(async () => {\n await flicking.renderer.render();\n }).catch(err => {\n if (axesEvent && err instanceof FlickingError && err.code === ERROR.CODE.ANIMATION_INTERRUPTED) return;\n throw err;\n });\n }\n }\n}\n\nexport default Control;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Panel from \"./panel/Panel\";\n\n/**\n * A data component that has actual position where the camera should be stopped at\n * @ko 카메라가 정지해야하는 실제 위치를 담고 있는 데이터 컴포넌트\n */\nclass AnchorPoint {\n private _index: number;\n private _pos: number;\n private _panel: Panel;\n\n /**\n * Index of AnchorPoint\n * @ko AnchorPoint의 인덱스\n * @type {number}\n * @readonly\n */\n public get index() { return this._index; }\n /**\n * Position of AnchorPoint\n * @ko AnchorPoint의 좌표\n * @type {number}\n * @readonly\n */\n public get position() { return this._pos; }\n /**\n * A {@link Panel} instance AnchorPoint is referencing to\n * @ko AnchorPoint가 참조하고 있는 {@link Panel}\n * @type {Panel}\n * @readonly\n */\n public get panel() { return this._panel; }\n\n /**\n * @param {object} options An options object<ko>옵션 객체</ko>\n * @param {number} [options.index] Index of AnchorPoint<ko>AnchorPoint의 인덱스</ko>\n * @param {number} [options.position] Position of AnchorPoint<ko>AnchorPoint의 좌표</ko>\n * @param {Panel} [options.panel] A {@link Panel} instance AnchorPoint is referencing to<ko>AnchorPoint가 참조하고 있는 {@link Panel}</ko>\n */\n public constructor({\n index,\n position,\n panel\n }: {\n index: number;\n position: number;\n panel: Panel;\n }) {\n this._index = index;\n this._pos = position;\n this._panel = panel;\n }\n}\n\nexport default AnchorPoint;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { OnRelease } from \"@egjs/axes\";\n\nimport FlickingError from \"../core/FlickingError\";\nimport AnchorPoint from \"../core/AnchorPoint\";\nimport { circulateIndex, clamp, getFlickingAttached } from \"../utils\";\nimport * as AXES from \"../const/axes\";\nimport * as ERROR from \"../const/error\";\n\nimport Control from \"./Control\";\n\n/**\n * An options for the {@link SnapControl}\n * @ko {@link SnapControl} 생성시 사용되는 옵션\n * @interface\n * @property {number} count Maximum number of panels can go after release<ko>입력 중단 이후 통과하여 이동할 수 있는 패널의 최대 갯수</ko>\n */\nexport interface SnapControlOptions {\n count: number;\n}\n\n/**\n * A {@link Control} that uses a release momentum to choose destination panel\n * @ko 입력을 중단한 시점의 가속도에 영향받아 도달할 패널을 계산하는 이동 방식을 사용하는 {@link Control}\n */\nclass SnapControl extends Control {\n private _count: SnapControlOptions[\"count\"];\n\n /**\n * Maximum number of panels can go after release\n * @ko 입력 중단 이후 통과하여 이동할 수 있는 패널의 최대 갯수\n * @type {number}\n * @default Infinity\n */\n public get count() { return this._count; }\n\n public set count(val: SnapControlOptions[\"count\"]) { this._count = val; }\n\n /** */\n public constructor({\n count = Infinity\n }: Partial<SnapControlOptions> = {}) {\n super();\n\n this._count = count;\n }\n\n /**\n * Move {@link Camera} to the given position\n * @ko {@link Camera}를 주어진 좌표로 이동합니다\n * @param {number} position The target position to move<ko>이동할 좌표</ko>\n * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>\n * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}\n * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>\n * @fires Flicking#moveStart\n * @fires Flicking#move\n * @fires Flicking#moveEnd\n * @fires Flicking#willChange\n * @fires Flicking#changed\n * @fires Flicking#willRestore\n * @fires Flicking#restored\n * @fires Flicking#needPanel\n * @fires Flicking#visibleChange\n * @fires Flicking#reachEdge\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|\n * <ko>\n *\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|\n *\n * </ko>\n * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>\n */\n public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n const activeAnchor = camera.findActiveAnchor();\n const anchorAtCamera = camera.findNearestAnchor(camera.position);\n const state = flicking.control.controller.state;\n\n if (!activeAnchor || !anchorAtCamera) {\n return Promise.reject(new FlickingError(ERROR.MESSAGE.POSITION_NOT_REACHABLE(position), ERROR.CODE.POSITION_NOT_REACHABLE));\n }\n\n const snapThreshold = this._calcSnapThreshold(position, activeAnchor);\n\n const posDelta = flicking.animating\n ? state.delta\n : position - camera.position;\n const absPosDelta = Math.abs(posDelta);\n const snapDelta = axesEvent && axesEvent.delta[AXES.POSITION_KEY] !== 0\n ? Math.abs(axesEvent.delta[AXES.POSITION_KEY])\n : absPosDelta;\n let targetAnchor: AnchorPoint;\n\n if (snapDelta >= snapThreshold && snapDelta > 0) {\n // Move to anchor at position\n targetAnchor = this._findSnappedAnchor(position, anchorAtCamera);\n } else if (absPosDelta >= flicking.threshold && absPosDelta > 0) {\n // Move to the adjacent panel\n targetAnchor = this._findAdjacentAnchor(posDelta, anchorAtCamera);\n } else {\n // Restore to active panel\n targetAnchor = anchorAtCamera;\n }\n\n this._triggerIndexChangeEvent(targetAnchor.panel, position, axesEvent);\n\n return this._animateToPosition({\n position: camera.clampToReachablePosition(targetAnchor.position),\n duration,\n newActivePanel: targetAnchor.panel,\n axesEvent\n });\n }\n\n private _findSnappedAnchor(position: number, anchorAtCamera: AnchorPoint): AnchorPoint {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n const count = this._count;\n\n const currentPos = camera.position;\n\n const clampedPosition = camera.clampToReachablePosition(position);\n const anchorAtPosition = camera.findAnchorIncludePosition(clampedPosition);\n\n if (!anchorAtCamera || !anchorAtPosition) {\n throw new FlickingError(ERROR.MESSAGE.POSITION_NOT_REACHABLE(position), ERROR.CODE.POSITION_NOT_REACHABLE);\n }\n\n if (!isFinite(count)) {\n return anchorAtPosition;\n }\n\n const panelCount = flicking.panelCount;\n const anchors = camera.anchorPoints;\n\n let loopCount = Math.sign(position - currentPos) * Math.floor(Math.abs(position - currentPos) / camera.rangeDiff);\n if ((position > currentPos && anchorAtPosition.index < anchorAtCamera.index)\n || (anchorAtPosition.position > anchorAtCamera.position && anchorAtPosition.index === anchorAtCamera.index)) {\n loopCount += 1;\n } else if ((position < currentPos && anchorAtPosition.index > anchorAtCamera.index)\n || (anchorAtPosition.position < anchorAtCamera.position && anchorAtPosition.index === anchorAtCamera.index)) {\n loopCount -= 1;\n }\n\n const circularIndexOffset = loopCount * panelCount;\n const anchorAtPositionIndex = anchorAtPosition.index + circularIndexOffset;\n\n if (Math.abs(anchorAtPositionIndex - anchorAtCamera.index) <= count) {\n const anchor = anchors[anchorAtPosition.index];\n\n return new AnchorPoint({\n index: anchor.index,\n position: anchor.position + loopCount * camera.rangeDiff,\n panel: anchor.panel\n });\n }\n\n if (flicking.circularEnabled) {\n const targetAnchor = anchors[circulateIndex(anchorAtCamera.index + Math.sign(position - currentPos) * count, panelCount)];\n let loop = Math.floor(count / panelCount);\n\n if (position > currentPos && targetAnchor.index < anchorAtCamera.index) {\n loop += 1;\n } else if (position < currentPos && targetAnchor.index > anchorAtCamera.index) {\n loop -= 1;\n }\n\n return new AnchorPoint({\n index: targetAnchor.index,\n position: targetAnchor.position + loop * camera.rangeDiff,\n panel: targetAnchor.panel\n });\n } else {\n return anchors[clamp(anchorAtCamera.index + Math.sign(position - currentPos) * count, 0, anchors.length - 1)];\n }\n }\n\n private _findAdjacentAnchor(posDelta: number, anchorAtCamera: AnchorPoint): AnchorPoint {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n const adjacentAnchor = (posDelta > 0 ? camera.getNextAnchor(anchorAtCamera) : camera.getPrevAnchor(anchorAtCamera)) ?? anchorAtCamera;\n\n return adjacentAnchor;\n }\n\n private _calcSnapThreshold(position: number, activeAnchor: AnchorPoint): number {\n const isNextDirection = position > activeAnchor.position;\n const panel = activeAnchor.panel;\n const panelSize = panel.size;\n const alignPos = panel.alignPosition;\n\n // Minimum distance needed to decide prev/next panel as nearest\n /*\n * | Prev | Next |\n * |<------>|<------------>|\n * [ |<-Anchor ]\n */\n return isNextDirection\n ? panelSize - alignPos + panel.margin.next\n : alignPos + panel.margin.prev;\n }\n}\n\nexport default SnapControl;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { OnRelease } from \"@egjs/axes\";\n\nimport FlickingError from \"../core/FlickingError\";\nimport * as ERROR from \"../const/error\";\nimport { getFlickingAttached } from \"../utils\";\n\nimport Control from \"./Control\";\n\n/**\n * An options for the {@link FreeControl}\n * @ko {@link FreeControl} 생성시 사용되는 옵션\n * @interface\n * @property {boolean} stopAtEdge Make scroll animation to stop at the start/end of the scroll area, not going out the bounce area\n * <ko>스크롤 애니메이션을 스크롤 영역의 시작과 끝부분에서 멈추도록 하여, 바운스 영역을 넘어가지 않도록 합니다</ko>\n */\nexport interface FreeControlOptions {\n stopAtEdge: boolean;\n}\n\n/**\n * A {@link Control} that can be scrolled freely without alignment\n * @ko 패널이 정해진 지점에 정렬되지 않고, 자유롭게 스크롤할 수 있는 이동 방식을 사용하는 {@link Control}\n */\nclass FreeControl extends Control {\n private _stopAtEdge: FreeControlOptions[\"stopAtEdge\"];\n\n /**\n * Make scroll animation to stop at the start/end of the scroll area, not going out the bounce area\n * @ko 스크롤 애니메이션을 스크롤 영역의 시작과 끝부분에서 멈추도록 하여, 바운스 영역을 넘어가지 않도록 합니다\n * @type {boolean}\n * @default true\n */\n public get stopAtEdge() { return this._stopAtEdge; }\n\n public set stopAtEdge(val: FreeControlOptions[\"stopAtEdge\"]) { this._stopAtEdge = val; }\n\n /** */\n public constructor({\n stopAtEdge = true\n }: Partial<FreeControlOptions> = {}) {\n super();\n\n this._stopAtEdge = stopAtEdge;\n }\n\n /**\n * Update position after resizing\n * @ko resize 이후에 position을 업데이트합니다\n * @param {number} progressInPanel Previous camera's progress in active panel before resize<ko>Resize 이전 현재 선택된 패널 내에서의 카메라 progress 값</ko>\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before\n * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>\n * @chainable\n * @return {Promise<void>}\n */\n public updatePosition(progressInPanel: number): void {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n const activePanel = this._activePanel;\n\n if (activePanel) {\n const panelRange = activePanel.range;\n const newPosition = panelRange.min + (panelRange.max - panelRange.min) * progressInPanel;\n\n camera.lookAt(camera.clampToReachablePosition(newPosition));\n }\n }\n\n /**\n * Move {@link Camera} to the given position\n * @ko {@link Camera}를 주어진 좌표로 이동합니다\n * @param {number} position The target position to move<ko>이동할 좌표</ko>\n * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>\n * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}\n * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>\n * @fires Flicking#moveStart\n * @fires Flicking#move\n * @fires Flicking#moveEnd\n * @fires Flicking#willChange\n * @fires Flicking#changed\n * @fires Flicking#willRestore\n * @fires Flicking#restored\n * @fires Flicking#needPanel\n * @fires Flicking#visibleChange\n * @fires Flicking#reachEdge\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|\n * <ko>\n *\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|\n *\n * </ko>\n * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>\n */\n public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n\n const camera = flicking.camera;\n const targetPos = camera.clampToReachablePosition(position);\n\n const anchorAtPosition = camera.findAnchorIncludePosition(targetPos);\n\n if (!anchorAtPosition) {\n return Promise.reject(new FlickingError(ERROR.MESSAGE.POSITION_NOT_REACHABLE(position), ERROR.CODE.POSITION_NOT_REACHABLE));\n }\n\n const targetPanel = anchorAtPosition.panel;\n\n // Trigger only change event\n if (targetPanel !== this._activePanel) {\n this._triggerIndexChangeEvent(targetPanel, position, axesEvent);\n }\n\n return this._animateToPosition({ position: this._stopAtEdge ? targetPos : position, duration, newActivePanel: targetPanel, axesEvent });\n }\n}\n\nexport default FreeControl;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { OnRelease } from \"@egjs/axes\";\n\nimport Panel from \"../core/panel/Panel\";\nimport FlickingError from \"../core/FlickingError\";\nimport { clamp, getFlickingAttached, getMinusCompensatedIndex, isBetween } from \"../utils\";\nimport * as ERROR from \"../const/error\";\n\nimport Control from \"./Control\";\n/**\n * An options for the {@link StrictControl}\n * @ko {@link StrictControl} 생성시 사용되는 옵션\n * @interface\n * @property {number} count Maximum number of panels that can be moved at a time<ko>최대로 움직일 수 있는 패널의 개수</ko>\n */\nexport interface StrictControlOptions {\n count: number;\n}\n\n/**\n * A {@link Control} that allow you to select the maximum number of panels to move at a time\n * @ko 한번에 최대로 이동할 패널의 개수를 선택 가능한 {@link Control}\n */\nclass StrictControl extends Control {\n private _count: number;\n private _indexRange: { min: number; max: number };\n\n /**\n * Maximum number of panels that can be moved at a time\n * @ko 최대로 움직일 수 있는 패널의 개수\n * @type {number}\n * @default 1\n */\n public get count() { return this._count; }\n\n public set count(val: StrictControlOptions[\"count\"]) { this._count = val; }\n\n /** */\n public constructor({\n count = 1\n }: Partial<StrictControlOptions> = {}) {\n super();\n\n this._count = count;\n this._resetIndexRange();\n }\n\n /**\n * Destroy Control and return to initial state\n * @ko Control을 초기 상태로 되돌립니다\n * @return {void}\n */\n public destroy() {\n super.destroy();\n\n this._resetIndexRange();\n }\n\n /**\n * Update {@link Control#controller controller}'s state\n * @ko {@link Control#controller controller}의 내부 상태를 갱신합니다\n * @chainable\n * @return {this}\n */\n public updateInput(): this {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n const renderer = flicking.renderer;\n const controller = this._controller;\n const controlParams = camera.controlParams;\n const count = this._count;\n\n const activePanel = controller.state.animating\n ? camera.findNearestAnchor(camera.position)?.panel\n : this._activePanel;\n\n if (!activePanel) {\n controller.update(controlParams);\n this._resetIndexRange();\n return this;\n }\n\n const cameraRange = controlParams.range;\n const currentPos = activePanel.position;\n const currentIndex = activePanel.index;\n const panelCount = renderer.panelCount;\n\n let prevPanelIndex = currentIndex - count;\n let nextPanelIndex = currentIndex + count;\n\n if (prevPanelIndex < 0) {\n prevPanelIndex = flicking.circularEnabled\n ? getMinusCompensatedIndex((prevPanelIndex + 1) % panelCount - 1, panelCount)\n : clamp(prevPanelIndex, 0, panelCount - 1);\n }\n if (nextPanelIndex >= panelCount) {\n nextPanelIndex = flicking.circularEnabled\n ? nextPanelIndex % panelCount\n : clamp(nextPanelIndex, 0, panelCount - 1);\n }\n\n const prevPanel = renderer.panels[prevPanelIndex];\n const nextPanel = renderer.panels[nextPanelIndex];\n\n let prevPos = Math.max(prevPanel.position, cameraRange.min);\n let nextPos = Math.min(nextPanel.position, cameraRange.max);\n\n if (prevPos > currentPos) {\n prevPos -= camera.rangeDiff;\n }\n if (nextPos < currentPos) {\n nextPos += camera.rangeDiff;\n }\n\n controlParams.range = {\n min: prevPos,\n max: nextPos\n };\n\n if (controlParams.circular) {\n if (controlParams.position < prevPos) {\n controlParams.position += camera.rangeDiff;\n }\n\n if (controlParams.position > nextPos) {\n controlParams.position -= camera.rangeDiff;\n }\n }\n\n controlParams.circular = false;\n controller.update(controlParams);\n\n this._indexRange = {\n min: prevPanel.index,\n max: nextPanel.index\n };\n\n return this;\n }\n\n /**\n * Move {@link Camera} to the given position\n * @ko {@link Camera}를 주어진 좌표로 이동합니다\n * @param {number} position The target position to move<ko>이동할 좌표</ko>\n * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>\n * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}\n * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>\n * @fires Flicking#moveStart\n * @fires Flicking#move\n * @fires Flicking#moveEnd\n * @fires Flicking#willChange\n * @fires Flicking#changed\n * @fires Flicking#willRestore\n * @fires Flicking#restored\n * @fires Flicking#needPanel\n * @fires Flicking#visibleChange\n * @fires Flicking#reachEdge\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|\n * <ko>\n *\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|\n * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|\n *\n * </ko>\n * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>\n */\n public async moveToPosition(position: number, duration: number, axesEvent?: OnRelease) {\n const flicking = getFlickingAttached(this._flicking, \"Control\");\n const camera = flicking.camera;\n const activePanel = this._activePanel;\n const axesRange = this._controller.range;\n const indexRange = this._indexRange;\n const cameraRange = camera.range;\n\n const clampedPosition = clamp(camera.clampToReachablePosition(position), axesRange[0], axesRange[1]);\n const anchorAtPosition = camera.findAnchorIncludePosition(clampedPosition);\n\n if (!anchorAtPosition || !activePanel) {\n return Promise.reject(new FlickingError(ERROR.MESSAGE.POSITION_NOT_REACHABLE(position), ERROR.CODE.POSITION_NOT_REACHABLE));\n }\n\n const prevPos = activePanel.position;\n\n const isOverThreshold = Math.abs(position - prevPos) >= flicking.threshold;\n const adjacentAnchor = (position > prevPos)\n ? camera.getNextAnchor(anchorAtPosition)\n : camera.getPrevAnchor(anchorAtPosition);\n\n let targetPos: number;\n let targetPanel: Panel;\n\n const anchors = camera.anchorPoints;\n const firstAnchor = anchors[0];\n const lastAnchor = anchors[anchors.length - 1];\n\n const shouldBounceToFirst = position <= cameraRange.min && isBetween(firstAnchor.panel.index, indexRange.min, indexRange.max);\n const shouldBounceToLast = position >= cameraRange.max && isBetween(lastAnchor.panel.index, indexRange.min, indexRange.max);\n\n if (shouldBounceToFirst || shouldBounceToLast) {\n // In bounce area\n const targetAnchor = position < cameraRange.min ? firstAnchor : lastAnchor;\n\n targetPanel = targetAnchor.panel;\n targetPos = targetAnchor.position;\n } else if (isOverThreshold && anchorAtPosition.position !== activePanel.position) {\n // Move to anchor at position\n targetPanel = anchorAtPosition.panel;\n targetPos = anchorAtPosition.position;\n } else if (isOverThreshold && adjacentAnchor && isBetween(adjacentAnchor.index, indexRange.min, indexRange.max)) {\n // Move to adjacent anchor\n targetPanel = adjacentAnchor.panel;\n targetPos = adjacentAnchor.position;\n } else {\n // Restore to active panel\n targetPos = camera.clampToReachablePosition(activePanel.position);\n targetPanel = activePanel;\n }\n\n this._triggerIndexChangeEvent(targetPanel, position, axesEvent);\n\n return this._animateToPosition({\n position: targetPos,\n duration,\n newActivePanel: targetPanel,\n axesEvent\n });\n }\n\n public setActive = (newActivePanel: Panel, prevActivePanel: Panel | null, isTrusted: boolean) => {\n super.setActive(newActivePanel, prevActivePanel, isTrusted);\n this.updateInput();\n };\n\n private _resetIndexRange() {\n this._indexRange = { min: 0, max: 0 };\n }\n}\n\nexport default StrictControl;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { ComponentEvent } from \"@egjs/component\";\n\nimport Flicking, { FlickingOptions } from \"../Flicking\";\nimport FlickingError from \"../core/FlickingError\";\nimport Panel from \"../core/panel/Panel\";\nimport AnchorPoint from \"../core/AnchorPoint\";\nimport * as ERROR from \"../const/error\";\nimport { ALIGN, DIRECTION, EVENTS } from \"../const/external\";\nimport { checkExistence, clamp, find, getFlickingAttached, getProgress, includes, parseAlign } from \"../utils\";\n\nexport interface CameraOptions {\n align: FlickingOptions[\"align\"];\n}\n\n/**\n * A component that manages actual movement inside the viewport\n * @ko 뷰포트 내에서의 실제 움직임을 담당하는 컴포넌트\n */\nabstract class Camera {\n // Options\n protected _align: FlickingOptions[\"align\"];\n\n // Internal states\n protected _flicking: Flicking | null;\n protected _el: HTMLElement;\n protected _transform: string;\n protected _position: number;\n protected _alignPos: number;\n protected _offset: number;\n protected _range: { min: number; max: number };\n protected _visiblePanels: Panel[];\n protected _anchors: AnchorPoint[];\n protected _needPanelTriggered: { prev: boolean; next: boolean };\n\n // Internal states getter\n /**\n * The camera(`.flicking-camera`) element\n * @ko 카메라(`.flicking-camera`) 엘리먼트\n * @type {HTMLElement}\n * @readonly\n */\n public get element() { return this._el; }\n /**\n * Current position of the camera\n * @ko Camera의 현재 좌표\n * @type {number}\n * @readonly\n */\n public get position() { return this._position; }\n /**\n * Align position inside the viewport where {@link Panel}'s {@link Panel#alignPosition alignPosition} should be located at\n * @ko 패널의 정렬 기준 위치. 뷰포트 내에서 {@link Panel}의 {@link Panel#alignPosition alignPosition}이 위치해야 하는 곳입니다\n * @type {number}\n * @readonly\n */\n public get alignPosition() { return this._alignPos; }\n /**\n * Position offset, used for the {@link Flicking#renderOnlyVisible renderOnlyVisible} option\n * @ko Camera의 좌표 오프셋. {@link Flicking#renderOnlyVisible renderOnlyVisible} 옵션을 위해 사용됩니다.\n * @type {number}\n * @default 0\n * @readonly\n */\n public get offset() { return this._offset; }\n /**\n * A range that Camera's {@link Camera#position position} can reach\n * @ko Camera의 {@link Camera#position position}이 도달 가능한 범위\n * @type {object}\n * @property {number} min A minimum position<ko>최소 위치</ko>\n * @property {number} min A maximum position<ko>최대 위치</ko>\n * @readonly\n */\n public get range() { return this._range; }\n /**\n * A difference between Camera's minimum and maximum position that can reach\n * @ko Camera가 도달 가능한 최소/최대 좌표의 차이\n * @type {number}\n * @readonly\n */\n public get rangeDiff() { return this._range.max - this._range.min; }\n /**\n * An array of visible panels from the current position\n * @ko 현재 보이는 패널들의 배열\n * @type {Panel[]}\n * @readonly\n */\n public get visiblePanels() { return this._visiblePanels; }\n /**\n * A range of the visible area from the current position\n * @ko 현재 위치에서 보이는 범위\n * @type {object}\n * @property {number} min A minimum position<ko>최소 위치</ko>\n * @property {number} min A maximum position<ko>최대 위치</ko>\n * @readonly\n */\n public get visibleRange() { return { min: this._position - this._alignPos, max: this._position - this._alignPos + this.size }; }\n /**\n * An array of {@link AnchorPoint}s that Camera can be stopped at\n * @ko 카메라가 도달 가능한 {@link AnchorPoint}의 목록\n * @type {AnchorPoint[]}\n * @readonly\n */\n public get anchorPoints() { return this._anchors; }\n /**\n * A current parameters of the Camera for updating {@link AxesController}\n * @ko {@link AxesController}를 업데이트하기 위한 현재 Camera 패러미터들\n * @type {ControlParams}\n * @readonly\n */\n public get controlParams() { return { range: this._range, position: this._position, circular: false }; }\n /**\n * A Boolean value indicating whether Camera's over the minimum or maximum position reachable\n * @ko 현재 카메라가 도달 가능한 범위의 최소 혹은 최대점을 넘어섰는지를 나타냅니다\n * @type {boolean}\n * @readonly\n */\n public get atEdge() { return this._position <= this._range.min || this._position >= this._range.max; }\n /**\n * Return the size of the viewport\n * @ko 뷰포트 크기를 반환합니다\n * @type {number}\n * @readonly\n */\n public get size() {\n const flicking = this._flicking;\n return flicking\n ? flicking.horizontal\n ? flicking.viewport.width\n : flicking.viewport.height\n : 0;\n }\n\n /**\n * Return the camera's position progress from the first panel to last panel\n * Range is from 0 to last panel's index\n * @ko 첫번째 패널로부터 마지막 패널까지의 카메라 위치의 진행도를 반환합니다\n * 범위는 0부터 마지막 패널의 인덱스까지입니다\n * @type {number}\n * @readonly\n */\n public get progress() {\n const flicking = this._flicking;\n const position = this._position + this._offset;\n const nearestAnchor = this.findNearestAnchor(this._position);\n\n if (!flicking || !nearestAnchor) {\n return NaN;\n }\n\n const nearestPanel = nearestAnchor.panel;\n const panelPos = nearestPanel.position + nearestPanel.offset;\n const bounceSize = flicking.control.controller.bounce!;\n\n const { min: prevRange, max: nextRange } = this.range;\n const rangeDiff = this.rangeDiff;\n\n if (position === panelPos) {\n return nearestPanel.index;\n }\n\n if (position < panelPos) {\n const prevPanel = nearestPanel.prev();\n let prevPosition = prevPanel\n ? prevPanel.position + prevPanel.offset\n : prevRange - bounceSize[0];\n\n // Looped\n if (prevPosition > panelPos) {\n prevPosition -= rangeDiff;\n }\n\n return nearestPanel.index - 1 + getProgress(position, prevPosition, panelPos);\n } else {\n const nextPanel = nearestPanel.next();\n let nextPosition = nextPanel\n ? nextPanel.position + nextPanel.offset\n : nextRange + bounceSize[1];\n\n // Looped\n if (nextPosition < panelPos) {\n nextPosition += rangeDiff;\n }\n\n return nearestPanel.index + getProgress(position, panelPos, nextPosition);\n }\n }\n\n // Options Getter\n /**\n * A value indicating where the {@link Camera#alignPosition alignPosition} should be located at inside the viewport element\n * @ko {@link Camera#alignPosition alignPosition}이 뷰포트 엘리먼트 내의 어디에 위치해야 하는지를 나타내는 값\n * @type {ALIGN | string | number}\n */\n public get align() { return this._align; }\n\n // Options Setter\n public set align(val: FlickingOptions[\"align\"]) {\n this._align = val;\n }\n\n /** */\n public constructor({\n align = ALIGN.CENTER\n }: Partial<CameraOptions> = {}) {\n this._flicking = null;\n this._resetInternalValues();\n\n // Options\n this._align = align;\n }\n\n /**\n * Update {@link Camera#range range} of Camera\n * @ko Camera의 {@link Camera#range range}를 업데이트합니다\n * @method\n * @abstract\n * @memberof Camera\n * @instance\n * @name updateRange\n * @chainable\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before\n * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>\n * @return {this}\n */\n public abstract updateRange(): this;\n\n /**\n * Initialize Camera\n * @ko Camera를 초기화합니다\n * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>\n * @chainable\n * @throws {FlickingError}\n * {@link ERROR_CODE VAL_MUST_NOT_NULL} If the camera element(`.flicking-camera`) does not exist inside viewport element\n * <ko>{@link ERROR_CODE VAL_MUST_NOT_NULL} 뷰포트 엘리먼트 내부에 카메라 엘리먼트(`.flicking-camera`)가 존재하지 않을 경우</ko>\n * @return {this}\n */\n public init(flicking: Flicking): this {\n this._flicking = flicking;\n\n const viewportEl = flicking.viewport.element;\n\n checkExistence(viewportEl.firstElementChild, \"First element child of the viewport element\");\n this._el = viewportEl.firstElementChild as HTMLElement;\n this._checkTranslateSupport();\n\n return this;\n }\n\n /**\n * Destroy Camera and return to initial state\n * @ko Camera를 초기 상태로 되돌립니다\n * @return {void}\n */\n public destroy(): this {\n this._flicking = null;\n this._resetInternalValues();\n return this;\n }\n\n /**\n * Move to the given position and apply CSS transform\n * @ko 해당 좌표로 이동하고, CSS transform을 적용합니다\n * @param {number} pos A new position<ko>움직일 위치</ko>\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before\n * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>\n * @return {this}\n */\n public lookAt(pos: number): void {\n const prevPos = this._position;\n\n this._position = pos;\n this._refreshVisiblePanels();\n this._checkNeedPanel();\n this._checkReachEnd(prevPos, pos);\n this._applyTransform();\n }\n\n /**\n * Return a previous {@link AnchorPoint} of given {@link AnchorPoint}\n * If it does not exist, return `null` instead\n * @ko 주어진 {@link AnchorPoint}의 이전 {@link AnchorPoint}를 반환합니다\n * 존재하지 않을 경우 `null`을 반환합니다\n * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>\n * @return {AnchorPoint | null} The previous {@link AnchorPoint}<ko>이전 {@link AnchorPoint}</ko>\n */\n public getPrevAnchor(anchor: AnchorPoint): AnchorPoint | null {\n return this._anchors[anchor.index - 1] || null;\n }\n\n /**\n * Return a next {@link AnchorPoint} of given {@link AnchorPoint}\n * If it does not exist, return `null` instead\n * @ko 주어진 {@link AnchorPoint}의 다음 {@link AnchorPoint}를 반환합니다\n * 존재하지 않을 경우 `null`을 반환합니다\n * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>\n * @return {AnchorPoint | null} The next {@link AnchorPoint}<ko>다음 {@link AnchorPoint}</ko>\n */\n public getNextAnchor(anchor: AnchorPoint): AnchorPoint | null {\n return this._anchors[anchor.index + 1] || null;\n }\n\n /**\n * Return the camera's position progress in the panel below\n * Value is from 0 to 1 when the camera's inside panel\n * Value can be lower than 0 or bigger than 1 when it's in the margin area\n * @ko 현재 카메라 아래 패널에서의 위치 진행도를 반환합니다\n * 반환값은 카메라가 패널 내부에 있을 경우 0부터 1까지의 값을 갖습니다\n * 패널의 margin 영역에 있을 경우 0보다 작거나 1보다 큰 값을 반환할 수 있습니다\n */\n public getProgressInPanel(panel: Panel) {\n const panelRange = panel.range;\n\n return (this._position - panelRange.min) / (panelRange.max - panelRange.min);\n }\n\n /**\n * Return {@link AnchorPoint} that includes given position\n * If there's no {@link AnchorPoint} that includes the given position, return `null` instead\n * @ko 주어진 좌표를 포함하는 {@link AnchorPoint}를 반환합니다\n * 주어진 좌표를 포함하는 {@link AnchorPoint}가 없을 경우 `null`을 반환합니다\n * @param {number} position A position to check<ko>확인할 좌표</ko>\n * @return {AnchorPoint | null} The {@link AnchorPoint} that includes the given position<ko>해당 좌표를 포함하는 {@link AnchorPoint}</ko>\n */\n public findAnchorIncludePosition(position: number): AnchorPoint | null {\n const anchors = this._anchors;\n const anchorsIncludingPosition = anchors.filter(anchor => anchor.panel.includePosition(position, true));\n\n return anchorsIncludingPosition.reduce((nearest: AnchorPoint | null, anchor) => {\n if (!nearest) return anchor;\n\n return Math.abs(nearest.position - position) < Math.abs(anchor.position - position)\n ? nearest\n : anchor;\n }, null);\n }\n\n /**\n * Return {@link AnchorPoint} nearest to given position\n * If there're no {@link AnchorPoint}s, return `null` instead\n * @ko 해당 좌표에서 가장 가까운 {@link AnchorPoint}를 반환합니다\n * {@link AnchorPoint}가 하나도 없을 경우 `null`을 반환합니다\n * @param {number} position A position to check<ko>확인할 좌표</ko>\n * @return {AnchorPoint | null} The {@link AnchorPoint} nearest to the given position<ko>해당 좌표에 가장 인접한 {@link AnchorPoint}</ko>\n */\n public findNearestAnchor(position: number): AnchorPoint | null {\n const anchors = this._anchors;\n\n if (anchors.length <= 0) return null;\n\n let prevDist = Infinity;\n for (let anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {\n const anchor = anchors[anchorIdx];\n const dist = Math.abs(anchor.position - position);\n\n if (dist > prevDist) {\n // Return previous anchor\n return anchors[anchorIdx - 1];\n }\n\n prevDist = dist;\n }\n\n // Return last anchor\n return anchors[anchors.length - 1];\n }\n\n /**\n * Return {@link AnchorPoint} that matches {@link Flicking#currentPanel}\n * @ko 현재 {@link Flicking#currentPanel}에 해당하는 {@link AnchorPoint}를 반환합니다\n * @return {AnchorPoint | null}\n */\n public findActiveAnchor(): AnchorPoint | null {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const activeIndex = flicking.control.activeIndex;\n\n return find(this._anchors, anchor => anchor.panel.index === activeIndex);\n }\n\n /**\n * Clamp the given position between camera's range\n * @ko 주어진 좌표를 Camera가 도달 가능한 범위 사이의 값으로 만듭니다\n * @param {number} position A position to clamp<ko>범위를 제한할 좌표</ko>\n * @return {number} A clamped position<ko>범위 제한된 좌표</ko>\n */\n public clampToReachablePosition(position: number): number {\n const range = this._range;\n return clamp(position, range.min, range.max);\n }\n\n /**\n * Check whether the given panel is inside of the Camera's range\n * @ko 해당 {@link Panel}이 Camera가 도달 가능한 범위 내에 있는지를 반환합니다\n * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>\n * @return {boolean} Whether the panel's inside Camera's range<ko>도달 가능한 범위 내에 해당 패널이 존재하는지 여부</ko>\n */\n public canReach(panel: Panel): boolean {\n const range = this._range;\n\n if (panel.removed) return false;\n\n const panelPos = panel.position;\n\n return panelPos >= range.min && panelPos <= range.max;\n }\n\n /**\n * Check whether the given panel element is visible at the current position\n * @ko 현재 좌표에서 해당 패널 엘리먼트를 볼 수 있는지 여부를 반환합니다\n * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>\n * @return Whether the panel element is visible at the current position<ko>현재 위치에서 해당 패널 엘리먼트가 보이는지 여부</ko>\n */\n public canSee(panel: Panel): boolean {\n const visibleRange = this.visibleRange;\n // Should not include margin, as we don't declare what the margin is visible as what the panel is visible.\n return panel.includeRange(visibleRange.min, visibleRange.max, false);\n }\n\n /**\n * Update Camera's {@link Camera#alignPosition alignPosition}\n * @ko Camera의 {@link Camera#alignPosition alignPosition}을 업데이트합니다\n * @chainable\n * @return {this}\n */\n public updateAlignPos(): this {\n const align = this._align;\n\n const alignVal = typeof align === \"object\"\n ? (align as { camera: string | number }).camera\n : align;\n\n this._alignPos = parseAlign(alignVal, this.size);\n\n return this;\n }\n\n /**\n * Update Camera's {@link Camera#anchorPoints anchorPoints}\n * @ko Camera의 {@link Camera#anchorPoints anchorPoints}를 업데이트합니다\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before\n * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>\n * @chainable\n * @return {this}\n */\n public updateAnchors(): this {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const panels = flicking.renderer.panels;\n\n this._anchors = panels.map((panel, index) => new AnchorPoint({\n index,\n position: panel.position,\n panel\n }));\n\n return this;\n }\n\n /**\n * Update Viewport's height to active panel's height\n * @ko 현재 선택된 패널의 높이와 동일하도록 뷰포트의 높이를 업데이트합니다\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before\n * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>\n * @chainable\n * @return {this}\n */\n public updateAdaptiveHeight() {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const activePanel = flicking.control.activePanel;\n\n if (!flicking.horizontal || !flicking.adaptive || !activePanel) return;\n\n flicking.viewport.setSize({\n height: activePanel.height\n });\n }\n\n public updateOffset() {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const unRenderedPanels = flicking.panels.filter(panel => !panel.rendered);\n const position = this._position;\n\n this._offset = unRenderedPanels\n .filter(panel => panel.position + panel.offset < position)\n .reduce((offset, panel) => offset + panel.sizeIncludingMargin, 0);\n\n this._applyTransform();\n }\n\n /**\n * Reset the history of {@link Flicking#event:needPanel needPanel} events so it can be triggered again\n * @ko 발생한 {@link Flicking#event:needPanel needPanel} 이벤트들을 초기화하여 다시 발생할 수 있도록 합니다\n * @chainable\n * @return {this}\n */\n public resetNeedPanelHistory(): this {\n this._needPanelTriggered = { prev: false, next: false };\n return this;\n }\n\n protected _resetInternalValues() {\n this._position = 0;\n this._alignPos = 0;\n this._offset = 0;\n this._range = { min: 0, max: 0 };\n this._visiblePanels = [];\n this._anchors = [];\n this._needPanelTriggered = { prev: false, next: false };\n }\n\n protected _refreshVisiblePanels() {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const panels = flicking.renderer.panels;\n\n const newVisiblePanels = panels.filter(panel => this.canSee(panel));\n const prevVisiblePanels = this._visiblePanels;\n this._visiblePanels = newVisiblePanels;\n\n const added: Panel[] = newVisiblePanels.filter(panel => !includes(prevVisiblePanels, panel));\n const removed: Panel[] = prevVisiblePanels.filter(panel => !includes(newVisiblePanels, panel));\n\n if (added.length > 0 || removed.length > 0) {\n void flicking.renderer.render().then(() => {\n flicking.trigger(new ComponentEvent(EVENTS.VISIBLE_CHANGE, {\n added,\n removed,\n visiblePanels: newVisiblePanels\n }));\n });\n }\n }\n\n protected _checkNeedPanel(): void {\n const needPanelTriggered = this._needPanelTriggered;\n\n if (needPanelTriggered.prev && needPanelTriggered.next) return;\n\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const panels = flicking.renderer.panels;\n\n if (panels.length <= 0) {\n if (!needPanelTriggered.prev) {\n flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, { direction: DIRECTION.PREV }));\n needPanelTriggered.prev = true;\n }\n if (!needPanelTriggered.next) {\n flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, { direction: DIRECTION.NEXT }));\n needPanelTriggered.next = true;\n }\n\n return;\n }\n\n const cameraPosition = this._position;\n const cameraSize = this.size;\n const cameraRange = this._range;\n const needPanelThreshold = flicking.needPanelThreshold;\n\n const cameraPrev = cameraPosition - this._alignPos;\n const cameraNext = cameraPrev + cameraSize;\n\n const firstPanel = panels[0];\n const lastPanel = panels[panels.length - 1];\n\n if (!needPanelTriggered.prev) {\n const firstPanelPrev = firstPanel.range.min;\n\n if (cameraPrev <= (firstPanelPrev + needPanelThreshold) || cameraPosition <= (cameraRange.min + needPanelThreshold)) {\n flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, { direction: DIRECTION.PREV }));\n needPanelTriggered.prev = true;\n }\n }\n\n if (!needPanelTriggered.next) {\n const lastPanelNext = lastPanel.range.max;\n\n if (cameraNext >= (lastPanelNext - needPanelThreshold) || cameraPosition >= (cameraRange.max - needPanelThreshold)) {\n flicking.trigger(new ComponentEvent(EVENTS.NEED_PANEL, { direction: DIRECTION.NEXT }));\n needPanelTriggered.next = true;\n }\n }\n }\n\n protected _checkReachEnd(prevPos: number, newPos: number): void {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const range = this._range;\n\n const wasBetweenRange = prevPos > range.min && prevPos < range.max;\n const isBetweenRange = newPos > range.min && newPos < range.max;\n\n if (!wasBetweenRange || isBetweenRange) return;\n\n const direction = newPos <= range.min ? DIRECTION.PREV : DIRECTION.NEXT;\n\n flicking.trigger(new ComponentEvent(EVENTS.REACH_EDGE, {\n direction\n }));\n }\n\n protected _applyTransform(): void {\n const el = this._el;\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n\n const actualPosition = this._position - this._alignPos - this._offset;\n\n el.style[this._transform] = flicking.horizontal\n ? `translate(${-actualPosition}px)`\n : `translate(0, ${-actualPosition}px)`;\n }\n\n protected _checkTranslateSupport = () => {\n const transforms = [\"webkitTransform\", \"msTransform\", \"MozTransform\", \"OTransform\", \"transform\"];\n\n const supportedStyle = document.documentElement.style;\n let transformName = \"\";\n for (const prefixedTransform of transforms) {\n if (prefixedTransform in supportedStyle) {\n transformName = prefixedTransform;\n }\n }\n\n if (!transformName) {\n throw new FlickingError(ERROR.MESSAGE.TRANSFORM_NOT_SUPPORTED, ERROR.CODE.TRANSFORM_NOT_SUPPORTED);\n }\n\n this._transform = transformName;\n };\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { getFlickingAttached } from \"../utils\";\n\nimport Camera from \"./Camera\";\n\n/**\n * A {@link Camera} that can move from the position of the first panel to the position of the last panel\n * @ko 첫번째 패널의 좌표로부터 마지막 패널의 좌표로까지 이동할 수 있는 종류의 {@link Camera}\n */\nclass LinearCamera extends Camera {\n /**\n * Update {@link Camera#range range} of Camera\n * @ko Camera의 {@link Camera#range range}를 업데이트합니다\n * @chainable\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before\n * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>\n * @return {this}\n */\n public updateRange() {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const renderer = flicking.renderer;\n\n const firstPanel = renderer.getPanel(0);\n const lastPanel = renderer.getPanel(renderer.panelCount - 1);\n\n this._range = { min: firstPanel?.position ?? 0, max: lastPanel?.position ?? 0 };\n return this;\n }\n}\n\nexport default LinearCamera;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Panel from \"../core/panel/Panel\";\nimport AnchorPoint from \"../core/AnchorPoint\";\nimport { DIRECTION } from \"../const/external\";\nimport { circulatePosition, getFlickingAttached } from \"../utils\";\nimport { ValueOf } from \"../type/internal\";\n\nimport Camera from \"./Camera\";\n\n/**\n * A data of the position that changes order of the panel elements\n * @ko 패널 엘리먼트 순서가 변경되는 좌표의 데이터\n * @interface\n * @property {Panel} panel Toggling panel<ko>순서를 변경할 패널</ko>\n * @property {DIRECTION} direction Toggling position<ko>순서를 변경할 방향</ko>\n * @property {boolean} toggled Whether the panel has toggled its position to `direction`<ko>`direction` 방향으로 패널 위치를 변경했는지 여부를 나타내는 값</ko>\n */\nexport interface TogglePoint {\n panel: Panel;\n direction: ValueOf<typeof DIRECTION>;\n toggled: boolean;\n}\n\n/**\n * A {@link Camera} that connects the last panel and the first panel, enabling continuous loop\n * @ko 첫번째 패널과 마지막 패널이 이어진 상태로, 무한히 회전할 수 있는 종류의 {@link Camera}\n */\nclass CircularCamera extends Camera {\n private _circularOffset: number = 0;\n private _circularEnabled: boolean = false;\n\n public get offset() { return this._offset - this._circularOffset; }\n public get controlParams() { return { range: this._range, position: this._position, circular: this._circularEnabled }; }\n\n public getPrevAnchor(anchor: AnchorPoint): AnchorPoint | null {\n if (!this._circularEnabled || anchor.index !== 0) return super.getPrevAnchor(anchor);\n\n const anchors = this._anchors;\n const rangeDiff = this.rangeDiff;\n const lastAnchor = anchors[anchors.length - 1];\n\n return new AnchorPoint({\n index: lastAnchor.index,\n position: lastAnchor.position - rangeDiff,\n panel: lastAnchor.panel\n });\n }\n\n public getNextAnchor(anchor: AnchorPoint): AnchorPoint | null {\n const anchors = this._anchors;\n\n if (!this._circularEnabled || anchor.index !== anchors.length - 1) return super.getNextAnchor(anchor);\n\n const rangeDiff = this.rangeDiff;\n const firstAnchor = anchors[0];\n\n return new AnchorPoint({\n index: firstAnchor.index,\n position: firstAnchor.position + rangeDiff,\n panel: firstAnchor.panel\n });\n }\n\n public findAnchorIncludePosition(position: number): AnchorPoint | null {\n if (!this._circularEnabled) return super.findAnchorIncludePosition(position);\n\n const range = this._range;\n const positionInRange = circulatePosition(position, range.min, range.max);\n const anchorInRange = super.findAnchorIncludePosition(positionInRange);\n\n if (!anchorInRange) return null;\n\n const rangeDiff = this.rangeDiff;\n\n if (position < range.min) {\n const loopCount = -Math.floor((range.min - position) / rangeDiff) - 1;\n\n return new AnchorPoint({\n index: anchorInRange.index,\n position: anchorInRange.position + rangeDiff * loopCount,\n panel: anchorInRange.panel\n });\n } else if (position > range.max) {\n const loopCount = Math.floor((position - range.max) / rangeDiff) + 1;\n\n return new AnchorPoint({\n index: anchorInRange.index,\n position: anchorInRange.position + rangeDiff * loopCount,\n panel: anchorInRange.panel\n });\n }\n\n return anchorInRange;\n }\n\n public clampToReachablePosition(position: number): number {\n // Basically all position is reachable for circular camera\n return this._circularEnabled\n ? position\n : super.clampToReachablePosition(position);\n }\n\n public canReach(panel: Panel): boolean {\n if (panel.removed) return false;\n\n return this._circularEnabled\n // Always reachable on circular mode\n ? true\n : super.canReach(panel);\n }\n\n public canSee(panel: Panel): boolean {\n const range = this._range;\n const rangeDiff = this.rangeDiff;\n const visibleRange = this.visibleRange;\n const visibleInCurrentRange = super.canSee(panel);\n\n if (!this._circularEnabled) {\n return visibleInCurrentRange;\n }\n\n // Check looped visible area for circular case\n if (visibleRange.min < range.min) {\n return visibleInCurrentRange || panel.includeRange(visibleRange.min + rangeDiff, visibleRange.max + rangeDiff, false);\n } else if (visibleRange.max > range.max) {\n return visibleInCurrentRange || panel.includeRange(visibleRange.min - rangeDiff, visibleRange.max - rangeDiff, false);\n }\n\n return visibleInCurrentRange;\n }\n\n /**\n * Update {@link Camera#range range} of Camera\n * @ko Camera의 {@link Camera#range range}를 업데이트합니다\n * @chainable\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before\n * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>\n * @return {this}\n */\n public updateRange() {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const renderer = flicking.renderer;\n\n const panels = renderer.panels;\n if (panels.length <= 0) {\n this._resetInternalValues();\n return this;\n }\n\n const firstPanel = panels[0]!;\n const lastPanel = panels[panels.length - 1]!;\n const firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;\n const lastPanelNext = lastPanel.range.max + lastPanel.margin.next;\n\n const visibleSize = this.size;\n const panelSizeSum = lastPanelNext - firstPanelPrev;\n\n const canSetCircularMode = panels\n .every(panel => panelSizeSum - panel.size >= visibleSize);\n this._circularEnabled = canSetCircularMode;\n\n if (canSetCircularMode) {\n this._range = { min: firstPanelPrev, max: lastPanelNext };\n\n panels.forEach(panel => panel.updateCircularToggleDirection());\n } else {\n this._range = { min: firstPanel.position, max: lastPanel.position };\n }\n\n this._updateCircularOffset();\n\n return this;\n }\n\n public lookAt(pos: number) {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const prevPos = this._position;\n\n if (pos === prevPos) return super.lookAt(pos);\n\n const panels = flicking.renderer.panels;\n const toggled = panels.map(panel => panel.toggle(prevPos, pos));\n\n this._position = pos;\n\n if (toggled.some(isToggled => isToggled)) {\n this._updateCircularOffset();\n void flicking.renderer.render();\n }\n\n return super.lookAt(pos);\n }\n\n protected _applyTransform(): void {\n const el = this._el;\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n\n const actualPosition = this._position - this._alignPos - this._offset + this._circularOffset;\n\n el.style[this._transform] = flicking.horizontal\n ? `translate(${-actualPosition}px)`\n : `translate(0, ${-actualPosition}px)`;\n }\n\n protected _resetInternalValues() {\n super._resetInternalValues();\n this._circularOffset = 0;\n this._circularEnabled = false;\n }\n\n private _calcPanelAreaSum(panels: Panel[]) {\n return panels.reduce((sum: number, panel: Panel) => sum + panel.sizeIncludingMargin, 0);\n }\n\n private _updateCircularOffset() {\n if (!this._circularEnabled) {\n this._circularOffset = 0;\n return;\n }\n\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const toggledPrev: Panel[] = [];\n const toggledNext: Panel[] = [];\n\n flicking.panels\n .filter(panel => panel.toggled)\n .forEach(panel => {\n if (panel.toggleDirection === DIRECTION.PREV) {\n toggledPrev.push(panel);\n } else {\n toggledNext.push(panel);\n }\n });\n\n this._circularOffset = this._calcPanelAreaSum(toggledPrev) - this._calcPanelAreaSum(toggledNext);\n }\n}\n\nexport default CircularCamera;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Panel from \"../core/panel/Panel\";\nimport AnchorPoint from \"../core/AnchorPoint\";\nimport { getFlickingAttached, parseAlign } from \"../utils\";\n\nimport Camera from \"./Camera\";\n\n/**\n * A {@link Camera} that set range not to go out of the first/last panel, so it won't show empty spaces before/after the first/last panel\n * @ko 첫번째와 마지막 패널 밖으로 넘어가지 못하도록 범위를 설정하여, 첫번째/마지막 패널 전/후의 빈 공간을 보이지 않도록 하는 종류의 {@link Camera}\n */\nclass BoundCamera extends Camera {\n /**\n * Update {@link Camera#range range} of Camera\n * @ko Camera의 {@link Camera#range range}를 업데이트합니다\n * @chainable\n * @throws {FlickingError}\n * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before\n * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>\n * @return {this}\n */\n public updateRange() {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const renderer = flicking.renderer;\n const alignPos = this._alignPos;\n\n const firstPanel = renderer.getPanel(0);\n const lastPanel = renderer.getPanel(renderer.panelCount - 1);\n\n if (!firstPanel || !lastPanel) {\n this._range = { min: 0, max: 0 };\n return this;\n }\n\n const viewportSize = this.size;\n const firstPanelPrev = firstPanel.range.min;\n const lastPanelNext = lastPanel.range.max;\n const panelAreaSize = lastPanelNext - firstPanelPrev;\n const isBiggerThanViewport = viewportSize < panelAreaSize;\n\n const firstPos = firstPanelPrev + alignPos;\n const lastPos = lastPanelNext - viewportSize + alignPos;\n\n if (isBiggerThanViewport) {\n this._range = { min: firstPos, max: lastPos };\n } else {\n const align = this._align;\n const alignVal = typeof align === \"object\"\n ? (align as { camera: string | number }).camera\n : align;\n\n const pos = firstPos + parseAlign(alignVal, lastPos - firstPos);\n\n this._range = { min: pos, max: pos };\n }\n\n return this;\n }\n\n public updateAnchors(): this {\n const flicking = getFlickingAttached(this._flicking, \"Camera\");\n const panels = flicking.renderer.panels;\n\n if (panels.length <= 0) {\n this._anchors = [];\n return this;\n }\n\n const range = this._range;\n const reachablePanels = panels.filter(panel => this.canReach(panel));\n\n if (reachablePanels.length > 0) {\n const shouldPrependBoundAnchor = reachablePanels[0].position !== range.min;\n const shouldAppendBoundAnchor = reachablePanels[reachablePanels.length - 1].position !== range.max;\n const indexOffset = shouldPrependBoundAnchor ? 1 : 0;\n\n const newAnchors = reachablePanels.map((panel, idx) => new AnchorPoint({\n index: idx + indexOffset,\n position: panel.position,\n panel\n }));\n\n if (shouldPrependBoundAnchor) {\n newAnchors.splice(0, 0, new AnchorPoint({\n index: 0,\n position: range.min,\n panel: panels[reachablePanels[0].index - 1]\n }));\n }\n\n if (shouldAppendBoundAnchor) {\n newAnchors.push(new AnchorPoint({\n index: newAnchors.length,\n position: range.max,\n panel: panels[reachablePanels[reachablePanels.length - 1].index + 1]\n }));\n }\n\n this._anchors = newAnchors;\n } else if (range.min !== range.max) {\n // There're more than 2 panels\n const nearestPanelAtMin = this._findNearestPanel(range.min, panels);\n const panelAtMin = nearestPanelAtMin.index === panels.length - 1\n ? nearestPanelAtMin.prev()!\n : nearestPanelAtMin;\n const panelAtMax = panelAtMin.next()!;\n\n this._anchors = [\n new AnchorPoint({\n index: 0,\n position: range.min,\n panel: panelAtMin\n }),\n new AnchorPoint({\n index: 1,\n position: range.max,\n panel: panelAtMax\n })\n ];\n } else {\n this._anchors = [new AnchorPoint({\n index: 0,\n position: range.min,\n panel: this._findNearestPanel(range.min, panels)\n })];\n }\n\n return this;\n }\n\n public findAnchorIncludePosition(position: number): AnchorPoint | null {\n const range = this._range;\n const anchors = this._anchors;\n\n if (anchors.length <= 0) return null;\n\n if (position <= range.min) {\n return anchors[0];\n } else if (position >= range.max) {\n return anchors[anchors.length - 1];\n } else {\n return super.findAnchorIncludePosition(position);\n }\n }\n\n private _findNearestPanel(pos: number, panels: Panel[]): Panel {\n let prevDist = Infinity;\n for (let panelIdx = 0; panelIdx < panels.length; panelIdx++) {\n const panel = panels[panelIdx];\n const dist = Math.abs(panel.position - pos);\n\n if (dist > prevDist) {\n // Return previous anchor\n return panels[panelIdx - 1];\n }\n\n prevDist = dist;\n }\n\n // Return last anchor\n return panels[panels.length - 1];\n }\n}\n\nexport default BoundCamera;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { ComponentEvent } from \"@egjs/component\";\nimport ImReady from \"@egjs/imready\";\n\nimport Flicking, { FlickingOptions } from \"../Flicking\";\nimport Panel, { PanelOptions } from \"../core/panel/Panel\";\nimport FlickingError from \"../core/FlickingError\";\nimport { ALIGN, EVENTS } from \"../const/external\";\nimport * as ERROR from \"../const/error\";\nimport { getFlickingAttached, getMinusCompensatedIndex, includes } from \"../utils\";\n\nexport interface RendererOptions {\n align: FlickingOptions[\"align\"];\n}\n\n/**\n * A component that manages {@link Panel} and its elements\n * @ko {@link Panel}과 그 엘리먼트들을 관리하는 컴포넌트\n */\nabstract class Renderer {\n // Internal States\n protected _flicking: Flicking | null;\n protected _panels: Panel[];\n\n // Options\n protected _align: RendererOptions[\"align\"];\n\n // Internal states Getter\n /**\n * Array of panels\n * @ko 전체 패널들의 배열\n * @type {Panel[]}\n * @readonly\n * @see Panel\n */\n public get panels() { return this._panels; }\n /**\n * Count of panels\n * @ko 전체 패널의 개수\n * @type {number}\n * @readonly\n */\n public get panelCount() { return this._panels.length; }\n\n // Options Getter\n /**\n * A {@link Panel}'s {@link Panel#align align} value that applied to all panels\n * @ko {@link Panel}에 공통적으로 적용할 {@link Panel#align align} 값\n * @type {Constants.ALIGN | string | number}\n */\n public get align() { return this._align; }\n\n // Options Setter\n public set align(val: RendererOptions[\"align\"]) {\n this._align = val;\n\n const panelAlign = this._getPanelAlign();\n this._panels.forEach(panel => { panel.align = panelAlign; });\n }\n\n /**\n * @param {object} options An options object<ko>옵션 오브젝트</ko>\n * @param {Constants.ALIGN | string | number} [options.align] An {@link Flicking#align align} value that will be applied to all panels<ko>전체 패널에 적용될 {@link Flicking#align align} 값</ko>\n */\n public constructor({\n align = ALIGN.CENTER\n }: Partial<RendererOptions> = {}) {\n this._flicking = null;\n this._panels = [];\n\n // Bind options\n this._align = align;\n }\n\n /**\n * Render panel elements inside the camera element\n * @ko 패널 엘리먼트들을 카메라 엘리먼트 내부에 렌더링합니다\n * @method\n * @abstract\n * @memberof Renderer\n * @instance\n * @name render\n * @chainable\n * @return {this}\n */\n public abstract render(): Promise<void>;\n public abstract forceRenderAllPanels(): Promise<void>;\n\n protected abstract _collectPanels(): void;\n protected abstract _createPanel(el: any, options: PanelOptions): Panel;\n protected abstract _insertPanelElements(panels: Panel[], nextSibling: Panel | null): void;\n protected abstract _removePanelElements(panels: Panel[]): void;\n\n /**\n * Initialize Renderer\n * @ko Renderer를 초기화합니다\n * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>\n * @chainable\n * @return {this}\n */\n public init(flicking: Flicking): this {\n this._flicking = flicking;\n this._collectPanels();\n\n return this;\n }\n\n /**\n * Destroy Renderer and return to initial state\n * @ko Renderer를 초기 상태로 되돌립니다\n * @return {void}\n */\n public destroy(): void {\n this._flicking = null;\n this._panels = [];\n }\n\n /**\n * Return the {@link Panel} at the given index. `null` if it doesn't exists.\n * @ko 주어진 인덱스에 해당하는 {@link Panel}을 반환합니다. 주어진 인덱스에 해당하는 패널이 존재하지 않을 경우 `null`을 반환합니다.\n * @return {Panel | null} Panel at the given index<ko>주어진 인덱스에 해당하는 패널</ko>\n * @see Panel\n */\n public getPanel(index: number): Panel | null {\n return this._panels[index] || null;\n }\n\n /**\n * Update all panel sizes\n * @ko 모든 패널의 크기를 업데이트합니다\n * @chainable\n * @return {this}\n */\n public updatePanelSize(): this {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n\n if (flicking.panelsPerView > 0) {\n this._updatePanelSizeByGrid(flicking);\n } else {\n flicking.panels.forEach(panel => panel.resize());\n }\n\n return this;\n }\n\n /**\n * Insert new panels at given index\n * This will increase index of panels after by the number of panels added\n * @ko 주어진 인덱스에 새로운 패널들을 추가합니다\n * 해당 인덱스보다 같거나 큰 인덱스를 가진 기존 패널들은 추가한 패널의 개수만큼 인덱스가 증가합니다.\n * @param {number} index Index to insert new panels at<ko>새로 패널들을 추가할 인덱스</ko>\n * @param {any[]} elements An array of element or framework component with element in it<ko>엘리먼트의 배열 혹은 프레임워크에서 엘리먼트를 포함한 컴포넌트들의 배열</ko>\n * @return {Panel[]} An array of prepended panels<ko>추가된 패널들의 배열</ko>\n */\n public batchInsert(...items: Array<{\n index: number;\n elements: any[];\n }>): Panel[] {\n const panels = this._panels;\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n\n const { control } = flicking;\n const align = this._getPanelAlign();\n\n const allPanelsInserted = items.reduce((addedPanels, item) => {\n const insertingIdx = getMinusCompensatedIndex(item.index, panels.length);\n const panelsPushed = panels.slice(insertingIdx);\n const panelsInserted = item.elements.map((el, idx) => this._createPanel(el, { index: insertingIdx + idx, align, flicking }));\n\n panels.splice(insertingIdx, 0, ...panelsInserted);\n\n // Insert the actual elements as camera element's children\n this._insertPanelElements(panelsInserted, panelsPushed[0] ?? null);\n\n // Resize the newly added panels\n panelsInserted.forEach(panel => panel.resize());\n\n // Update panel indexes & positions\n panelsPushed.forEach(panel => {\n panel.increaseIndex(panelsInserted.length);\n panel.updatePosition();\n });\n\n return [...addedPanels, ...panelsInserted];\n }, []);\n\n if (allPanelsInserted.length <= 0) return [];\n\n // Update camera & control\n this._updateCameraAndControl();\n\n void this.render();\n\n // Move to the first panel added if no panels existed\n // FIXME: fix for animating case\n if (allPanelsInserted.length > 0 && !control.animating) {\n void control.moveToPanel(control.activePanel || allPanelsInserted[0], {\n duration: 0\n }).catch(() => void 0);\n }\n\n flicking.camera.updateOffset();\n\n flicking.trigger(new ComponentEvent(EVENTS.PANEL_CHANGE, {\n added: allPanelsInserted,\n removed: []\n }));\n\n this.checkPanelContentsReady(allPanelsInserted);\n\n return allPanelsInserted;\n }\n\n /**\n * Remove the panel at the given index\n * This will decrease index of panels after by the number of panels removed\n * @ko 주어진 인덱스의 패널을 제거합니다\n * 해당 인덱스보다 큰 인덱스를 가진 기존 패널들은 제거한 패널의 개수만큼 인덱스가 감소합니다\n * @param {number} 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 An array of removed panels<ko>제거된 패널들의 배열</ko>\n */\n public batchRemove(...items: Array<{ index: number; deleteCount: number }>): Panel[] {\n const panels = this._panels;\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n\n const { camera, control } = flicking;\n const activePanel = control.activePanel;\n const activeIndex = control.activeIndex;\n\n const allPanelsRemoved = items.reduce((removed, item) => {\n const { index, deleteCount } = item;\n const removingIdx = getMinusCompensatedIndex(index, panels.length);\n\n const panelsPulled = panels.slice(removingIdx + deleteCount);\n const panelsRemoved = panels.splice(removingIdx, deleteCount);\n\n if (panelsRemoved.length <= 0) return [];\n\n // Update panel indexes & positions\n panelsPulled.forEach(panel => {\n panel.decreaseIndex(panelsRemoved.length);\n panel.updatePosition();\n });\n\n this._removePanelElements(panelsRemoved);\n\n // Remove panel elements\n panelsRemoved.forEach(panel => panel.destroy());\n\n // Update camera & control\n this._updateCameraAndControl();\n\n if (includes(panelsRemoved, activePanel)) {\n control.resetActive();\n }\n\n return [...removed, ...panelsRemoved];\n }, []);\n\n void this.render();\n\n // FIXME: fix for animating case\n if (allPanelsRemoved.length > 0 && !control.animating) {\n const targetPanel = includes(allPanelsRemoved, activePanel)\n ? (panels[activeIndex] || panels[panels.length - 1])\n : activePanel;\n\n if (targetPanel) {\n void control.moveToPanel(targetPanel, {\n duration: 0\n }).catch(() => void 0);\n } else {\n // All panels removed\n camera.lookAt(0);\n }\n }\n\n flicking.camera.updateOffset();\n\n flicking.trigger(new ComponentEvent(EVENTS.PANEL_CHANGE, {\n added: [],\n removed: allPanelsRemoved\n }));\n\n return allPanelsRemoved;\n }\n\n /**\n * @internal\n */\n public checkPanelContentsReady(checkingPanels: Panel[]) {\n const resizeOnContentsReady = getFlickingAttached(this._flicking, \"Renderer\").resizeOnContentsReady;\n const panels = this._panels;\n\n if (!resizeOnContentsReady) return;\n\n const hasContents = (panel: Panel) => !!panel.element.querySelector(\"img, video\");\n checkingPanels = checkingPanels.filter(panel => hasContents(panel));\n\n if (checkingPanels.length <= 0) return;\n\n const contentsReadyChecker = new ImReady();\n\n checkingPanels.forEach(panel => {\n panel.loading = true;\n });\n\n contentsReadyChecker.on(\"readyElement\", e => {\n const flicking = this._flicking;\n\n if (!flicking) {\n // Renderer's destroy() is called before\n contentsReadyChecker.destroy();\n return;\n }\n\n const panel = checkingPanels[e.index];\n const camera = flicking.camera;\n const control = flicking.control;\n const prevProgressInPanel = control.activePanel\n ? camera.getProgressInPanel(control.activePanel)\n : 0;\n\n panel.loading = false;\n panel.resize();\n panels.slice(panel.index + 1).forEach(panelBehind => panelBehind.updatePosition());\n\n if (!flicking.initialized) return;\n\n camera.updateRange();\n camera.updateAnchors();\n\n if (control.animating) {\n // TODO: Need Axes update\n } else {\n control.updatePosition(prevProgressInPanel);\n control.updateInput();\n }\n });\n\n contentsReadyChecker.on(\"preReady\", e => {\n if (this._flicking) {\n void this.render();\n }\n\n if (e.readyCount === e.totalCount) {\n contentsReadyChecker.destroy();\n }\n });\n\n contentsReadyChecker.on(\"ready\", () => {\n if (this._flicking) {\n void this.render();\n }\n contentsReadyChecker.destroy();\n });\n\n contentsReadyChecker.check(checkingPanels.map(panel => panel.element));\n }\n\n protected _getPanelAlign() {\n const align = this._align;\n\n return typeof align === \"object\"\n ? (align as { panel: string | number }).panel\n : align;\n }\n\n protected _updateCameraAndControl() {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n const { camera, control } = flicking;\n\n camera.updateRange();\n camera.updateAnchors();\n camera.resetNeedPanelHistory();\n control.updateInput();\n }\n\n protected _updateRenderingPanels(): void {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n\n if (flicking.renderOnlyVisible) {\n this._showOnlyVisiblePanels(flicking);\n } else {\n flicking.panels.forEach(panel => panel.markForShow());\n }\n }\n\n protected _showOnlyVisiblePanels(flicking: Flicking) {\n const panels = flicking.renderer.panels;\n const camera = flicking.camera;\n\n const visibleIndexes = camera.visiblePanels.reduce((visibles, panel) => {\n visibles[panel.index] = true;\n return visibles;\n }, {});\n\n panels.forEach(panel => {\n if (panel.index in visibleIndexes || panel.loading) {\n panel.markForShow();\n } else if (!flicking.holding) {\n // During the input sequence,\n // Do not remove panel elements as it won't trigger touchend event.\n panel.markForHide();\n }\n });\n\n camera.updateOffset();\n }\n\n protected _updatePanelSizeByGrid(flicking: Flicking) {\n const panels = flicking.panels;\n const panelsPerView = flicking.panelsPerView;\n\n if (panelsPerView <= 0) {\n throw new FlickingError(ERROR.MESSAGE.WRONG_OPTION(\"panelsPerView\", panelsPerView), ERROR.CODE.WRONG_OPTION);\n }\n if (panels.length <= 0) return;\n\n // resize only the first panel\n const firstPanel = panels[0];\n firstPanel.resize();\n\n const viewportSize = flicking.camera.size;\n const gap = firstPanel.margin.prev + firstPanel.margin.next;\n\n const panelSize = (viewportSize - gap * (panelsPerView - 1)) / panelsPerView;\n const panelSizeObj = flicking.horizontal\n ? { width: panelSize }\n : { height: panelSize };\n const firstPanelSizeObj = {\n size: panelSize,\n height: firstPanel.height,\n margin: firstPanel.margin\n };\n\n if (!flicking.noPanelStyleOverride) {\n flicking.panels.forEach(panel => panel.setSize(panelSizeObj));\n }\n\n flicking.panels.forEach(panel => panel.resize(firstPanelSizeObj));\n }\n}\n\nexport default Renderer;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Flicking from \"../../Flicking\";\nimport { getProgress, getStyle, isString, parseAlign } from \"../../utils\";\nimport { ALIGN, DIRECTION } from \"../../const/external\";\nimport { LiteralUnion, ValueOf } from \"../../type/internal\";\n\nexport interface PanelOptions {\n index: number;\n align: LiteralUnion<ValueOf<typeof ALIGN>> | number;\n flicking: Flicking;\n}\n\nabstract class Panel {\n // Internal States\n protected _flicking: Flicking;\n protected _index: number;\n protected _pos: number;\n protected _size: number;\n protected _height: number;\n protected _margin: { prev: number; next: number };\n protected _alignPos: number; // Actual align pos\n protected _removed: boolean;\n protected _loading: boolean;\n protected _toggleDirection: ValueOf<typeof DIRECTION>;\n protected _toggled: boolean;\n protected _togglePosition: number;\n\n // Options\n protected _align: PanelOptions[\"align\"];\n\n // Internal States Getter\n /**\n * `HTMLElement` that panel's referencing\n * @ko 패널이 참조하고 있는 `HTMLElement`\n * @type {HTMLElement}\n * @readonly\n */\n abstract get element(): HTMLElement;\n /**\n * Index of the panel\n * @ko 패널의 인덱스\n * @type {number}\n * @readonly\n */\n public get index() { return this._index; }\n /**\n * Position of the panel, including {@link Panel#alignPosition alignPosition}\n * @ko 패널의 현재 좌표, {@link Panel#alignPosition alignPosition}을 포함하고 있습니다\n * @type {number}\n * @readonly\n */\n public get position() { return this._pos + this._alignPos; }\n /**\n * Cached size of the panel element\n * This is equal to {@link Panel#element element}'s `offsetWidth` if {@link Flicking#horizontal horizontal} is `true`, and `offsetHeight` else\n * @ko 패널 엘리먼트의 캐시된 크기\n * 이 값은 {@link Flicking#horizontal horizontal}이 `true`일 경우 {@link Panel#element element}의 `offsetWidth`와 동일하고, `false`일 경우 `offsetHeight`와 동일합니다\n * @type {number}\n * @readonly\n */\n public get size() { return this._size; }\n /**\n * Panel's size including CSS `margin`\n * This value includes {@link Panel#element element}'s margin left/right if {@link Flicking#horizontal horizontal} is `true`, and margin top/bottom else\n * @ko CSS `margin`을 포함한 패널의 크기\n * 이 값은 {@link Flicking#horizontal horizontal}이 `true`일 경우 margin left/right을 포함하고, `false`일 경우 margin top/bottom을 포함합니다\n * @type {number}\n * @readonly\n */\n public get sizeIncludingMargin() { return this._size + this._margin.prev + this._margin.next; }\n /**\n * Height of the panel element\n * @ko 패널 엘리먼트의 높이\n * @type {number}\n * @readonly\n */\n public get height() { return this._height; }\n /**\n * Cached CSS `margin` value of the panel element\n * @ko 패널 엘리먼트의 CSS `margin` 값\n * @type {object}\n * @property {number} prev CSS `margin-left` when the {@link Flicking#horizontal horizontal} is `true`, and `margin-top` else\n * <ko>{@link Flicking#horizontal horizontal}이 `true`일 경우 `margin-left`, `false`일 경우 `margin-top`에 해당하는 값</ko>\n * @property {number} next CSS `margin-right` when the {@link Flicking#horizontal horizontal} is `true`, and `margin-bottom` else\n * <ko>{@link Flicking#horizontal horizontal}이 `true`일 경우 `margin-right`, `false`일 경우 `margin-bottom`에 해당하는 값</ko>\n * @readonly\n */\n public get margin() { return this._margin; }\n /**\n * Align position inside the panel where {@link Camera}'s {@link Camera#alignPosition alignPosition} inside viewport should be located at\n * @ko 패널의 정렬 기준 위치. {@link Camera}의 뷰포트 내에서의 {@link Camera#alignPosition alignPosition}이 위치해야 하는 곳입니다\n * @type {number}\n * @readonly\n */\n public get alignPosition() { return this._alignPos; }\n /**\n * A value indicating whether the panel's {@link Flicking#remove remove}d\n * @ko 패널이 {@link Flicking#remove remove}되었는지 여부를 나타내는 값\n * @type {boolean}\n * @readonly\n */\n public get removed() { return this._removed; }\n /**\n * A value indicating whether the panel's image/video is not loaded and waiting for resize\n * @ko 패널 내부의 이미지/비디오가 아직 로드되지 않아 {@link Panel#resize resize}될 것인지를 나타내는 값\n * @type {boolean}\n * @readonly\n */\n public get loading() { return this._loading; }\n /**\n * A value indicating whether the panel's element is being rendered on the screen\n * @ko 패널의 엘리먼트가 화면상에 렌더링되고있는지 여부를 나타내는 값\n * @type {boolean}\n * @readonly\n */\n public abstract get rendered();\n /**\n * Panel element's range of the bounding box\n * @ko 패널 엘리먼트의 Bounding box 범위\n * @type {object}\n * @property {number} [min] Bounding box's left({@link Flicking#horizontal horizontal}: true) / top({@link Flicking#horizontal horizontal}: false)\n * @property {number} [max] Bounding box's right({@link Flicking#horizontal horizontal}: true) / bottom({@link Flicking#horizontal horizontal}: false)\n * @readonly\n */\n public get range() { return { min: this._pos, max: this._pos + this._size }; }\n /**\n * A value indicating whether the panel's position is toggled by circular behavior\n * @ko 패널의 위치가 circular 동작에 의해 토글되었는지 여부를 나타내는 값\n * @type {boolean}\n * @readonly\n */\n public get toggled() { return this._toggled; }\n /**\n * A direction where the panel's position is toggled\n * @ko 패널의 위치가 circular 동작에 의해 토글되는 방향\n * @type {DIRECTION}\n * @readonly\n */\n public get toggleDirection() { return this._toggleDirection; }\n /**\n * Actual position offset determined by {@link Panel#order}\n * @ko {@link Panel#order}에 의한 실제 위치 변경값\n * @type {number}\n * @readonly\n */\n public get offset() {\n const toggleDirection = this._toggleDirection;\n const cameraRangeDiff = this._flicking.camera.rangeDiff;\n\n return toggleDirection === DIRECTION.NONE || !this._toggled\n ? 0\n : toggleDirection === DIRECTION.PREV\n ? -cameraRangeDiff\n : cameraRangeDiff;\n }\n\n /**\n * Progress of movement between previous or next panel relative to current panel\n * @ko 이 패널로부터 이전/다음 패널으로의 이동 진행률\n * @type {number}\n * @readonly\n */\n public get progress() {\n const flicking = this._flicking;\n\n return this.index - flicking.camera.progress;\n }\n\n /**\n * Progress of movement between points that panel is completely invisible outside of viewport(prev direction: -1, selected point: 0, next direction: 1)\n * @ko 현재 패널이 뷰포트 영역 밖으로 완전히 사라지는 지점을 기준으로 하는 진행도(prev방향: -1, 선택 지점: 0, next방향: 1)\n * @type {number}\n * @readonly\n */\n public get outsetProgress() {\n const position = this.position + this.offset;\n const alignPosition = this._alignPos;\n const camera = this._flicking.camera;\n const camPos = camera.position;\n\n if (camPos === position) {\n return 0;\n }\n\n if (camPos < position) {\n const disappearPosNext = position + (camera.size - camera.alignPosition) + alignPosition;\n\n return -getProgress(camPos, position, disappearPosNext);\n } else {\n const disappearPosPrev = position - (camera.alignPosition + this._size - alignPosition);\n\n return 1 - getProgress(camPos, disappearPosPrev, position);\n }\n }\n\n /**\n * Percentage of area where panel is visible in the viewport\n * @ko 뷰포트 안에서 패널이 보이는 영역의 비율\n * @type {number}\n * @readonly\n */\n public get visibleRatio() {\n const range = this.range;\n const size = this._size;\n const offset = this.offset;\n const visibleRange = this._flicking.camera.visibleRange;\n\n const checkingRange = {\n min: range.min + offset,\n max: range.max + offset\n };\n\n if (checkingRange.max <= visibleRange.min || checkingRange.min >= visibleRange.max) {\n return 0;\n }\n\n let visibleSize = size;\n\n if (visibleRange.min > checkingRange.min) {\n visibleSize -= visibleRange.min - checkingRange.min;\n }\n if (visibleRange.max < checkingRange.max) {\n visibleSize -= checkingRange.max - visibleRange.max;\n }\n\n return visibleSize / size;\n }\n\n public set loading(val: boolean) { this._loading = val; }\n\n // Options Getter\n /**\n * A value indicating where the {@link Panel#alignPosition alignPosition} should be located at inside the panel element\n * @ko {@link Panel#alignPosition alignPosition}이 패널 내의 어디에 위치해야 하는지를 나타내는 값\n * @type {Constants.ALIGN | string | number}\n */\n public get align() { return this._align; }\n\n // Options Setter\n public set align(val: PanelOptions[\"align\"]) { this._align = val; }\n\n /**\n * @param {object} options An options object<ko>옵션 오브젝트</ko>\n * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>\n * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>\n * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>\n */\n public constructor({\n index,\n align,\n flicking\n }: PanelOptions) {\n this._index = index;\n this._flicking = flicking;\n\n this._align = align;\n\n this._removed = false;\n this._loading = false;\n this._resetInternalStates();\n }\n\n /**\n * Mark panel element to be appended on the camera element\n * @internal\n */\n public abstract markForShow();\n\n /**\n * Mark panel element to be removed from the camera element\n * @internal\n */\n public abstract markForHide();\n\n /**\n * Update size of the panel\n * @ko 패널의 크기를 갱신합니다\n * @param {object} cached Predefined cached size of the panel<ko>사전에 캐시된 패널의 크기 정보</ko>\n * @chainable\n * @return {this}\n */\n public resize(cached?: {\n size: number;\n height: number;\n margin: { prev: number; next: number };\n }): this {\n const el = this.element;\n const elStyle = getStyle(el);\n const flicking = this._flicking;\n const horizontal = flicking.horizontal;\n\n if (cached) {\n this._size = cached.size;\n this._margin = { ...cached.margin };\n this._height = cached.height;\n } else {\n this._size = horizontal ? el.offsetWidth : el.offsetHeight;\n this._margin = horizontal\n ? {\n prev: parseFloat(elStyle.marginLeft || \"0\"),\n next: parseFloat(elStyle.marginRight || \"0\")\n } : {\n prev: parseFloat(elStyle.marginTop || \"0\"),\n next: parseFloat(elStyle.marginBottom || \"0\")\n };\n this._height = horizontal ? el.offsetHeight : this._size;\n }\n\n this.updatePosition();\n this._updateAlignPos();\n\n return this;\n }\n\n /**\n * Change panel's size. This will change the actual size of the panel element by changing its CSS width/height property\n * @ko 패널 크기를 변경합니다. 패널 엘리먼트에 해당 크기의 CSS width/height를 적용합니다\n * @param {object} [size] New panel size<ko>새 패널 크기</ko>\n * @param {number|string} [size.width] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>\n * @param {number|string} [size.height] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>\n * @chainable\n * @return {this}\n */\n public setSize({\n width,\n height\n }: Partial<{\n width: number | string;\n height: number | string;\n }>): this {\n const el = this.element;\n\n if (width != null) {\n if (isString(width)) {\n el.style.width = width;\n } else {\n el.style.width = `${width}px`;\n }\n }\n if (height != null) {\n if (isString(height)) {\n el.style.height = height;\n } else {\n el.style.height = `${height}px`;\n }\n }\n\n return this;\n }\n\n /**\n * Check whether the given element is inside of this panel's {@link Panel#element element}\n * @ko 해당 엘리먼트가 이 패널의 {@link Panel#element element} 내에 포함되어 있는지를 반환합니다\n * @param {HTMLElement} element The HTMLElement to check<ko>확인하고자 하는 HTMLElement</ko>\n * @return {boolean} A Boolean value indicating the element is inside of this panel {@link Panel#element element}<ko>패널의 {@link Panel#element element}내에 해당 엘리먼트 포함 여부</ko>\n */\n public contains(element: HTMLElement): boolean {\n return !!this.element?.contains(element);\n }\n\n /**\n * Reset internal state and set {@link Panel#removed removed} to `true`\n * @ko 내부 상태를 초기화하고 {@link Panel#removed removed}를 `true`로 설정합니다.\n * @return {void}\n */\n public destroy(): void {\n this._resetInternalStates();\n this._removed = true;\n }\n\n /**\n * Check whether the given position is inside of this panel's {@link Panel#range range}\n * @ko 주어진 좌표가 현재 패널의 {@link Panel#range range}내에 속해있는지를 반환합니다.\n * @param {number} pos A position to check<ko>확인하고자 하는 좌표</ko>\n * @param {boolean} [includeMargin=false] Include {@link Panel#margin margin} to the range<ko>패널 영역에 {@link Panel#margin margin}값을 포함시킵니다</ko>\n * @return {boolean} A Boolean value indicating whether the given position is included in the panel range<ko>해당 좌표가 패널 영역 내에 속해있는지 여부</ko>\n */\n public includePosition(pos: number, includeMargin: boolean = false): boolean {\n return this.includeRange(pos, pos, includeMargin);\n }\n\n /**\n * Check whether the given range is fully included in this panel's area\n * @ko 주어진 범위가 이 패널 내부에 완전히 포함되는지를 반환합니다\n * @param {number} min Minimum value of the range to check<ko>확인하고자 하는 최소 범위</ko>\n * @param {number} max Maximum value of the range to check<ko>확인하고자 하는 최대 범위</ko>\n * @param {boolean} [includeMargin=false] Include {@link Panel#margin margin} to the range<ko>패널 영역에 {@link Panel#margin margin}값을 포함시킵니다</ko>\n * @returns {boolean} A Boolean value indicating whether the given range is fully included in the panel range<ko>해당 범위가 패널 영역 내에 완전히 속해있는지 여부</ko>\n */\n public includeRange(min: number, max: number, includeMargin: boolean = false): boolean {\n const margin = this._margin;\n const panelRange = this.range;\n\n if (includeMargin) {\n panelRange.min -= margin.prev;\n panelRange.max += margin.next;\n }\n\n return max >= panelRange.min && min <= panelRange.max;\n }\n\n /**\n * Move {@link Camera} to this panel\n * @ko {@link Camera}를 이 패널로 이동합니다\n * @param {number} [duration] Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>\n * @returns {Promise<void>} A Promise which will be resolved after reaching the panel<ko>패널 도달시에 resolve되는 Promise</ko>\n */\n public focus(duration?: number) {\n return this._flicking.moveTo(this._index, duration);\n }\n\n /**\n * Get previous(`index - 1`) panel. When the previous panel does not exist, this will return `null` instead\n * If the {@link Flicking#circularEnabled circular} is enabled, this will return the last panel if called from the first panel\n * @ko 이전(`index - 1`) 패널을 반환합니다. 이전 패널이 없을 경우 `null`을 반환합니다\n * {@link Flicking#circularEnabled circular} 모드가 활성화되었을 때 첫번째 패널에서 이 메소드를 호출할 경우 마지막 패널을 반환합니다\n * @returns {Panel | null} The previous panel<ko>이전 패널</ko>\n */\n public prev(): Panel | null {\n const index = this._index;\n const flicking = this._flicking;\n const renderer = flicking.renderer;\n const panelCount = renderer.panelCount;\n\n if (panelCount === 1) return null;\n\n return flicking.circularEnabled\n ? renderer.getPanel(index === 0 ? panelCount - 1 : index - 1)\n : renderer.getPanel(index - 1);\n }\n\n /**\n * Get next(`index + 1`) panel. When the next panel does not exist, this will return `null` instead\n * If the {@link Flicking#circularEnabled circular} is enabled, this will return the first panel if called from the last panel\n * @ko 다음(`index + 1`) 패널을 반환합니다. 다음 패널이 없을 경우 `null`을 반환합니다\n * {@link Flicking#circularEnabled circular} 모드가 활성화되었을 때 마지막 패널에서 이 메소드를 호출할 경우 첫번째 패널을 반환합니다\n * @returns {Panel | null} The previous panel<ko>다음 패널</ko>\n */\n public next(): Panel | null {\n const index = this._index;\n const flicking = this._flicking;\n const renderer = flicking.renderer;\n const panelCount = renderer.panelCount;\n\n if (panelCount === 1) return null;\n\n return flicking.circularEnabled\n ? renderer.getPanel(index === panelCount - 1 ? 0 : index + 1)\n : renderer.getPanel(index + 1);\n }\n\n /**\n * Increase panel's index by the given value\n * @ko 패널의 인덱스를 주어진 값만큼 증가시킵니다\n * @internal\n * @chainable\n * @param val An integer greater than or equal to 0<ko>0보다 같거나 큰 정수</ko>\n * @returns {this}\n */\n public increaseIndex(val: number): this {\n this._index += Math.max(val, 0);\n return this;\n }\n\n /**\n * Decrease panel's index by the given value\n * @ko 패널의 인덱스를 주어진 값만큼 감소시킵니다\n * @internal\n * @chainable\n * @param val An integer greater than or equal to 0<ko>0보다 같거나 큰 정수</ko>\n * @returns {this}\n */\n public decreaseIndex(val: number): this {\n this._index -= Math.max(val, 0);\n return this;\n }\n\n /**\n * @internal\n */\n public updatePosition(): this {\n const prevPanel = this._flicking.renderer.panels[this._index - 1];\n\n this._pos = prevPanel\n ? prevPanel.range.max + prevPanel.margin.next + this._margin.prev\n : this._margin.prev;\n\n return this;\n }\n\n /**\n * @internal\n * @return {boolean} toggled\n */\n public toggle(prevPos: number, newPos: number): boolean {\n const toggleDirection = this._toggleDirection;\n const togglePosition = this._togglePosition;\n\n if (toggleDirection === DIRECTION.NONE || newPos === prevPos) return false;\n\n const prevToggled = this._toggled;\n\n if (newPos > prevPos) {\n if (togglePosition >= prevPos && togglePosition <= newPos) {\n this._toggled = toggleDirection === DIRECTION.NEXT;\n }\n } else {\n if (togglePosition <= prevPos && togglePosition >= newPos) {\n this._toggled = toggleDirection !== DIRECTION.NEXT;\n }\n }\n\n return prevToggled !== this._toggled;\n }\n\n /**\n * @internal\n */\n public updateCircularToggleDirection(): this {\n const flicking = this._flicking;\n\n if (!flicking.circularEnabled) {\n this._toggleDirection = DIRECTION.NONE;\n this._toggled = false;\n return this;\n }\n\n const camera = flicking.camera;\n const camRange = camera.range;\n const camAlignPosition = camera.alignPosition;\n const camVisibleRange = camera.visibleRange;\n const camVisibleSize = camVisibleRange.max - camVisibleRange.min;\n\n const minimumVisible = camRange.min - camAlignPosition;\n const maximumVisible = camRange.max - camAlignPosition + camVisibleSize;\n\n const shouldBeVisibleAtMin = this.includeRange(maximumVisible - camVisibleSize, maximumVisible, false);\n const shouldBeVisibleAtMax = this.includeRange(minimumVisible, minimumVisible + camVisibleSize, false);\n\n this._toggled = false;\n if (shouldBeVisibleAtMin) {\n this._toggleDirection = DIRECTION.PREV;\n this._togglePosition = this.range.max + camRange.min - camRange.max + camAlignPosition;\n this.toggle(Infinity, camera.position);\n } else if (shouldBeVisibleAtMax) {\n this._toggleDirection = DIRECTION.NEXT;\n this._togglePosition = this.range.min + camRange.max - camVisibleSize + camAlignPosition;\n this.toggle(-Infinity, camera.position);\n } else {\n this._toggleDirection = DIRECTION.NONE;\n this._togglePosition = 0;\n }\n\n return this;\n }\n\n private _updateAlignPos() {\n this._alignPos = parseAlign(this._align, this._size);\n }\n\n private _resetInternalStates() {\n this._size = 0;\n this._pos = 0;\n this._margin = { prev: 0, next: 0 };\n this._height = 0;\n this._alignPos = 0;\n this._toggled = false;\n this._togglePosition = 0;\n this._toggleDirection = DIRECTION.NONE;\n }\n}\n\nexport default Panel;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Panel, { PanelOptions } from \"./Panel\";\n\nexport interface ElementPanelOptions extends PanelOptions {\n el: HTMLElement;\n}\n\n/**\n * An slide data component that holds information of a single HTMLElement\n * @ko 슬라이드 데이터 컴포넌트로, 단일 HTMLElement의 정보를 갖고 있습니다\n */\nclass ElementPanel extends Panel {\n private _el: HTMLElement;\n private _rendered: boolean;\n\n /**\n * `HTMLElement` that panel's referencing\n * @ko 패널이 참조하고 있는 `HTMLElement`\n * @type {HTMLElement}\n * @readonly\n */\n public get element() { return this._el; }\n\n public get rendered() { return this._rendered; }\n\n /**\n * @param {object} options An options object<ko>옵션 오브젝트</ko>\n * @param {HTMLElement} [options.el] A `HTMLElement` panel's referencing<ko>패널이 참조하는 `HTMLElement`</ko>\n * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>\n * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>\n * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>\n */\n public constructor(options: ElementPanelOptions) {\n super(options);\n\n this._el = options.el;\n this._rendered = true;\n }\n\n public markForShow() {\n this._rendered = true;\n }\n\n public markForHide() {\n this._rendered = false;\n }\n}\n\nexport default ElementPanel;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { getFlickingAttached, toArray } from \"../utils\";\nimport Panel, { PanelOptions } from \"../core/panel/Panel\";\nimport ElementPanel from \"../core/panel/ElementPanel\";\n\nimport Renderer from \"./Renderer\";\n\n/**\n *\n */\nclass VanillaRenderer extends Renderer {\n // eslint-disable-next-line @typescript-eslint/require-await\n public async render() {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n const cameraEl = flicking.camera.element;\n const wasRenderedPanels = this._panels.filter(panel => panel.element.parentElement === cameraEl);\n\n this._updateRenderingPanels();\n const renderingPanels = this._getRenderingPanelsByOrder();\n\n this._removePanelElements(wasRenderedPanels.filter(panel => !panel.rendered));\n this._insertPanelElements(renderingPanels.filter(panel => panel.element.parentElement !== cameraEl), null);\n this._resetPanelElementOrder(renderingPanels);\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n public async forceRenderAllPanels() {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n const camera = flicking.camera;\n const cameraElement = camera.element;\n const fragment = document.createDocumentFragment();\n\n this._panels.forEach(panel => fragment.appendChild(panel.element));\n\n this._removeAllChildsFromCamera();\n\n cameraElement.appendChild(fragment);\n }\n\n protected _collectPanels() {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n\n const cameraElement = flicking.camera.element;\n\n // Remove all text nodes in the camera element\n toArray(cameraElement.childNodes).forEach(node => {\n if (node.nodeType === Node.TEXT_NODE) {\n cameraElement.removeChild(node);\n }\n });\n\n const align = this._getPanelAlign();\n const cameraChilds = toArray(cameraElement.children);\n\n this._panels = cameraChilds.map(\n (el: HTMLElement, index: number) => new ElementPanel({ flicking, el, index, align })\n );\n }\n\n protected _createPanel(el: HTMLElement, options: PanelOptions): ElementPanel {\n return new ElementPanel({ el, ...options });\n }\n\n protected _insertPanelElements(panels: Panel[], nextSibling: Panel | null) {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n const camera = flicking.camera;\n const cameraElement = camera.element;\n const nextSiblingElement = nextSibling?.element || null;\n const fragment = document.createDocumentFragment();\n\n panels.forEach(panel => fragment.appendChild(panel.element));\n cameraElement.insertBefore(fragment, nextSiblingElement);\n\n return this;\n }\n\n protected _removePanelElements(panels: Panel[]): this {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n const cameraElement = flicking.camera.element;\n\n panels.forEach(panel => {\n cameraElement.removeChild(panel.element);\n });\n\n return this;\n }\n\n private _resetPanelElementOrder(panels: Panel[]) {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n const cameraEl = flicking.camera.element;\n\n // We're using reversed panels here as last panel should be the last element of camera element\n const reversedPanels = [...panels].reverse();\n reversedPanels.forEach((panel, idx) => {\n const nextPanel = reversedPanels[idx - 1];\n const nextPanelEl = nextPanel ? nextPanel.element : null;\n\n if (panel.element.nextElementSibling !== nextPanelEl) {\n cameraEl.insertBefore(panel.element, nextPanelEl);\n }\n });\n }\n\n private _removeAllChildsFromCamera() {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n const cameraElement = flicking.camera.element;\n\n // Remove other elements\n while (cameraElement.firstChild) {\n cameraElement.removeChild(cameraElement.firstChild);\n }\n }\n\n private _getRenderingPanelsByOrder(): Panel[] {\n const flicking = getFlickingAttached(this._flicking, \"Renderer\");\n const panels = flicking.renderer.panels;\n\n return panels.filter(panel => panel.rendered)\n .sort((a, b) => (a.position + a.offset) - (b.position + b.offset));\n }\n}\n\nexport default VanillaRenderer;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Panel from \"../core/panel/Panel\";\n\nimport Renderer from \"./Renderer\";\n\n/**\n *\n */\nabstract class ExternalRenderer extends Renderer {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected _insertPanelElements(panels: Panel[], nextSibling: Panel | null): void {\n // DO NOTHING\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected _removePanelElements(panels: Panel[]): void {\n // DO NOTHING\n }\n}\n\nexport default ExternalRenderer;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component, { ComponentEvent } from \"@egjs/component\";\n\nimport FlickingError from \"./core/FlickingError\";\nimport Viewport from \"./core/Viewport\";\nimport { Panel } from \"./core/panel\";\nimport { Control, SnapControl, SnapControlOptions, FreeControl, StrictControl, FreeControlOptions, StrictControlOptions } from \"./control\";\nimport { BoundCamera, Camera, CircularCamera, LinearCamera } from \"./camera\";\nimport { Renderer, VanillaRenderer, ExternalRenderer } from \"./renderer\";\nimport { EVENTS, ALIGN, MOVE_TYPE, DIRECTION } from \"./const/external\";\nimport * as ERROR from \"./const/error\";\nimport { findIndex, getElement, includes, parseElement } from \"./utils\";\nimport { HoldStartEvent, HoldEndEvent, MoveStartEvent, SelectEvent, MoveEvent, MoveEndEvent, WillChangeEvent, WillRestoreEvent, NeedPanelEvent, VisibleChangeEvent, ReachEdgeEvent, ReadyEvent, AfterResizeEvent, BeforeResizeEvent, ChangedEvent, RestoredEvent, PanelChangeEvent } from \"./type/event\";\nimport { LiteralUnion, ValueOf } from \"./type/internal\";\nimport { ElementLike, Plugin, Status, MoveTypeOptions } from \"./type/external\";\n\n/**\n * @interface\n */\nexport interface FlickingEvents {\n [EVENTS.READY]: ReadyEvent;\n [EVENTS.BEFORE_RESIZE]: BeforeResizeEvent;\n [EVENTS.AFTER_RESIZE]: AfterResizeEvent;\n [EVENTS.HOLD_START]: HoldStartEvent;\n [EVENTS.HOLD_END]: HoldEndEvent;\n [EVENTS.MOVE_START]: MoveStartEvent;\n [EVENTS.MOVE]: MoveEvent;\n [EVENTS.MOVE_END]: MoveEndEvent;\n [EVENTS.WILL_CHANGE]: WillChangeEvent;\n [EVENTS.CHANGED]: ChangedEvent;\n [EVENTS.WILL_RESTORE]: WillRestoreEvent;\n [EVENTS.RESTORED]: RestoredEvent;\n [EVENTS.SELECT]: SelectEvent;\n [EVENTS.NEED_PANEL]: NeedPanelEvent;\n [EVENTS.VISIBLE_CHANGE]: VisibleChangeEvent;\n [EVENTS.REACH_EDGE]: ReachEdgeEvent;\n [EVENTS.PANEL_CHANGE]: PanelChangeEvent;\n}\n\n/**\n * @interface\n */\nexport interface FlickingOptions {\n // UI / LAYOUT\n align: LiteralUnion<ValueOf<typeof ALIGN>> | number | { panel: number | string; camera: number | string };\n defaultIndex: number;\n horizontal: boolean;\n circular: boolean;\n bound: boolean;\n adaptive: boolean;\n panelsPerView: number;\n noPanelStyleOverride: boolean;\n resizeOnContentsReady: boolean;\n // EVENT\n needPanelThreshold: number;\n preventEventsBeforeInit: boolean;\n // ANIMATION\n deceleration: number;\n duration: number;\n easing: (x: number) => number;\n // INPUT\n inputType: string[];\n moveType: ValueOf<typeof MOVE_TYPE> | MoveTypeOptions<ValueOf<typeof MOVE_TYPE>>;\n threshold: number;\n interruptable: boolean;\n bounce: number | string | [number | string, number | string];\n iOSEdgeSwipeThreshold: number;\n preventClickOnDrag: boolean;\n disableOnInit: boolean;\n // PERFORMANCE\n renderOnlyVisible: boolean;\n // OTHERS\n autoInit: boolean;\n autoResize: boolean;\n renderExternal: {\n renderer: typeof ExternalRenderer;\n rendererOptions: {[key: string]: any};\n } | null;\n}\n\n/**\n * @extends Component\n * @support {\"ie\": \"9+(with polyfill)\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"4.X+\"}\n * @requires {@link https://github.com/naver/egjs-component|@egjs/component}\n * @requires {@link https://github.com/naver/egjs-axes|@egjs/axes}\n */\nclass Flicking extends Component<FlickingEvents> {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @type {string}\n * @readonly\n * @example\n * ```ts\n * Flicking.VERSION; // ex) 4.0.0\n * ```\n */\n public static VERSION = \"#__VERSION__#\";\n\n // Core components\n private _viewport: Viewport;\n private _camera: Camera;\n private _control: Control;\n private _renderer: Renderer;\n\n // Options\n private _align: FlickingOptions[\"align\"];\n private _defaultIndex: FlickingOptions[\"defaultIndex\"];\n private _horizontal: FlickingOptions[\"horizontal\"];\n private _circular: FlickingOptions[\"circular\"];\n private _bound: FlickingOptions[\"bound\"];\n private _adaptive: FlickingOptions[\"adaptive\"];\n private _panelsPerView: FlickingOptions[\"panelsPerView\"];\n private _noPanelStyleOverride: FlickingOptions[\"noPanelStyleOverride\"];\n private _resizeOnContentsReady: FlickingOptions[\"resizeOnContentsReady\"];\n\n private _needPanelThreshold: FlickingOptions[\"needPanelThreshold\"];\n private _preventEventsBeforeInit: FlickingOptions[\"preventEventsBeforeInit\"];\n\n private _deceleration: FlickingOptions[\"deceleration\"];\n private _duration: FlickingOptions[\"duration\"];\n private _easing: FlickingOptions[\"easing\"];\n\n private _inputType: FlickingOptions[\"inputType\"];\n private _moveType: FlickingOptions[\"moveType\"];\n private _threshold: FlickingOptions[\"threshold\"];\n private _interruptable: FlickingOptions[\"interruptable\"];\n private _bounce: FlickingOptions[\"bounce\"];\n private _iOSEdgeSwipeThreshold: FlickingOptions[\"iOSEdgeSwipeThreshold\"];\n private _preventClickOnDrag: FlickingOptions[\"preventClickOnDrag\"];\n private _disableOnInit: FlickingOptions[\"disableOnInit\"];\n\n private _renderOnlyVisible: FlickingOptions[\"renderOnlyVisible\"];\n\n private _autoResize: FlickingOptions[\"autoResize\"];\n private _autoInit: FlickingOptions[\"autoInit\"];\n private _renderExternal: FlickingOptions[\"renderExternal\"];\n\n // Internal State\n private _initialized: boolean;\n private _plugins: Plugin[];\n\n // Components\n /**\n * {@link Control} instance of the Flicking\n * @ko 현재 Flicking에 활성화된 {@link Control} 인스턴스\n * @type {Control}\n * @default SnapControl\n * @readonly\n * @see Control\n * @see SnapControl\n * @see FreeControl\n */\n public get control() { return this._control; }\n /**\n * {@link Camera} instance of the Flicking\n * @ko 현재 Flicking에 활성화된 {@link Camera} 인스턴스\n * @type {Camera}\n * @default LinearCamera\n * @readonly\n * @see Camera\n * @see LinearCamera\n * @see BoundCamera\n * @see CircularCamera\n */\n public get camera() { return this._camera; }\n /**\n * {@link Renderer} instance of the Flicking\n * @ko 현재 Flicking에 활성화된 {@link Renderer} 인스턴스\n * @type {Renderer}\n * @default VanillaRenderer\n * @readonly\n * @see Renderer\n * @see VanillaRenderer\n * @see ExternalRenderer\n */\n public get renderer() { return this._renderer; }\n /**\n * A component that manages viewport size\n * @ko 뷰포트 크기 정보를 담당하는 컴포넌트\n * @type {Viewport}\n * @readonly\n * @see Viewport\n */\n public get viewport() { return this._viewport; }\n // Internal States\n /**\n * Whether Flicking's {@link Flicking#init init()} is called.\n * This is `true` when {@link Flicking#init init()} is called, and is `false` after calling {@link Flicking#destroy destroy()}.\n * @ko Flicking의 {@link Flicking#init init()}이 호출되었는지를 나타내는 멤버 변수.\n * 이 값은 {@link Flicking#init init()}이 호출되었으면 `true`로 변하고, {@link Flicking#destroy destroy()}호출 이후에 다시 `false`로 변경됩니다.\n * @type {boolean}\n * @default false\n * @readonly\n */\n public get initialized() { return this._initialized; }\n /**\n * Whether the `circular` option is enabled.\n * The {@link Flicking#circular circular} option can't be enabled when sum of the panel sizes are too small.\n * @ko {@link Flicking#circular circular} 옵션이 활성화되었는지 여부를 나타내는 멤버 변수.\n * {@link Flicking#circular circular} 옵션은 패널의 크기의 합이 충분하지 않을 경우 비활성화됩니다.\n * @type {boolean}\n * @default false\n * @readonly\n */\n public get circularEnabled() { return this._camera.controlParams.circular; }\n /**\n * Index number of the {@link Flicking#currentPanel currentPanel}\n * @ko {@link Flicking#currentPanel currentPanel}의 인덱스 번호\n * @type {number}\n * @default 0\n * @readonly\n */\n public get index() { return this._control.activeIndex; }\n /**\n * The root(`.flicking-viewport`) element\n * @ko root(`.flicking-viewport`) 엘리먼트\n * @type {HTMLElement}\n * @readonly\n */\n public get element() { return this._viewport.element; }\n /**\n * Currently active panel\n * @ko 현재 선택된 패널\n * @type {Panel}\n * @readonly\n * @see Panel\n */\n public get currentPanel() { return this._control.activePanel; }\n /**\n * Array of panels\n * @ko 전체 패널들의 배열\n * @type {Panel[]}\n * @readonly\n * @see Panel\n */\n public get panels() { return this._renderer.panels; }\n /**\n * Count of panels\n * @ko 전체 패널의 개수\n * @type {number}\n * @readonly\n */\n public get panelCount() { return this._renderer.panelCount; }\n /**\n * Array of panels that is visible at the current position\n * @ko 현재 보이는 패널의 배열\n * @type {Panel[]}\n * @readonly\n * @see Panel\n */\n public get visiblePanels() { return this._camera.visiblePanels; }\n /**\n * Whether Flicking's animating\n * @ko 현재 애니메이션 동작 여부\n * @type {boolean}\n * @readonly\n */\n public get animating() { return this._control.animating; }\n /**\n * Whether user is clicking or touching\n * @ko 현재 사용자가 클릭/터치중인지 여부\n * @type {boolean}\n * @readonly\n */\n public get holding() { return this._control.holding; }\n /**\n * A current list of activated plugins\n * @ko 현재 활성화된 플러그인 목록\n * @type {Plugin[]}\n * @readonly\n */\n public get activePlugins() { return this._plugins; }\n\n // Options Getter\n // UI / LAYOUT\n /**\n * Align position of the panels within viewport. You can set different values each for the panel and camera\n * @ko 뷰포트 내에서 패널 정렬방식을 설정하는 옵션. 카메라와 패널 개별로 옵션을 설정할 수도 있습니다\n * @type {ALIGN | string | number | { panel: string | number, camera: string | number }}\n * @property {ALIGN | string | number} panel The align value for each {@link Panel}s<ko>개개의 {@link Panel}에 적용할 값</ko>\n * @property {ALIGN | string | number} camera The align value for {@link Camera}<ko>{@link Camera}에 적용할 값</ko>\n * @default \"center\"\n * @example\n * ```ts\n * const possibleOptions = [\n * // Literal strings\n * \"prev\", \"center\", \"next\",\n * // % values, applied to both panel & camera\n * \"0%\", \"25%\", \"42%\",\n * // px values, arithmetic calculation with (+/-) is also allowed.\n * \"0px\", \"100px\", \"50% - 25px\",\n * // numbers, same to number + px (\"0px\", \"100px\")\n * 0, 100, 1000,\n * // Setting a different value for panel & camera\n * { panel: \"10%\", camera: \"25%\" }\n * ];\n *\n * possibleOptions.forEach(align => {\n * new Flicking(\"#el\", { align });\n * });\n * ```\n */\n public get align() { return this._align; }\n /**\n * Index of the panel to move when Flicking's {@link Flicking#init init()} is called. A zero-based integer\n * @ko Flicking의 {@link Flicking#init init()}이 호출될 때 이동할 디폴트 패널의 인덱스로, 0부터 시작하는 정수입니다\n * @type {number}\n * @default 0\n */\n public get defaultIndex() { return this._defaultIndex; }\n /**\n * Direction of panel movement (true: horizontal, false: vertical)\n * @ko 패널 이동 방향 (true: 가로방향, false: 세로방향)\n * @type {boolean}\n * @default true\n */\n public get horizontal() { return this._horizontal; }\n /**\n * Enables circular(continuous loop) mode, which connects first/last panel for continuous scrolling.\n * @ko 순환 모드를 활성화합니다. 순환 모드에서는 양 끝의 패널이 서로 연결되어 끊김없는 스크롤이 가능합니다.\n * @type {boolean}\n * @default false\n */\n public get circular() { return this._circular; }\n /**\n * Prevent the view(camera element) from going out of the first/last panel, so it won't show empty spaces before/after the first/last panel\n * Only can be enabled when `circular=false`\n * @ko 뷰(카메라 엘리먼트)가 첫번째와 마지막 패널 밖으로 넘어가지 못하게 하여, 첫번째/마지막 패널 전/후의 빈 공간을 보이지 않도록 하는 옵션입니다\n * `circular=false`인 경우에만 사용할 수 있습니다\n * @type {boolean}\n * @default false\n */\n public get bound() { return this._bound; }\n /**\n * Update height of the viewport element after movement same to the height of the panel below. This can be only enabled when `horizontal=true`\n * @ko 이동한 후 뷰포트 엘리먼트의 크기를 현재 패널의 높이와 동일하게 설정합니다. `horizontal=true`인 경우에만 사용할 수 있습니다.\n * @type {boolean}\n * @default false\n */\n public get adaptive() { return this._adaptive; }\n /**\n * A visible number of panels on viewport. Enabling this option will automatically resize panel size\n * @ko 한 화면에 보이는 패널의 개수. 이 옵션을 활성화할 경우 패널의 크기를 강제로 재조정합니다\n * @type {number}\n * @default -1\n */\n public get panelsPerView() { return this._panelsPerView; }\n /**\n * Enabling this option will not change `width/height` style of the panels if {@link Flicking#panelsPerView} is enabled.\n * This behavior can be useful in terms of performance when you're manually managing all panel sizes\n * @ko 이 옵션을 활성화할 경우, {@link Flicking#panelsPerView} 옵션이 활성화되었을 때 패널의 `width/height` 스타일을 변경하지 않도록 설정합니다.\n * 모든 패널들의 크기를 직접 관리하고 있을 경우, 이 옵션을 활성화하면 성능면에서 유리할 수 있습니다\n * @type {boolean}\n * @default false\n */\n public get noPanelStyleOverride() { return this._noPanelStyleOverride; }\n /**\n * Enabling this option will automatically call {@link Flicking#resize} when all image/video inside panels are loaded.\n * This can be useful when you have contents inside Flicking that changes its size when it's loaded\n * @ko 이 옵션을 활성화할 경우, Flicking 패널 내부의 이미지/비디오들이 로드되었을 때 자동으로 {@link Flicking#resize}를 호출합니다.\n * 이 동작은 Flicking 내부에 로드 전/후로 크기가 변하는 콘텐츠를 포함하고 있을 때 유용하게 사용하실 수 있습니다.\n * @type {boolean}\n * @default false\n */\n public get resizeOnContentsReady() { return this._resizeOnContentsReady; }\n // EVENTS\n /**\n * A Threshold from viewport edge before triggering `needPanel` event\n * @ko `needPanel`이벤트가 발생하기 위한 뷰포트 끝으로부터의 최대 거리\n * @type {number}\n * @default 0\n */\n public get needPanelThreshold() { return this._needPanelThreshold; }\n /**\n * When enabled, events are not triggered before `ready` when initializing\n * @ko 활성화할 경우 초기화시 `ready` 이벤트 이전의 이벤트가 발생하지 않습니다.\n * @type {boolean}\n * @default true\n */\n public get preventEventsBeforeInit() { return this._preventEventsBeforeInit; }\n // ANIMATION\n /**\n * Deceleration value for panel movement animation which is triggered by user input. A higher value means a shorter animation time\n * @ko 사용자의 동작으로 가속도가 적용된 패널 이동 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아집니다\n * @type {number}\n * @default 0.0075\n */\n public get deceleration() { return this._deceleration; }\n /**\n * An easing function applied to the panel movement animation. Default value is `easeOutCubic`\n * @ko 패널 이동 애니메이션에 적용할 easing 함수. 기본값은 `easeOutCubic`이다\n * @type {function}\n * @default x => 1 - Math.pow(1 - x, 3)\n * @see Easing Functions Cheat Sheet {@link http://easings.net/} <ko>이징 함수 Cheat Sheet {@link http://easings.net/}</ko>\n */\n public get easing() { return this._easing; }\n /**\n * Default duration of the animation (ms)\n * @ko 디폴트 애니메이션 재생 시간 (ms)\n * @type {number}\n * @default 500\n */\n public get duration() { return this._duration; }\n // INPUT\n /**\n * Types of input devices to enable\n * @ko 활성화할 입력 장치 종류\n * @type {string[]}\n * @default [\"touch\", \"mouse\"]\n * @see {@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption Possible values (PanInputOption#inputType)}\n * <ko>{@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption 가능한 값들 (PanInputOption#inputType)}</ko>\n */\n public get inputType() { return this._inputType; }\n /**\n * Movement style by user input. This will change instance type of {@link Flicking#control}\n * You can use the values of the constant {@link MOVE_TYPE}\n * @ko 사용자 입력에 의한 이동 방식. 이 값에 따라 {@link Flicking#control}의 인스턴스 타입이 결정됩니다\n * 상수 {@link MOVE_TYPE}에 정의된 값들을 이용할 수 있습니다\n * @type {MOVE_TYPE | Pair<string, object>}\n * @default \"snap\"\n * @example\n * |moveType|control|options|\n * |:---:|:---:|:---:|\n * |\"snap\"|{@link SnapControl}||\n * |\"freeScroll\"|{@link FreeControl}|{@link FreeControlOptions}|\n *\n * ```ts\n * import Flicking, { MOVE_TYPE } from \"@egjs/flicking\";\n *\n * const flicking = new Flicking({\n * moveType: MOVE_TYPE.SNAP\n * });\n * ```\n *\n * ```ts\n * const flicking = new Flicking({\n * // If you want more specific settings for the moveType\n * // [moveType, options for that moveType]\n * // In this case, it's [\"freeScroll\", FreeControlOptions]\n * moveType: [MOVE_TYPE.FREE_SCROLL, { stopAtEdge: true }]\n * });\n * ```\n */\n public get moveType() { return this._moveType; }\n /**\n * Movement threshold to change panel (unit: px). It should be dragged above the threshold to change the current panel.\n * @ko 패널 변경을 위한 이동 임계값 (단위: px). 주어진 값 이상으로 스크롤해야만 패널 변경이 가능하다.\n * @type {number}\n * @default 40\n */\n public get threshold() { return this._threshold; }\n /**\n * Set animation to be interruptable by click/touch.\n * @ko 사용자의 클릭/터치로 인해 애니메이션을 도중에 멈출 수 있도록 설정합니다.\n * @type {boolean}\n * @default true\n */\n public get interruptable() { return this._interruptable; }\n /**\n * The size value of the bounce area. Only can be enabled when `circular=false`.\n * You can set different bounce value for prev/next direction by using array.\n * `number` for px value, and `string` for px, and % value relative to viewport size.\n * You have to call {@link Control#updateInput} after changing this to take effect.\n * @ko Flicking이 최대 영역을 넘어서 갈 수 있는 최대 크기. `circular=false`인 경우에만 사용할 수 있습니다.\n * 배열을 통해 prev/next 방향에 대해 서로 다른 바운스 값을 지정할 수 있습니다.\n * `number`를 통해 px값을, `stirng`을 통해 px 혹은 뷰포트 크기 대비 %값을 사용할 수 있습니다.\n * 이 값을 변경시 {@link Control#updateInput}를 호출해야 합니다.\n * @type {string | number | Array<string | number>}\n * @default \"20%\"\n * @example\n * ```ts\n * const possibleOptions = [\n * // % values, relative to viewport element(\".flicking-viewport\")'s size\n * \"0%\", \"25%\", \"42%\",\n * // px values, arithmetic calculation with (+/-) is also allowed.\n * \"0px\", \"100px\", \"50% - 25px\",\n * // numbers, same to number + px (\"0px\", \"100px\")\n * 0, 100, 1000\n * ];\n * ```\n *\n * @example\n * ```ts\n * const flicking = new Flicking(\"#el\", { bounce: \"20%\" });\n *\n * flicking.bounce = \"100%\";\n * flicking.control.updateInput(); // Call this to update!\n * ```\n */\n public get bounce() { return this._bounce; }\n /**\n * Size of the area from the right edge in iOS safari (in px) which enables swipe-back or swipe-forward\n * @ko iOS Safari에서 swipe를 통한 뒤로가기/앞으로가기를 활성화하는 오른쪽 끝으로부터의 영역의 크기 (px)\n * @type {number}\n * @default 30\n */\n public get iOSEdgeSwipeThreshold() { return this._iOSEdgeSwipeThreshold; }\n /**\n * Automatically prevent `click` event if the user has dragged at least a single pixel on the viewport element\n * @ko 사용자가 뷰포트 영역을 1픽셀이라도 드래그했을 경우 자동으로 {@link https://developer.mozilla.org/ko/docs/Web/API/Element/click_event click} 이벤트를 취소합니다\n * @type {boolean}\n * @default true\n */\n public get preventClickOnDrag() { return this._preventClickOnDrag; }\n /**\n * Automatically call {@link Flicking#disableInput disableInput()} on initialization\n * @ko Flicking init시에 {@link Flicking#disableInput disableInput()}을 바로 호출합니다\n * @type {boolean}\n * @default false\n */\n public get disableOnInit() { return this._disableOnInit; }\n // PERFORMANCE\n /**\n * Whether to render visible panels only. This can dramatically increase performance when there're many panels.\n * @ko 보이는 패널만 렌더링할지 여부를 설정합니다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있습니다.\n * @type {boolean}\n * @default false\n */\n public get renderOnlyVisible() { return this._renderOnlyVisible; }\n // OTHERS\n /**\n * Call {@link Flicking#init init()} automatically when creating Flicking's instance\n * @ko Flicking 인스턴스를 생성할 때 자동으로 {@link Flicking#init init()}를 호출합니다\n * @type {boolean}\n * @default true\n * @readonly\n */\n public get autoInit() { return this._autoInit; }\n /**\n * Attach Flicking's {@link Flicking#resize resize} method to window's resize event.\n * Flicking will automatically call {@link Flicking#resize resize} window size and orientation change.\n * @ko Flicking의 {@link Flicking#resize resize} 메소드를 window의 resize 이벤트 핸들러로 등록합니다.\n * 설정시 window 창 크기 및 orientation 변경에 의해 자동으로 {@link Flicking#resize resize}를 호출합니다.\n * @type {boolean}\n * @default true\n */\n public get autoResize() { return this._autoResize; }\n /**\n * This is an option for the frameworks(React, Vue, Angular, ...). Don't set it as it's automatically managed by Flicking.\n * @ko 프레임워크(React, Vue, Angular, ...)에서만 사용하는 옵션으로, 자동으로 설정되므로 따로 사용하실 필요 없습니다!\n * @type {boolean}\n * @default false\n * @internal\n * @readonly\n */\n public get renderExternal() { return this._renderExternal; }\n\n // Options Setter\n // UI / LAYOUT\n public set align(val: FlickingOptions[\"align\"]) {\n this._align = val;\n this._renderer.align = val;\n this._camera.align = val;\n }\n\n public set defaultIndex(val: FlickingOptions[\"defaultIndex\"]) { this._defaultIndex = val; }\n public set horizontal(val: FlickingOptions[\"horizontal\"]) { this._horizontal = val; }\n public set circular(val: FlickingOptions[\"circular\"]) { this._circular = val; }\n public set bound(val: FlickingOptions[\"bound\"]) { this._bound = val; }\n public set adaptive(val: FlickingOptions[\"adaptive\"]) { this._adaptive = val; }\n public set panelsPerView(val: FlickingOptions[\"panelsPerView\"]) { this._panelsPerView = val; }\n public set noPanelStyleOverride(val: FlickingOptions[\"noPanelStyleOverride\"]) { this._noPanelStyleOverride = val; }\n public set resizeOnContentsReady(val: FlickingOptions[\"resizeOnContentsReady\"]) { this._resizeOnContentsReady = val; }\n // EVENTS\n public set needPanelThreshold(val: FlickingOptions[\"needPanelThreshold\"]) { this._needPanelThreshold = val; }\n public set preventEventsBeforeInit(val: FlickingOptions[\"preventEventsBeforeInit\"]) { this._preventEventsBeforeInit = val; }\n // ANIMATION\n public set deceleration(val: FlickingOptions[\"deceleration\"]) { this._deceleration = val; }\n public set easing(val: FlickingOptions[\"easing\"]) { this._easing = val; }\n public set duration(val: FlickingOptions[\"duration\"]) { this._duration = val; }\n // INPUT\n public set inputType(val: FlickingOptions[\"inputType\"]) { this._inputType = val; }\n public set moveType(val: FlickingOptions[\"moveType\"]) { this._moveType = val; }\n public set threshold(val: FlickingOptions[\"threshold\"]) { this._threshold = val; }\n public set interruptable(val: FlickingOptions[\"interruptable\"]) { this._interruptable = val; }\n public set bounce(val: FlickingOptions[\"bounce\"]) { this._bounce = val; }\n public set iOSEdgeSwipeThreshold(val: FlickingOptions[\"iOSEdgeSwipeThreshold\"]) { this._iOSEdgeSwipeThreshold = val; }\n public set preventClickOnDrag(val: FlickingOptions[\"preventClickOnDrag\"]) {\n const prevVal = this._preventClickOnDrag;\n\n if (val === prevVal) return;\n\n const controller = this._control.controller;\n\n if (val) {\n controller.addPreventClickHandler();\n } else {\n controller.removePreventClickHandler();\n }\n\n this._preventClickOnDrag = val;\n }\n\n public set disableOnInit(val: FlickingOptions[\"disableOnInit\"]) { this._disableOnInit = val; }\n // PERFORMANCE\n public set renderOnlyVisible(val: FlickingOptions[\"renderOnlyVisible\"]) { this._renderOnlyVisible = val; }\n // OTHERS\n public set autoResize(val: FlickingOptions[\"autoResize\"]) { this._autoResize = val; }\n\n /**\n * @param root A root HTMLElement to initialize Flicking on it. When it's a typeof `string`, it should be a css selector string\n * <ko>Flicking을 초기화할 HTMLElement로, `string` 타입으로 지정시 css 선택자 문자열을 지정해야 합니다.</ko>\n * @param {object} [options={}] An options object for Flicking.<ko>Flicking에 적용할 옵션 오브젝트</ko>\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE WRONG_TYPE}|When the root is not either string or HTMLElement|\n * |{@link ERROR_CODE ELEMENT_NOT_FOUND}|When the element with given CSS selector does not exist|\n * <ko>\n *\n * |code|조건|\n * |---|---|\n * |{@link ERROR_CODE WRONG_TYPE}|루트 엘리먼트가 string이나 HTMLElement가 아닐 경우|\n * |{@link ERROR_CODE ELEMENT_NOT_FOUND}|주어진 CSS selector로 엘리먼트를 찾지 못했을 경우|\n *\n * </ko>\n * @example\n * ```ts\n * import Flicking from \"@egjs/flicking\";\n *\n * // Creating new instance of Flicking with HTMLElement\n * const flicking = new Flicking(document.querySelector(\".flicking-viewport\"), { circular: true });\n *\n * // Creating new instance of Flicking with CSS selector\n * const flicking2 = new Flicking(\".flicking-viewport\", { circular: true });\n * ```\n */\n public constructor(root: HTMLElement | string, {\n align = ALIGN.CENTER,\n defaultIndex = 0,\n horizontal = true,\n circular = false,\n bound = false,\n adaptive = false,\n panelsPerView = -1,\n noPanelStyleOverride = false,\n resizeOnContentsReady = false,\n needPanelThreshold = 0,\n preventEventsBeforeInit = true,\n deceleration = 0.0075,\n duration = 500,\n easing = x => 1 - Math.pow(1 - x, 3),\n inputType = [\"mouse\", \"touch\"],\n moveType = \"snap\",\n threshold = 40,\n interruptable = true,\n bounce = \"20%\",\n iOSEdgeSwipeThreshold = 30,\n preventClickOnDrag = true,\n disableOnInit = false,\n renderOnlyVisible = false,\n autoInit = true,\n autoResize = true,\n renderExternal = null\n }: Partial<FlickingOptions> = {}) {\n super();\n\n // Internal states\n this._initialized = false;\n this._plugins = [];\n\n // Bind options\n this._align = align;\n this._defaultIndex = defaultIndex;\n this._horizontal = horizontal;\n this._circular = circular;\n this._bound = bound;\n this._adaptive = adaptive;\n this._panelsPerView = panelsPerView;\n this._noPanelStyleOverride = noPanelStyleOverride;\n this._resizeOnContentsReady = resizeOnContentsReady;\n this._needPanelThreshold = needPanelThreshold;\n this._preventEventsBeforeInit = preventEventsBeforeInit;\n this._deceleration = deceleration;\n this._duration = duration;\n this._easing = easing;\n this._inputType = inputType;\n this._moveType = moveType;\n this._threshold = threshold;\n this._interruptable = interruptable;\n this._bounce = bounce;\n this._iOSEdgeSwipeThreshold = iOSEdgeSwipeThreshold;\n this._preventClickOnDrag = preventClickOnDrag;\n this._disableOnInit = disableOnInit;\n this._renderOnlyVisible = renderOnlyVisible;\n this._autoResize = autoResize;\n this._autoInit = autoInit;\n this._renderExternal = renderExternal;\n\n // Create core components\n this._viewport = new Viewport(getElement(root));\n this._renderer = this._createRenderer();\n this._camera = this._createCamera();\n this._control = this._createControl();\n\n this.resize = this.resize.bind(this);\n\n if (this._autoInit) {\n void this.init();\n }\n }\n\n /**\n * Initialize Flicking and move to the default index\n * This is automatically called on Flicking's constructor when `autoInit` is true(default)\n * @ko Flicking을 초기화하고, 디폴트 인덱스로 이동합니다\n * 이 메소드는 `autoInit` 옵션이 true(default)일 경우 Flicking이 생성될 때 자동으로 호출됩니다\n * @fires Flicking#ready\n * @return {this}\n */\n public async init(): Promise<void> {\n if (this._initialized) return;\n\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const originalTrigger = this.trigger;\n const preventEventsBeforeInit = this._preventEventsBeforeInit;\n\n camera.init(this);\n renderer.init(this);\n control.init(this);\n\n if (preventEventsBeforeInit) {\n this.trigger = () => this;\n }\n\n await this.resize();\n\n // Look at initial panel\n await this._moveToInitialPanel();\n\n if (this._autoResize) {\n window.addEventListener(\"resize\", this.resize);\n }\n if (this._preventClickOnDrag) {\n control.controller.addPreventClickHandler();\n }\n if (this._disableOnInit) {\n this.disableInput();\n }\n renderer.checkPanelContentsReady(renderer.panels);\n\n this._plugins.forEach(plugin => plugin.init(this));\n\n // Done initializing & emit ready event\n this._initialized = true;\n if (preventEventsBeforeInit) {\n this.trigger = originalTrigger;\n }\n this.trigger(new ComponentEvent(EVENTS.READY));\n\n return;\n }\n\n /**\n * Destroy Flicking and remove all event handlers\n * @ko Flicking과 하위 컴포넌트들을 초기 상태로 되돌리고, 부착된 모든 이벤트 핸들러를 제거합니다\n * @return {void}\n */\n public destroy(): void {\n this.off();\n window.removeEventListener(\"resize\", this.resize);\n\n this._control.destroy();\n this._camera.destroy();\n this._renderer.destroy();\n\n this._plugins.forEach(plugin => plugin.destroy());\n\n this._initialized = false;\n }\n\n /**\n * Move to the previous panel (current index - 1)\n * @ko 이전 패널로 이동합니다 (현재 인덱스 - 1)\n * @param {number} [duration={@link Flicking#duration options.duration}] Duration of the panel movement animation (unit: ms)<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>\n * @async\n * @fires Flicking#moveStart\n * @fires Flicking#move\n * @fires Flicking#moveEnd\n * @fires Flicking#willChange\n * @fires Flicking#changed\n * @fires Flicking#willRestore\n * @fires Flicking#restored\n * @fires Flicking#needPanel\n * @fires Flicking#visibleChange\n * @fires Flicking#reachEdge\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|When the previous panel does not exist|\n * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|When the animation is already playing|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the any of the event's `stop()` is called|\n * <ko>\n *\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|이전 패널이 존재하지 않을 경우|\n * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|애니메이션이 이미 진행중인 경우|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|\n * </ko>\n * @return {Promise<void>} A Promise which will be resolved after reaching the previous panel<ko>이전 패널 도달시에 resolve되는 Promise</ko>\n */\n public prev(duration: number = this._duration): Promise<void> {\n return this.moveTo(this._control.activePanel?.prev()?.index ?? -1, duration, DIRECTION.PREV);\n }\n\n /**\n * Move to the next panel (current index + 1)\n * @ko 다음 패널로 이동합니다 (현재 인덱스 + 1)\n * @param {number} [duration={@link Flicking#duration options.duration}] Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>\n * @async\n * @fires Flicking#moveStart\n * @fires Flicking#move\n * @fires Flicking#moveEnd\n * @fires Flicking#willChange\n * @fires Flicking#changed\n * @fires Flicking#willRestore\n * @fires Flicking#restored\n * @fires Flicking#needPanel\n * @fires Flicking#visibleChange\n * @fires Flicking#reachEdge\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|When the next panel does not exist|\n * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|When the animation is already playing|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the any of the event's `stop()` is called|\n * <ko>\n *\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|다음 패널이 존재하지 않을 경우|\n * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|애니메이션이 이미 진행중인 경우|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|\n *\n * </ko>\n * @return {Promise<void>} A Promise which will be resolved after reaching the next panel<ko>다음 패널 도달시에 resolve되는 Promise</ko>\n */\n public next(duration: number = this._duration) {\n return this.moveTo(this._control.activePanel?.next()?.index ?? this._renderer.panelCount, duration, DIRECTION.NEXT);\n }\n\n /**\n * Move to the panel with given index\n * @ko 주어진 인덱스에 해당하는 패널로 이동합니다\n * @param {number} index The index of the panel to move<ko>이동할 패널의 인덱스</ko>\n * @param {number} [duration={@link Flicking#duration options.duration}] Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>\n * @param {DIRECTION} [direction=DIRECTION.NONE] Direction to move, only available in the {@link Flicking#circular circular} mode<ko>이동할 방향. {@link Flicking#circular circular} 옵션 활성화시에만 사용 가능합니다</ko>\n * @async\n * @fires Flicking#moveStart\n * @fires Flicking#move\n * @fires Flicking#moveEnd\n * @fires Flicking#willChange\n * @fires Flicking#changed\n * @fires Flicking#willRestore\n * @fires Flicking#restored\n * @fires Flicking#needPanel\n * @fires Flicking#visibleChange\n * @fires Flicking#reachEdge\n * @throws {FlickingError}\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|When the root is not either string or HTMLElement|\n * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|When the animation is already playing|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the any of the event's `stop()` is called|\n * <ko>\n *\n * |code|condition|\n * |---|---|\n * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|해당 인덱스를 가진 패널이 존재하지 않을 경우|\n * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|애니메이션이 이미 진행중인 경우|\n * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|\n * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|\n *\n * </ko>\n * @return {Promise<void>} A Promise which will be resolved after reaching the target panel<ko>해당 패널 도달시에 resolve되는 Promise</ko>\n */\n public moveTo(index: number, duration: number = this._duration, direction: ValueOf<typeof DIRECTION> = DIRECTION.NONE) {\n const renderer = this._renderer;\n const panelCount = renderer.panelCount;\n\n const panel = renderer.getPanel(index);\n\n if (!panel) {\n return Promise.reject(new FlickingError(ERROR.MESSAGE.INDEX_OUT_OF_RANGE(index, 0, panelCount - 1), ERROR.CODE.INDEX_OUT_OF_RANGE));\n }\n\n if (this._control.animating) {\n return Promise.reject(new FlickingError(ERROR.MESSAGE.ANIMATION_ALREADY_PLAYING, ERROR.CODE.ANIMATION_ALREADY_PLAYING));\n }\n\n return this._control.moveToPanel(panel, {\n duration,\n direction\n });\n }\n\n /**\n * Return the {@link Panel} at the given index. `null` if it doesn't exists.\n * @ko 주어진 인덱스에 해당하는 {@link Panel}을 반환합니다. 주어진 인덱스에 해당하는 패널이 존재하지 않을 경우 `null`을 반환합니다.\n * @return {Panel | null} Panel at the given index<ko>주어진 인덱스에 해당하는 패널</ko>\n * @see Panel\n * @example\n * ```ts\n * const panel = flicking.getPanel(0);\n * // Which is a shorthand to...\n * const samePanel = flicking.panels[0];\n * ```\n */\n public getPanel(index: number): Panel | null {\n return this._renderer.getPanel(index);\n }\n\n /**\n * Enable input from the user (mouse/touch)\n * @ko 사용자의 입력(마우스/터치)를 활성화합니다\n * @return {this}\n */\n public enableInput(): this {\n this._control.enable();\n return this;\n }\n\n /**\n * Disable input from the user (mouse/touch)\n * @ko 사용자의 입력(마우스/터치)를 막습니다\n * @return {this}\n */\n public disableInput(): this {\n this._control.disable();\n return this;\n }\n\n /**\n * Get current flicking status. You can restore current state by giving returned value to {@link Flicking#setStatus setStatus()}\n * @ko 현재 상태를 반환합니다. 반환받은 값을 {@link Flicking#setStatus setStatus()} 메소드의 인자로 지정하면 현재 상태를 복원할 수 있습니다\n * @param {object} options Status retrieving options<ko>Status 반환 옵션</ko>\n * @param {boolean} [options.index=true] Include current panel index to the returning status. Camera will automatically move to the given index when the {@link Flicking#setStatus setStatus} is called<ko>현재 패널 인덱스를 반환값에 포함시킵니다. {@link Flicking#setStatus setStatus} 호출시 자동으로 해당 인덱스로 카메라를 움직입니다</ko>\n * @param {boolean} [options.position=true] Include camera position to the returning status. This works only when the {@link Flicking#moveType moveType} is `freeScroll`<ko>카메라의 현재 위치를 반환값에 포함시킵니다. 이 옵션은 {@link Flicking#moveType moveType}이 `freeScroll`일 경우에만 동작합니다</ko>\n * @param {boolean} [options.includePanelHTML=false] Include panel's `outerHTML` to the returning status<ko>패널의 `outerHTML`을 반환값에 포함시킵니다</ko>\n * @param {boolean} [options.visiblePanelsOnly=false] Include only {@link Flicking#visiblePanel visiblePanel}'s HTML. This option is available only when the `includePanelHTML` is true\n * <ko>현재 보이는 패널({@link Flicking#visiblePanel visiblePanel})의 HTML만 반환합니다. `includePanelHTML`이 `true`일 경우에만 동작합니다.</ko>\n * @return {Partial<Status>} An object with current status value information<ko>현재 상태값 정보를 가진 객체.</ko>\n */\n public getStatus({\n index = true,\n position = true,\n includePanelHTML = false,\n visiblePanelsOnly = false\n }: Partial<{\n index: boolean;\n position: boolean;\n includePanelHTML: boolean;\n visiblePanelsOnly: boolean;\n }> = {}): Status {\n const camera = this._camera;\n const panels = visiblePanelsOnly ? this.visiblePanels : this.panels;\n\n const status: Status = {\n panels: panels.map(panel => {\n const panelInfo: Status[\"panels\"][0] = { index: panel.index };\n\n if (includePanelHTML) {\n panelInfo.html = panel.element.outerHTML;\n }\n\n return panelInfo;\n })\n };\n\n if (index) {\n status.index = this.index;\n }\n if (position) {\n const nearestAnchor = camera.findNearestAnchor(camera.position);\n\n if (nearestAnchor) {\n status.position = {\n panel: nearestAnchor.panel.index,\n progressInPanel: camera.getProgressInPanel(nearestAnchor.panel)\n };\n }\n\n }\n\n if (visiblePanelsOnly) {\n const visiblePanels = this.visiblePanels;\n\n status.visibleOffset = visiblePanels[0]?.index ?? 0;\n }\n\n return status;\n }\n\n /**\n * Restore to the state of the given {@link Status}\n * @ko 주어진 {@link Status}의 상태로 복원합니다\n * @param {Partial<Status>} status Status value to be restored. You should use the return value of the {@link Flicking#getStatus getStatus()} method<ko>복원할 상태 값. {@link Flicking#getStatus getStatus()} 메서드의 반환값을 지정하면 됩니다</ko>\n * @return {void}\n */\n public setStatus(status: Status): void {\n if (!this._initialized) {\n throw new FlickingError(ERROR.MESSAGE.NOT_INITIALIZED, ERROR.CODE.NOT_INITIALIZED);\n }\n\n const {\n index,\n position,\n visibleOffset,\n panels\n } = status;\n\n const renderer = this._renderer;\n const control = this._control;\n\n // Can't add/remove panels on external rendering\n if (panels[0]?.html && !this._renderExternal) {\n renderer.batchRemove({ index: 0, deleteCount: this.panels.length });\n renderer.batchInsert({ index: 0, elements: parseElement(panels.map(panel => panel.html!)) });\n }\n\n if (index) {\n const panelIndex = visibleOffset\n ? index - visibleOffset\n : index;\n\n void this.moveTo(panelIndex, 0).catch(() => void 0);\n }\n\n if (position && this._moveType === MOVE_TYPE.FREE_SCROLL) {\n const { panel, progressInPanel } = position;\n const panelIndex = visibleOffset\n ? panel - visibleOffset\n : panel;\n const panelRange = renderer.panels[panelIndex].range;\n const newCameraPos = panelRange.min + (panelRange.max - panelRange.min) * progressInPanel;\n\n void control.moveToPosition(newCameraPos, 0).catch(() => void 0);\n }\n }\n\n /**\n * Add plugins that can have different effects on Flicking\n * @ko 플리킹에 다양한 효과를 부여할 수 있는 플러그인을 추가합니다\n * @param {...Plugin} plugins The plugin(s) to add<ko>추가할 플러그인(들)</ko>\n * @return {this}\n * @see https://github.com/naver/egjs-flicking-plugins\n */\n public addPlugins(...plugins: Plugin[]) {\n if (this._initialized) {\n plugins.forEach(item => item.init(this));\n }\n\n this._plugins.push(...plugins);\n\n return this;\n }\n\n /**\n * Remove plugins from Flicking.\n * @ko 플리킹으로부터 플러그인들을 제거합니다.\n * @param {...Plugin} plugin The plugin(s) to remove.<ko>제거 플러그인(들).</ko>\n * @return {this}\n * @see https://github.com/naver/egjs-flicking-plugins\n */\n public removePlugins(...plugins: Plugin[]) {\n plugins.forEach(item => {\n const foundIndex = findIndex(this._plugins, val => val === item);\n\n if (foundIndex >= 0) {\n item.destroy();\n this._plugins.splice(foundIndex, 1);\n }\n });\n\n return this;\n }\n\n /**\n * Update viewport/panel sizes\n * @ko 패널 및 뷰포트의 크기를 갱신합니다\n * @method\n * @fires Flicking#beforeResize\n * @fires Flicking#afterResize\n * @return {this}\n */\n public async resize(): Promise<void> {\n const viewport = this._viewport;\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n const activePanel = control.activePanel;\n const prevWidth = viewport.width;\n const prevHeight = viewport.height;\n const prevProgressInPanel = activePanel\n ? camera.getProgressInPanel(activePanel)\n : 0;\n\n this.trigger(new ComponentEvent(EVENTS.BEFORE_RESIZE, {\n width: prevWidth,\n height: prevHeight,\n element: viewport.element\n }));\n\n viewport.resize();\n await renderer.forceRenderAllPanels(); // Render all panel elements, to update sizes\n renderer.updatePanelSize();\n camera.updateAlignPos();\n camera.updateRange();\n camera.updateAnchors();\n await renderer.render();\n\n if (control.animating) {\n // TODO:\n } else {\n control.updatePosition(prevProgressInPanel);\n control.updateInput();\n }\n\n const newWidth = viewport.width;\n const newHeight = viewport.height;\n const sizeChanged = newWidth !== prevWidth || newHeight !== prevHeight;\n\n this.trigger(new ComponentEvent(EVENTS.AFTER_RESIZE, {\n width: viewport.width,\n height: viewport.height,\n prev: {\n width: prevWidth,\n height: prevHeight\n },\n sizeChanged,\n element: viewport.element\n }));\n }\n\n /**\n * Add new panels after the last panel\n * @ko 패널 목록의 제일 끝에 새로운 패널들을 추가합니다\n * @param {ElementLike | ElementLike[]} element A new HTMLElement, a outerHTML of element, or an array of both\n * <ko>새로운 HTMLElement, 혹은 엘리먼트의 outerHTML, 혹은 그것들의 배열</ko>\n * @return {Panel[]} An array of appended panels<ko>추가된 패널들의 배열</ko>\n * @see Panel\n * @see ElementLike\n * @throws {FlickingError} {@link ERROR_CODE ERROR_CODE.NOT_ALLOWED_IN_FRAMEWORK} if called on frameworks (React, Angular, Vue...)\n * @example\n * ```ts\n * const flicking = new Flicking(\"#flick\");\n * // These are possible parameters\n * flicking.append(document.createElement(\"div\"));\n * flicking.append(\"\\<div\\>Panel\\</div\\>\");\n * flicking.append([\"\\<div\\>Panel\\</div\\>\", document.createElement(\"div\")]);\n * // Even this is possible\n * flicking.append(\"\\<div\\>Panel 1\\</div\\>\\<div\\>Panel 2\\</div\\>\");\n * ```\n */\n public append(element: ElementLike | ElementLike[]): Panel[] {\n return this.insert(this._renderer.panelCount, element);\n }\n\n /**\n * Add new panels before the first panel\n * This will increase index of panels after by the number of panels added\n * @ko 패널 목록의 제일 앞(index 0)에 새로운 패널들을 추가합니다\n * 추가한 패널의 개수만큼 기존 패널들의 인덱스가 증가합니다.\n * @param {ElementLike | ElementLike[]} element A new HTMLElement, a outerHTML of element, or an array of both\n * <ko>새로운 HTMLElement, 혹은 엘리먼트의 outerHTML, 혹은 그것들의 배열</ko>\n * @return {Panel[]} An array of prepended panels<ko>추가된 패널들의 배열</ko>\n * @see Panel\n * @see ElementLike\n * @throws {FlickingError} {@link ERROR_CODE ERROR_CODE.NOT_ALLOWED_IN_FRAMEWORK} if called on frameworks (React, Angular, Vue...)\n * @example\n * ```ts\n * const flicking = new eg.Flicking(\"#flick\");\n * flicking.prepend(document.createElement(\"div\"));\n * flicking.prepend(\"\\<div\\>Panel\\</div\\>\");\n * flicking.prepend([\"\\<div\\>Panel\\</div\\>\", document.createElement(\"div\")]);\n * // Even this is possible\n * flicking.prepend(\"\\<div\\>Panel 1\\</div\\>\\<div\\>Panel 2\\</div\\>\");\n * ```\n */\n public prepend(element: ElementLike | ElementLike[]): Panel[] {\n return this.insert(0, element);\n }\n\n /**\n * Insert new panels at given index\n * This will increase index of panels after by the number of panels added\n * @ko 주어진 인덱스에 새로운 패널들을 추가합니다\n * 해당 인덱스보다 같거나 큰 인덱스를 가진 기존 패널들은 추가한 패널의 개수만큼 인덱스가 증가합니다.\n * @param {number} index Index to insert new panels at<ko>새로 패널들을 추가할 인덱스</ko>\n * @param {ElementLike | ElementLike[]} element A new HTMLElement, a outerHTML of element, or an array of both\n * <ko>새로운 HTMLElement, 혹은 엘리먼트의 outerHTML, 혹은 그것들의 배열</ko>\n * @return {Panel[]} An array of prepended panels<ko>추가된 패널들의 배열</ko>\n * @throws {FlickingError} {@link ERROR_CODE ERROR_CODE.NOT_ALLOWED_IN_FRAMEWORK} if called on frameworks (React, Angular, Vue...)\n * @example\n * ```ts\n * const flicking = new eg.Flicking(\"#flick\");\n * flicking.insert(0, document.createElement(\"div\"));\n * flicking.insert(2, \"\\<div\\>Panel\\</div\\>\");\n * flicking.insert(1, [\"\\<div\\>Panel\\</div\\>\", document.createElement(\"div\")]);\n * // Even this is possible\n * flicking.insert(3, \"\\<div\\>Panel 1\\</div\\>\\<div\\>Panel 2\\</div\\>\");\n * ```\n */\n public insert(index: number, element: ElementLike | ElementLike[]): Panel[] {\n if (this._renderExternal) {\n throw new FlickingError(ERROR.MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, ERROR.CODE.NOT_ALLOWED_IN_FRAMEWORK);\n }\n\n return this._renderer.batchInsert({ index, elements: parseElement(element) });\n }\n\n /**\n * Remove the panel at the given index\n * This will decrease index of panels after by the number of panels removed\n * @ko 주어진 인덱스의 패널을 제거합니다\n * 해당 인덱스보다 큰 인덱스를 가진 기존 패널들은 제거한 패널의 개수만큼 인덱스가 감소합니다\n * @param {number} 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 {Panel[]} An array of removed panels<ko>제거된 패널들의 배열</ko>\n */\n public remove(index: number, deleteCount: number = 1): Panel[] {\n if (this._renderExternal) {\n throw new FlickingError(ERROR.MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, ERROR.CODE.NOT_ALLOWED_IN_FRAMEWORK);\n }\n\n return this._renderer.batchRemove({ index, deleteCount });\n }\n\n private _createControl(): Control {\n const moveType = this._moveType;\n const moveTypes = Object.keys(MOVE_TYPE).map(key => MOVE_TYPE[key] as ValueOf<typeof MOVE_TYPE>);\n\n const moveTypeStr = Array.isArray(moveType)\n ? moveType[0]\n : moveType;\n\n const moveTypeOptions = Array.isArray(moveType)\n ? moveType[1] ?? {}\n : {};\n\n if (!includes(moveTypes, moveTypeStr)) {\n throw new FlickingError(ERROR.MESSAGE.WRONG_OPTION(\"moveType\", JSON.stringify(moveType)), ERROR.CODE.WRONG_OPTION);\n }\n\n switch (moveTypeStr) {\n case MOVE_TYPE.SNAP:\n return new SnapControl(moveTypeOptions as SnapControlOptions);\n case MOVE_TYPE.FREE_SCROLL:\n return new FreeControl(moveTypeOptions as FreeControlOptions);\n case MOVE_TYPE.STRICT:\n return new StrictControl(moveTypeOptions as StrictControlOptions);\n }\n }\n\n private _createCamera(): Camera {\n const cameraOption = { align: this._align };\n\n if (this._circular) {\n if (this._bound) {\n // eslint-disable-next-line no-console\n console.warn(\"\\\"circular\\\" and \\\"bound\\\" option cannot be used together, ignoring bound.\");\n }\n return new CircularCamera(cameraOption);\n } else if (this._bound) {\n return new BoundCamera(cameraOption);\n } else {\n return new LinearCamera(cameraOption);\n }\n }\n\n private _createRenderer(): Renderer {\n const rendererOptions = {\n align: this._align\n };\n\n const renderExternal = this._renderExternal;\n\n return renderExternal\n ? new (renderExternal.renderer as any)({ ...rendererOptions, ...renderExternal.rendererOptions })\n : new VanillaRenderer(rendererOptions);\n }\n\n private async _moveToInitialPanel(): Promise<void> {\n const renderer = this._renderer;\n const control = this._control;\n const initialPanel = renderer.getPanel(this._defaultIndex) || renderer.getPanel(0);\n\n if (!initialPanel) return;\n\n control.setActive(initialPanel, null, false);\n\n return control.moveToPanel(initialPanel, {\n duration: 0\n });\n }\n}\n\nexport default Flicking;\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Panel, { PanelOptions } from \"./Panel\";\n\nexport interface ExternalPanelOptions<T> extends PanelOptions {\n externalComponent: T;\n}\n\n/**\n * An slide data component that holds information of a single HTMLElement\n * @ko 슬라이드 데이터 컴포넌트로, 단일 HTMLElement의 정보를 갖고 있습니다\n */\nabstract class ExternalPanel<T = any> extends Panel {\n protected _externalComponent: T;\n\n /**\n * @param {object} options An options object<ko>옵션 오브젝트</ko>\n * @param {HTMLElement} [options.el] A `HTMLElement` panel's referencing<ko>패널이 참조하는 `HTMLElement`</ko>\n * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>\n * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>\n * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>\n */\n public constructor(options: ExternalPanelOptions<T>) {\n super(options);\n\n this._externalComponent = options.externalComponent;\n }\n}\n\nexport default ExternalPanel;\n","import { DiffResult } from \"@egjs/list-differ\";\n\nimport Flicking from \"../Flicking\";\nimport Renderer from \"../renderer/Renderer\";\n\nexport default (flicking: Flicking, diffResult: DiffResult<any>, rendered: any[]) => {\n const renderer = flicking.renderer;\n const panels = renderer.panels;\n\n if (diffResult.removed.length > 0) {\n let endIdx = -1;\n let prevIdx = -1;\n\n diffResult.removed.forEach(removedIdx => {\n if (endIdx < 0) {\n endIdx = removedIdx;\n }\n\n if (prevIdx >= 0 && removedIdx !== prevIdx - 1) {\n batchRemove(renderer, prevIdx, endIdx + 1);\n\n endIdx = removedIdx;\n prevIdx = removedIdx;\n } else {\n prevIdx = removedIdx;\n }\n });\n\n batchRemove(renderer, prevIdx, endIdx + 1);\n }\n\n diffResult.ordered.forEach(([prevIdx, newIdx]) => {\n const prevPanel = panels[prevIdx];\n const indexDiff = newIdx - prevIdx;\n\n if (indexDiff > 0) {\n const middlePanels = panels.slice(prevIdx + 1, newIdx + 1);\n\n prevPanel.increaseIndex(indexDiff);\n middlePanels.forEach(panel => panel.decreaseIndex(1));\n } else {\n const middlePanels = panels.slice(newIdx, prevIdx);\n\n prevPanel.decreaseIndex(-indexDiff);\n middlePanels.forEach(panel => panel.increaseIndex(1));\n }\n // Update position\n prevPanel.resize();\n });\n\n if (diffResult.ordered.length > 0) {\n panels.sort((panel1, panel2) => panel1.index - panel2.index);\n }\n\n if (diffResult.added.length > 0) {\n let startIdx = -1;\n let prevIdx = -1;\n\n diffResult.added.forEach((addedIdx, idx) => {\n if (startIdx < 0) {\n startIdx = idx;\n }\n\n if (prevIdx >= 0 && addedIdx !== prevIdx + 1) {\n batchInsert(renderer, diffResult, rendered, startIdx, idx + 1);\n\n startIdx = -1;\n prevIdx = -1;\n } else {\n prevIdx = addedIdx;\n }\n });\n\n if (startIdx >= 0) {\n batchInsert(renderer, diffResult, rendered, startIdx);\n }\n }\n};\n\nconst batchInsert = (renderer: Renderer, diffResult: DiffResult<any>, rendered: any[], startIdx: number, endIdx?: number) => {\n renderer.batchInsert(\n ...diffResult.added.slice(startIdx, endIdx).map((index, elIdx) => ({ index, elements: [rendered[elIdx + diffResult.prevList.length]] }))\n );\n};\n\nconst batchRemove = (renderer: Renderer, startIdx: number, endIdx?: number) => {\n const removed = renderer.panels.slice(startIdx, endIdx);\n\n renderer.batchRemove({ index: startIdx, deleteCount: removed.length });\n};\n\n","import { FlickingOptions } from \"../Flicking\";\nimport { ALIGN } from \"../const/external\";\nimport { parseArithmeticExpression } from \"../utils\";\n\nexport default (align: FlickingOptions[\"align\"] = ALIGN.CENTER, horizontal: boolean = true, firstPanelSize?: string) => {\n const cameraAlign = getCameraAlign(align);\n const panelAlign = getPanelAlign(align);\n\n if (panelAlign == null) return \"\";\n\n const camPosition = `calc(${cameraAlign} - (${firstPanelSize || \"0px\"} * ${panelAlign.percentage}) - ${panelAlign.absolute}px)`;\n\n return horizontal\n ? `translate(${camPosition})`\n : `translate(0, ${camPosition})`;\n};\n\nconst getCameraAlign = (align: FlickingOptions[\"align\"]) => {\n const alignVal = typeof align === \"object\"\n ? (align as { camera: string | number }).camera\n : align;\n\n return parseAlign(alignVal);\n};\n\nconst getPanelAlign = (align: FlickingOptions[\"align\"]) => {\n const alignVal = typeof align === \"object\"\n ? (align as { panel: string | number }).panel\n : align;\n\n return parseArithmeticExpression(parseAlign(alignVal));\n};\n\nconst parseAlign = (alignVal: number | string) => {\n if (typeof alignVal === \"number\") {\n return `${alignVal}px`;\n }\n\n switch (alignVal) {\n case ALIGN.CENTER:\n return \"50%\";\n case ALIGN.NEXT:\n return \"100%\";\n case ALIGN.PREV:\n return \"0%\";\n default:\n return alignVal;\n }\n};\n","import Component from \"@egjs/component\";\n\nimport Flicking from \"../Flicking\";\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 */\nconst withFlickingMethods = (prototype: any, flickingName: string) => {\n [Component.prototype, Flicking.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto).filter(name => !prototype[name] && !name.startsWith(\"_\") && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[flickingName], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return descriptor.get?.call(this[flickingName]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[flickingName], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withFlickingMethods;\n","import { DiffResult } from \"@egjs/list-differ\";\n\nimport Flicking from \"../Flicking\";\n\nexport default <T>(flicking: Flicking, diffResult: DiffResult<T>) => {\n const removedPanels = diffResult.removed.reduce((map, idx) => {\n map[idx] = true;\n return map;\n }, {});\n\n const maintainedMap = diffResult.maintained.reduce((map, [prev, current]) => {\n map[prev] = current;\n return map;\n }, {});\n\n return [\n ...flicking.panels\n .filter(panel => !removedPanels[panel.index])\n // Sort panels by position\n .sort((panel1, panel2) => (panel1.position + panel1.offset) - (panel2.position + panel2.offset))\n .map(panel => diffResult.list[maintainedMap[panel.index]]),\n ...diffResult.added.map(idx => diffResult.list[idx])\n ];\n};\n\n","/*\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Flicking from \"./Flicking\";\nimport * as Core from \"./core\";\nimport * as Camera from \"./camera\";\nimport * as Control from \"./control\";\nimport * as Renderer from \"./renderer\";\nimport * as Constants from \"./const/external\";\nimport * as CFC from \"./cfc\";\nimport { merge } from \"./utils\";\n\nmerge(Flicking, Core);\nmerge(Flicking, Camera);\nmerge(Flicking, Control);\nmerge(Flicking, Renderer);\nmerge(Flicking, Constants);\nmerge(Flicking, CFC);\n\nexport default Flicking;\n"],"names":["merge","target","_i","sources","forEach","source","Object","keys","key","getFlickingAttached","val","nameToThrowOnError","FlickingError","ERROR","NOT_ATTACHED_TO_FLICKING","toArray","iterable","slice","call","parseAlign","align","size","alignPoint","isString","ALIGN","PREV","CENTER","NEXT","parseArithmeticSize","WRONG_OPTION","cssValue","base","parsed","parseArithmeticExpression","percentage","absolute","getDirection","start","end","DIRECTION","NONE","parseElement","element","Array","isArray","elements","el","tempDiv","document","createElement","innerHTML","push","children","firstChild","removeChild","nodeType","Node","ELEMENT_NODE","WRONG_TYPE","getMinusCompensatedIndex","idx","max","clamp","includes","array","array_1","__values","circulatePosition","pos","min","getProgress","prev","next","getStyle","window","getComputedStyle","currentStyle","isBetween","CODE","ELEMENT_NOT_FOUND","VAL_MUST_NOT_NULL","INDEX_OUT_OF_RANGE","POSITION_NOT_REACHABLE","TRANSFORM_NOT_SUPPORTED","STOP_CALLED_BY_USER","ANIMATION_INTERRUPTED","ANIMATION_ALREADY_PLAYING","NOT_ALLOWED_IN_FRAMEWORK","NOT_INITIALIZED","NO_ACTIVE","MESSAGE","wrongVal","correctTypes","map","type","join","selector","name","optionName","position","EVENTS","READY","BEFORE_RESIZE","AFTER_RESIZE","HOLD_START","HOLD_END","MOVE_START","MOVE","MOVE_END","WILL_CHANGE","CHANGED","WILL_RESTORE","RESTORED","SELECT","NEED_PANEL","VISIBLE_CHANGE","REACH_EDGE","PANEL_CHANGE","MOVE_TYPE","SNAP","FREE_SCROLL","STRICT","x","Math","cssRegex","matchResult","exec","sign","value","unit","parsedValue","parseFloat","signMultiplier","setPrototypeOf","obj","proto","__proto__","__extends","Error","message","code","_super","_this","prototype","this","_el","_width","_padding","left","right","_height","top","bottom","_a","width","height","padding","isBorderBoxSizing","_isBorderBoxSizing","style","newWidth","newHeight","resize","elStyle","clientWidth","clientHeight","paddingLeft","paddingRight","paddingTop","paddingBottom","boxSizing","STATE_TYPE","EVENT","HOLD","CHANGE","RELEASE","ANIMATION_END","FINISH","POSITION_KEY","_delta","_targetPanel","prevState","ctx","camera","flicking","axesEvent","transitTo","delta","AXES","prevPosition","newPosition","circularEnabled","range","lookAt","moveEvent","ComponentEvent","isTrusted","holding","direction","trigger","isCanceled","DISABLED","renderer","panelCount","holdStartEvent","HOLDING","animatingContext","control","controller","moveStartEvent","ANIMATING","onChange","State","inputEvent","offset","horizontal","offsetX","offsetY","DRAGGING","flick","setTo","IDLE","_releaseEvent","clickedElement","srcEvent","touch","changedTouches","elementFromPoint","clientX","clientY","cameraPosition","clickedPanelPosition","panels","clickedPanel","panels_1","panel","contains","index","_moveToChangedPosition","destPos","duration","moveToPosition","updateInput","setActive","activePanel","stop","_state","eventType","externalCtx","currentState","onHold","onRelease","onAnimationEnd","onFinish","nextStateType","nextState","IdleState","HoldingState","DraggingState","AnimatingState","DisabledState","onEnter","_axes","_stateMachine","state","_animatingContext","axes","circular","axis","_panInput","isEnable","get","bounce","_flicking","Axes","deceleration","interruptable","easing","PanInput","viewport","inputType","iOSEdgeSwipeThreshold","scale","releaseOnScroll","connect","on","e","fire","removePreventClickHandler","destroy","_resetInternalValues","enable","disable","controlParams","parsedVal","axm","set","cameraEl","_onAxesHold","_onAxesChange","addEventListener","_preventClickWhenDragged","off","removeEventListener","Promise","reject","startPos","resolve","animate","once","interruptionHandler","animationFinishHandler","newPos","_dragged","preventDefault","stopPropagation","StateMachine","_controller","_activePanel","animating","init","_progressInPanel","clampToReachablePosition","update","_b","nearestAnchor","findNearestAnchor","removed","canReach","camPos_1","camRangeDiff","rangeDiff","filter","reduce","nearestPosition","abs","Infinity","_triggerIndexChangeEvent","_animateToPosition","newActivePanel","prevActivePanel","updateAdaptiveHeight","prevIndex","prevPanel","triggeringEvent","event","animateTo","targetPanel","then","render","catch","err","AxesController","_index","_pos","_panel","_c","count","_count","activeAnchor","findActiveAnchor","anchorAtCamera","snapThreshold","_calcSnapThreshold","posDelta","absPosDelta","snapDelta","targetAnchor","_findSnappedAnchor","threshold","_findAdjacentAnchor","currentPos","clampedPosition","anchorAtPosition","findAnchorIncludePosition","isFinite","anchors","anchorPoints","loopCount","floor","anchorAtPositionIndex","anchor","AnchorPoint","loop","length","getNextAnchor","getPrevAnchor","isNextDirection","panelSize","alignPos","alignPosition","margin","Control","stopAtEdge","_stopAtEdge","progressInPanel","panelRange","targetPos","_resetIndexRange","cameraRange","currentIndex","prevPanelIndex","nextPanelIndex","nextPanel","prevPos","nextPos","_indexRange","axesRange","indexRange","isOverThreshold","adjacentAnchor","firstAnchor","lastAnchor","shouldBounceToFirst","shouldBounceToLast","_position","_alignPos","_offset","_range","_visiblePanels","_anchors","NaN","nearestPanel","panelPos","bounceSize","prevRange","nextRange","nextPosition","_align","viewportEl","nameOnErrMsg","checkExistence","firstElementChild","_checkTranslateSupport","_refreshVisiblePanels","_checkNeedPanel","_checkReachEnd","_applyTransform","includePosition","nearest","prevDist","anchorIdx","dist","activeIndex","checker","array_2","find","visibleRange","includeRange","alignVal","adaptive","setSize","unRenderedPanels","rendered","sizeIncludingMargin","_needPanelTriggered","newVisiblePanels","canSee","prevVisiblePanels","added","visiblePanels","needPanelTriggered","cameraSize","needPanelThreshold","cameraPrev","cameraNext","firstPanel","lastPanel","wasBetweenRange","isBetweenRange","actualPosition","_transform","supportedStyle","documentElement","transformName","transforms_1","prefixedTransform","Camera","getPanel","_circularOffset","_circularEnabled","positionInRange","anchorInRange","visibleInCurrentRange","firstPanelPrev","lastPanelNext","visibleSize","panelSizeSum","canSetCircularMode","every","updateCircularToggleDirection","_updateCircularOffset","toggled","toggle","some","isToggled","sum","toggledPrev","toggledNext","toggleDirection","_calcPanelAreaSum","viewportSize","firstPos","lastPos","shouldPrependBoundAnchor","shouldAppendBoundAnchor","indexOffset_1","panelAtMin","reachablePanels","newAnchors","splice","panelAtMax","nearestPanelAtMin","_findNearestPanel","panelIdx","_panels","panelAlign","_getPanelAlign","_collectPanels","panelsPerView","_updatePanelSizeByGrid","items","allPanelsInserted","addedPanels","item","insertingIdx","panelsPushed","panelsInserted","_createPanel","_insertPanelElements","increaseIndex","updatePosition","_updateCameraAndControl","moveToPanel","updateOffset","checkPanelContentsReady","allPanelsRemoved","deleteCount","removingIdx","panelsPulled","panelsRemoved","decreaseIndex","_removePanelElements","resetActive","checkingPanels","contentsReadyChecker","resizeOnContentsReady","querySelector","ImReady","loading","prevProgressInPanel","getProgressInPanel","panelBehind","initialized","updateRange","updateAnchors","readyCount","totalCount","check","resetNeedPanelHistory","renderOnlyVisible","_showOnlyVisiblePanels","markForShow","visibleIndexes","visibles","markForHide","panelSizeObj","firstPanelSizeObj","noPanelStyleOverride","_size","_margin","_removed","_loading","_toggled","_toggleDirection","cameraRangeDiff","progress","camPos","disappearPosNext","disappearPosPrev","checkingRange","cached","offsetWidth","offsetHeight","marginLeft","marginRight","marginTop","marginBottom","_updateAlignPos","_resetInternalStates","includeMargin","moveTo","togglePosition","_togglePosition","prevToggled","camRange","camAlignPosition","camVisibleRange","camVisibleSize","minimumVisible","maximumVisible","shouldBeVisibleAtMin","shouldBeVisibleAtMax","options","_rendered","Panel","wasRenderedPanels","parentElement","_updateRenderingPanels","renderingPanels","_getRenderingPanelsByOrder","_resetPanelElementOrder","cameraElement","fragment","createDocumentFragment","appendChild","_removeAllChildsFromCamera","childNodes","node","TEXT_NODE","cameraChilds","ElementPanel","nextSibling","nextSiblingElement","insertBefore","reversedPanels","__spreadArray","reverse","nextPanelEl","nextElementSibling","sort","a","b","Renderer","root","_d","defaultIndex","_e","_f","_g","bound","_h","_j","_k","_l","_m","_o","preventEventsBeforeInit","_p","_q","_r","pow","_s","_t","moveType","_u","_v","_w","_x","_y","preventClickOnDrag","_z","disableOnInit","_0","_1","autoInit","_2","autoResize","_3","renderExternal","_initialized","_plugins","_defaultIndex","_horizontal","_circular","_bound","_adaptive","_panelsPerView","_noPanelStyleOverride","_resizeOnContentsReady","_needPanelThreshold","_preventEventsBeforeInit","_deceleration","_duration","_easing","_inputType","_moveType","_threshold","_interruptable","_bounce","_iOSEdgeSwipeThreshold","_preventClickOnDrag","_disableOnInit","_renderOnlyVisible","_autoResize","_autoInit","_renderExternal","_viewport","Viewport","parent","targetEl","queryResult","getElement","_renderer","_createRenderer","_camera","_createCamera","_control","_createControl","bind","addPreventClickHandler","originalTrigger","_moveToInitialPanel","disableInput","plugin","includePanelHTML","visiblePanelsOnly","status","panelInfo","html","outerHTML","visibleOffset","batchRemove","batchInsert","newCameraPos","plugins","foundIndex","findIndex","prevWidth","prevHeight","forceRenderAllPanels","updatePanelSize","updateAlignPos","sizeChanged","insert","moveTypes","moveTypeStr","moveTypeOptions","JSON","stringify","SnapControl","FreeControl","StrictControl","cameraOption","console","warn","CircularCamera","BoundCamera","LinearCamera","rendererOptions","VanillaRenderer","initialPanel","Flicking","Component","_externalComponent","externalComponent","diffResult","startIdx","endIdx","elIdx","prevList","flickingName","getOwnPropertyNames","startsWith","getterDescriptor","descriptor","getOwnPropertyDescriptor","defineProperty","args","endIdx_1","prevIdx_1","startIdx_1","prevIdx_2","removedIdx","ordered","middlePanels","__read","prevIdx","newIdx","indexDiff","panel1","panel2","addedIdx","removedPanels","maintainedMap","maintained","current","list","firstPanelSize","cameraAlign","camPosition","Constants","CFC"],"mappings":"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"}
\No newline at end of file