diff --git a/.gitignore b/.gitignore
index 0340ad986..24faf6df0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -223,4 +223,4 @@ demo/_data/version.yml
outjs/
declaration/
-dist/
+
diff --git a/dist/flicking-inline.css b/dist/flicking-inline.css
new file mode 100644
index 000000000..ac0a4ee31
--- /dev/null
+++ b/dist/flicking-inline.css
@@ -0,0 +1,45 @@
+.flicking-viewport {
+ position: relative;
+ overflow: hidden;
+}
+
+.flicking-viewport:not(.vertical) {
+ width: 100%;
+ height: 100%;
+}
+
+.flicking-viewport.vertical,
+.flicking-viewport.vertical > .flicking-camera {
+ display: inline-block;
+}
+
+.flicking-viewport.vertical.middle > .flicking-camera > * {
+ vertical-align: middle;
+}
+
+.flicking-viewport.vertical.bottom > .flicking-camera > * {
+ vertical-align: bottom;
+}
+
+.flicking-viewport.vertical > .flicking-camera > * {
+ display: block;
+}
+
+.flicking-viewport.flicking-hidden > .flicking-camera > * {
+ visibility: hidden;
+}
+
+.flicking-camera {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ z-index: 1;
+ white-space: nowrap;
+ will-change: transform;
+}
+
+.flicking-camera > * {
+ display: inline-block;
+ white-space: normal;
+ vertical-align: top;
+}
diff --git a/dist/flicking-inline.min.css b/dist/flicking-inline.min.css
new file mode 100644
index 000000000..8fc4674ab
--- /dev/null
+++ b/dist/flicking-inline.min.css
@@ -0,0 +1 @@
+.flicking-viewport{position:relative;overflow:hidden}.flicking-viewport:not(.vertical){width:100%;height:100%}.flicking-viewport.vertical,.flicking-viewport.vertical>.flicking-camera{display:inline-block}.flicking-viewport.vertical.middle>.flicking-camera>*{vertical-align:middle}.flicking-viewport.vertical.bottom>.flicking-camera>*{vertical-align:bottom}.flicking-viewport.vertical>.flicking-camera>*{display:block}.flicking-viewport.flicking-hidden>.flicking-camera>*{visibility:hidden}.flicking-camera{width:100%;height:100%;position:relative;z-index:1;white-space:nowrap;will-change:transform}.flicking-camera>*{display:inline-block;white-space:normal;vertical-align:top}
\ No newline at end of file
diff --git a/dist/flicking.cjs.js b/dist/flicking.cjs.js
new file mode 100644
index 000000000..7cb5bbbc6
--- /dev/null
+++ b/dist/flicking.cjs.js
@@ -0,0 +1,8204 @@
+/*
+Copyright (c) 2015-present NAVER Corp.
+name: @egjs/flicking
+license: MIT
+author: NAVER Corp.
+repository: https://github.com/naver/egjs-flicking
+version: 4.11.3
+*/
+'use strict';
+
+var Component = require('@egjs/component');
+var Axes = require('@egjs/axes');
+var ImReady = require('@egjs/imready');
+
+/******************************************************************************
+Copyright (c) Microsoft Corporation.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+***************************************************************************** */
+/* global Reflect, Promise, SuppressedError, Symbol */
+
+var extendStatics = function (d, b) {
+ extendStatics = Object.setPrototypeOf || {
+ __proto__: []
+ } instanceof Array && function (d, b) {
+ d.__proto__ = b;
+ } || function (d, b) {
+ for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
+ };
+ return extendStatics(d, b);
+};
+function __extends(d, b) {
+ if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
+ extendStatics(d, b);
+ function __() {
+ this.constructor = d;
+ }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+}
+var __assign = function () {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+function __awaiter(thisArg, _arguments, P, generator) {
+ function adopt(value) {
+ return value instanceof P ? value : new P(function (resolve) {
+ resolve(value);
+ });
+ }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) {
+ try {
+ step(generator.next(value));
+ } catch (e) {
+ reject(e);
+ }
+ }
+ function rejected(value) {
+ try {
+ step(generator["throw"](value));
+ } catch (e) {
+ reject(e);
+ }
+ }
+ function step(result) {
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
+ }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+}
+function __generator(thisArg, body) {
+ var _ = {
+ label: 0,
+ sent: function () {
+ if (t[0] & 1) throw t[1];
+ return t[1];
+ },
+ trys: [],
+ ops: []
+ },
+ f,
+ y,
+ t,
+ g;
+ return g = {
+ next: verb(0),
+ "throw": verb(1),
+ "return": verb(2)
+ }, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
+ return this;
+ }), g;
+ function verb(n) {
+ return function (v) {
+ return step([n, v]);
+ };
+ }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0:
+ case 1:
+ t = op;
+ break;
+ case 4:
+ _.label++;
+ return {
+ value: op[1],
+ done: false
+ };
+ case 5:
+ _.label++;
+ y = op[1];
+ op = [0];
+ continue;
+ case 7:
+ op = _.ops.pop();
+ _.trys.pop();
+ continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
+ _ = 0;
+ continue;
+ }
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
+ _.label = op[1];
+ break;
+ }
+ if (op[0] === 6 && _.label < t[1]) {
+ _.label = t[1];
+ t = op;
+ break;
+ }
+ if (t && _.label < t[2]) {
+ _.label = t[2];
+ _.ops.push(op);
+ break;
+ }
+ if (t[2]) _.ops.pop();
+ _.trys.pop();
+ continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) {
+ op = [6, e];
+ y = 0;
+ } finally {
+ f = t = 0;
+ }
+ if (op[0] & 5) throw op[1];
+ return {
+ value: op[0] ? op[1] : void 0,
+ done: true
+ };
+ }
+}
+function __values(o) {
+ var s = typeof Symbol === "function" && Symbol.iterator,
+ m = s && o[s],
+ i = 0;
+ if (m) return m.call(o);
+ if (o && typeof o.length === "number") return {
+ next: function () {
+ if (o && i >= o.length) o = void 0;
+ return {
+ value: o && o[i++],
+ done: !o
+ };
+ }
+ };
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
+}
+function __read(o, n) {
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
+ if (!m) return o;
+ var i = m.call(o),
+ r,
+ ar = [],
+ e;
+ try {
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
+ } catch (error) {
+ e = {
+ error: error
+ };
+ } finally {
+ try {
+ if (r && !r.done && (m = i["return"])) m.call(i);
+ } finally {
+ if (e) throw e.error;
+ }
+ }
+ return ar;
+}
+
+/** @deprecated */
+function __spread() {
+ for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
+ return ar;
+}
+typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
+ var e = new Error(message);
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
+};
+
+/*
+ * Copyright (c) 2015 NAVER Corp.
+ * egjs projects are licensed under the MIT license
+ */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/**
+ * Error codes of {@link FlickingError}. Below are the conditions where each error code occurs.
+ * @ko {@link FlickingError}의 에러 코드. 아래는 각각의 에러 코드가 발생하는 조건입니다.
+ * @name ERROR_CODE
+ * @constant
+ * @type object
+ * @property {number} WRONG_TYPE Parameter type is wrong패러미터의 타입이 잘못되었을 경우
+ * @property {number} ELEMENT_NOT_FOUND Element is not found inside page with the given CSS selector주어진 CSS selector로 페이지 내에서 해당 엘리먼트를 찾지 못했을 경우
+ * @property {number} VAL_MUST_NOT_NULL Expected non-null value, but given `null` or `undefined`값을 기대했으나, `null`이나 `undefined`를 받은 경우
+ * @property {number} NOT_ATTACHED_TO_FLICKING When Flicking's component is not initialized (i.e. {@link Flicking#init} is not called)Flicking 내부 컴포넌트가 초기화되지 않은 경우 ({@link Flicking#init}이 호출되지 않은 경우)
+ * @property {number} WRONG_OPTION One of the options is wrong옵션들 중 잘못된 값이 있을 때
+ * @property {number} INDEX_OUT_OF_RANGE When the given index is out of possible range인덱스가 주어진 범위를 벗어난 경우
+ * @property {number} POSITION_NOT_REACHABLE When {@link Control#moveToPosition}'s position parameter is out of possible range.{@link Control#moveToPosition}의 `position` 패러미터가 도달 가능한 범위를 벗어난 경우
+ * @property {number} TRANSFORM_NOT_SUPPORTED CSS `transform` property is not available(<=IE8) CSS `transform` 속성을 사용할 수 없는 경우(<=IE8)
+ * @property {number} STOP_CALLED_BY_USER When the event's `stop()` is called by user.사용자에 의해 이벤트의 `stop()`이 호출된 경우
+ * @property {number} ANIMATION_INTERRUPTED When the animation is interrupted by user.사용자에 의해 애니메이션이 중단된 경우
+ * @property {number} ANIMATION_ALREADY_PLAYING When the animation is already playing.현재 애니메이션이 이미 진행중인 경우
+ * @property {number} NOT_ALLOWED_IN_FRAMEWORK When the non-allowed method is called from frameworks (React, Angular, Vue...)
+ * 프레임워크(React, Angular, Vue ...)에서 사용 불가능한 메소드를 호출했을 경우
+ * @property {number} NOT_INITIALIZED When the {@link Flicking#init} is not called before but is needed{@link Flicking#init}의 호출이 필요하나, 아직 호출되지 않았을 경우
+ * @property {number} NO_ACTIVE When there're no active panel that flicking has selected. This may be due to the absence of any panels현재 Flicking이 선택한 패널이 없을 경우. 일반적으로 패널이 하나도 없는 경우에 발생할 수 있습니다
+ * @property {number} NOT_ALLOWED_IN_VIRTUAL When the non-allowed method is called while the virtual option is enabledvirtual 옵션이 활성화된 상태에서 사용 불가능한 메소드가 호출되었을 경우
+ */
+var CODE = {
+ WRONG_TYPE: 0,
+ ELEMENT_NOT_FOUND: 1,
+ VAL_MUST_NOT_NULL: 2,
+ NOT_ATTACHED_TO_FLICKING: 3,
+ WRONG_OPTION: 4,
+ INDEX_OUT_OF_RANGE: 5,
+ POSITION_NOT_REACHABLE: 6,
+ TRANSFORM_NOT_SUPPORTED: 7,
+ STOP_CALLED_BY_USER: 8,
+ ANIMATION_INTERRUPTED: 9,
+ ANIMATION_ALREADY_PLAYING: 10,
+ NOT_ALLOWED_IN_FRAMEWORK: 11,
+ NOT_INITIALIZED: 12,
+ NO_ACTIVE: 13,
+ NOT_ALLOWED_IN_VIRTUAL: 14
+};
+var MESSAGE = {
+ WRONG_TYPE: function (wrongVal, correctTypes) {
+ return wrongVal + "(" + typeof wrongVal + ") is not a " + correctTypes.map(function (type) {
+ return "\"" + type + "\"";
+ }).join(" or ") + ".";
+ },
+ ELEMENT_NOT_FOUND: function (selector) {
+ return "Element with selector \"" + selector + "\" not found.";
+ },
+ VAL_MUST_NOT_NULL: function (val, name) {
+ return name + " should be provided. Given: " + val;
+ },
+ NOT_ATTACHED_TO_FLICKING: "This module is not attached to the Flicking instance. \"init()\" should be called first.",
+ WRONG_OPTION: function (optionName, val) {
+ return "Option \"" + optionName + "\" is not in correct format, given: " + val;
+ },
+ INDEX_OUT_OF_RANGE: function (val, min, max) {
+ return "Index \"" + val + "\" is out of range: should be between " + min + " and " + max + ".";
+ },
+ POSITION_NOT_REACHABLE: function (position) {
+ return "Position \"" + position + "\" is not reachable.";
+ },
+ TRANSFORM_NOT_SUPPORTED: "Browser does not support CSS transform.",
+ STOP_CALLED_BY_USER: "Event stop() is called by user.",
+ ANIMATION_INTERRUPTED: "Animation is interrupted by user input.",
+ ANIMATION_ALREADY_PLAYING: "Animation is already playing.",
+ NOT_ALLOWED_IN_FRAMEWORK: "This behavior is not allowed in the frameworks like React, Vue, or Angular.",
+ NOT_INITIALIZED: "Flicking is not initialized yet, call init() first.",
+ NO_ACTIVE: "There's no active panel that Flicking has selected. This may be due to the absence of any panels.",
+ NOT_ALLOWED_IN_VIRTUAL: "This behavior is not allowed when the virtual option is enabled"
+};
+
+/*
+ * Copyright (c) 2015 NAVER Corp.
+ * egjs projects are licensed under the MIT license
+ */
+/**
+ * Event type object with event name strings of {@link Flicking}
+ * @ko {@link Flicking}의 이벤트 이름 문자열들을 담은 객체
+ * @type {object}
+ * @property {"holdStart"} HOLD_START holdStart eventholdStart 이벤트
+ * @property {"holdEnd"} HOLD_END holdEnd eventholdEnd 이벤트
+ * @property {"moveStart"} MOVE_START moveStart eventmoveStart 이벤트
+ * @property {"move"} MOVE move eventmove 이벤트
+ * @property {"moveEnd"} MOVE_END moveEnd eventmoveEnd 이벤트
+ * @property {"willChange"} WILL_CHANGE willChange eventwillChange 이벤트
+ * @property {"changed"} CHANGED changed eventchanged 이벤트
+ * @property {"willRestore"} WILL_RESTORE willRestore eventwillRestore 이벤트
+ * @property {"restored"} RESTORED restored eventrestored 이벤트
+ * @property {"select"} SELECT select eventselect 이벤트
+ * @property {"needPanel"} NEED_PANEL needPanel eventneedPanel 이벤트
+ * @property {"panelChange"} PANEL_CHANGE panelChange eventpanelChange 이벤트
+ * @example
+ * ```ts
+ * import { EVENTS } from "@egjs/flicking";
+ * EVENTS.MOVE_START; // "moveStart"
+ * ```
+ */
+var EVENTS = {
+ READY: "ready",
+ BEFORE_RESIZE: "beforeResize",
+ AFTER_RESIZE: "afterResize",
+ HOLD_START: "holdStart",
+ HOLD_END: "holdEnd",
+ MOVE_START: "moveStart",
+ MOVE: "move",
+ MOVE_END: "moveEnd",
+ WILL_CHANGE: "willChange",
+ CHANGED: "changed",
+ WILL_RESTORE: "willRestore",
+ RESTORED: "restored",
+ SELECT: "select",
+ NEED_PANEL: "needPanel",
+ VISIBLE_CHANGE: "visibleChange",
+ REACH_EDGE: "reachEdge",
+ PANEL_CHANGE: "panelChange"
+};
+/**
+ * An object with all possible predefined literal string for the {@link Flicking#align align} option
+ * @ko {@link Flicking#align align} 옵션에 사용되는 미리 정의된 리터럴 상수들을 담고 있는 객체
+ * @type {object}
+ * @property {"prev"} PREV left/top align좌/상 정렬
+ * @property {"center"} CENTER center align중앙 정렬
+ * @property {"next"} NEXT right/bottom align우/하 정렬
+ */
+var ALIGN = {
+ PREV: "prev",
+ CENTER: "center",
+ NEXT: "next"
+};
+/**
+ * An object of directions
+ * @ko 방향을 나타내는 값들을 담고 있는 객체
+ * @type {object}
+ * @property {"PREV"} PREV "left" when {@link Flicking#horizontal horizontal} is true, and "top" when {@link Flicking#horizontal horizontal} is false
+ * {@link Flicking#horizontal horizontal}가 `true`일 경우 왼쪽, {@link Flicking#horizontal horizontal}가 `false`일 경우 위쪽을 의미합니다
+ * @property {"NEXT"} NEXT "right" when {@link Flicking#horizontal horizontal} is true, and "bottom" when {@link Flicking#horizontal horizontal} is false
+ * {@link Flicking#horizontal horizontal}가 `true`일 경우 오른쪽, {@link Flicking#horizontal horizontal}가 `false`일 경우 아래쪽을 의미합니다
+ * @property {null} NONE This value usually means it's the same position주로 제자리인 경우를 의미합니다
+ */
+var DIRECTION = {
+ PREV: "PREV",
+ NEXT: "NEXT",
+ NONE: null
+};
+/**
+ * An object with all possible {@link Flicking#moveType moveType}s
+ * @ko Flicking이 제공하는 {@link Flicking#moveType moveType}들을 담고 있는 객체
+ * @type {object}
+ * @property {"snap"} SNAP Flicking's {@link Flicking#moveType moveType} that enables {@link SnapControl} as a Flicking's {@link Flicking#control control}
+ * Flicking의 {@link Flicking#control control}을 {@link SnapControl}로 설정하게 하는 {@link Flicking#moveType moveType}
+ * @property {"freeScroll"} FREE_SCROLL Flicking's {@link Flicking#moveType moveType} that enables {@link FreeControl} as a Flicking's {@link Flicking#control control}
+ * Flicking의 {@link Flicking#control control}을 {@link FreeControl}로 설정하게 하는 {@link Flicking#moveType moveType}
+ * @property {"strict"} STRICT Flicking's {@link Flicking#moveType moveType} that enables {@link StrictControl} as a Flicking's {@link Flicking#control control}
+ * Flicking의 {@link Flicking#control control}을 {@link StrictControl}로 설정하게 하는 {@link Flicking#moveType moveType}
+ */
+var MOVE_TYPE = {
+ SNAP: "snap",
+ FREE_SCROLL: "freeScroll",
+ STRICT: "strict"
+};
+var CLASS = {
+ VERTICAL: "vertical",
+ HIDDEN: "flicking-hidden",
+ DEFAULT_VIRTUAL: "flicking-panel"
+};
+/**
+ * An object with all possible {@link Flicking#circularFallback circularFallback}s
+ * @ko Flicking의 {@link Flicking#circularFallback circularFallback}에 설정 가능한 값들을 담고 있는 객체
+ * @type {object}
+ * @property {string} LINEAR "linear"
+ * @property {string} BOUND "bound"
+ */
+var CIRCULAR_FALLBACK = {
+ LINEAR: "linear",
+ BOUND: "bound"
+};
+/**
+ * An object for identifying {@link https://developer.mozilla.org/en-US/docs/Web/CSS/direction direction} CSS property applied to the camera element(`.flicking-camera`)
+ * @ko 카메라 엘리먼트(`.flicking-camera`)에 적용된 {@link https://developer.mozilla.org/en-US/docs/Web/CSS/direction direction} CSS 속성을 구분하기 위한 객체
+ * @type {object}
+ * @property {string} LTR "ltr"
+ * @property {string} RTL "rtl"
+ */
+var ORDER = {
+ LTR: "ltr",
+ RTL: "rtl"
+};
+
+// eslint-disable-next-line @typescript-eslint/ban-types
+var merge = function (target) {
+ var sources = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ sources[_i - 1] = arguments[_i];
+ }
+ sources.forEach(function (source) {
+ Object.keys(source).forEach(function (key) {
+ target[key] = source[key];
+ });
+ });
+ return target;
+};
+var getElement = function (el, parent) {
+ var targetEl = null;
+ if (isString(el)) {
+ var parentEl = parent ? parent : document;
+ var queryResult = parentEl.querySelector(el);
+ if (!queryResult) {
+ throw new FlickingError(MESSAGE.ELEMENT_NOT_FOUND(el), CODE.ELEMENT_NOT_FOUND);
+ }
+ targetEl = queryResult;
+ } else if (el && el.nodeType === Node.ELEMENT_NODE) {
+ targetEl = el;
+ }
+ if (!targetEl) {
+ throw new FlickingError(MESSAGE.WRONG_TYPE(el, ["HTMLElement", "string"]), CODE.WRONG_TYPE);
+ }
+ return targetEl;
+};
+var checkExistence = function (value, nameOnErrMsg) {
+ if (value == null) {
+ throw new FlickingError(MESSAGE.VAL_MUST_NOT_NULL(value, nameOnErrMsg), CODE.VAL_MUST_NOT_NULL);
+ }
+};
+var clamp = function (x, min, max) {
+ return Math.max(Math.min(x, max), min);
+};
+var getFlickingAttached = function (val) {
+ if (!val) {
+ throw new FlickingError(MESSAGE.NOT_ATTACHED_TO_FLICKING, CODE.NOT_ATTACHED_TO_FLICKING);
+ }
+ return val;
+};
+var toArray = function (iterable) {
+ return [].slice.call(iterable);
+};
+var parseAlign$1 = function (align, size) {
+ var alignPoint;
+ if (isString(align)) {
+ switch (align) {
+ case ALIGN.PREV:
+ alignPoint = 0;
+ break;
+ case ALIGN.CENTER:
+ alignPoint = 0.5 * size;
+ break;
+ case ALIGN.NEXT:
+ alignPoint = size;
+ break;
+ default:
+ alignPoint = parseArithmeticSize(align, size);
+ if (alignPoint == null) {
+ throw new FlickingError(MESSAGE.WRONG_OPTION("align", align), CODE.WRONG_OPTION);
+ }
+ }
+ } else {
+ alignPoint = align;
+ }
+ return alignPoint;
+};
+var parseBounce = function (bounce, size) {
+ var parsedBounce;
+ if (Array.isArray(bounce)) {
+ parsedBounce = bounce.map(function (val) {
+ return parseArithmeticSize(val, size);
+ });
+ } else {
+ var parsedVal = parseArithmeticSize(bounce, size);
+ parsedBounce = [parsedVal, parsedVal];
+ }
+ return parsedBounce.map(function (val) {
+ if (val == null) {
+ throw new FlickingError(MESSAGE.WRONG_OPTION("bounce", bounce), CODE.WRONG_OPTION);
+ }
+ return val;
+ });
+};
+var parseArithmeticSize = function (cssValue, base) {
+ var parsed = parseArithmeticExpression(cssValue);
+ if (parsed == null) return null;
+ return parsed.percentage * base + parsed.absolute;
+};
+var parseArithmeticExpression = function (cssValue) {
+ var cssRegex = /(?:(\+|\-)\s*)?(\d+(?:\.\d+)?(%|px)?)/g;
+ if (typeof cssValue === "number") {
+ return {
+ percentage: 0,
+ absolute: cssValue
+ };
+ }
+ var parsed = {
+ percentage: 0,
+ absolute: 0
+ };
+ var idx = 0;
+ var matchResult = cssRegex.exec(cssValue);
+ while (matchResult != null) {
+ var sign = matchResult[1];
+ var value = matchResult[2];
+ var unit = matchResult[3];
+ var parsedValue = parseFloat(value);
+ if (idx <= 0) {
+ sign = sign || "+";
+ }
+ // Return default value for values not in good form
+ if (!sign) {
+ return null;
+ }
+ var signMultiplier = sign === "+" ? 1 : -1;
+ if (unit === "%") {
+ parsed.percentage += signMultiplier * (parsedValue / 100);
+ } else {
+ parsed.absolute += signMultiplier * parsedValue;
+ }
+ // Match next occurrence
+ ++idx;
+ matchResult = cssRegex.exec(cssValue);
+ }
+ // None-matched
+ if (idx === 0) {
+ return null;
+ }
+ return parsed;
+};
+var parseCSSSizeValue = function (val) {
+ return isString(val) ? val : val + "px";
+};
+var parsePanelAlign = function (align) {
+ return typeof align === "object" ? align.panel : align;
+};
+var getDirection = function (start, end) {
+ if (start === end) return DIRECTION.NONE;
+ return start < end ? DIRECTION.NEXT : DIRECTION.PREV;
+};
+var parseElement = function (element) {
+ if (!Array.isArray(element)) {
+ element = [element];
+ }
+ var elements = [];
+ element.forEach(function (el) {
+ if (isString(el)) {
+ var tempDiv = document.createElement("div");
+ tempDiv.innerHTML = el;
+ elements.push.apply(elements, __spread(toArray(tempDiv.children)));
+ while (tempDiv.firstChild) {
+ tempDiv.removeChild(tempDiv.firstChild);
+ }
+ } else if (el && el.nodeType === Node.ELEMENT_NODE) {
+ elements.push(el);
+ } else {
+ throw new FlickingError(MESSAGE.WRONG_TYPE(el, ["HTMLElement", "string"]), CODE.WRONG_TYPE);
+ }
+ });
+ return elements;
+};
+var getMinusCompensatedIndex = function (idx, max) {
+ return idx < 0 ? clamp(idx + max, 0, max) : clamp(idx, 0, max);
+};
+var includes = function (array, target) {
+ var e_1, _a;
+ try {
+ for (var array_1 = __values(array), array_1_1 = array_1.next(); !array_1_1.done; array_1_1 = array_1.next()) {
+ var val = array_1_1.value;
+ if (val === target) return true;
+ }
+ } catch (e_1_1) {
+ e_1 = {
+ error: e_1_1
+ };
+ } finally {
+ try {
+ if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1);
+ } finally {
+ if (e_1) throw e_1.error;
+ }
+ }
+ return false;
+};
+var isString = function (val) {
+ return typeof val === "string";
+};
+var circulatePosition = function (pos, min, max) {
+ var size = max - min;
+ if (pos < min) {
+ var offset = (min - pos) % size;
+ pos = max - offset;
+ } else if (pos > max) {
+ var offset = (pos - max) % size;
+ pos = min + offset;
+ }
+ return pos;
+};
+var find = function (array, checker) {
+ var e_2, _a;
+ try {
+ for (var array_2 = __values(array), array_2_1 = array_2.next(); !array_2_1.done; array_2_1 = array_2.next()) {
+ var val = array_2_1.value;
+ if (checker(val)) {
+ return val;
+ }
+ }
+ } catch (e_2_1) {
+ e_2 = {
+ error: e_2_1
+ };
+ } finally {
+ try {
+ if (array_2_1 && !array_2_1.done && (_a = array_2.return)) _a.call(array_2);
+ } finally {
+ if (e_2) throw e_2.error;
+ }
+ }
+ return null;
+};
+var findRight = function (array, checker) {
+ for (var idx = array.length - 1; idx >= 0; idx--) {
+ var val = array[idx];
+ if (checker(val)) {
+ return val;
+ }
+ }
+ return null;
+};
+var findIndex = function (array, checker) {
+ for (var idx = 0; idx < array.length; idx++) {
+ if (checker(array[idx])) {
+ return idx;
+ }
+ }
+ return -1;
+};
+var getProgress = function (pos, prev, next) {
+ return (pos - prev) / (next - prev);
+};
+// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+var getStyle = function (el) {
+ return window.getComputedStyle(el) || el.currentStyle;
+};
+var setSize = function (el, _a) {
+ var width = _a.width,
+ height = _a.height;
+ if (width != null) {
+ if (isString(width)) {
+ el.style.width = width;
+ } else {
+ el.style.width = width + "px";
+ }
+ }
+ if (height != null) {
+ if (isString(height)) {
+ el.style.height = height;
+ } else {
+ el.style.height = height + "px";
+ }
+ }
+};
+var isBetween = function (val, min, max) {
+ return val >= min && val <= max;
+};
+var circulateIndex = function (index, max) {
+ if (index >= max) {
+ return index % max;
+ } else if (index < 0) {
+ return getMinusCompensatedIndex((index + 1) % max - 1, max);
+ } else {
+ return index;
+ }
+};
+var range = function (end) {
+ var arr = new Array(end);
+ for (var i = 0; i < end; i++) {
+ arr[i] = i;
+ }
+ return arr;
+};
+var getElementSize = function (_a) {
+ var el = _a.el,
+ horizontal = _a.horizontal,
+ useFractionalSize = _a.useFractionalSize,
+ useOffset = _a.useOffset,
+ style = _a.style;
+ var size = 0;
+ if (useFractionalSize) {
+ var baseSize = parseFloat(horizontal ? style.width : style.height) || 0;
+ var isBorderBoxSizing = style.boxSizing === "border-box";
+ var border = horizontal ? parseFloat(style.borderLeftWidth || "0") + parseFloat(style.borderRightWidth || "0") : parseFloat(style.borderTopWidth || "0") + parseFloat(style.borderBottomWidth || "0");
+ if (isBorderBoxSizing) {
+ size = useOffset ? baseSize : baseSize - border;
+ } else {
+ var padding = horizontal ? parseFloat(style.paddingLeft || "0") + parseFloat(style.paddingRight || "0") : parseFloat(style.paddingTop || "0") + parseFloat(style.paddingBottom || "0");
+ size = useOffset ? baseSize + padding + border : baseSize + padding;
+ }
+ } else {
+ var sizeStr = horizontal ? "Width" : "Height";
+ size = useOffset ? el["offset" + sizeStr] : el["client" + sizeStr];
+ }
+ return Math.max(size, 0);
+};
+var setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
+ obj.__proto__ = proto;
+ return obj;
+};
+
+/*
+ * Copyright (c) 2015 NAVER Corp.
+ * egjs projects are licensed under the MIT license
+ */
+/**
+ * Special type of known error that {@link Flicking} throws.
+ * @ko Flicking 내부에서 알려진 오류 발생시 throw되는 에러
+ * @property {number} code Error code에러 코드
+ * @property {string} message Error message에러 메시지
+ * @see {@link ERROR_CODE ERROR_CODE}
+ * @example
+ * ```ts
+ * import Flicking, { FlickingError, ERROR_CODES } from "@egjs/flicking";
+ * try {
+ * const flicking = new Flicking(".flicking-viewport")
+ * } catch (e) {
+ * if (e instanceof FlickingError && e.code === ERROR_CODES.ELEMENT_NOT_FOUND) {
+ * console.error("Element not found")
+ * }
+ * }
+ * ```
+ */
+var FlickingError = /*#__PURE__*/function (_super) {
+ __extends(FlickingError, _super);
+ /**
+ * @param message Error message에러 메시지
+ * @param code Error code에러 코드
+ */
+ function FlickingError(message, code) {
+ var _this = _super.call(this, message) || this;
+ setPrototypeOf(_this, FlickingError.prototype);
+ _this.name = "FlickingError";
+ _this.code = code;
+ return _this;
+ }
+ return FlickingError;
+}(Error);
+
+/**
+ * A component that manages viewport size
+ * @ko 뷰포트 크기 정보를 담당하는 컴포넌트
+ */
+var Viewport = /*#__PURE__*/function () {
+ /**
+ * @param el A viewport element뷰포트 엘리먼트
+ */
+ function Viewport(flicking, el) {
+ this._flicking = flicking;
+ this._el = el;
+ this._width = 0;
+ this._height = 0;
+ this._padding = {
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0
+ };
+ this._isBorderBoxSizing = false;
+ }
+ var __proto = Viewport.prototype;
+ Object.defineProperty(__proto, "element", {
+ /**
+ * A viewport(root) element
+ * @ko 뷰포트(root) 엘리먼트
+ * @type {HTMLElement}
+ * @readonly
+ */
+ get: function () {
+ return this._el;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "width", {
+ /**
+ * Viewport width, without paddings
+ * @ko 뷰포트 너비
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._width - this._padding.left - this._padding.right;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "height", {
+ /**
+ * Viewport height, without paddings
+ * @ko 뷰포트 높이
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._height - this._padding.top - this._padding.bottom;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "padding", {
+ /**
+ * Viewport paddings
+ * @ko 뷰포트 CSS padding 값
+ * @type {object}
+ * @property {number} left CSS `padding-left`
+ * @property {number} right CSS `padding-right`
+ * @property {number} top CSS `padding-top`
+ * @property {number} bottom CSS `padding-bottom`
+ * @readonly
+ */
+ get: function () {
+ return this._padding;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Change viewport's size.
+ * This will change the actual size of `.flicking-viewport` element by changing its CSS width/height property
+ * @ko 뷰포트 크기를 변경합니다.
+ * `.flicking-viewport` 엘리먼트에 해당 크기의 CSS width/height를 적용합니다
+ * @param {object} [size] New viewport size새 뷰포트 크기
+ * @param {number|string} [size.width] CSS string or number(in px)CSS 문자열 또는 숫자(px)
+ * @param {number|string} [size.height] CSS string or number(in px)CSS 문자열 또는 숫자(px)
+ */
+ __proto.setSize = function (_a) {
+ var width = _a.width,
+ height = _a.height;
+ var el = this._el;
+ var padding = this._padding;
+ var isBorderBoxSizing = this._isBorderBoxSizing;
+ if (width != null) {
+ if (isString(width)) {
+ el.style.width = width;
+ } else {
+ var newWidth = isBorderBoxSizing ? width + padding.left + padding.right : width;
+ el.style.width = newWidth + "px";
+ }
+ }
+ if (height != null) {
+ if (isString(height)) {
+ el.style.height = height;
+ } else {
+ var newHeight = isBorderBoxSizing ? height + padding.top + padding.bottom : height;
+ el.style.height = newHeight + "px";
+ }
+ }
+ this.resize();
+ };
+ /**
+ * Update width/height to the current viewport element's size
+ * @ko 현재 뷰포트 엘리먼트의 크기로 너비/높이를 업데이트합니다
+ */
+ __proto.resize = function () {
+ var el = this._el;
+ var elStyle = getStyle(el);
+ var useFractionalSize = this._flicking.useFractionalSize;
+ this._width = getElementSize({
+ el: el,
+ horizontal: true,
+ useFractionalSize: useFractionalSize,
+ useOffset: false,
+ style: elStyle
+ });
+ this._height = getElementSize({
+ el: el,
+ horizontal: false,
+ useFractionalSize: useFractionalSize,
+ useOffset: false,
+ style: elStyle
+ });
+ this._padding = {
+ left: elStyle.paddingLeft ? parseFloat(elStyle.paddingLeft) : 0,
+ right: elStyle.paddingRight ? parseFloat(elStyle.paddingRight) : 0,
+ top: elStyle.paddingTop ? parseFloat(elStyle.paddingTop) : 0,
+ bottom: elStyle.paddingBottom ? parseFloat(elStyle.paddingBottom) : 0
+ };
+ this._isBorderBoxSizing = elStyle.boxSizing === "border-box";
+ };
+ return Viewport;
+}();
+
+var AutoResizer = /*#__PURE__*/function () {
+ function AutoResizer(flicking) {
+ var _this = this;
+ this._onResize = function () {
+ var flicking = _this._flicking;
+ var resizeDebounce = flicking.resizeDebounce;
+ var maxResizeDebounce = flicking.maxResizeDebounce;
+ if (resizeDebounce <= 0) {
+ void flicking.resize();
+ } else {
+ if (_this._maxResizeDebounceTimer <= 0) {
+ if (maxResizeDebounce > 0 && maxResizeDebounce >= resizeDebounce) {
+ _this._maxResizeDebounceTimer = window.setTimeout(_this._doScheduledResize, maxResizeDebounce);
+ }
+ }
+ if (_this._resizeTimer > 0) {
+ clearTimeout(_this._resizeTimer);
+ _this._resizeTimer = 0;
+ }
+ _this._resizeTimer = window.setTimeout(_this._doScheduledResize, resizeDebounce);
+ }
+ };
+ this._doScheduledResize = function () {
+ clearTimeout(_this._resizeTimer);
+ clearTimeout(_this._maxResizeDebounceTimer);
+ _this._maxResizeDebounceTimer = -1;
+ _this._resizeTimer = -1;
+ void _this._flicking.resize();
+ };
+ // eslint-disable-next-line @typescript-eslint/member-ordering
+ this._skipFirstResize = function () {
+ var isFirstResize = true;
+ return function () {
+ if (isFirstResize) {
+ isFirstResize = false;
+ return;
+ }
+ _this._onResize();
+ };
+ }();
+ this._flicking = flicking;
+ this._enabled = false;
+ this._resizeObserver = null;
+ this._resizeTimer = -1;
+ this._maxResizeDebounceTimer = -1;
+ }
+ var __proto = AutoResizer.prototype;
+ Object.defineProperty(__proto, "enabled", {
+ get: function () {
+ return this._enabled;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ __proto.enable = function () {
+ var flicking = this._flicking;
+ var viewport = flicking.viewport;
+ if (this._enabled) {
+ this.disable();
+ }
+ if (flicking.useResizeObserver && !!window.ResizeObserver) {
+ var viewportSizeNot0 = viewport.width !== 0 || viewport.height !== 0;
+ var resizeObserver = viewportSizeNot0 ? new ResizeObserver(this._skipFirstResize) : new ResizeObserver(this._onResize);
+ resizeObserver.observe(flicking.viewport.element);
+ this._resizeObserver = resizeObserver;
+ } else {
+ window.addEventListener("resize", this._onResize);
+ }
+ this._enabled = true;
+ return this;
+ };
+ __proto.disable = function () {
+ if (!this._enabled) return this;
+ var resizeObserver = this._resizeObserver;
+ if (resizeObserver) {
+ resizeObserver.disconnect();
+ this._resizeObserver = null;
+ } else {
+ window.removeEventListener("resize", this._onResize);
+ }
+ this._enabled = false;
+ return this;
+ };
+ return AutoResizer;
+}();
+
+/**
+ * @internal
+ */
+var VanillaElementProvider = /*#__PURE__*/function () {
+ function VanillaElementProvider(element) {
+ this._element = element;
+ this._rendered = true;
+ }
+ var __proto = VanillaElementProvider.prototype;
+ Object.defineProperty(__proto, "element", {
+ get: function () {
+ return this._element;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "rendered", {
+ get: function () {
+ return this._rendered;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ __proto.show = function (flicking) {
+ var el = this.element;
+ var cameraEl = flicking.camera.element;
+ if (el.parentElement !== cameraEl) {
+ cameraEl.appendChild(el);
+ this._rendered = true;
+ }
+ };
+ __proto.hide = function (flicking) {
+ var el = this.element;
+ var cameraEl = flicking.camera.element;
+ if (el.parentElement === cameraEl) {
+ cameraEl.removeChild(el);
+ this._rendered = false;
+ }
+ };
+ return VanillaElementProvider;
+}();
+
+/*
+ * Copyright (c) 2015 NAVER Corp.
+ * egjs projects are licensed under the MIT license
+ */
+/**
+ * @internal
+ */
+var VirtualElementProvider = /*#__PURE__*/function () {
+ function VirtualElementProvider(flicking) {
+ this._flicking = flicking;
+ }
+ var __proto = VirtualElementProvider.prototype;
+ Object.defineProperty(__proto, "element", {
+ get: function () {
+ return this._virtualElement.nativeElement;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "rendered", {
+ get: function () {
+ return this._virtualElement.visible;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "_virtualElement", {
+ get: function () {
+ var flicking = this._flicking;
+ var elIndex = this._panel.elementIndex;
+ var virtualElements = flicking.virtual.elements;
+ return virtualElements[elIndex];
+ },
+ enumerable: false,
+ configurable: true
+ });
+ __proto.init = function (panel) {
+ this._panel = panel;
+ };
+ __proto.show = function () {
+ // DO_NOTHING
+ // Actual element visibility is controlled by VirtualManager
+ };
+ __proto.hide = function () {
+ // DO_NOTHING
+ // Actual element visibility is controlled by VirtualManager
+ };
+ return VirtualElementProvider;
+}();
+
+/**
+ * A manager class to add / remove virtual panels
+ */
+var VirtualManager = /*#__PURE__*/function () {
+ function VirtualManager(flicking, options) {
+ var _a, _b, _c, _d;
+ this._flicking = flicking;
+ this._renderPanel = (_a = options === null || options === void 0 ? void 0 : options.renderPanel) !== null && _a !== void 0 ? _a : function () {
+ return "";
+ };
+ this._initialPanelCount = (_b = options === null || options === void 0 ? void 0 : options.initialPanelCount) !== null && _b !== void 0 ? _b : -1;
+ this._cache = (_c = options === null || options === void 0 ? void 0 : options.cache) !== null && _c !== void 0 ? _c : false;
+ this._panelClass = (_d = options === null || options === void 0 ? void 0 : options.panelClass) !== null && _d !== void 0 ? _d : CLASS.DEFAULT_VIRTUAL;
+ this._elements = [];
+ }
+ var __proto = VirtualManager.prototype;
+ Object.defineProperty(__proto, "elements", {
+ get: function () {
+ return this._elements;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "renderPanel", {
+ // Options
+ /**
+ * A rendering function for the panel element's innerHTML
+ * @ko 패널 엘리먼트의 innerHTML을 렌더링하는 함수
+ * @type {function}
+ * @param {VirtualPanel} panel Instance of the panel패널 인스턴스
+ * @param {number} index Index of the panel패널 인덱스
+ * @default "() => {}"
+ */
+ get: function () {
+ return this._renderPanel;
+ },
+ set: function (val) {
+ this._renderPanel = val;
+ this._flicking.renderer.panels.forEach(function (panel) {
+ return panel.uncacheRenderResult();
+ });
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "initialPanelCount", {
+ /**
+ * Initial panel count to render
+ * @ko 최초로 렌더링할 패널의 개수
+ * @readonly
+ * @type {number}
+ * @default -1
+ */
+ get: function () {
+ return this._initialPanelCount;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "cache", {
+ /**
+ * Whether to cache rendered panel's innerHTML
+ * @ko 렌더링된 패널의 innerHTML 정보를 캐시할지 여부
+ * @type {boolean}
+ * @default false
+ */
+ get: function () {
+ return this._cache;
+ },
+ set: function (val) {
+ this._cache = val;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "panelClass", {
+ /**
+ * The class name that will be applied to rendered panel elements
+ * @ko 렌더링되는 패널 엘리먼트에 적용될 클래스 이름
+ * @type {string}
+ * @default "flicking-panel"
+ */
+ get: function () {
+ return this._panelClass;
+ },
+ set: function (val) {
+ this._panelClass = val;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ __proto.init = function () {
+ var flicking = this._flicking;
+ if (!flicking.virtualEnabled) return;
+ if (!flicking.externalRenderer && !flicking.renderExternal) {
+ this._initVirtualElements();
+ }
+ var virtualElements = flicking.camera.children;
+ this._elements = virtualElements.map(function (el) {
+ return {
+ nativeElement: el,
+ visible: true
+ };
+ });
+ };
+ __proto.show = function (index) {
+ var el = this._elements[index];
+ var nativeEl = el.nativeElement;
+ el.visible = true;
+ if (nativeEl.style.display) {
+ nativeEl.style.display = "";
+ }
+ };
+ __proto.hide = function (index) {
+ var el = this._elements[index];
+ var nativeEl = el.nativeElement;
+ el.visible = false;
+ nativeEl.style.display = "none";
+ };
+ /**
+ * Add new virtual panels at the end of the list
+ * @ko 새로운 가상 패널들을 리스트의 끝에 추가합니다
+ * @param {number} count The number of panels to add추가할 패널의 개수
+ * @returns {Array} The new panels added새롭게 추가된 패널들
+ */
+ __proto.append = function (count) {
+ if (count === void 0) {
+ count = 1;
+ }
+ var flicking = this._flicking;
+ return this.insert(flicking.panels.length, count);
+ };
+ /**
+ * Add new virtual panels at the start of the list
+ * @ko 새로운 가상 패널들을 리스트의 시작에 추가합니다
+ * @param {number} count The number of panels to add추가할 패널의 개수
+ * @returns {Array} The new panels added새롭게 추가된 패널들
+ */
+ __proto.prepend = function (count) {
+ if (count === void 0) {
+ count = 1;
+ }
+ return this.insert(0, count);
+ };
+ /**
+ * Add new virtual panels at the given index
+ * @ko 새로운 가상 패널들을 주어진 인덱스에 추가합니다
+ * @param {number} count The number of panels to add추가할 패널의 개수
+ * @returns {Array} The new panels added새롭게 추가된 패널들
+ */
+ __proto.insert = function (index, count) {
+ if (count === void 0) {
+ count = 1;
+ }
+ if (count <= 0) return [];
+ var flicking = this._flicking;
+ return flicking.renderer.batchInsert({
+ index: index,
+ elements: range(count),
+ hasDOMInElements: false
+ });
+ };
+ /**
+ * Remove panels at the given index
+ * @ko 주어진 인덱스에서 패널들을 삭제합니다
+ * @param {number} count The number of panels to remove삭제할 패널의 개수
+ * @returns {Array} The panels removed삭제된 패널들
+ */
+ __proto.remove = function (index, count) {
+ if (count <= 0) return [];
+ var flicking = this._flicking;
+ return flicking.renderer.batchRemove({
+ index: index,
+ deleteCount: count,
+ hasDOMInElements: false
+ });
+ };
+ __proto._initVirtualElements = function () {
+ var _this = this;
+ var flicking = this._flicking;
+ var cameraElement = flicking.camera.element;
+ var panelsPerView = flicking.panelsPerView;
+ var fragment = document.createDocumentFragment();
+ var newElements = range(panelsPerView + 1).map(function (idx) {
+ var panelEl = document.createElement("div");
+ panelEl.className = _this._panelClass;
+ panelEl.dataset.elementIndex = idx.toString();
+ return panelEl;
+ });
+ newElements.forEach(function (el) {
+ fragment.appendChild(el);
+ });
+ cameraElement.appendChild(fragment);
+ };
+ return VirtualManager;
+}();
+
+/**
+ * All possible @egjs/axes event keys
+ * @internal
+ */
+var EVENT = {
+ HOLD: "hold",
+ CHANGE: "change",
+ RELEASE: "release",
+ ANIMATION_END: "animationEnd",
+ FINISH: "finish"
+};
+/**
+ * An Axis key that Flicking uses
+ * @internal
+ */
+var POSITION_KEY = "flick";
+
+var STATE_TYPE;
+(function (STATE_TYPE) {
+ STATE_TYPE[STATE_TYPE["IDLE"] = 0] = "IDLE";
+ STATE_TYPE[STATE_TYPE["HOLDING"] = 1] = "HOLDING";
+ STATE_TYPE[STATE_TYPE["DRAGGING"] = 2] = "DRAGGING";
+ STATE_TYPE[STATE_TYPE["ANIMATING"] = 3] = "ANIMATING";
+ STATE_TYPE[STATE_TYPE["DISABLED"] = 4] = "DISABLED";
+})(STATE_TYPE || (STATE_TYPE = {}));
+/**
+ * A component that shows the current status of the user input or the animation
+ * @ko 현재 사용자 입력 또는 애니메이션 상태를 나타내는 컴포넌트
+ * @internal
+ */
+var State = /*#__PURE__*/function () {
+ function State() {
+ this._delta = 0;
+ this._targetPanel = null;
+ }
+ var __proto = State.prototype;
+ Object.defineProperty(__proto, "delta", {
+ /**
+ * A sum of delta values of change events from the last hold event of Axes
+ * @ko 이전 hold이벤트부터 change에 의해 발생한 이동 delta값의 합산
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._delta;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "targetPanel", {
+ /**
+ * A panel to set as {@link Control#activePanel} after the animation is finished
+ * @ko 애니메이션 종료시 {@link Control#activePanel}로 설정할 패널
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._targetPanel;
+ },
+ set: function (val) {
+ this._targetPanel = val;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * An callback which is called when state has changed to this state
+ * @ko 현재 상태로 돌입했을때 호출되는 콜백 함수
+ * @param {State} prevState An previous state이전 상태값
+ * @return {void}
+ */
+ __proto.onEnter = function (prevState) {
+ this._delta = prevState._delta;
+ this._targetPanel = prevState._targetPanel;
+ };
+ /**
+ * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} event
+ * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} 이벤트 핸들러
+ * @param {object} [ctx] Event context이벤트 콘텍스트
+ * @param {Flicking} [ctx.flicking] An instance of FlickingFlicking 인스턴스
+ * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} event of Axes
+ * Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} 이벤트
+ * @param {function} [ctx.transitTo] A function for changing current state to other state다른 상태로 변경하기 위한 함수
+ * @return {void}
+ */
+ __proto.onHold = function (ctx) {
+ // DO NOTHING
+ };
+ /**
+ * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} event
+ * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} 이벤트 핸들러
+ * @param {object} [ctx] Event context이벤트 콘텍스트
+ * @param {Flicking} [ctx.flicking] An instance of FlickingFlicking 인스턴스
+ * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} event of Axes
+ * Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} 이벤트
+ * @param {function} [ctx.transitTo] A function for changing current state to other state다른 상태로 변경하기 위한 함수
+ * @return {void}
+ */
+ __proto.onChange = function (ctx) {
+ // DO NOTHING
+ };
+ /**
+ * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event
+ * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트 핸들러
+ * @param {object} [ctx] Event context이벤트 콘텍스트
+ * @param {Flicking} [ctx.flicking] An instance of FlickingFlicking 인스턴스
+ * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of Axes
+ * Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트
+ * @param {function} [ctx.transitTo] A function for changing current state to other state다른 상태로 변경하기 위한 함수
+ * @return {void}
+ */
+ __proto.onRelease = function (ctx) {
+ // DO NOTHING
+ };
+ /**
+ * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} event
+ * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} 이벤트 핸들러
+ * @param {object} [ctx] Event context이벤트 콘텍스트
+ * @param {Flicking} [ctx.flicking] An instance of FlickingFlicking 인스턴스
+ * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} event of Axes
+ * Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} 이벤트
+ * @param {function} [ctx.transitTo] A function for changing current state to other state다른 상태로 변경하기 위한 함수
+ * @return {void}
+ */
+ __proto.onAnimationEnd = function (ctx) {
+ // DO NOTHING
+ };
+ /**
+ * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} event
+ * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} 이벤트 핸들러
+ * @param {object} [ctx] Event context이벤트 콘텍스트
+ * @param {Flicking} [ctx.flicking] An instance of FlickingFlicking 인스턴스
+ * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} event of AxesAxes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} 이벤트
+ * @param {function} [ctx.transitTo] A function for changing current state to other state다른 상태로 변경하기 위한 함수
+ * @return {void}
+ */
+ __proto.onFinish = function (ctx) {
+ // DO NOTHING
+ };
+ __proto._moveToChangedPosition = function (ctx) {
+ var flicking = ctx.flicking,
+ axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ var delta = axesEvent.delta[POSITION_KEY];
+ if (!delta) {
+ return;
+ }
+ this._delta += delta;
+ var camera = flicking.camera;
+ var prevPosition = camera.position;
+ var position = axesEvent.pos[POSITION_KEY];
+ var newPosition = flicking.circularEnabled ? circulatePosition(position, camera.range.min, camera.range.max) : position;
+ camera.lookAt(newPosition);
+ var moveEvent = new Component.ComponentEvent(EVENTS.MOVE, {
+ isTrusted: axesEvent.isTrusted,
+ holding: this.holding,
+ direction: getDirection(0, axesEvent.delta[POSITION_KEY]),
+ axesEvent: axesEvent
+ });
+ flicking.trigger(moveEvent);
+ if (moveEvent.isCanceled()) {
+ // Return to previous position
+ camera.lookAt(prevPosition);
+ transitTo(STATE_TYPE.DISABLED);
+ }
+ };
+ return State;
+}();
+
+/**
+ * A default state when there's no user input and no animation's playing
+ * @ko 사용자의 입력이 없고, 애니메이션이 동작하고있지 않은 기본 상태
+ * @internal
+ */
+var IdleState = /*#__PURE__*/function (_super) {
+ __extends(IdleState, _super);
+ function IdleState() {
+ var _this = _super !== null && _super.apply(this, arguments) || this;
+ /**
+ * Whether user is clicking or touching
+ * @ko 현재 사용자가 클릭/터치중인지 여부
+ * @type {false}
+ * @readonly
+ */
+ _this.holding = false;
+ /**
+ * Whether Flicking's animating
+ * @ko 현재 애니메이션 동작 여부
+ * @type {false}
+ * @readonly
+ */
+ _this.animating = false;
+ return _this;
+ }
+ var __proto = IdleState.prototype;
+ __proto.onEnter = function () {
+ this._delta = 0;
+ this._targetPanel = null;
+ };
+ __proto.onHold = function (ctx) {
+ // Shouldn't do any action until any panels on flicking area
+ var flicking = ctx.flicking,
+ axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ if (flicking.renderer.panelCount <= 0) {
+ transitTo(STATE_TYPE.DISABLED);
+ return;
+ }
+ var holdStartEvent = new Component.ComponentEvent(EVENTS.HOLD_START, {
+ axesEvent: axesEvent
+ });
+ flicking.trigger(holdStartEvent);
+ if (holdStartEvent.isCanceled()) {
+ transitTo(STATE_TYPE.DISABLED);
+ } else {
+ transitTo(STATE_TYPE.HOLDING);
+ }
+ };
+ // By methods call
+ __proto.onChange = function (ctx) {
+ var flicking = ctx.flicking,
+ axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ var controller = flicking.control.controller;
+ var animatingContext = controller.animatingContext;
+ var moveStartEvent = new Component.ComponentEvent(EVENTS.MOVE_START, {
+ isTrusted: axesEvent.isTrusted,
+ holding: this.holding,
+ direction: getDirection(animatingContext.start, animatingContext.end),
+ axesEvent: axesEvent
+ });
+ flicking.trigger(moveStartEvent);
+ if (moveStartEvent.isCanceled()) {
+ transitTo(STATE_TYPE.DISABLED);
+ } else {
+ // Trigger AnimatingState's onChange, to trigger "move" event immediately
+ transitTo(STATE_TYPE.ANIMATING).onChange(ctx);
+ }
+ };
+ return IdleState;
+}(State);
+
+/**
+ * A state that activates when user's holding the Flicking area, but not moved a single pixel yet
+ * @ko 사용자의 입력이 시작되었으나, 아직 움직이지는 않은 상태
+ * @internal
+ */
+var HoldingState = /*#__PURE__*/function (_super) {
+ __extends(HoldingState, _super);
+ function HoldingState() {
+ var _this = _super !== null && _super.apply(this, arguments) || this;
+ /**
+ * Whether user is clicking or touching
+ * @ko 현재 사용자가 클릭/터치중인지 여부
+ * @type {true}
+ * @readonly
+ */
+ _this.holding = true;
+ /**
+ * Whether Flicking's animating
+ * @ko 현재 애니메이션 동작 여부
+ * @type {false}
+ * @readonly
+ */
+ _this.animating = false;
+ _this._releaseEvent = null;
+ return _this;
+ }
+ var __proto = HoldingState.prototype;
+ __proto.onChange = function (ctx) {
+ var flicking = ctx.flicking,
+ axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ var inputEvent = axesEvent.inputEvent;
+ var offset = flicking.horizontal ? inputEvent.offsetX : inputEvent.offsetY;
+ var moveStartEvent = new Component.ComponentEvent(EVENTS.MOVE_START, {
+ isTrusted: axesEvent.isTrusted,
+ holding: this.holding,
+ direction: getDirection(0, -offset),
+ axesEvent: axesEvent
+ });
+ flicking.trigger(moveStartEvent);
+ if (moveStartEvent.isCanceled()) {
+ transitTo(STATE_TYPE.DISABLED);
+ } else {
+ // Trigger DraggingState's onChange, to trigger "move" event immediately
+ transitTo(STATE_TYPE.DRAGGING).onChange(ctx);
+ }
+ };
+ __proto.onRelease = function (ctx) {
+ var flicking = ctx.flicking,
+ axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ flicking.trigger(new Component.ComponentEvent(EVENTS.HOLD_END, {
+ axesEvent: axesEvent
+ }));
+ if (axesEvent.delta.flick !== 0) {
+ // Sometimes "release" event on axes triggered before "change" event
+ // Especially if user flicked panel fast in really short amount of time
+ // if delta is not zero, that means above case happened.
+ // Event flow should be HOLD_START -> MOVE_START -> MOVE -> HOLD_END
+ // At least one move event should be included between holdStart and holdEnd
+ axesEvent.setTo({
+ flick: flicking.camera.position
+ }, 0);
+ transitTo(STATE_TYPE.IDLE);
+ return;
+ }
+ // Can't handle select event here,
+ // As "finish" axes event happens
+ this._releaseEvent = axesEvent;
+ };
+ __proto.onFinish = function (ctx) {
+ var e_1, _a;
+ var flicking = ctx.flicking,
+ transitTo = ctx.transitTo;
+ // Should transite to IDLE state before select event
+ // As user expects hold is already finished
+ transitTo(STATE_TYPE.IDLE);
+ if (!this._releaseEvent) {
+ return;
+ }
+ // Handle release event here
+ // To prevent finish event called twice
+ var releaseEvent = this._releaseEvent;
+ // Static click
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */
+ var srcEvent = releaseEvent.inputEvent.srcEvent;
+ var clickedElement;
+ if (srcEvent.type === "touchend") {
+ var touchEvent = srcEvent;
+ var touch = touchEvent.changedTouches[0];
+ clickedElement = document.elementFromPoint(touch.clientX, touch.clientY);
+ } else {
+ clickedElement = srcEvent.target;
+ }
+ /* eslint-enable */
+ var panels = flicking.renderer.panels;
+ var clickedPanel = null;
+ try {
+ for (var panels_1 = __values(panels), panels_1_1 = panels_1.next(); !panels_1_1.done; panels_1_1 = panels_1.next()) {
+ var panel = panels_1_1.value;
+ if (panel.contains(clickedElement)) {
+ clickedPanel = panel;
+ break;
+ }
+ }
+ } catch (e_1_1) {
+ e_1 = {
+ error: e_1_1
+ };
+ } finally {
+ try {
+ if (panels_1_1 && !panels_1_1.done && (_a = panels_1.return)) _a.call(panels_1);
+ } finally {
+ if (e_1) throw e_1.error;
+ }
+ }
+ if (clickedPanel) {
+ var cameraPosition = flicking.camera.position;
+ var clickedPanelPosition = clickedPanel.position;
+ flicking.trigger(new Component.ComponentEvent(EVENTS.SELECT, {
+ index: clickedPanel.index,
+ panel: clickedPanel,
+ // Direction to the clicked panel
+ direction: getDirection(cameraPosition, clickedPanelPosition)
+ }));
+ }
+ };
+ return HoldingState;
+}(State);
+
+/**
+ * A state that activates when user's dragging the Flicking area
+ * @ko 사용자가 드래깅중인 상태
+ * @internal
+ */
+var DraggingState = /*#__PURE__*/function (_super) {
+ __extends(DraggingState, _super);
+ function DraggingState() {
+ var _this = _super !== null && _super.apply(this, arguments) || this;
+ /**
+ * Whether user is clicking or touching
+ * @ko 현재 사용자가 클릭/터치중인지 여부
+ * @type {true}
+ * @readonly
+ */
+ _this.holding = true;
+ /**
+ * Whether Flicking's animating
+ * @ko 현재 애니메이션 동작 여부
+ * @type {true}
+ * @readonly
+ */
+ _this.animating = true;
+ return _this;
+ }
+ var __proto = DraggingState.prototype;
+ __proto.onChange = function (ctx) {
+ this._moveToChangedPosition(ctx);
+ };
+ __proto.onRelease = function (ctx) {
+ var _a;
+ var flicking = ctx.flicking,
+ axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ // Update last position to cope with Axes's animating behavior
+ // Axes uses start position when animation start
+ flicking.trigger(new Component.ComponentEvent(EVENTS.HOLD_END, {
+ axesEvent: axesEvent
+ }));
+ if (flicking.renderer.panelCount <= 0) {
+ // There're no panels
+ transitTo(STATE_TYPE.IDLE);
+ return;
+ }
+ transitTo(STATE_TYPE.ANIMATING);
+ var control = flicking.control;
+ var position = axesEvent.destPos[POSITION_KEY];
+ var duration = Math.max(axesEvent.duration, flicking.duration);
+ try {
+ void control.moveToPosition(position, duration, axesEvent);
+ } catch (err) {
+ transitTo(STATE_TYPE.IDLE);
+ axesEvent.setTo((_a = {}, _a[POSITION_KEY] = flicking.camera.position, _a), 0);
+ }
+ };
+ return DraggingState;
+}(State);
+
+/**
+ * A state that activates when Flicking's animating by user input or method call
+ * @ko 사용자 입력이나 메소드 호출에 의해 Flicking의 애니메이션이 동작중인 상태
+ * @internal
+ */
+var AnimatingState = /*#__PURE__*/function (_super) {
+ __extends(AnimatingState, _super);
+ function AnimatingState() {
+ var _this = _super !== null && _super.apply(this, arguments) || this;
+ /**
+ * Whether user is clicking or touching
+ * @ko 현재 사용자가 클릭/터치중인지 여부
+ * @type {false}
+ * @readonly
+ */
+ _this.holding = false;
+ /**
+ * Whether Flicking's animating
+ * @ko 현재 애니메이션 동작 여부
+ * @type {true}
+ * @readonly
+ */
+ _this.animating = true;
+ return _this;
+ }
+ var __proto = AnimatingState.prototype;
+ __proto.onHold = function (ctx) {
+ var flicking = ctx.flicking,
+ axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ var targetPanel = this._targetPanel;
+ var control = flicking.control;
+ this._delta = 0;
+ flicking.control.updateInput();
+ if (flicking.changeOnHold && targetPanel) {
+ control.setActive(targetPanel, control.activePanel, axesEvent.isTrusted);
+ }
+ var holdStartEvent = new Component.ComponentEvent(EVENTS.HOLD_START, {
+ axesEvent: axesEvent
+ });
+ flicking.trigger(holdStartEvent);
+ if (holdStartEvent.isCanceled()) {
+ transitTo(STATE_TYPE.DISABLED);
+ } else {
+ transitTo(STATE_TYPE.DRAGGING);
+ }
+ };
+ __proto.onChange = function (ctx) {
+ this._moveToChangedPosition(ctx);
+ };
+ __proto.onFinish = function (ctx) {
+ var flicking = ctx.flicking,
+ axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ var control = flicking.control;
+ var controller = control.controller;
+ var animatingContext = controller.animatingContext;
+ transitTo(STATE_TYPE.IDLE);
+ flicking.trigger(new Component.ComponentEvent(EVENTS.MOVE_END, {
+ isTrusted: axesEvent.isTrusted,
+ direction: getDirection(animatingContext.start, animatingContext.end),
+ axesEvent: axesEvent
+ }));
+ var targetPanel = this._targetPanel;
+ if (targetPanel) {
+ control.setActive(targetPanel, control.activePanel, axesEvent.isTrusted);
+ }
+ };
+ return AnimatingState;
+}(State);
+
+/**
+ * A state that activates when Flicking is stopped by event's `stop` method
+ * @ko 이벤트의 `stop`호출에 의해 Flicking이 정지된 상태
+ * @internal
+ */
+var DisabledState = /*#__PURE__*/function (_super) {
+ __extends(DisabledState, _super);
+ function DisabledState() {
+ var _this = _super !== null && _super.apply(this, arguments) || this;
+ /**
+ * Whether user is clicking or touching
+ * @ko 현재 사용자가 클릭/터치중인지 여부
+ * @type {false}
+ * @readonly
+ */
+ _this.holding = false;
+ /**
+ * Whether Flicking's animating
+ * @ko 현재 애니메이션 동작 여부
+ * @type {true}
+ * @readonly
+ */
+ _this.animating = true;
+ return _this;
+ }
+ var __proto = DisabledState.prototype;
+ __proto.onAnimationEnd = function (ctx) {
+ var transitTo = ctx.transitTo;
+ transitTo(STATE_TYPE.IDLE);
+ };
+ __proto.onChange = function (ctx) {
+ var axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ // Can stop Axes's change event
+ axesEvent.stop();
+ transitTo(STATE_TYPE.IDLE);
+ };
+ __proto.onRelease = function (ctx) {
+ var axesEvent = ctx.axesEvent,
+ transitTo = ctx.transitTo;
+ // This is needed when stopped hold start event
+ if (axesEvent.delta.flick === 0) {
+ transitTo(STATE_TYPE.IDLE);
+ }
+ };
+ return DisabledState;
+}(State);
+
+/**
+ * @internal
+ */
+var StateMachine = /*#__PURE__*/function () {
+ function StateMachine() {
+ var _this = this;
+ this.transitTo = function (nextStateType) {
+ var nextState;
+ switch (nextStateType) {
+ case STATE_TYPE.IDLE:
+ nextState = new IdleState();
+ break;
+ case STATE_TYPE.HOLDING:
+ nextState = new HoldingState();
+ break;
+ case STATE_TYPE.DRAGGING:
+ nextState = new DraggingState();
+ break;
+ case STATE_TYPE.ANIMATING:
+ nextState = new AnimatingState();
+ break;
+ case STATE_TYPE.DISABLED:
+ nextState = new DisabledState();
+ break;
+ }
+ nextState.onEnter(_this._state);
+ _this._state = nextState;
+ return _this._state;
+ };
+ this._state = new IdleState();
+ }
+ var __proto = StateMachine.prototype;
+ Object.defineProperty(__proto, "state", {
+ get: function () {
+ return this._state;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ __proto.fire = function (eventType, externalCtx) {
+ var currentState = this._state;
+ var ctx = __assign(__assign({}, externalCtx), {
+ transitTo: this.transitTo
+ });
+ switch (eventType) {
+ case EVENT.HOLD:
+ currentState.onHold(ctx);
+ break;
+ case EVENT.CHANGE:
+ currentState.onChange(ctx);
+ break;
+ case EVENT.RELEASE:
+ currentState.onRelease(ctx);
+ break;
+ case EVENT.ANIMATION_END:
+ currentState.onAnimationEnd(ctx);
+ break;
+ case EVENT.FINISH:
+ currentState.onFinish(ctx);
+ break;
+ }
+ };
+ return StateMachine;
+}();
+
+/**
+ * A controller that handles the {@link https://naver.github.io/egjs-axes/ @egjs/axes} events
+ * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 이벤트를 처리하는 컨트롤러 컴포넌트
+ * @internal
+ */
+var AxesController = /*#__PURE__*/function () {
+ /** */
+ function AxesController() {
+ var _this = this;
+ this._onAxesHold = function () {
+ _this._dragged = false;
+ };
+ this._onAxesChange = function () {
+ var _a;
+ _this._dragged = !!((_a = _this._panInput) === null || _a === void 0 ? void 0 : _a.isEnabled());
+ };
+ this._preventClickWhenDragged = function (e) {
+ if (_this._dragged) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ _this._dragged = false;
+ };
+ this._resetInternalValues();
+ this._stateMachine = new StateMachine();
+ }
+ var __proto = AxesController.prototype;
+ Object.defineProperty(__proto, "axes", {
+ /**
+ * An {@link https://naver.github.io/egjs-axes/docs/api/Axes Axes} instance
+ * @ko {@link https://naver.github.io/egjs-axes/docs/api/Axes Axes}의 인스턴스
+ * @type {Axes | null}
+ * @see https://naver.github.io/egjs-axes/docs/api/Axes
+ * @readonly
+ */
+ get: function () {
+ return this._axes;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "panInput", {
+ /**
+ * An {@link https://naver.github.io/egjs-axes/docs/api/PanInput PanInput} instance
+ * @ko {@link https://naver.github.io/egjs-axes/docs/api/PanInput PanInput}의 인스턴스
+ * @type {PanInput | null}
+ * @see https://naver.github.io/egjs-axes/docs/api/PanInput
+ * @readonly
+ */
+ get: function () {
+ return this._panInput;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "stateMachine", {
+ /**
+ * @internal
+ */
+ get: function () {
+ return this._stateMachine;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "state", {
+ /**
+ * A activated {@link State} that shows the current status of the user input or the animation
+ * @ko 현재 활성화된 {@link State} 인스턴스로 사용자 입력 또는 애니메이션 상태를 나타냅니다
+ * @type {State}
+ */
+ get: function () {
+ return this._stateMachine.state;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "animatingContext", {
+ /**
+ * A context of the current animation playing
+ * @ko 현재 재생중인 애니메이션 정보
+ * @type {object}
+ * @property {number} start A start position of the animation애니메이션 시작 지점
+ * @property {number} end A end position of the animation애니메이션 끝 지점
+ * @property {number} offset camera offset카메라 오프셋
+ * @readonly
+ */
+ get: function () {
+ return this._animatingContext;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "controlParams", {
+ /**
+ * A current control parameters of the Axes instance
+ * @ko 활성화된 현재 Axes 패러미터들
+ * @type {ControlParams}
+ */
+ get: function () {
+ var axes = this._axes;
+ if (!axes) {
+ return {
+ range: {
+ min: 0,
+ max: 0
+ },
+ position: 0,
+ circular: false
+ };
+ }
+ var axis = axes.axis[POSITION_KEY];
+ return {
+ range: {
+ min: axis.range[0],
+ max: axis.range[1]
+ },
+ circular: axis.circular[0],
+ position: this.position
+ };
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "enabled", {
+ /**
+ * A Boolean indicating whether the user input is enabled
+ * @ko 현재 사용자 입력이 활성화되었는지를 나타내는 값
+ * @type {boolean}
+ * @readonly
+ */
+ get: function () {
+ var _a, _b;
+ return (_b = (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.isEnabled()) !== null && _b !== void 0 ? _b : false;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "position", {
+ /**
+ * Current position value in {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance
+ * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} 인스턴스 내부의 현재 좌표 값
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ var _a, _b;
+ return (_b = (_a = this._axes) === null || _a === void 0 ? void 0 : _a.get([POSITION_KEY])[POSITION_KEY]) !== null && _b !== void 0 ? _b : 0;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "range", {
+ /**
+ * Current range value in {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance
+ * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} 인스턴스 내부의 현재 이동 범위 값
+ * @type {number[]}
+ * @readonly
+ */
+ get: function () {
+ var _a, _b;
+ return (_b = (_a = this._axes) === null || _a === void 0 ? void 0 : _a.axis[POSITION_KEY].range) !== null && _b !== void 0 ? _b : [0, 0];
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "bounce", {
+ /**
+ * Actual bounce size(px)
+ * @ko 적용된 bounce 크기(px 단위)
+ * @type {number[]}
+ * @readonly
+ */
+ get: function () {
+ var _a;
+ return (_a = this._axes) === null || _a === void 0 ? void 0 : _a.axis[POSITION_KEY].bounce;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Initialize AxesController
+ * @ko AxesController를 초기화합니다
+ * @param {Flicking} flicking An instance of Flicking
+ * @chainable
+ * @return {this}
+ */
+ __proto.init = function (flicking) {
+ var _a;
+ var _this = this;
+ this._flicking = flicking;
+ this._axes = new Axes((_a = {}, _a[POSITION_KEY] = {
+ range: [0, 0],
+ circular: false,
+ bounce: [0, 0]
+ }, _a), {
+ deceleration: flicking.deceleration,
+ interruptable: flicking.interruptable,
+ nested: flicking.nested,
+ easing: flicking.easing
+ });
+ this._panInput = new Axes.PanInput(flicking.viewport.element, {
+ inputType: flicking.inputType,
+ threshold: 1,
+ iOSEdgeSwipeThreshold: flicking.iOSEdgeSwipeThreshold,
+ preventDefaultOnDrag: flicking.preventDefaultOnDrag,
+ scale: flicking.horizontal ? [flicking.camera.panelOrder === ORDER.RTL ? 1 : -1, 0] : [0, -1],
+ releaseOnScroll: true
+ });
+ var axes = this._axes;
+ axes.connect(flicking.horizontal ? [POSITION_KEY, ""] : ["", POSITION_KEY], this._panInput);
+ var _loop_1 = function (key) {
+ var eventType = EVENT[key];
+ axes.on(eventType, function (e) {
+ _this._stateMachine.fire(eventType, {
+ flicking: flicking,
+ axesEvent: e
+ });
+ });
+ };
+ for (var key in EVENT) {
+ _loop_1(key);
+ }
+ return this;
+ };
+ /**
+ * Destroy AxesController and return to initial state
+ * @ko AxesController를 초기 상태로 되돌립니다
+ * @return {void}
+ */
+ __proto.destroy = function () {
+ var _a;
+ if (this._axes) {
+ this.removePreventClickHandler();
+ this._axes.destroy();
+ }
+ (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.destroy();
+ this._resetInternalValues();
+ };
+ /**
+ * Enable input from the user (mouse/touch)
+ * @ko 사용자의 입력(마우스/터치)를 활성화합니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.enable = function () {
+ var _a;
+ (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.enable();
+ return this;
+ };
+ /**
+ * Disable input from the user (mouse/touch)
+ * @ko 사용자의 입력(마우스/터치)를 막습니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.disable = function () {
+ var _a;
+ (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.disable();
+ return this;
+ };
+ /**
+ * Releases ongoing user input (mouse/touch)
+ * @ko 사용자의 현재 입력(마우스/터치)를 중단시킵니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.release = function () {
+ var _a;
+ (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.release();
+ return this;
+ };
+ /**
+ * Change the destination and duration of the animation currently playing
+ * @ko 재생 중인 애니메이션의 목적지와 재생 시간을 변경합니다
+ * @param {number} position A position to move이동할 좌표
+ * @param {number} duration Duration of the animation (unit: ms)애니메이션 진행 시간 (단위: ms)
+ * @chainable
+ * @return {this}
+ */
+ __proto.updateAnimation = function (position, duration) {
+ var _a;
+ var _b;
+ this._animatingContext = __assign(__assign({}, this._animatingContext), {
+ end: position
+ });
+ (_b = this._axes) === null || _b === void 0 ? void 0 : _b.updateAnimation({
+ destPos: (_a = {}, _a[POSITION_KEY] = position, _a),
+ duration: duration
+ });
+ return this;
+ };
+ /**
+ * Stops the animation currently playing
+ * @ko 재생 중인 애니메이션을 중단시킵니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.stopAnimation = function () {
+ var _a;
+ (_a = this._axes) === null || _a === void 0 ? void 0 : _a.stopAnimation();
+ return this;
+ };
+ /**
+ * Update {@link https://naver.github.io/egjs-axes/ @egjs/axes}'s state
+ * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 상태를 갱신합니다
+ * @chainable
+ * @throws {FlickingError}
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link AxesController#init init} is not called before
+ * {@link AxesController#init init}이 이전에 호출되지 않은 경우
+ * @return {this}
+ */
+ __proto.update = function (controlParams) {
+ var _a;
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ var axes = this._axes;
+ var axis = axes.axis[POSITION_KEY];
+ axis.circular = [controlParams.circular, controlParams.circular];
+ axis.range = [controlParams.range.min, controlParams.range.max];
+ axis.bounce = parseBounce(flicking.bounce, camera.size);
+ axes.axisManager.set((_a = {}, _a[POSITION_KEY] = controlParams.position, _a));
+ return this;
+ };
+ /**
+ * Attach a handler to the camera element to prevent click events during animation
+ * @ko 카메라 엘리먼트에 애니메이션 도중에 클릭 이벤트를 방지하는 핸들러를 부착합니다
+ * @return {this}
+ */
+ __proto.addPreventClickHandler = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ var axes = this._axes;
+ var cameraEl = flicking.camera.element;
+ axes.on(EVENT.HOLD, this._onAxesHold);
+ axes.on(EVENT.CHANGE, this._onAxesChange);
+ cameraEl.addEventListener("click", this._preventClickWhenDragged, true);
+ return this;
+ };
+ /**
+ * Detach a handler to the camera element to prevent click events during animation
+ * @ko 카메라 엘리먼트에 애니메이션 도중에 클릭 이벤트를 방지하는 핸들러를 탈착합니다
+ * @return {this}
+ */
+ __proto.removePreventClickHandler = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ var axes = this._axes;
+ var cameraEl = flicking.camera.element;
+ axes.off(EVENT.HOLD, this._onAxesHold);
+ axes.off(EVENT.CHANGE, this._onAxesChange);
+ cameraEl.removeEventListener("click", this._preventClickWhenDragged, true);
+ return this;
+ };
+ /**
+ * Run Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#setTo setTo} using the given position
+ * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#setTo setTo} 메소드를 주어진 좌표를 이용하여 수행합니다
+ * @param {number} position A position to move이동할 좌표
+ * @param {number} duration Duration of the animation (unit: ms)애니메이션 진행 시간 (단위: ms)
+ * @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이 값이 주어졌을 경우, 해당 이벤트의 {@link https://naver#github#io/egjs-axes/release/latest/doc/eg#Axes#html#setTo setTo} 메소드를 대신해서 사용합니다.
+ * @throws {FlickingError}
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
+ *
+ *
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
+ *
+ *
+ * @return {Promise} A Promise which will be resolved after reaching the target position해당 좌표 도달시에 resolve되는 Promise
+ */
+ __proto.animateTo = function (position, duration, axesEvent) {
+ var _this = this;
+ var _a;
+ var axes = this._axes;
+ var state = this._stateMachine.state;
+ if (!axes) {
+ return Promise.reject(new FlickingError(MESSAGE.NOT_ATTACHED_TO_FLICKING, CODE.NOT_ATTACHED_TO_FLICKING));
+ }
+ var startPos = axes.get([POSITION_KEY])[POSITION_KEY];
+ if (startPos === position) {
+ var flicking = getFlickingAttached(this._flicking);
+ flicking.camera.lookAt(position);
+ if (state.targetPanel) {
+ flicking.control.setActive(state.targetPanel, flicking.control.activePanel, (_a = axesEvent === null || axesEvent === void 0 ? void 0 : axesEvent.isTrusted) !== null && _a !== void 0 ? _a : false);
+ }
+ return Promise.resolve();
+ }
+ this._animatingContext = {
+ start: startPos,
+ end: position,
+ offset: 0
+ };
+ var animate = function () {
+ var _a, _b;
+ var resetContext = function () {
+ _this._animatingContext = {
+ start: 0,
+ end: 0,
+ offset: 0
+ };
+ };
+ axes.once(EVENT.FINISH, resetContext);
+ if (axesEvent) {
+ axesEvent.setTo((_a = {}, _a[POSITION_KEY] = position, _a), duration);
+ } else {
+ axes.setTo((_b = {}, _b[POSITION_KEY] = position, _b), duration);
+ }
+ };
+ return new Promise(function (resolve, reject) {
+ var animationFinishHandler = function () {
+ axes.off(EVENT.HOLD, interruptionHandler);
+ resolve();
+ };
+ var interruptionHandler = function () {
+ axes.off(EVENT.FINISH, animationFinishHandler);
+ reject(new FlickingError(MESSAGE.ANIMATION_INTERRUPTED, CODE.ANIMATION_INTERRUPTED));
+ };
+ axes.once(EVENT.FINISH, animationFinishHandler);
+ axes.once(EVENT.HOLD, interruptionHandler);
+ animate();
+ });
+ };
+ __proto.updateDirection = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ var axes = this._axes;
+ var panInput = this._panInput;
+ axes.disconnect(panInput);
+ axes.connect(flicking.horizontal ? [POSITION_KEY, ""] : ["", POSITION_KEY], panInput);
+ panInput.options.scale = flicking.horizontal ? [flicking.camera.panelOrder === ORDER.RTL ? 1 : -1, 0] : [0, -1];
+ };
+ __proto._resetInternalValues = function () {
+ this._flicking = null;
+ this._axes = null;
+ this._panInput = null;
+ this._animatingContext = {
+ start: 0,
+ end: 0,
+ offset: 0
+ };
+ this._dragged = false;
+ };
+ return AxesController;
+}();
+
+/**
+ * A component that manages inputs and animation of Flicking
+ * @ko Flicking의 입력 장치 & 애니메이션을 담당하는 컴포넌트
+ */
+var Control = /*#__PURE__*/function () {
+ /** */
+ function Control() {
+ this._flicking = null;
+ this._controller = new AxesController();
+ this._activePanel = null;
+ }
+ var __proto = Control.prototype;
+ Object.defineProperty(__proto, "controller", {
+ /**
+ * A controller that handles the {@link https://naver.github.io/egjs-axes/ @egjs/axes} events
+ * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 이벤트를 처리하는 컨트롤러 컴포넌트
+ * @type {AxesController}
+ * @readonly
+ */
+ get: function () {
+ return this._controller;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "activeIndex", {
+ /**
+ * Index number of the {@link Flicking#currentPanel currentPanel}
+ * @ko {@link Flicking#currentPanel currentPanel}의 인덱스 번호
+ * @type {number}
+ * @default 0
+ * @readonly
+ */
+ get: function () {
+ var _a, _b;
+ return (_b = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.index) !== null && _b !== void 0 ? _b : -1;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "activePanel", {
+ /**
+ * An active panel
+ * @ko 현재 선택된 패널
+ * @type {Panel | null}
+ * @readonly
+ */
+ get: function () {
+ return this._activePanel;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "animating", {
+ /**
+ * Whether Flicking's animating
+ * @ko 현재 애니메이션 동작 여부
+ * @type {boolean}
+ * @readonly
+ */
+ get: function () {
+ return this._controller.state.animating;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "holding", {
+ /**
+ * Whether user is clicking or touching
+ * @ko 현재 사용자가 클릭/터치중인지 여부
+ * @type {boolean}
+ * @readonly
+ */
+ get: function () {
+ return this._controller.state.holding;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Initialize Control
+ * @ko Control을 초기화합니다
+ * @param {Flicking} flicking An instance of {@link Flicking}Flicking의 인스턴스
+ * @chainable
+ * @return {this}
+ */
+ __proto.init = function (flicking) {
+ this._flicking = flicking;
+ this._controller.init(flicking);
+ return this;
+ };
+ /**
+ * Destroy Control and return to initial state
+ * @ko Control을 초기 상태로 되돌립니다
+ * @return {void}
+ */
+ __proto.destroy = function () {
+ this._controller.destroy();
+ this._flicking = null;
+ this._activePanel = null;
+ };
+ /**
+ * Enable input from the user (mouse/touch)
+ * @ko 사용자의 입력(마우스/터치)를 활성화합니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.enable = function () {
+ this._controller.enable();
+ return this;
+ };
+ /**
+ * Disable input from the user (mouse/touch)
+ * @ko 사용자의 입력(마우스/터치)를 막습니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.disable = function () {
+ this._controller.disable();
+ return this;
+ };
+ /**
+ * Releases ongoing user input (mouse/touch)
+ * @ko 사용자의 현재 입력(마우스/터치)를 중단시킵니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.release = function () {
+ this._controller.release();
+ return this;
+ };
+ /**
+ * Change the destination and duration of the animation currently playing
+ * @ko 재생 중인 애니메이션의 목적지와 재생 시간을 변경합니다
+ * @param {Panel} panel The target panel to move이동할 패널
+ * @param {number} duration Duration of the animation (unit: ms)애니메이션 진행 시간 (단위: ms)
+ * @param {DIRECTION} direction Direction to move, only available in the {@link Flicking#circular circular} mode이동할 방향. {@link Flicking#circular circular} 옵션 활성화시에만 사용 가능합니다
+ * @chainable
+ * @throws {FlickingError}
+ * {@link ERROR_CODE POSITION_NOT_REACHABLE} When the given panel is already removed or not in the Camera's {@link Camera#range range}
+ * {@link ERROR_CODE POSITION_NOT_REACHABLE} 주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우
+ * @return {this}
+ */
+ __proto.updateAnimation = function (panel, duration, direction) {
+ var state = this._controller.state;
+ var position = this._getPosition(panel, direction !== null && direction !== void 0 ? direction : DIRECTION.NONE);
+ state.targetPanel = panel;
+ this._controller.updateAnimation(position, duration);
+ return this;
+ };
+ /**
+ * Stops the animation currently playing
+ * @ko 재생 중인 애니메이션을 중단시킵니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.stopAnimation = function () {
+ var state = this._controller.state;
+ state.targetPanel = null;
+ this._controller.stopAnimation();
+ return this;
+ };
+ /**
+ * Update position after resizing
+ * @ko resize 이후에 position을 업데이트합니다
+ * @param {number} progressInPanel Previous camera's progress in active panel before resizeResize 이전 현재 선택된 패널 내에서의 카메라 progress 값
+ * @throws {FlickingError}
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우
+ * @chainable
+ * @return {Promise}
+ */
+ __proto.updatePosition = function (progressInPanel) {
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ var activePanel = this._activePanel;
+ if (activePanel) {
+ camera.lookAt(camera.clampToReachablePosition(activePanel.position));
+ }
+ };
+ /**
+ * Update {@link Control#controller controller}'s state
+ * @ko {@link Control#controller controller}의 내부 상태를 갱신합니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.updateInput = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ this._controller.update(camera.controlParams);
+ return this;
+ };
+ /**
+ * Reset {@link Control#activePanel activePanel} to `null`
+ * @ko {@link Control#activePanel activePanel}을 `null`로 초기화합니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.resetActive = function () {
+ this._activePanel = null;
+ return this;
+ };
+ /**
+ * Move {@link Camera} to the given panel
+ * @ko {@link Camera}를 해당 패널 위로 이동합니다
+ * @param {Panel} panel The target panel to move이동할 패널
+ * @param {object} options An options object옵션 오브젝트
+ * @param {number} duration Duration of the animation (unit: ms)애니메이션 진행 시간 (단위: ms)
+ * @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}
+ * {@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트
+ * @param {DIRECTION} [direction=DIRECTION.NONE] Direction to move, only available in the {@link Flicking#circular circular} mode이동할 방향. {@link Flicking#circular circular} 옵션 활성화시에만 사용 가능합니다
+ * @fires Flicking#moveStart
+ * @fires Flicking#move
+ * @fires Flicking#moveEnd
+ * @fires Flicking#willChange
+ * @fires Flicking#changed
+ * @fires Flicking#willRestore
+ * @fires Flicking#restored
+ * @fires Flicking#needPanel
+ * @fires Flicking#visibleChange
+ * @fires Flicking#reachEdge
+ * @throws {FlickingError}
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
+ * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
+ *
+ *
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
+ * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
+ *
+ *
+ * @return {Promise} A Promise which will be resolved after reaching the target panel해당 패널 도달시에 resolve되는 Promise
+ */
+ __proto.moveToPanel = function (panel, _a) {
+ var duration = _a.duration,
+ _b = _a.direction,
+ direction = _b === void 0 ? DIRECTION.NONE : _b,
+ axesEvent = _a.axesEvent;
+ return __awaiter(this, void 0, void 0, function () {
+ var position;
+ return __generator(this, function (_c) {
+ position = this._getPosition(panel, direction);
+ this._triggerIndexChangeEvent(panel, panel.position, axesEvent);
+ return [2 /*return*/, this._animateToPosition({
+ position: position,
+ duration: duration,
+ newActivePanel: panel,
+ axesEvent: axesEvent
+ })];
+ });
+ });
+ };
+ /**
+ * @internal
+ */
+ __proto.setActive = function (newActivePanel, prevActivePanel, isTrusted) {
+ var _a;
+ var flicking = getFlickingAttached(this._flicking);
+ this._activePanel = newActivePanel;
+ this._nextPanel = null;
+ flicking.camera.updateAdaptiveHeight();
+ if (newActivePanel !== prevActivePanel) {
+ flicking.trigger(new Component.ComponentEvent(EVENTS.CHANGED, {
+ index: newActivePanel.index,
+ panel: newActivePanel,
+ prevIndex: (_a = prevActivePanel === null || prevActivePanel === void 0 ? void 0 : prevActivePanel.index) !== null && _a !== void 0 ? _a : -1,
+ prevPanel: prevActivePanel,
+ isTrusted: isTrusted,
+ direction: prevActivePanel ? getDirection(prevActivePanel.position, newActivePanel.position) : DIRECTION.NONE
+ }));
+ } else {
+ flicking.trigger(new Component.ComponentEvent(EVENTS.RESTORED, {
+ isTrusted: isTrusted
+ }));
+ }
+ };
+ /**
+ * @internal
+ */
+ __proto.copy = function (control) {
+ this._flicking = control._flicking;
+ this._activePanel = control._activePanel;
+ this._controller = control._controller;
+ };
+ __proto._triggerIndexChangeEvent = function (panel, position, axesEvent) {
+ var _a;
+ var flicking = getFlickingAttached(this._flicking);
+ var triggeringEvent = panel !== this._activePanel ? EVENTS.WILL_CHANGE : EVENTS.WILL_RESTORE;
+ var camera = flicking.camera;
+ var activePanel = this._activePanel;
+ var event = new Component.ComponentEvent(triggeringEvent, {
+ index: panel.index,
+ panel: panel,
+ isTrusted: (axesEvent === null || axesEvent === void 0 ? void 0 : axesEvent.isTrusted) || false,
+ direction: getDirection((_a = activePanel === null || activePanel === void 0 ? void 0 : activePanel.position) !== null && _a !== void 0 ? _a : camera.position, position)
+ });
+ this._nextPanel = panel;
+ flicking.trigger(event);
+ if (event.isCanceled()) {
+ throw new FlickingError(MESSAGE.STOP_CALLED_BY_USER, CODE.STOP_CALLED_BY_USER);
+ }
+ };
+ __proto._animateToPosition = function (_a) {
+ var position = _a.position,
+ duration = _a.duration,
+ newActivePanel = _a.newActivePanel,
+ axesEvent = _a.axesEvent;
+ return __awaiter(this, void 0, void 0, function () {
+ var flicking, animate, state;
+ var _this = this;
+ return __generator(this, function (_b) {
+ flicking = getFlickingAttached(this._flicking);
+ animate = function () {
+ return _this._controller.animateTo(position, duration, axesEvent);
+ };
+ state = this._controller.state;
+ state.targetPanel = newActivePanel;
+ if (duration <= 0) {
+ return [2 /*return*/, animate()];
+ } else {
+ return [2 /*return*/, animate().then(function () {
+ return __awaiter(_this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ return [4 /*yield*/, flicking.renderer.render()];
+ case 1:
+ _a.sent();
+ return [2 /*return*/];
+ }
+ });
+ });
+ }).catch(function (err) {
+ if (axesEvent && err instanceof FlickingError && err.code === CODE.ANIMATION_INTERRUPTED) return;
+ throw err;
+ })];
+ }
+ });
+ });
+ };
+
+ __proto._getPosition = function (panel, direction) {
+ if (direction === void 0) {
+ direction = DIRECTION.NONE;
+ }
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ var position = panel.position;
+ var nearestAnchor = camera.findNearestAnchor(position);
+ if (panel.removed || !nearestAnchor) {
+ throw new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(panel.position), CODE.POSITION_NOT_REACHABLE);
+ }
+ if (!camera.canReach(panel)) {
+ // Override position & panel if that panel is not reachable
+ position = nearestAnchor.position;
+ panel = nearestAnchor.panel;
+ } else if (flicking.circularEnabled) {
+ // Circular mode is enabled, find nearest distance to panel
+ var camPos_1 = this._controller.position; // Actual position of the Axes
+ var camRangeDiff = camera.rangeDiff;
+ var possiblePositions = [position, position + camRangeDiff, position - camRangeDiff].filter(function (pos) {
+ if (direction === DIRECTION.NONE) return true;
+ return direction === DIRECTION.PREV ? pos <= camPos_1 : pos >= camPos_1;
+ });
+ position = possiblePositions.reduce(function (nearestPosition, pos) {
+ if (Math.abs(camPos_1 - pos) < Math.abs(camPos_1 - nearestPosition)) {
+ return pos;
+ } else {
+ return nearestPosition;
+ }
+ }, Infinity);
+ }
+ return position;
+ };
+ return Control;
+}();
+
+/**
+ * A data component that has actual position where the camera should be stopped at
+ * @ko 카메라가 정지해야하는 실제 위치를 담고 있는 데이터 컴포넌트
+ */
+var AnchorPoint = /*#__PURE__*/function () {
+ /**
+ * @param {object} options An options object옵션 객체
+ * @param {number} [options.index] Index of AnchorPointAnchorPoint의 인덱스
+ * @param {number} [options.position] Position of AnchorPointAnchorPoint의 좌표
+ * @param {Panel} [options.panel] A {@link Panel} instance AnchorPoint is referencing toAnchorPoint가 참조하고 있는 {@link Panel}
+ */
+ function AnchorPoint(_a) {
+ var index = _a.index,
+ position = _a.position,
+ panel = _a.panel;
+ this._index = index;
+ this._pos = position;
+ this._panel = panel;
+ }
+ var __proto = AnchorPoint.prototype;
+ Object.defineProperty(__proto, "index", {
+ /**
+ * Index of AnchorPoint
+ * @ko AnchorPoint의 인덱스
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._index;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "position", {
+ /**
+ * Position of AnchorPoint
+ * @ko AnchorPoint의 좌표
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._pos;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "panel", {
+ /**
+ * A {@link Panel} instance AnchorPoint is referencing to
+ * @ko AnchorPoint가 참조하고 있는 {@link Panel}
+ * @type {Panel}
+ * @readonly
+ */
+ get: function () {
+ return this._panel;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ return AnchorPoint;
+}();
+
+/**
+ * A {@link Control} that uses a release momentum to choose destination panel
+ * @ko 입력을 중단한 시점의 가속도에 영향받아 도달할 패널을 계산하는 이동 방식을 사용하는 {@link Control}
+ */
+var SnapControl = /*#__PURE__*/function (_super) {
+ __extends(SnapControl, _super);
+ /** */
+ function SnapControl(_a) {
+ var _b = (_a === void 0 ? {} : _a).count,
+ count = _b === void 0 ? Infinity : _b;
+ var _this = _super.call(this) || this;
+ _this._count = count;
+ return _this;
+ }
+ var __proto = SnapControl.prototype;
+ Object.defineProperty(__proto, "count", {
+ /**
+ * Maximum number of panels can go after release
+ * @ko 입력 중단 이후 통과하여 이동할 수 있는 패널의 최대 갯수
+ * @type {number}
+ * @default Infinity
+ */
+ get: function () {
+ return this._count;
+ },
+ set: function (val) {
+ this._count = val;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Move {@link Camera} to the given position
+ * @ko {@link Camera}를 주어진 좌표로 이동합니다
+ * @param {number} position The target position to move이동할 좌표
+ * @param {number} duration Duration of the panel movement animation (unit: ms).패널 이동 애니메이션 진행 시간 (단위: ms)
+ * @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}
+ * {@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트
+ * @fires Flicking#moveStart
+ * @fires Flicking#move
+ * @fires Flicking#moveEnd
+ * @fires Flicking#willChange
+ * @fires Flicking#changed
+ * @fires Flicking#willRestore
+ * @fires Flicking#restored
+ * @fires Flicking#needPanel
+ * @fires Flicking#visibleChange
+ * @fires Flicking#reachEdge
+ * @throws {FlickingError}
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
+ * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
+ *
+ *
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
+ * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
+ *
+ *
+ * @return {Promise} A Promise which will be resolved after reaching the target position해당 좌표 도달시에 resolve되는 Promise
+ */
+ __proto.moveToPosition = function (position, duration, axesEvent) {
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ var activeAnchor = camera.findActiveAnchor();
+ var anchorAtCamera = camera.findNearestAnchor(camera.position);
+ var state = this._controller.state;
+ if (!activeAnchor || !anchorAtCamera) {
+ return Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE));
+ }
+ var snapThreshold = this._calcSnapThreshold(position, activeAnchor);
+ var posDelta = flicking.animating ? state.delta : position - camera.position;
+ var absPosDelta = Math.abs(posDelta);
+ var snapDelta = axesEvent && axesEvent.delta[POSITION_KEY] !== 0 ? Math.abs(axesEvent.delta[POSITION_KEY]) : absPosDelta;
+ var targetAnchor;
+ if (snapDelta >= snapThreshold && snapDelta > 0) {
+ // Move to anchor at position
+ targetAnchor = this._findSnappedAnchor(position, anchorAtCamera);
+ } else if (absPosDelta >= flicking.threshold && absPosDelta > 0) {
+ // Move to the adjacent panel
+ targetAnchor = this._findAdjacentAnchor(position, posDelta, anchorAtCamera);
+ } else {
+ // Fallback to nearest panel from current camera
+ return this.moveToPanel(anchorAtCamera.panel, {
+ duration: duration,
+ axesEvent: axesEvent
+ });
+ }
+ this._triggerIndexChangeEvent(targetAnchor.panel, position, axesEvent);
+ return this._animateToPosition({
+ position: camera.clampToReachablePosition(targetAnchor.position),
+ duration: duration,
+ newActivePanel: targetAnchor.panel,
+ axesEvent: axesEvent
+ });
+ };
+ __proto._findSnappedAnchor = function (position, anchorAtCamera) {
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ var count = this._count;
+ var currentPos = camera.position;
+ var clampedPosition = camera.clampToReachablePosition(position);
+ var anchorAtPosition = camera.findAnchorIncludePosition(clampedPosition);
+ if (!anchorAtCamera || !anchorAtPosition) {
+ throw new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE);
+ }
+ if (!isFinite(count)) {
+ return anchorAtPosition;
+ }
+ var panelCount = flicking.panelCount;
+ var anchors = camera.anchorPoints;
+ var loopCount = Math.sign(position - currentPos) * Math.floor(Math.abs(position - currentPos) / camera.rangeDiff);
+ if (position > currentPos && anchorAtPosition.index < anchorAtCamera.index || anchorAtPosition.position > anchorAtCamera.position && anchorAtPosition.index === anchorAtCamera.index) {
+ loopCount += 1;
+ } else if (position < currentPos && anchorAtPosition.index > anchorAtCamera.index || anchorAtPosition.position < anchorAtCamera.position && anchorAtPosition.index === anchorAtCamera.index) {
+ loopCount -= 1;
+ }
+ var circularIndexOffset = loopCount * panelCount;
+ var anchorAtPositionIndex = anchorAtPosition.index + circularIndexOffset;
+ if (Math.abs(anchorAtPositionIndex - anchorAtCamera.index) <= count) {
+ var anchor = anchors[anchorAtPosition.index];
+ return new AnchorPoint({
+ index: anchor.index,
+ position: anchor.position + loopCount * camera.rangeDiff,
+ panel: anchor.panel
+ });
+ }
+ if (flicking.circularEnabled) {
+ var targetAnchor = anchors[circulateIndex(anchorAtCamera.index + Math.sign(position - currentPos) * count, panelCount)];
+ var loop = Math.floor(count / panelCount);
+ if (position > currentPos && targetAnchor.index < anchorAtCamera.index) {
+ loop += 1;
+ } else if (position < currentPos && targetAnchor.index > anchorAtCamera.index) {
+ loop -= 1;
+ }
+ return new AnchorPoint({
+ index: targetAnchor.index,
+ position: targetAnchor.position + loop * camera.rangeDiff,
+ panel: targetAnchor.panel
+ });
+ } else {
+ return anchors[clamp(anchorAtCamera.index + Math.sign(position - currentPos) * count, 0, anchors.length - 1)];
+ }
+ };
+ __proto._findAdjacentAnchor = function (position, posDelta, anchorAtCamera) {
+ var _a;
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ if (camera.circularEnabled) {
+ var anchorIncludePosition = camera.findAnchorIncludePosition(position);
+ if (anchorIncludePosition && anchorIncludePosition.position !== anchorAtCamera.position) {
+ return anchorIncludePosition;
+ }
+ }
+ var adjacentAnchor = (_a = posDelta > 0 ? camera.getNextAnchor(anchorAtCamera) : camera.getPrevAnchor(anchorAtCamera)) !== null && _a !== void 0 ? _a : anchorAtCamera;
+ return adjacentAnchor;
+ };
+ __proto._calcSnapThreshold = function (position, activeAnchor) {
+ var isNextDirection = position > activeAnchor.position;
+ var panel = activeAnchor.panel;
+ var panelSize = panel.size;
+ var alignPos = panel.alignPosition;
+ // Minimum distance needed to decide prev/next panel as nearest
+ /*
+ * | Prev | Next |
+ * |<------>|<------------>|
+ * [ |<-Anchor ]
+ */
+ return isNextDirection ? panelSize - alignPos + panel.margin.next : alignPos + panel.margin.prev;
+ };
+ return SnapControl;
+}(Control);
+
+/**
+ * A {@link Control} that can be scrolled freely without alignment
+ * @ko 패널이 정해진 지점에 정렬되지 않고, 자유롭게 스크롤할 수 있는 이동 방식을 사용하는 {@link Control}
+ */
+var FreeControl = /*#__PURE__*/function (_super) {
+ __extends(FreeControl, _super);
+ /** */
+ function FreeControl(_a) {
+ var _b = (_a === void 0 ? {} : _a).stopAtEdge,
+ stopAtEdge = _b === void 0 ? true : _b;
+ var _this = _super.call(this) || this;
+ _this._stopAtEdge = stopAtEdge;
+ return _this;
+ }
+ var __proto = FreeControl.prototype;
+ Object.defineProperty(__proto, "stopAtEdge", {
+ /**
+ * Make scroll animation to stop at the start/end of the scroll area, not going out the bounce area
+ * @ko 스크롤 애니메이션을 스크롤 영역의 시작과 끝부분에서 멈추도록 하여, 바운스 영역을 넘어가지 않도록 합니다
+ * @type {boolean}
+ * @default true
+ */
+ get: function () {
+ return this._stopAtEdge;
+ },
+ set: function (val) {
+ this._stopAtEdge = val;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Update position after resizing
+ * @ko resize 이후에 position을 업데이트합니다
+ * @param {number} progressInPanel Previous camera's progress in active panel before resizeResize 이전 현재 선택된 패널 내에서의 카메라 progress 값
+ * @throws {FlickingError}
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우
+ * @chainable
+ * @return {Promise}
+ */
+ __proto.updatePosition = function (progressInPanel) {
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ var activePanel = this._activePanel;
+ if (activePanel) {
+ var panelRange = activePanel.range;
+ var newPosition = panelRange.min + (panelRange.max - panelRange.min) * progressInPanel;
+ camera.lookAt(camera.clampToReachablePosition(newPosition));
+ }
+ };
+ /**
+ * Move {@link Camera} to the given position
+ * @ko {@link Camera}를 주어진 좌표로 이동합니다
+ * @param {number} position The target position to move이동할 좌표
+ * @param {number} duration Duration of the panel movement animation (unit: ms).패널 이동 애니메이션 진행 시간 (단위: ms)
+ * @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}
+ * {@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트
+ * @fires Flicking#moveStart
+ * @fires Flicking#move
+ * @fires Flicking#moveEnd
+ * @fires Flicking#willChange
+ * @fires Flicking#changed
+ * @fires Flicking#willRestore
+ * @fires Flicking#restored
+ * @fires Flicking#needPanel
+ * @fires Flicking#visibleChange
+ * @fires Flicking#reachEdge
+ * @throws {FlickingError}
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
+ * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
+ *
+ *
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
+ * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
+ *
+ *
+ * @return {Promise} A Promise which will be resolved after reaching the target position해당 좌표 도달시에 resolve되는 Promise
+ */
+ __proto.moveToPosition = function (position, duration, axesEvent) {
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ var targetPos = camera.clampToReachablePosition(position);
+ var anchorAtPosition = camera.findAnchorIncludePosition(targetPos);
+ if (!anchorAtPosition) {
+ return Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE));
+ }
+ var targetPanel = anchorAtPosition.panel;
+ // Trigger only change event
+ if (targetPanel !== this._activePanel) {
+ this._triggerIndexChangeEvent(targetPanel, position, axesEvent);
+ }
+ return this._animateToPosition({
+ position: this._stopAtEdge ? targetPos : position,
+ duration: duration,
+ newActivePanel: targetPanel,
+ axesEvent: axesEvent
+ });
+ };
+ return FreeControl;
+}(Control);
+
+/**
+ * A {@link Control} that allow you to select the maximum number of panels to move at a time
+ * @ko 한번에 최대로 이동할 패널의 개수를 선택 가능한 {@link Control}
+ */
+var StrictControl = /*#__PURE__*/function (_super) {
+ __extends(StrictControl, _super);
+ /** */
+ function StrictControl(_a) {
+ var _b = (_a === void 0 ? {} : _a).count,
+ count = _b === void 0 ? 1 : _b;
+ var _this = _super.call(this) || this;
+ _this.setActive = function (newActivePanel, prevActivePanel, isTrusted) {
+ _super.prototype.setActive.call(_this, newActivePanel, prevActivePanel, isTrusted);
+ _this.updateInput();
+ };
+ _this._count = count;
+ _this._resetIndexRange();
+ return _this;
+ }
+ var __proto = StrictControl.prototype;
+ Object.defineProperty(__proto, "count", {
+ /**
+ * Maximum number of panels that can be moved at a time
+ * @ko 최대로 움직일 수 있는 패널의 개수
+ * @type {number}
+ * @default 1
+ */
+ get: function () {
+ return this._count;
+ },
+ set: function (val) {
+ this._count = val;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Destroy Control and return to initial state
+ * @ko Control을 초기 상태로 되돌립니다
+ * @return {void}
+ */
+ __proto.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this._resetIndexRange();
+ };
+ /**
+ * Update {@link Control#controller controller}'s state
+ * @ko {@link Control#controller controller}의 내부 상태를 갱신합니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.updateInput = function () {
+ var _a;
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ var renderer = flicking.renderer;
+ var controller = this._controller;
+ var controlParams = camera.controlParams;
+ var count = this._count;
+ var activePanel = controller.state.animating ? (_a = camera.findNearestAnchor(camera.position)) === null || _a === void 0 ? void 0 : _a.panel : this._activePanel;
+ if (!activePanel) {
+ controller.update(controlParams);
+ this._resetIndexRange();
+ return this;
+ }
+ var cameraRange = controlParams.range;
+ var currentPos = activePanel.position;
+ var currentIndex = activePanel.index;
+ var panelCount = renderer.panelCount;
+ var prevPanelIndex = currentIndex - count;
+ var nextPanelIndex = currentIndex + count;
+ if (prevPanelIndex < 0) {
+ prevPanelIndex = flicking.circularEnabled ? getMinusCompensatedIndex((prevPanelIndex + 1) % panelCount - 1, panelCount) : clamp(prevPanelIndex, 0, panelCount - 1);
+ }
+ if (nextPanelIndex >= panelCount) {
+ nextPanelIndex = flicking.circularEnabled ? nextPanelIndex % panelCount : clamp(nextPanelIndex, 0, panelCount - 1);
+ }
+ var prevPanel = renderer.panels[prevPanelIndex];
+ var nextPanel = renderer.panels[nextPanelIndex];
+ var prevPos = Math.max(prevPanel.position, cameraRange.min);
+ var nextPos = Math.min(nextPanel.position, cameraRange.max);
+ if (prevPos > currentPos) {
+ prevPos -= camera.rangeDiff;
+ }
+ if (nextPos < currentPos) {
+ nextPos += camera.rangeDiff;
+ }
+ controlParams.range = {
+ min: prevPos,
+ max: nextPos
+ };
+ if (controlParams.circular) {
+ if (controlParams.position < prevPos) {
+ controlParams.position += camera.rangeDiff;
+ }
+ if (controlParams.position > nextPos) {
+ controlParams.position -= camera.rangeDiff;
+ }
+ }
+ controlParams.circular = false;
+ controller.update(controlParams);
+ this._indexRange = {
+ min: prevPanel.index,
+ max: nextPanel.index
+ };
+ return this;
+ };
+ __proto.moveToPanel = function (panel, options) {
+ return __awaiter(this, void 0, void 0, function () {
+ var flicking, camera, controller;
+ return __generator(this, function (_a) {
+ flicking = getFlickingAttached(this._flicking);
+ camera = flicking.camera;
+ controller = this._controller;
+ controller.update(camera.controlParams);
+ return [2 /*return*/, _super.prototype.moveToPanel.call(this, panel, options)];
+ });
+ });
+ };
+ /**
+ * Move {@link Camera} to the given position
+ * @ko {@link Camera}를 주어진 좌표로 이동합니다
+ * @param {number} position The target position to move이동할 좌표
+ * @param {number} duration Duration of the panel movement animation (unit: ms).패널 이동 애니메이션 진행 시간 (단위: ms)
+ * @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}
+ * {@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트
+ * @fires Flicking#moveStart
+ * @fires Flicking#move
+ * @fires Flicking#moveEnd
+ * @fires Flicking#willChange
+ * @fires Flicking#changed
+ * @fires Flicking#willRestore
+ * @fires Flicking#restored
+ * @fires Flicking#needPanel
+ * @fires Flicking#visibleChange
+ * @fires Flicking#reachEdge
+ * @throws {FlickingError}
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
+ * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
+ *
+ *
+ * |code|condition|
+ * |---|---|
+ * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
+ * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
+ * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
+ * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
+ *
+ *
+ * @return {Promise} A Promise which will be resolved after reaching the target position해당 좌표 도달시에 resolve되는 Promise
+ */
+ __proto.moveToPosition = function (position, duration, axesEvent) {
+ var _a;
+ var flicking = getFlickingAttached(this._flicking);
+ var camera = flicking.camera;
+ var currentPanel = (_a = this._nextPanel) !== null && _a !== void 0 ? _a : this._activePanel;
+ var axesRange = this._controller.range;
+ var indexRange = this._indexRange;
+ var cameraRange = camera.range;
+ var state = this._controller.state;
+ var clampedPosition = clamp(camera.clampToReachablePosition(position), axesRange[0], axesRange[1]);
+ var anchorAtPosition = camera.findAnchorIncludePosition(clampedPosition);
+ if (!anchorAtPosition || !currentPanel) {
+ return Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE));
+ }
+ var prevPos = currentPanel.position;
+ var posDelta = flicking.animating ? state.delta : position - camera.position;
+ var isOverThreshold = Math.abs(posDelta) >= flicking.threshold;
+ var adjacentAnchor = position > prevPos ? camera.getNextAnchor(anchorAtPosition) : camera.getPrevAnchor(anchorAtPosition);
+ var targetPos;
+ var targetPanel;
+ var anchors = camera.anchorPoints;
+ var firstAnchor = anchors[0];
+ var lastAnchor = anchors[anchors.length - 1];
+ var shouldBounceToFirst = position <= cameraRange.min && isBetween(firstAnchor.panel.index, indexRange.min, indexRange.max);
+ var shouldBounceToLast = position >= cameraRange.max && isBetween(lastAnchor.panel.index, indexRange.min, indexRange.max);
+ var isAdjacent = adjacentAnchor && (indexRange.min <= indexRange.max ? isBetween(adjacentAnchor.index, indexRange.min, indexRange.max) : adjacentAnchor.index >= indexRange.min || adjacentAnchor.index <= indexRange.max);
+ if (shouldBounceToFirst || shouldBounceToLast) {
+ // In bounce area
+ var targetAnchor = position < cameraRange.min ? firstAnchor : lastAnchor;
+ targetPanel = targetAnchor.panel;
+ targetPos = targetAnchor.position;
+ } else if (isOverThreshold && anchorAtPosition.position !== currentPanel.position) {
+ // Move to anchor at position
+ targetPanel = anchorAtPosition.panel;
+ targetPos = anchorAtPosition.position;
+ } else if (isOverThreshold && isAdjacent) {
+ // Move to adjacent anchor
+ targetPanel = adjacentAnchor.panel;
+ targetPos = adjacentAnchor.position;
+ } else {
+ // Fallback to nearest panel from current camera
+ var anchorAtCamera = camera.findNearestAnchor(camera.position);
+ if (!anchorAtCamera) {
+ return Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE));
+ }
+ return this.moveToPanel(anchorAtCamera.panel, {
+ duration: duration,
+ axesEvent: axesEvent
+ });
+ }
+ this._triggerIndexChangeEvent(targetPanel, position, axesEvent);
+ return this._animateToPosition({
+ position: targetPos,
+ duration: duration,
+ newActivePanel: targetPanel,
+ axesEvent: axesEvent
+ });
+ };
+ __proto._resetIndexRange = function () {
+ this._indexRange = {
+ min: 0,
+ max: 0
+ };
+ };
+ return StrictControl;
+}(Control);
+
+/**
+ * A mode of camera
+ */
+var CameraMode = /*#__PURE__*/function () {
+ /** */
+ function CameraMode(flicking) {
+ this._flicking = flicking;
+ }
+ var __proto = CameraMode.prototype;
+ __proto.getAnchors = function () {
+ var panels = this._flicking.renderer.panels;
+ return panels.map(function (panel, index) {
+ return new AnchorPoint({
+ index: index,
+ position: panel.position,
+ panel: panel
+ });
+ });
+ };
+ __proto.findAnchorIncludePosition = function (position) {
+ var anchors = this._flicking.camera.anchorPoints;
+ var anchorsIncludingPosition = anchors.filter(function (anchor) {
+ return anchor.panel.includePosition(position, true);
+ });
+ return anchorsIncludingPosition.reduce(function (nearest, anchor) {
+ if (!nearest) return anchor;
+ return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
+ }, null);
+ };
+ __proto.findNearestAnchor = function (position) {
+ var anchors = this._flicking.camera.anchorPoints;
+ if (anchors.length <= 0) return null;
+ var prevDist = Infinity;
+ for (var anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {
+ var anchor = anchors[anchorIdx];
+ var dist = Math.abs(anchor.position - position);
+ if (dist > prevDist) {
+ // Return previous anchor
+ return anchors[anchorIdx - 1];
+ }
+ prevDist = dist;
+ }
+ // Return last anchor
+ return anchors[anchors.length - 1];
+ };
+ __proto.clampToReachablePosition = function (position) {
+ var camera = this._flicking.camera;
+ var range = camera.range;
+ return clamp(position, range.min, range.max);
+ };
+ __proto.getCircularOffset = function () {
+ return 0;
+ };
+ __proto.canReach = function (panel) {
+ var camera = this._flicking.camera;
+ var range = camera.range;
+ if (panel.removed) return false;
+ var panelPos = panel.position;
+ return panelPos >= range.min && panelPos <= range.max;
+ };
+ __proto.canSee = function (panel) {
+ var camera = this._flicking.camera;
+ var visibleRange = camera.visibleRange;
+ // Should not include margin, as we don't declare what the margin is visible as what the panel is visible.
+ return panel.isVisibleOnRange(visibleRange.min, visibleRange.max);
+ };
+ return CameraMode;
+}();
+
+var LinearCameraMode = /*#__PURE__*/function (_super) {
+ __extends(LinearCameraMode, _super);
+ function LinearCameraMode() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ var __proto = LinearCameraMode.prototype;
+ __proto.checkAvailability = function () {
+ // It's always available
+ return true;
+ };
+ __proto.getRange = function () {
+ var _a, _b;
+ var renderer = this._flicking.renderer;
+ var firstPanel = renderer.getPanel(0);
+ var lastPanel = renderer.getPanel(renderer.panelCount - 1);
+ return {
+ min: (_a = firstPanel === null || firstPanel === void 0 ? void 0 : firstPanel.position) !== null && _a !== void 0 ? _a : 0,
+ max: (_b = lastPanel === null || lastPanel === void 0 ? void 0 : lastPanel.position) !== null && _b !== void 0 ? _b : 0
+ };
+ };
+ return LinearCameraMode;
+}(CameraMode);
+
+/**
+ * A {@link Camera} mode that connects the last panel and the first panel, enabling continuous loop
+ * @ko 첫번째 패널과 마지막 패널이 이어진 상태로, 무한히 회전할 수 있는 종류의 {@link Camera} 모드
+ */
+var CircularCameraMode = /*#__PURE__*/function (_super) {
+ __extends(CircularCameraMode, _super);
+ function CircularCameraMode() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ var __proto = CircularCameraMode.prototype;
+ __proto.checkAvailability = function () {
+ var flicking = this._flicking;
+ var renderer = flicking.renderer;
+ var panels = renderer.panels;
+ if (panels.length <= 0) {
+ return false;
+ }
+ var firstPanel = panels[0];
+ var lastPanel = panels[panels.length - 1];
+ var firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;
+ var lastPanelNext = lastPanel.range.max + lastPanel.margin.next;
+ var visibleSize = flicking.camera.size;
+ var panelSizeSum = lastPanelNext - firstPanelPrev;
+ var canSetCircularMode = panels.every(function (panel) {
+ return panelSizeSum - panel.size >= visibleSize;
+ });
+ return canSetCircularMode;
+ };
+ __proto.getRange = function () {
+ var flicking = this._flicking;
+ var panels = flicking.renderer.panels;
+ if (panels.length <= 0) {
+ return {
+ min: 0,
+ max: 0
+ };
+ }
+ var firstPanel = panels[0];
+ var lastPanel = panels[panels.length - 1];
+ var firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;
+ var lastPanelNext = lastPanel.range.max + lastPanel.margin.next;
+ return {
+ min: firstPanelPrev,
+ max: lastPanelNext
+ };
+ };
+ __proto.getAnchors = function () {
+ var flicking = this._flicking;
+ var panels = flicking.renderer.panels;
+ return panels.map(function (panel, index) {
+ return new AnchorPoint({
+ index: index,
+ position: panel.position,
+ panel: panel
+ });
+ });
+ };
+ __proto.findNearestAnchor = function (position) {
+ var camera = this._flicking.camera;
+ var anchors = camera.anchorPoints;
+ if (anchors.length <= 0) return null;
+ var camRange = camera.range;
+ var minDist = Infinity;
+ var minDistIndex = -1;
+ for (var anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {
+ var anchor = anchors[anchorIdx];
+ var dist = Math.min(Math.abs(anchor.position - position), Math.abs(anchor.position - camRange.min + camRange.max - position), Math.abs(position - camRange.min + camRange.max - anchor.position));
+ if (dist < minDist) {
+ minDist = dist;
+ minDistIndex = anchorIdx;
+ }
+ }
+ // Return last anchor
+ return anchors[minDistIndex];
+ };
+ __proto.findAnchorIncludePosition = function (position) {
+ var camera = this._flicking.camera;
+ var range = camera.range;
+ var anchors = camera.anchorPoints;
+ var rangeDiff = camera.rangeDiff;
+ var anchorCount = anchors.length;
+ var positionInRange = circulatePosition(position, range.min, range.max);
+ var anchorInRange = _super.prototype.findAnchorIncludePosition.call(this, positionInRange);
+ if (anchorCount > 0 && (position === range.min || position === range.max)) {
+ var possibleAnchors = [anchorInRange, new AnchorPoint({
+ index: 0,
+ position: anchors[0].position + rangeDiff,
+ panel: anchors[0].panel
+ }), new AnchorPoint({
+ index: anchorCount - 1,
+ position: anchors[anchorCount - 1].position - rangeDiff,
+ panel: anchors[anchorCount - 1].panel
+ })].filter(function (anchor) {
+ return !!anchor;
+ });
+ anchorInRange = possibleAnchors.reduce(function (nearest, anchor) {
+ if (!nearest) return anchor;
+ return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
+ }, null);
+ }
+ if (!anchorInRange) return null;
+ if (position < range.min) {
+ var loopCount = -Math.floor((range.min - position) / rangeDiff) - 1;
+ return new AnchorPoint({
+ index: anchorInRange.index,
+ position: anchorInRange.position + rangeDiff * loopCount,
+ panel: anchorInRange.panel
+ });
+ } else if (position > range.max) {
+ var loopCount = Math.floor((position - range.max) / rangeDiff) + 1;
+ return new AnchorPoint({
+ index: anchorInRange.index,
+ position: anchorInRange.position + rangeDiff * loopCount,
+ panel: anchorInRange.panel
+ });
+ }
+ return anchorInRange;
+ };
+ __proto.getCircularOffset = function () {
+ var flicking = this._flicking;
+ var camera = flicking.camera;
+ if (!camera.circularEnabled) return 0;
+ var toggled = flicking.panels.filter(function (panel) {
+ return panel.toggled;
+ });
+ var toggledPrev = toggled.filter(function (panel) {
+ return panel.toggleDirection === DIRECTION.PREV;
+ });
+ var toggledNext = toggled.filter(function (panel) {
+ return panel.toggleDirection === DIRECTION.NEXT;
+ });
+ return this._calcPanelAreaSum(toggledPrev) - this._calcPanelAreaSum(toggledNext);
+ };
+ __proto.clampToReachablePosition = function (position) {
+ // Basically all position is reachable for circular camera
+ return position;
+ };
+ __proto.canReach = function (panel) {
+ if (panel.removed) return false;
+ // Always reachable on circular mode
+ return true;
+ };
+ __proto.canSee = function (panel) {
+ var camera = this._flicking.camera;
+ var range = camera.range;
+ var rangeDiff = camera.rangeDiff;
+ var visibleRange = camera.visibleRange;
+ var visibleInCurrentRange = _super.prototype.canSee.call(this, panel);
+ // Check looped visible area for circular case
+ if (visibleRange.min < range.min) {
+ return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min + rangeDiff, visibleRange.max + rangeDiff);
+ } else if (visibleRange.max > range.max) {
+ return visibleInCurrentRange || panel.isVisibleOnRange(visibleRange.min - rangeDiff, visibleRange.max - rangeDiff);
+ }
+ return visibleInCurrentRange;
+ };
+ __proto._calcPanelAreaSum = function (panels) {
+ return panels.reduce(function (sum, panel) {
+ return sum + panel.sizeIncludingMargin;
+ }, 0);
+ };
+ return CircularCameraMode;
+}(CameraMode);
+
+var BoundCameraMode = /*#__PURE__*/function (_super) {
+ __extends(BoundCameraMode, _super);
+ function BoundCameraMode() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ var __proto = BoundCameraMode.prototype;
+ __proto.checkAvailability = function () {
+ var flicking = this._flicking;
+ var renderer = flicking.renderer;
+ var firstPanel = renderer.getPanel(0);
+ var lastPanel = renderer.getPanel(renderer.panelCount - 1);
+ if (!firstPanel || !lastPanel) {
+ return false;
+ }
+ var viewportSize = flicking.camera.size;
+ var firstPanelPrev = firstPanel.range.min;
+ var lastPanelNext = lastPanel.range.max;
+ var panelAreaSize = lastPanelNext - firstPanelPrev;
+ var isBiggerThanViewport = viewportSize < panelAreaSize;
+ return isBiggerThanViewport;
+ };
+ __proto.getRange = function () {
+ var flicking = this._flicking;
+ var renderer = flicking.renderer;
+ var alignPos = flicking.camera.alignPosition;
+ var firstPanel = renderer.getPanel(0);
+ var lastPanel = renderer.getPanel(renderer.panelCount - 1);
+ if (!firstPanel || !lastPanel) {
+ return {
+ min: 0,
+ max: 0
+ };
+ }
+ var viewportSize = flicking.camera.size;
+ var firstPanelPrev = firstPanel.range.min;
+ var lastPanelNext = lastPanel.range.max;
+ var panelAreaSize = lastPanelNext - firstPanelPrev;
+ var isBiggerThanViewport = viewportSize < panelAreaSize;
+ var firstPos = firstPanelPrev + alignPos;
+ var lastPos = lastPanelNext - viewportSize + alignPos;
+ if (isBiggerThanViewport) {
+ return {
+ min: firstPos,
+ max: lastPos
+ };
+ } else {
+ var align = flicking.camera.align;
+ var alignVal = typeof align === "object" ? align.camera : align;
+ var pos = firstPos + parseAlign$1(alignVal, lastPos - firstPos);
+ return {
+ min: pos,
+ max: pos
+ };
+ }
+ };
+ __proto.getAnchors = function () {
+ var flicking = this._flicking;
+ var camera = flicking.camera;
+ var panels = flicking.renderer.panels;
+ if (panels.length <= 0) {
+ return [];
+ }
+ var range = flicking.camera.range;
+ var reachablePanels = panels.filter(function (panel) {
+ return camera.canReach(panel);
+ });
+ if (reachablePanels.length > 0) {
+ var shouldPrependBoundAnchor = reachablePanels[0].position !== range.min;
+ var shouldAppendBoundAnchor = reachablePanels[reachablePanels.length - 1].position !== range.max;
+ var indexOffset_1 = shouldPrependBoundAnchor ? 1 : 0;
+ var newAnchors = reachablePanels.map(function (panel, idx) {
+ return new AnchorPoint({
+ index: idx + indexOffset_1,
+ position: panel.position,
+ panel: panel
+ });
+ });
+ if (shouldPrependBoundAnchor) {
+ newAnchors.splice(0, 0, new AnchorPoint({
+ index: 0,
+ position: range.min,
+ panel: panels[reachablePanels[0].index - 1]
+ }));
+ }
+ if (shouldAppendBoundAnchor) {
+ newAnchors.push(new AnchorPoint({
+ index: newAnchors.length,
+ position: range.max,
+ panel: panels[reachablePanels[reachablePanels.length - 1].index + 1]
+ }));
+ }
+ return newAnchors;
+ } else if (range.min !== range.max) {
+ // There're more than 2 panels
+ var nearestPanelAtMin = this._findNearestPanel(range.min, panels);
+ var panelAtMin = nearestPanelAtMin.index === panels.length - 1 ? nearestPanelAtMin.prev() : nearestPanelAtMin;
+ var panelAtMax = panelAtMin.next();
+ return [new AnchorPoint({
+ index: 0,
+ position: range.min,
+ panel: panelAtMin
+ }), new AnchorPoint({
+ index: 1,
+ position: range.max,
+ panel: panelAtMax
+ })];
+ } else {
+ return [new AnchorPoint({
+ index: 0,
+ position: range.min,
+ panel: this._findNearestPanel(range.min, panels)
+ })];
+ }
+ };
+ __proto.findAnchorIncludePosition = function (position) {
+ var camera = this._flicking.camera;
+ var range = camera.range;
+ var anchors = camera.anchorPoints;
+ if (anchors.length <= 0) return null;
+ if (position <= range.min) {
+ return anchors[0];
+ } else if (position >= range.max) {
+ return anchors[anchors.length - 1];
+ } else {
+ return _super.prototype.findAnchorIncludePosition.call(this, position);
+ }
+ };
+ __proto._findNearestPanel = function (pos, panels) {
+ var prevDist = Infinity;
+ for (var panelIdx = 0; panelIdx < panels.length; panelIdx++) {
+ var panel = panels[panelIdx];
+ var dist = Math.abs(panel.position - pos);
+ if (dist > prevDist) {
+ // Return previous anchor
+ return panels[panelIdx - 1];
+ }
+ prevDist = dist;
+ }
+ // Return last anchor
+ return panels[panels.length - 1];
+ };
+ return BoundCameraMode;
+}(CameraMode);
+
+/**
+ * A component that manages actual movement inside the viewport
+ * @ko 뷰포트 내에서의 실제 움직임을 담당하는 컴포넌트
+ */
+var Camera = /*#__PURE__*/function () {
+ /** */
+ function Camera(flicking, _a) {
+ var _this = this;
+ var _b = (_a === void 0 ? {} : _a).align,
+ align = _b === void 0 ? ALIGN.CENTER : _b;
+ this._checkTranslateSupport = function () {
+ var e_1, _a;
+ var transforms = ["webkitTransform", "msTransform", "MozTransform", "OTransform", "transform"];
+ var supportedStyle = document.documentElement.style;
+ var transformName = "";
+ try {
+ for (var transforms_1 = __values(transforms), transforms_1_1 = transforms_1.next(); !transforms_1_1.done; transforms_1_1 = transforms_1.next()) {
+ var prefixedTransform = transforms_1_1.value;
+ if (prefixedTransform in supportedStyle) {
+ transformName = prefixedTransform;
+ }
+ }
+ } catch (e_1_1) {
+ e_1 = {
+ error: e_1_1
+ };
+ } finally {
+ try {
+ if (transforms_1_1 && !transforms_1_1.done && (_a = transforms_1.return)) _a.call(transforms_1);
+ } finally {
+ if (e_1) throw e_1.error;
+ }
+ }
+ if (!transformName) {
+ throw new FlickingError(MESSAGE.TRANSFORM_NOT_SUPPORTED, CODE.TRANSFORM_NOT_SUPPORTED);
+ }
+ _this._transform = transformName;
+ };
+ this._flicking = flicking;
+ this._resetInternalValues();
+ // Options
+ this._align = align;
+ }
+ var __proto = Camera.prototype;
+ Object.defineProperty(__proto, "element", {
+ // Internal states getter
+ /**
+ * The camera element(`.flicking-camera`)
+ * @ko 카메라 엘리먼트(`.flicking-camera`)
+ * @type {HTMLElement}
+ * @readonly
+ */
+ get: function () {
+ return this._el;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "children", {
+ /**
+ * An array of the child elements of the camera element(`.flicking-camera`)
+ * @ko 카메라 엘리먼트(`.flicking-camera`)의 자식 엘리먼트 배열
+ * @type {HTMLElement[]}
+ * @readonly
+ */
+ get: function () {
+ return toArray(this._el.children);
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "position", {
+ /**
+ * Current position of the camera
+ * @ko Camera의 현재 좌표
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._position;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "alignPosition", {
+ /**
+ * Align position inside the viewport where {@link Panel}'s {@link Panel#alignPosition alignPosition} should be located at
+ * @ko 패널의 정렬 기준 위치. 뷰포트 내에서 {@link Panel}의 {@link Panel#alignPosition alignPosition}이 위치해야 하는 곳입니다
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._alignPos;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "offset", {
+ /**
+ * Position offset, used for the {@link Flicking#renderOnlyVisible renderOnlyVisible} option
+ * @ko Camera의 좌표 오프셋. {@link Flicking#renderOnlyVisible renderOnlyVisible} 옵션을 위해 사용됩니다.
+ * @type {number}
+ * @default 0
+ * @readonly
+ */
+ get: function () {
+ return this._offset - this._circularOffset;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "circularEnabled", {
+ /**
+ * Whether the `circular` option is enabled.
+ * The {@link Flicking#circular circular} option can't be enabled when sum of the panel sizes are too small.
+ * @ko {@link Flicking#circular circular} 옵션이 활성화되었는지 여부를 나타내는 멤버 변수.
+ * {@link Flicking#circular circular} 옵션은 패널의 크기의 합이 충분하지 않을 경우 비활성화됩니다.
+ * @type {boolean}
+ * @default false
+ * @readonly
+ */
+ get: function () {
+ return this._circularEnabled;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "mode", {
+ /**
+ * A current camera mode
+ * @type {CameraMode}
+ * @readonly
+ */
+ get: function () {
+ return this._mode;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "range", {
+ /**
+ * A range that Camera's {@link Camera#position position} can reach
+ * @ko Camera의 {@link Camera#position position}이 도달 가능한 범위
+ * @type {object}
+ * @property {number} min A minimum position최소 위치
+ * @property {number} max A maximum position최대 위치
+ * @readonly
+ */
+ get: function () {
+ return this._range;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "rangeDiff", {
+ /**
+ * A difference between Camera's minimum and maximum position that can reach
+ * @ko Camera가 도달 가능한 최소/최대 좌표의 차이
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._range.max - this._range.min;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "visiblePanels", {
+ /**
+ * An array of visible panels from the current position
+ * @ko 현재 보이는 패널들의 배열
+ * @type {Panel[]}
+ * @readonly
+ */
+ get: function () {
+ return this._visiblePanels;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "visibleRange", {
+ /**
+ * A range of the visible area from the current position
+ * @ko 현재 위치에서 보이는 범위
+ * @type {object}
+ * @property {number} min A minimum position최소 위치
+ * @property {number} min A maximum position최대 위치
+ * @readonly
+ */
+ get: function () {
+ return {
+ min: this._position - this._alignPos,
+ max: this._position - this._alignPos + this.size
+ };
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "anchorPoints", {
+ /**
+ * An array of {@link AnchorPoint}s that Camera can be stopped at
+ * @ko 카메라가 도달 가능한 {@link AnchorPoint}의 목록
+ * @type {AnchorPoint[]}
+ * @readonly
+ */
+ get: function () {
+ return this._anchors;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "controlParams", {
+ /**
+ * A current parameters of the Camera for updating {@link AxesController}
+ * @ko {@link AxesController}를 업데이트하기 위한 현재 Camera 패러미터들
+ * @type {ControlParams}
+ * @readonly
+ */
+ get: function () {
+ return {
+ range: this._range,
+ position: this._position,
+ circular: this._circularEnabled
+ };
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "atEdge", {
+ /**
+ * A Boolean value indicating whether Camera's over the minimum or maximum position reachable
+ * @ko 현재 카메라가 도달 가능한 범위의 최소 혹은 최대점을 넘어섰는지를 나타냅니다
+ * @type {boolean}
+ * @readonly
+ */
+ get: function () {
+ return this._position <= this._range.min || this._position >= this._range.max;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "size", {
+ /**
+ * Return the size of the viewport
+ * @ko 뷰포트 크기를 반환합니다
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ var flicking = this._flicking;
+ return flicking ? flicking.horizontal ? flicking.viewport.width : flicking.viewport.height : 0;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "progress", {
+ /**
+ * Return the camera's position progress from the first panel to last panel
+ * Range is from 0 to last panel's index
+ * @ko 첫번째 패널로부터 마지막 패널까지의 카메라 위치의 진행도를 반환합니다
+ * 범위는 0부터 마지막 패널의 인덱스까지입니다
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ var flicking = this._flicking;
+ var position = this._position + this._offset;
+ var nearestAnchor = this.findNearestAnchor(this._position);
+ if (!flicking || !nearestAnchor) {
+ return NaN;
+ }
+ var nearestPanel = nearestAnchor.panel;
+ var panelPos = nearestPanel.position + nearestPanel.offset;
+ var bounceSize = flicking.control.controller.bounce;
+ var _a = this.range,
+ prevRange = _a.min,
+ nextRange = _a.max;
+ var rangeDiff = this.rangeDiff;
+ if (position === panelPos) {
+ return nearestPanel.index;
+ }
+ if (position < panelPos) {
+ var prevPanel = nearestPanel.prev();
+ var prevPosition = prevPanel ? prevPanel.position + prevPanel.offset : prevRange - bounceSize[0];
+ // Looped
+ if (prevPosition > panelPos) {
+ prevPosition -= rangeDiff;
+ }
+ return nearestPanel.index - 1 + getProgress(position, prevPosition, panelPos);
+ } else {
+ var nextPanel = nearestPanel.next();
+ var nextPosition = nextPanel ? nextPanel.position + nextPanel.offset : nextRange + bounceSize[1];
+ // Looped
+ if (nextPosition < panelPos) {
+ nextPosition += rangeDiff;
+ }
+ return nearestPanel.index + getProgress(position, panelPos, nextPosition);
+ }
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "panelOrder", {
+ /**
+ * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/direction direction} CSS property applied to the camera element(`.flicking-camera`)
+ * @ko 카메라 엘리먼트(`.flicking-camera`)에 적용된 {@link https://developer.mozilla.org/en-US/docs/Web/CSS/direction direction} CSS 속성
+ * @type {string}
+ * @readonly
+ */
+ get: function () {
+ return this._panelOrder;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "align", {
+ // Options Getter
+ /**
+ * A value indicating where the {@link Camera#alignPosition alignPosition} should be located at inside the viewport element
+ * @ko {@link Camera#alignPosition alignPosition}이 뷰포트 엘리먼트 내의 어디에 위치해야 하는지를 나타내는 값
+ * @type {ALIGN | string | number}
+ */
+ get: function () {
+ return this._align;
+ },
+ // Options Setter
+ set: function (val) {
+ this._align = val;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Initialize Camera
+ * @ko Camera를 초기화합니다
+ * @throws {FlickingError}
+ * {@link ERROR_CODE VAL_MUST_NOT_NULL} If the camera element(`.flicking-camera`) does not exist inside viewport element
+ * {@link ERROR_CODE VAL_MUST_NOT_NULL} 뷰포트 엘리먼트 내부에 카메라 엘리먼트(`.flicking-camera`)가 존재하지 않을 경우
+ * @return {this}
+ */
+ __proto.init = function () {
+ var viewportEl = this._flicking.viewport.element;
+ checkExistence(viewportEl.firstElementChild, "First element child of the viewport element");
+ this._el = viewportEl.firstElementChild;
+ this._checkTranslateSupport();
+ this._updateMode();
+ this.updatePanelOrder();
+ return this;
+ };
+ /**
+ * Destroy Camera and return to initial state
+ * @ko Camera를 초기 상태로 되돌립니다
+ * @return {void}
+ */
+ __proto.destroy = function () {
+ this._resetInternalValues();
+ return this;
+ };
+ /**
+ * Move to the given position and apply CSS transform
+ * @ko 해당 좌표로 이동하고, CSS transform을 적용합니다
+ * @param {number} pos A new position움직일 위치
+ * @throws {FlickingError}
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우
+ * @return {this}
+ */
+ __proto.lookAt = function (pos) {
+ var _this = this;
+ var flicking = getFlickingAttached(this._flicking);
+ var prevPos = this._position;
+ this._position = pos;
+ var toggled = this._togglePanels(prevPos, pos);
+ this._refreshVisiblePanels();
+ this._checkNeedPanel();
+ this._checkReachEnd(prevPos, pos);
+ if (toggled) {
+ void flicking.renderer.render().then(function () {
+ _this.updateOffset();
+ });
+ } else {
+ this.applyTransform();
+ }
+ };
+ /**
+ * Return a previous {@link AnchorPoint} of given {@link AnchorPoint}
+ * If it does not exist, return `null` instead
+ * @ko 주어진 {@link AnchorPoint}의 이전 {@link AnchorPoint}를 반환합니다
+ * 존재하지 않을 경우 `null`을 반환합니다
+ * @param {AnchorPoint} anchor A reference {@link AnchorPoint}기준 {@link AnchorPoint}
+ * @return {AnchorPoint | null} The previous {@link AnchorPoint}이전 {@link AnchorPoint}
+ */
+ __proto.getPrevAnchor = function (anchor) {
+ if (!this._circularEnabled || anchor.index !== 0) {
+ return this._anchors[anchor.index - 1] || null;
+ } else {
+ var anchors = this._anchors;
+ var rangeDiff = this.rangeDiff;
+ var lastAnchor = anchors[anchors.length - 1];
+ return new AnchorPoint({
+ index: lastAnchor.index,
+ position: lastAnchor.position - rangeDiff,
+ panel: lastAnchor.panel
+ });
+ }
+ };
+ /**
+ * Return a next {@link AnchorPoint} of given {@link AnchorPoint}
+ * If it does not exist, return `null` instead
+ * @ko 주어진 {@link AnchorPoint}의 다음 {@link AnchorPoint}를 반환합니다
+ * 존재하지 않을 경우 `null`을 반환합니다
+ * @param {AnchorPoint} anchor A reference {@link AnchorPoint}기준 {@link AnchorPoint}
+ * @return {AnchorPoint | null} The next {@link AnchorPoint}다음 {@link AnchorPoint}
+ */
+ __proto.getNextAnchor = function (anchor) {
+ var anchors = this._anchors;
+ if (!this._circularEnabled || anchor.index !== anchors.length - 1) {
+ return anchors[anchor.index + 1] || null;
+ } else {
+ var rangeDiff = this.rangeDiff;
+ var firstAnchor = anchors[0];
+ return new AnchorPoint({
+ index: firstAnchor.index,
+ position: firstAnchor.position + rangeDiff,
+ panel: firstAnchor.panel
+ });
+ }
+ };
+ /**
+ * Return the camera's position progress in the panel below
+ * Value is from 0 to 1 when the camera's inside panel
+ * Value can be lower than 0 or bigger than 1 when it's in the margin area
+ * @ko 현재 카메라 아래 패널에서의 위치 진행도를 반환합니다
+ * 반환값은 카메라가 패널 내부에 있을 경우 0부터 1까지의 값을 갖습니다
+ * 패널의 margin 영역에 있을 경우 0보다 작거나 1보다 큰 값을 반환할 수 있습니다
+ */
+ __proto.getProgressInPanel = function (panel) {
+ var panelRange = panel.range;
+ return (this._position - panelRange.min) / (panelRange.max - panelRange.min);
+ };
+ /**
+ * Return {@link AnchorPoint} that includes given position
+ * If there's no {@link AnchorPoint} that includes the given position, return `null` instead
+ * @ko 주어진 좌표를 포함하는 {@link AnchorPoint}를 반환합니다
+ * 주어진 좌표를 포함하는 {@link AnchorPoint}가 없을 경우 `null`을 반환합니다
+ * @param {number} position A position to check확인할 좌표
+ * @return {AnchorPoint | null} The {@link AnchorPoint} that includes the given position해당 좌표를 포함하는 {@link AnchorPoint}
+ */
+ __proto.findAnchorIncludePosition = function (position) {
+ return this._mode.findAnchorIncludePosition(position);
+ };
+ /**
+ * Return {@link AnchorPoint} nearest to given position
+ * If there're no {@link AnchorPoint}s, return `null` instead
+ * @ko 해당 좌표에서 가장 가까운 {@link AnchorPoint}를 반환합니다
+ * {@link AnchorPoint}가 하나도 없을 경우 `null`을 반환합니다
+ * @param {number} position A position to check확인할 좌표
+ * @return {AnchorPoint | null} The {@link AnchorPoint} nearest to the given position해당 좌표에 가장 인접한 {@link AnchorPoint}
+ */
+ __proto.findNearestAnchor = function (position) {
+ return this._mode.findNearestAnchor(position);
+ };
+ /**
+ * Return {@link AnchorPoint} that matches {@link Flicking#currentPanel}
+ * @ko 현재 {@link Flicking#currentPanel}에 해당하는 {@link AnchorPoint}를 반환합니다
+ * @return {AnchorPoint | null}
+ */
+ __proto.findActiveAnchor = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ var activeIndex = flicking.control.activeIndex;
+ return find(this._anchors, function (anchor) {
+ return anchor.panel.index === activeIndex;
+ });
+ };
+ /**
+ * Clamp the given position between camera's range
+ * @ko 주어진 좌표를 Camera가 도달 가능한 범위 사이의 값으로 만듭니다
+ * @param {number} position A position to clamp범위를 제한할 좌표
+ * @return {number} A clamped position범위 제한된 좌표
+ */
+ __proto.clampToReachablePosition = function (position) {
+ return this._mode.clampToReachablePosition(position);
+ };
+ /**
+ * Check whether the given panel is inside of the Camera's range
+ * @ko 해당 {@link Panel}이 Camera가 도달 가능한 범위 내에 있는지를 반환합니다
+ * @param panel An instance of {@link Panel} to check확인할 {@link Panel}의 인스턴스
+ * @return {boolean} Whether the panel's inside Camera's range도달 가능한 범위 내에 해당 패널이 존재하는지 여부
+ */
+ __proto.canReach = function (panel) {
+ return this._mode.canReach(panel);
+ };
+ /**
+ * Check whether the given panel element is visible at the current position
+ * @ko 현재 좌표에서 해당 패널 엘리먼트를 볼 수 있는지 여부를 반환합니다
+ * @param panel An instance of {@link Panel} to check확인할 {@link Panel}의 인스턴스
+ * @return Whether the panel element is visible at the current position현재 위치에서 해당 패널 엘리먼트가 보이는지 여부
+ */
+ __proto.canSee = function (panel) {
+ return this._mode.canSee(panel);
+ };
+ /**
+ * Update {@link Camera#range range} of Camera
+ * @ko Camera의 {@link Camera#range range}를 업데이트합니다
+ * @method
+ * @abstract
+ * @memberof Camera
+ * @instance
+ * @name updateRange
+ * @chainable
+ * @throws {FlickingError}
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우
+ * @return {this}
+ */
+ __proto.updateRange = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ var renderer = flicking.renderer;
+ var panels = renderer.panels;
+ this._updateMode();
+ this._range = this._mode.getRange();
+ panels.forEach(function (panel) {
+ return panel.updateCircularToggleDirection();
+ });
+ return this;
+ };
+ /**
+ * Update Camera's {@link Camera#alignPosition alignPosition}
+ * @ko Camera의 {@link Camera#alignPosition alignPosition}을 업데이트합니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.updateAlignPos = function () {
+ var align = this._align;
+ var alignVal = typeof align === "object" ? align.camera : align;
+ this._alignPos = parseAlign$1(alignVal, this.size);
+ return this;
+ };
+ /**
+ * Update Camera's {@link Camera#anchorPoints anchorPoints}
+ * @ko Camera의 {@link Camera#anchorPoints anchorPoints}를 업데이트합니다
+ * @throws {FlickingError}
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우
+ * @chainable
+ * @return {this}
+ */
+ __proto.updateAnchors = function () {
+ this._anchors = this._mode.getAnchors();
+ return this;
+ };
+ /**
+ * Update Viewport's height to active panel's height
+ * @ko 현재 선택된 패널의 높이와 동일하도록 뷰포트의 높이를 업데이트합니다
+ * @throws {FlickingError}
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
+ * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우
+ * @chainable
+ * @return {this}
+ */
+ __proto.updateAdaptiveHeight = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ var activePanel = flicking.control.activePanel;
+ if (!flicking.horizontal || !flicking.adaptive || !activePanel) return;
+ flicking.viewport.setSize({
+ height: activePanel.height
+ });
+ };
+ /**
+ * Update current offset of the camera
+ * @ko 현재 카메라의 오프셋을 업데이트합니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.updateOffset = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ var position = this._position;
+ var unRenderedPanels = flicking.panels.filter(function (panel) {
+ return !panel.rendered;
+ });
+ this._offset = unRenderedPanels.filter(function (panel) {
+ return panel.position + panel.offset < position;
+ }).reduce(function (offset, panel) {
+ return offset + panel.sizeIncludingMargin;
+ }, 0);
+ this._circularOffset = this._mode.getCircularOffset();
+ this.applyTransform();
+ return this;
+ };
+ /**
+ * Update direction to match the {@link https://developer.mozilla.org/en-US/docs/Web/CSS/direction direction} CSS property applied to the camera element
+ * @ko 카메라 엘리먼트에 적용된 {@link https://developer.mozilla.org/en-US/docs/Web/CSS/direction direction} CSS 속성에 맞게 방향을 업데이트합니다
+ * @return {this}
+ */
+ __proto.updatePanelOrder = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ if (!flicking.horizontal) return this;
+ var el = this._el;
+ var direction = getStyle(el).direction;
+ if (direction !== this._panelOrder) {
+ this._panelOrder = direction === ORDER.RTL ? ORDER.RTL : ORDER.LTR;
+ if (flicking.initialized) {
+ flicking.control.controller.updateDirection();
+ }
+ }
+ return this;
+ };
+ /**
+ * Reset the history of {@link Flicking#event:needPanel needPanel} events so it can be triggered again
+ * @ko 발생한 {@link Flicking#event:needPanel needPanel} 이벤트들을 초기화하여 다시 발생할 수 있도록 합니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.resetNeedPanelHistory = function () {
+ this._needPanelTriggered = {
+ prev: false,
+ next: false
+ };
+ return this;
+ };
+ /**
+ * Apply "transform" style with the current position to camera element
+ * @ko 현재 위치를 기준으로한 transform 스타일을 카메라 엘리먼트에 적용합니다.
+ * @return {this}
+ */
+ __proto.applyTransform = function () {
+ var el = this._el;
+ var flicking = getFlickingAttached(this._flicking);
+ var renderer = flicking.renderer;
+ if (renderer.rendering || !flicking.initialized) return this;
+ var actualPosition = this._position - this._alignPos - this._offset + this._circularOffset;
+ el.style[this._transform] = flicking.horizontal ? "translate(" + (this._panelOrder === ORDER.RTL ? actualPosition : -actualPosition) + "px)" : "translate(0, " + -actualPosition + "px)";
+ return this;
+ };
+ __proto._resetInternalValues = function () {
+ this._position = 0;
+ this._alignPos = 0;
+ this._offset = 0;
+ this._circularOffset = 0;
+ this._circularEnabled = false;
+ this._range = {
+ min: 0,
+ max: 0
+ };
+ this._visiblePanels = [];
+ this._anchors = [];
+ this._needPanelTriggered = {
+ prev: false,
+ next: false
+ };
+ };
+ __proto._refreshVisiblePanels = function () {
+ var _this = this;
+ var flicking = getFlickingAttached(this._flicking);
+ var panels = flicking.renderer.panels;
+ var newVisiblePanels = panels.filter(function (panel) {
+ return _this.canSee(panel);
+ });
+ var prevVisiblePanels = this._visiblePanels;
+ this._visiblePanels = newVisiblePanels;
+ var added = newVisiblePanels.filter(function (panel) {
+ return !includes(prevVisiblePanels, panel);
+ });
+ var removed = prevVisiblePanels.filter(function (panel) {
+ return !includes(newVisiblePanels, panel);
+ });
+ if (added.length > 0 || removed.length > 0) {
+ void flicking.renderer.render().then(function () {
+ flicking.trigger(new Component.ComponentEvent(EVENTS.VISIBLE_CHANGE, {
+ added: added,
+ removed: removed,
+ visiblePanels: newVisiblePanels
+ }));
+ });
+ }
+ };
+ __proto._checkNeedPanel = function () {
+ var needPanelTriggered = this._needPanelTriggered;
+ if (needPanelTriggered.prev && needPanelTriggered.next) return;
+ var flicking = getFlickingAttached(this._flicking);
+ var panels = flicking.renderer.panels;
+ if (panels.length <= 0) {
+ if (!needPanelTriggered.prev) {
+ flicking.trigger(new Component.ComponentEvent(EVENTS.NEED_PANEL, {
+ direction: DIRECTION.PREV
+ }));
+ needPanelTriggered.prev = true;
+ }
+ if (!needPanelTriggered.next) {
+ flicking.trigger(new Component.ComponentEvent(EVENTS.NEED_PANEL, {
+ direction: DIRECTION.NEXT
+ }));
+ needPanelTriggered.next = true;
+ }
+ return;
+ }
+ var cameraPosition = this._position;
+ var cameraSize = this.size;
+ var cameraRange = this._range;
+ var needPanelThreshold = flicking.needPanelThreshold;
+ var cameraPrev = cameraPosition - this._alignPos;
+ var cameraNext = cameraPrev + cameraSize;
+ var firstPanel = panels[0];
+ var lastPanel = panels[panels.length - 1];
+ if (!needPanelTriggered.prev) {
+ var firstPanelPrev = firstPanel.range.min;
+ if (cameraPrev <= firstPanelPrev + needPanelThreshold || cameraPosition <= cameraRange.min + needPanelThreshold) {
+ flicking.trigger(new Component.ComponentEvent(EVENTS.NEED_PANEL, {
+ direction: DIRECTION.PREV
+ }));
+ needPanelTriggered.prev = true;
+ }
+ }
+ if (!needPanelTriggered.next) {
+ var lastPanelNext = lastPanel.range.max;
+ if (cameraNext >= lastPanelNext - needPanelThreshold || cameraPosition >= cameraRange.max - needPanelThreshold) {
+ flicking.trigger(new Component.ComponentEvent(EVENTS.NEED_PANEL, {
+ direction: DIRECTION.NEXT
+ }));
+ needPanelTriggered.next = true;
+ }
+ }
+ };
+ __proto._checkReachEnd = function (prevPos, newPos) {
+ var flicking = getFlickingAttached(this._flicking);
+ var range = this._range;
+ var wasBetweenRange = prevPos > range.min && prevPos < range.max;
+ var isBetweenRange = newPos > range.min && newPos < range.max;
+ if (!wasBetweenRange || isBetweenRange) return;
+ var direction = newPos <= range.min ? DIRECTION.PREV : DIRECTION.NEXT;
+ flicking.trigger(new Component.ComponentEvent(EVENTS.REACH_EDGE, {
+ direction: direction
+ }));
+ };
+ __proto._updateMode = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ if (flicking.circular) {
+ var circularMode = new CircularCameraMode(flicking);
+ var canSetCircularMode = circularMode.checkAvailability();
+ if (canSetCircularMode) {
+ this._mode = circularMode;
+ } else {
+ var fallbackMode = flicking.circularFallback;
+ this._mode = fallbackMode === CIRCULAR_FALLBACK.BOUND ? new BoundCameraMode(flicking) : new LinearCameraMode(flicking);
+ }
+ this._circularEnabled = canSetCircularMode;
+ } else {
+ this._mode = flicking.bound ? new BoundCameraMode(flicking) : new LinearCameraMode(flicking);
+ this._circularEnabled = false;
+ }
+ };
+ __proto._togglePanels = function (prevPos, pos) {
+ if (pos === prevPos) return false;
+ var flicking = getFlickingAttached(this._flicking);
+ var panels = flicking.renderer.panels;
+ var toggled = panels.map(function (panel) {
+ return panel.toggle(prevPos, pos);
+ });
+ return toggled.some(function (isToggled) {
+ return isToggled;
+ });
+ };
+ return Camera;
+}();
+
+/**
+ * A component that manages {@link Panel} and its elements
+ * @ko {@link Panel}과 그 엘리먼트들을 관리하는 컴포넌트
+ */
+var Renderer = /*#__PURE__*/function () {
+ /**
+ * @param {object} options An options object옵션 오브젝트
+ * @param {Constants.ALIGN | string | number} [options.align="center"] An {@link Flicking#align align} value that will be applied to all panels전체 패널에 적용될 {@link Flicking#align align} 값
+ * @param {object} [options.strategy] An instance of RenderingStrategy(internal module)RenderingStrategy의 인스턴스(내부 모듈)
+ */
+ function Renderer(_a) {
+ var _b = _a.align,
+ align = _b === void 0 ? ALIGN.CENTER : _b,
+ strategy = _a.strategy;
+ this._flicking = null;
+ this._panels = [];
+ this._rendering = false;
+ // Bind options
+ this._align = align;
+ this._strategy = strategy;
+ }
+ var __proto = Renderer.prototype;
+ Object.defineProperty(__proto, "panels", {
+ // Internal states Getter
+ /**
+ * Array of panels
+ * @ko 전체 패널들의 배열
+ * @type {Panel[]}
+ * @readonly
+ * @see Panel
+ */
+ get: function () {
+ return this._panels;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "rendering", {
+ /**
+ * A boolean value indicating whether rendering is in progress
+ * @ko 현재 렌더링이 시작되어 끝나기 전까지의 상태인지의 여부
+ * @type {boolean}
+ * @readonly
+ * @internal
+ */
+ get: function () {
+ return this._rendering;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "panelCount", {
+ /**
+ * Count of panels
+ * @ko 전체 패널의 개수
+ * @type {number}
+ * @readonly
+ */
+ get: function () {
+ return this._panels.length;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "strategy", {
+ /**
+ * @internal
+ */
+ get: function () {
+ return this._strategy;
+ },
+ enumerable: false,
+ configurable: true
+ });
+ Object.defineProperty(__proto, "align", {
+ // Options Getter
+ /**
+ * A {@link Panel}'s {@link Panel#align align} value that applied to all panels
+ * @ko {@link Panel}에 공통적으로 적용할 {@link Panel#align align} 값
+ * @type {Constants.ALIGN | string | number}
+ */
+ get: function () {
+ return this._align;
+ },
+ // Options Setter
+ set: function (val) {
+ this._align = val;
+ var panelAlign = parsePanelAlign(val);
+ this._panels.forEach(function (panel) {
+ panel.align = panelAlign;
+ });
+ },
+ enumerable: false,
+ configurable: true
+ });
+ /**
+ * Initialize Renderer
+ * @ko Renderer를 초기화합니다
+ * @param {Flicking} flicking An instance of {@link Flicking}Flicking의 인스턴스
+ * @chainable
+ * @return {this}
+ */
+ __proto.init = function (flicking) {
+ this._flicking = flicking;
+ this._collectPanels();
+ return this;
+ };
+ /**
+ * Destroy Renderer and return to initial state
+ * @ko Renderer를 초기 상태로 되돌립니다
+ * @return {void}
+ */
+ __proto.destroy = function () {
+ this._flicking = null;
+ this._panels = [];
+ };
+ /**
+ * Return the {@link Panel} at the given index. `null` if it doesn't exists.
+ * @ko 주어진 인덱스에 해당하는 {@link Panel}을 반환합니다. 주어진 인덱스에 해당하는 패널이 존재하지 않을 경우 `null`을 반환합니다.
+ * @return {Panel | null} Panel at the given index주어진 인덱스에 해당하는 패널
+ * @see Panel
+ */
+ __proto.getPanel = function (index) {
+ return this._panels[index] || null;
+ };
+ __proto.forceRenderAllPanels = function () {
+ this._panels.forEach(function (panel) {
+ return panel.markForShow();
+ });
+ return Promise.resolve();
+ };
+ /**
+ * Update all panel sizes
+ * @ko 모든 패널의 크기를 업데이트합니다
+ * @chainable
+ * @return {this}
+ */
+ __proto.updatePanelSize = function () {
+ var flicking = getFlickingAttached(this._flicking);
+ var panels = this._panels;
+ if (panels.length <= 0) return this;
+ if (flicking.panelsPerView > 0) {
+ var firstPanel = panels[0];
+ firstPanel.resize();
+ this._updatePanelSizeByGrid(firstPanel, panels);
+ } else {
+ flicking.panels.forEach(function (panel) {
+ return panel.resize();
+ });
+ }
+ return this;
+ };
+ /**
+ * Insert new panels at given index
+ * This will increase index of panels after by the number of panels added
+ * @ko 주어진 인덱스에 새로운 패널들을 추가합니다
+ * 해당 인덱스보다 같거나 큰 인덱스를 가진 기존 패널들은 추가한 패널의 개수만큼 인덱스가 증가합니다.
+ * @param {Array