UNPKG

300 kBJavaScriptView Raw
1/*
2Copyright (c) NAVER Corp.
3name: @egjs/infinitegrid
4license: MIT
5author: NAVER Corp.
6repository: https://github.com/naver/egjs-infinitegrid
7version: 4.6.0
8*/
9(function (global, factory) {
10 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
11 typeof define === 'function' && define.amd ? define(factory) :
12 (global = global || self, global.InfiniteGrid = factory());
13}(this, (function () { 'use strict';
14
15 /*! *****************************************************************************
16 Copyright (c) Microsoft Corporation.
17
18 Permission to use, copy, modify, and/or distribute this software for any
19 purpose with or without fee is hereby granted.
20
21 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
23 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
24 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
25 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 PERFORMANCE OF THIS SOFTWARE.
28 ***************************************************************************** */
29
30 /* global Reflect, Promise */
31 var extendStatics = function (d, b) {
32 extendStatics = Object.setPrototypeOf || {
33 __proto__: []
34 } instanceof Array && function (d, b) {
35 d.__proto__ = b;
36 } || function (d, b) {
37 for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
38 };
39
40 return extendStatics(d, b);
41 };
42
43 function __extends(d, b) {
44 if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
45 extendStatics(d, b);
46
47 function __() {
48 this.constructor = d;
49 }
50
51 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
52 }
53 var __assign = function () {
54 __assign = Object.assign || function __assign(t) {
55 for (var s, i = 1, n = arguments.length; i < n; i++) {
56 s = arguments[i];
57
58 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
59 }
60
61 return t;
62 };
63
64 return __assign.apply(this, arguments);
65 };
66 function __rest(s, e) {
67 var t = {};
68
69 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
70
71 if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
72 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
73 }
74 return t;
75 }
76 function __decorate(decorators, target, key, desc) {
77 var c = arguments.length,
78 r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
79 d;
80 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
81 return c > 3 && r && Object.defineProperty(target, key, r), r;
82 }
83 /** @deprecated */
84
85 function __spreadArrays() {
86 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
87
88 for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j];
89
90 return r;
91 }
92
93 /*
94 Copyright (c) NAVER Corp.
95 name: @egjs/component
96 license: MIT
97 author: NAVER Corp.
98 repository: https://github.com/naver/egjs-component
99 version: 3.0.1
100 */
101 /*! *****************************************************************************
102 Copyright (c) Microsoft Corporation.
103
104 Permission to use, copy, modify, and/or distribute this software for any
105 purpose with or without fee is hereby granted.
106
107 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
108 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
109 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
110 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
111 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
112 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
113 PERFORMANCE OF THIS SOFTWARE.
114 ***************************************************************************** */
115 function __values(o) {
116 var s = typeof Symbol === "function" && Symbol.iterator,
117 m = s && o[s],
118 i = 0;
119 if (m) return m.call(o);
120 if (o && typeof o.length === "number") return {
121 next: function () {
122 if (o && i >= o.length) o = void 0;
123 return {
124 value: o && o[i++],
125 done: !o
126 };
127 }
128 };
129 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
130 }
131 function __read(o, n) {
132 var m = typeof Symbol === "function" && o[Symbol.iterator];
133 if (!m) return o;
134 var i = m.call(o),
135 r,
136 ar = [],
137 e;
138
139 try {
140 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
141 } catch (error) {
142 e = {
143 error: error
144 };
145 } finally {
146 try {
147 if (r && !r.done && (m = i["return"])) m.call(i);
148 } finally {
149 if (e) throw e.error;
150 }
151 }
152
153 return ar;
154 }
155 function __spread() {
156 for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
157
158 return ar;
159 }
160
161 /*
162 * Copyright (c) 2015 NAVER Corp.
163 * egjs projects are licensed under the MIT license
164 */
165 var isUndefined = function (value) {
166 return typeof value === "undefined";
167 };
168
169 /**
170 * Event class to provide additional properties
171 * @ko Component에서 추가적인 프로퍼티를 제공하는 이벤트 클래스
172 */
173
174 var ComponentEvent =
175 /*#__PURE__*/
176 function () {
177 /**
178 * Create a new instance of ComponentEvent.
179 * @ko ComponentEvent의 새로운 인스턴스를 생성한다.
180 * @param eventType The name of the event.<ko>이벤트 이름.</ko>
181 * @param props An object that contains additional event properties.<ko>추가적인 이벤트 프로퍼티 오브젝트.</ko>
182 */
183 function ComponentEvent(eventType, props) {
184 var e_1, _a;
185
186 this.eventType = eventType;
187 this._canceled = false;
188 if (!props) return;
189
190 try {
191 for (var _b = __values(Object.keys(props)), _c = _b.next(); !_c.done; _c = _b.next()) {
192 var key = _c.value; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
193
194 this[key] = props[key];
195 }
196 } catch (e_1_1) {
197 e_1 = {
198 error: e_1_1
199 };
200 } finally {
201 try {
202 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
203 } finally {
204 if (e_1) throw e_1.error;
205 }
206 }
207 }
208 /**
209 * Stop the event. {@link ComponentEvent#isCanceled} will return `true` after.
210 * @ko 이벤트를 중단한다. 이후 {@link ComponentEvent#isCanceled}가 `true`를 반환한다.
211 */
212
213
214 var __proto = ComponentEvent.prototype;
215
216 __proto.stop = function () {
217 this._canceled = true;
218 };
219 /**
220 * Returns a boolean value that indicates whether {@link ComponentEvent#stop} is called before.
221 * @ko {@link ComponentEvent#stop}이 호출되었는지 여부를 반환한다.
222 * @return {boolean} A boolean value that indicates whether {@link ComponentEvent#stop} is called before.<ko>이전에 {@link ComponentEvent#stop}이 불려졌는지 여부를 반환한다.</ko>
223 */
224
225
226 __proto.isCanceled = function () {
227 return this._canceled;
228 };
229
230 return ComponentEvent;
231 }();
232
233 /**
234 * A class used to manage events in a component
235 * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스
236 */
237
238 var Component =
239 /*#__PURE__*/
240 function () {
241 /**
242 * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"}
243 */
244 function Component() {
245 this._eventHandler = {};
246 }
247 /**
248 * Trigger a custom event.
249 * @ko 커스텀 이벤트를 발생시킨다
250 * @param {string | ComponentEvent} event The name of the custom event to be triggered or an instance of the ComponentEvent<ko>발생할 커스텀 이벤트의 이름 또는 ComponentEvent의 인스턴스</ko>
251 * @param {any[]} params Event data to be sent when triggering a custom event <ko>커스텀 이벤트가 발생할 때 전달할 데이터</ko>
252 * @return An instance of the component itself<ko>컴포넌트 자신의 인스턴스</ko>
253 * @example
254 * ```ts
255 * import Component, { ComponentEvent } from "@egjs/component";
256 *
257 * class Some extends Component<{
258 * beforeHi: ComponentEvent<{ foo: number; bar: string }>;
259 * hi: { foo: { a: number; b: boolean } };
260 * someEvent: (foo: number, bar: string) => void;
261 * someOtherEvent: void; // When there's no event argument
262 * }> {
263 * some(){
264 * if(this.trigger("beforeHi")){ // When event call to stop return false.
265 * this.trigger("hi");// fire hi event.
266 * }
267 * }
268 * }
269 *
270 * const some = new Some();
271 * some.on("beforeHi", e => {
272 * if(condition){
273 * e.stop(); // When event call to stop, `hi` event not call.
274 * }
275 * // `currentTarget` is component instance.
276 * console.log(some === e.currentTarget); // true
277 *
278 * typeof e.foo; // number
279 * typeof e.bar; // string
280 * });
281 * some.on("hi", e => {
282 * typeof e.foo.b; // boolean
283 * });
284 * // If you want to more know event design. You can see article.
285 * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F
286 * ```
287 */
288
289
290 var __proto = Component.prototype;
291
292 __proto.trigger = function (event) {
293 var params = [];
294
295 for (var _i = 1; _i < arguments.length; _i++) {
296 params[_i - 1] = arguments[_i];
297 }
298
299 var eventName = event instanceof ComponentEvent ? event.eventType : event;
300
301 var handlers = __spread(this._eventHandler[eventName] || []);
302
303 if (handlers.length <= 0) {
304 return this;
305 }
306
307 if (event instanceof ComponentEvent) {
308 event.currentTarget = this;
309 handlers.forEach(function (handler) {
310 handler(event);
311 });
312 } else {
313 handlers.forEach(function (handler) {
314 // eslint-disable-next-line @typescript-eslint/no-unsafe-call
315 handler.apply(void 0, __spread(params));
316 });
317 }
318
319 return this;
320 };
321 /**
322 * Executed event just one time.
323 * @ko 이벤트가 한번만 실행된다.
324 * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.<ko>등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트</ko>
325 * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
326 * @return An instance of the component itself<ko>컴포넌트 자신의 인스턴스</ko>
327 * @example
328 * ```ts
329 * import Component, { ComponentEvent } from "@egjs/component";
330 *
331 * class Some extends Component<{
332 * hi: ComponentEvent;
333 * }> {
334 * hi() {
335 * alert("hi");
336 * }
337 * thing() {
338 * this.once("hi", this.hi);
339 * }
340 * }
341 *
342 * var some = new Some();
343 * some.thing();
344 * some.trigger(new ComponentEvent("hi"));
345 * // fire alert("hi");
346 * some.trigger(new ComponentEvent("hi"));
347 * // Nothing happens
348 * ```
349 */
350
351
352 __proto.once = function (eventName, handlerToAttach) {
353 var _this = this;
354
355 if (typeof eventName === "object" && isUndefined(handlerToAttach)) {
356 var eventHash = eventName;
357
358 for (var key in eventHash) {
359 this.once(key, eventHash[key]);
360 }
361
362 return this;
363 } else if (typeof eventName === "string" && typeof handlerToAttach === "function") {
364 var listener_1 = function () {
365 var args = [];
366
367 for (var _i = 0; _i < arguments.length; _i++) {
368 args[_i] = arguments[_i];
369 } // eslint-disable-next-line @typescript-eslint/no-unsafe-call
370
371
372 handlerToAttach.apply(void 0, __spread(args));
373
374 _this.off(eventName, listener_1);
375 };
376
377 this.on(eventName, listener_1);
378 }
379
380 return this;
381 };
382 /**
383 * Checks whether an event has been attached to a component.
384 * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다.
385 * @param {string} eventName The name of the event to be attached <ko>등록 여부를 확인할 이벤트의 이름</ko>
386 * @return {boolean} Indicates whether the event is attached. <ko>이벤트 등록 여부</ko>
387 * @example
388 * ```ts
389 * import Component from "@egjs/component";
390 *
391 * class Some extends Component<{
392 * hi: void;
393 * }> {
394 * some() {
395 * this.hasOn("hi");// check hi event.
396 * }
397 * }
398 * ```
399 */
400
401
402 __proto.hasOn = function (eventName) {
403 return !!this._eventHandler[eventName];
404 };
405 /**
406 * Attaches an event to a component.
407 * @ko 컴포넌트에 이벤트를 등록한다.
408 * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.<ko>등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트</ko>
409 * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
410 * @return An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
411 * @example
412 * ```ts
413 * import Component, { ComponentEvent } from "@egjs/component";
414 *
415 * class Some extends Component<{
416 * hi: void;
417 * }> {
418 * hi() {
419 * console.log("hi");
420 * }
421 * some() {
422 * this.on("hi",this.hi); //attach event
423 * }
424 * }
425 * ```
426 */
427
428
429 __proto.on = function (eventName, handlerToAttach) {
430 if (typeof eventName === "object" && isUndefined(handlerToAttach)) {
431 var eventHash = eventName;
432
433 for (var name in eventHash) {
434 this.on(name, eventHash[name]);
435 }
436
437 return this;
438 } else if (typeof eventName === "string" && typeof handlerToAttach === "function") {
439 var handlerList = this._eventHandler[eventName];
440
441 if (isUndefined(handlerList)) {
442 this._eventHandler[eventName] = [];
443 handlerList = this._eventHandler[eventName];
444 }
445
446 handlerList.push(handlerToAttach);
447 }
448
449 return this;
450 };
451 /**
452 * Detaches an event from the component.<br/>If the `eventName` is not given this will detach all event handlers attached.<br/>If the `handlerToDetach` is not given, this will detach all event handlers for `eventName`.
453 * @ko 컴포넌트에 등록된 이벤트를 해제한다.<br/>`eventName`이 주어지지 않았을 경우 모든 이벤트 핸들러를 제거한다.<br/>`handlerToAttach`가 주어지지 않았을 경우 `eventName`에 해당하는 모든 이벤트 핸들러를 제거한다.
454 * @param {string?} eventName The name of the event to be detached <ko>해제할 이벤트의 이름</ko>
455 * @param {function?} handlerToDetach The handler function of the event to be detached <ko>해제할 이벤트의 핸들러 함수</ko>
456 * @return An instance of a component itself <ko>컴포넌트 자신의 인스턴스</ko>
457 * @example
458 * ```ts
459 * import Component, { ComponentEvent } from "@egjs/component";
460 *
461 * class Some extends Component<{
462 * hi: void;
463 * }> {
464 * hi() {
465 * console.log("hi");
466 * }
467 * some() {
468 * this.off("hi",this.hi); //detach event
469 * }
470 * }
471 * ```
472 */
473
474
475 __proto.off = function (eventName, handlerToDetach) {
476 var e_1, _a; // Detach all event handlers.
477
478
479 if (isUndefined(eventName)) {
480 this._eventHandler = {};
481 return this;
482 } // Detach all handlers for eventname or detach event handlers by object.
483
484
485 if (isUndefined(handlerToDetach)) {
486 if (typeof eventName === "string") {
487 delete this._eventHandler[eventName];
488 return this;
489 } else {
490 var eventHash = eventName;
491
492 for (var name in eventHash) {
493 this.off(name, eventHash[name]);
494 }
495
496 return this;
497 }
498 } // Detach single event handler
499
500
501 var handlerList = this._eventHandler[eventName];
502
503 if (handlerList) {
504 var idx = 0;
505
506 try {
507 for (var handlerList_1 = __values(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) {
508 var handlerFunction = handlerList_1_1.value;
509
510 if (handlerFunction === handlerToDetach) {
511 handlerList.splice(idx, 1);
512
513 if (handlerList.length <= 0) {
514 delete this._eventHandler[eventName];
515 }
516
517 break;
518 }
519
520 idx++;
521 }
522 } catch (e_1_1) {
523 e_1 = {
524 error: e_1_1
525 };
526 } finally {
527 try {
528 if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1);
529 } finally {
530 if (e_1) throw e_1.error;
531 }
532 }
533 }
534
535 return this;
536 };
537 /**
538 * Version info string
539 * @ko 버전정보 문자열
540 * @name VERSION
541 * @static
542 * @example
543 * Component.VERSION; // ex) 3.0.0
544 * @memberof Component
545 */
546
547
548 Component.VERSION = "3.0.1";
549 return Component;
550 }();
551
552 /*
553 * Copyright (c) 2015 NAVER Corp.
554 * egjs projects are licensed under the MIT license
555 */
556
557 var ComponentEvent$1 = ComponentEvent;
558
559 /*
560 Copyright (c) 2019-present NAVER Corp.
561 name: @egjs/list-differ
562 license: MIT
563 author: NAVER Corp.
564 repository: https://github.com/naver/egjs-list-differ
565 version: 1.0.0
566 */
567 /*
568 egjs-list-differ
569 Copyright (c) 2019-present NAVER Corp.
570 MIT license
571 */
572 var PolyMap =
573 /*#__PURE__*/
574 function () {
575 function PolyMap() {
576 this.keys = [];
577 this.values = [];
578 }
579
580 var __proto = PolyMap.prototype;
581
582 __proto.get = function (key) {
583 return this.values[this.keys.indexOf(key)];
584 };
585
586 __proto.set = function (key, value) {
587 var keys = this.keys;
588 var values = this.values;
589 var prevIndex = keys.indexOf(key);
590 var index = prevIndex === -1 ? keys.length : prevIndex;
591 keys[index] = key;
592 values[index] = value;
593 };
594
595 return PolyMap;
596 }();
597
598 /*
599 egjs-list-differ
600 Copyright (c) 2019-present NAVER Corp.
601 MIT license
602 */
603 var HashMap =
604 /*#__PURE__*/
605 function () {
606 function HashMap() {
607 this.object = {};
608 }
609
610 var __proto = HashMap.prototype;
611
612 __proto.get = function (key) {
613 return this.object[key];
614 };
615
616 __proto.set = function (key, value) {
617 this.object[key] = value;
618 };
619
620 return HashMap;
621 }();
622
623 /*
624 egjs-list-differ
625 Copyright (c) 2019-present NAVER Corp.
626 MIT license
627 */
628 var SUPPORT_MAP = typeof Map === "function";
629
630 /*
631 egjs-list-differ
632 Copyright (c) 2019-present NAVER Corp.
633 MIT license
634 */
635 var Link =
636 /*#__PURE__*/
637 function () {
638 function Link() {}
639
640 var __proto = Link.prototype;
641
642 __proto.connect = function (prevLink, nextLink) {
643 this.prev = prevLink;
644 this.next = nextLink;
645 prevLink && (prevLink.next = this);
646 nextLink && (nextLink.prev = this);
647 };
648
649 __proto.disconnect = function () {
650 // In double linked list, diconnect the interconnected relationship.
651 var prevLink = this.prev;
652 var nextLink = this.next;
653 prevLink && (prevLink.next = nextLink);
654 nextLink && (nextLink.prev = prevLink);
655 };
656
657 __proto.getIndex = function () {
658 var link = this;
659 var index = -1;
660
661 while (link) {
662 link = link.prev;
663 ++index;
664 }
665
666 return index;
667 };
668
669 return Link;
670 }();
671
672 /*
673 egjs-list-differ
674 Copyright (c) 2019-present NAVER Corp.
675 MIT license
676 */
677
678 function orderChanged(changed, fixed) {
679 // It is roughly in the order of these examples.
680 // 4, 6, 0, 2, 1, 3, 5, 7
681 var fromLinks = []; // 0, 1, 2, 3, 4, 5, 6, 7
682
683 var toLinks = [];
684 changed.forEach(function (_a) {
685 var from = _a[0],
686 to = _a[1];
687 var link = new Link();
688 fromLinks[from] = link;
689 toLinks[to] = link;
690 }); // `fromLinks` are connected to each other by double linked list.
691
692 fromLinks.forEach(function (link, i) {
693 link.connect(fromLinks[i - 1]);
694 });
695 return changed.filter(function (_, i) {
696 return !fixed[i];
697 }).map(function (_a, i) {
698 var from = _a[0],
699 to = _a[1];
700
701 if (from === to) {
702 return [0, 0];
703 }
704
705 var fromLink = fromLinks[from];
706 var toLink = toLinks[to - 1];
707 var fromIndex = fromLink.getIndex(); // Disconnect the link connected to `fromLink`.
708
709 fromLink.disconnect(); // Connect `fromLink` to the right of `toLink`.
710
711 if (!toLink) {
712 fromLink.connect(undefined, fromLinks[0]);
713 } else {
714 fromLink.connect(toLink, toLink.next);
715 }
716
717 var toIndex = fromLink.getIndex();
718 return [fromIndex, toIndex];
719 });
720 }
721
722 var Result =
723 /*#__PURE__*/
724 function () {
725 function Result(prevList, list, added, removed, changed, maintained, changedBeforeAdded, fixed) {
726 this.prevList = prevList;
727 this.list = list;
728 this.added = added;
729 this.removed = removed;
730 this.changed = changed;
731 this.maintained = maintained;
732 this.changedBeforeAdded = changedBeforeAdded;
733 this.fixed = fixed;
734 }
735
736 var __proto = Result.prototype;
737 Object.defineProperty(__proto, "ordered", {
738 get: function () {
739 if (!this.cacheOrdered) {
740 this.caculateOrdered();
741 }
742
743 return this.cacheOrdered;
744 },
745 enumerable: true,
746 configurable: true
747 });
748 Object.defineProperty(__proto, "pureChanged", {
749 get: function () {
750 if (!this.cachePureChanged) {
751 this.caculateOrdered();
752 }
753
754 return this.cachePureChanged;
755 },
756 enumerable: true,
757 configurable: true
758 });
759
760 __proto.caculateOrdered = function () {
761 var ordered = orderChanged(this.changedBeforeAdded, this.fixed);
762 var changed = this.changed;
763 var pureChanged = [];
764 this.cacheOrdered = ordered.filter(function (_a, i) {
765 var from = _a[0],
766 to = _a[1];
767 var _b = changed[i],
768 fromBefore = _b[0],
769 toBefore = _b[1];
770
771 if (from !== to) {
772 pureChanged.push([fromBefore, toBefore]);
773 return true;
774 }
775 });
776 this.cachePureChanged = pureChanged;
777 };
778
779 return Result;
780 }();
781
782 /**
783 *
784 * @memberof eg.ListDiffer
785 * @static
786 * @function
787 * @param - Previous List <ko> 이전 목록 </ko>
788 * @param - List to Update <ko> 업데이트 할 목록 </ko>
789 * @param - This callback function returns the key of the item. <ko> 아이템의 키를 반환하는 콜백 함수입니다.</ko>
790 * @return - Returns the diff between `prevList` and `list` <ko> `prevList`와 `list`의 다른 점을 반환한다.</ko>
791 * @example
792 * import { diff } from "@egjs/list-differ";
793 * // script => eg.ListDiffer.diff
794 * const result = diff([0, 1, 2, 3, 4, 5], [7, 8, 0, 4, 3, 6, 2, 1], e => e);
795 * // List before update
796 * // [1, 2, 3, 4, 5]
797 * console.log(result.prevList);
798 * // Updated list
799 * // [4, 3, 6, 2, 1]
800 * console.log(result.list);
801 * // Index array of values added to `list`
802 * // [0, 1, 5]
803 * console.log(result.added);
804 * // Index array of values removed in `prevList`
805 * // [5]
806 * console.log(result.removed);
807 * // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`
808 * // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
809 * console.log(result.changed);
810 * // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
811 * // [[4, 3], [3, 4], [2, 6]]
812 * console.log(result.pureChanged);
813 * // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
814 * // [[4, 1], [4, 2], [4, 3]]
815 * console.log(result.ordered);
816 * // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved
817 * // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
818 * console.log(result.maintained);
819 */
820
821 function diff(prevList, list, findKeyCallback) {
822 var mapClass = SUPPORT_MAP ? Map : findKeyCallback ? HashMap : PolyMap;
823
824 var callback = findKeyCallback || function (e) {
825 return e;
826 };
827
828 var added = [];
829 var removed = [];
830 var maintained = [];
831 var prevKeys = prevList.map(callback);
832 var keys = list.map(callback);
833 var prevKeyMap = new mapClass();
834 var keyMap = new mapClass();
835 var changedBeforeAdded = [];
836 var fixed = [];
837 var removedMap = {};
838 var changed = [];
839 var addedCount = 0;
840 var removedCount = 0; // Add prevKeys and keys to the hashmap.
841
842 prevKeys.forEach(function (key, prevListIndex) {
843 prevKeyMap.set(key, prevListIndex);
844 });
845 keys.forEach(function (key, listIndex) {
846 keyMap.set(key, listIndex);
847 }); // Compare `prevKeys` and `keys` and add them to `removed` if they are not in `keys`.
848
849 prevKeys.forEach(function (key, prevListIndex) {
850 var listIndex = keyMap.get(key); // In prevList, but not in list, it is removed.
851
852 if (typeof listIndex === "undefined") {
853 ++removedCount;
854 removed.push(prevListIndex);
855 } else {
856 removedMap[listIndex] = removedCount;
857 }
858 }); // Compare `prevKeys` and `keys` and add them to `added` if they are not in `prevKeys`.
859
860 keys.forEach(function (key, listIndex) {
861 var prevListIndex = prevKeyMap.get(key); // In list, but not in prevList, it is added.
862
863 if (typeof prevListIndex === "undefined") {
864 added.push(listIndex);
865 ++addedCount;
866 } else {
867 maintained.push([prevListIndex, listIndex]);
868 removedCount = removedMap[listIndex] || 0;
869 changedBeforeAdded.push([prevListIndex - removedCount, listIndex - addedCount]);
870 fixed.push(listIndex === prevListIndex);
871
872 if (prevListIndex !== listIndex) {
873 changed.push([prevListIndex, listIndex]);
874 }
875 }
876 }); // Sort by ascending order of 'to(list's index).
877
878 removed.reverse();
879 return new Result(prevList, list, added, removed, changed, maintained, changedBeforeAdded, fixed);
880 }
881
882 /*
883 Copyright (c) 2019-present NAVER Corp.
884 name: @egjs/children-differ
885 license: MIT
886 author: NAVER Corp.
887 repository: https://github.com/naver/egjs-children-differ
888 version: 1.0.1
889 */
890
891 /*
892 egjs-children-differ
893 Copyright (c) 2019-present NAVER Corp.
894 MIT license
895 */
896 var findKeyCallback = typeof Map === "function" ? undefined : function () {
897 var childrenCount = 0;
898 return function (el) {
899 return el.__DIFF_KEY__ || (el.__DIFF_KEY__ = ++childrenCount);
900 };
901 }();
902
903 /*
904 egjs-children-differ
905 Copyright (c) 2019-present NAVER Corp.
906 MIT license
907 */
908 /**
909 *
910 * @memberof eg.ChildrenDiffer
911 * @static
912 * @function
913 * @param - Previous List <ko> 이전 목록 </ko>
914 * @param - List to Update <ko> 업데이트 할 목록 </ko>
915 * @return - Returns the diff between `prevList` and `list` <ko> `prevList`와 `list`의 다른 점을 반환한다.</ko>
916 * @example
917 * import { diff } from "@egjs/children-differ";
918 * // script => eg.ChildrenDiffer.diff
919 * const result = diff([0, 1, 2, 3, 4, 5], [7, 8, 0, 4, 3, 6, 2, 1]);
920 * // List before update
921 * // [1, 2, 3, 4, 5]
922 * console.log(result.prevList);
923 * // Updated list
924 * // [4, 3, 6, 2, 1]
925 * console.log(result.list);
926 * // Index array of values added to `list`
927 * // [0, 1, 5]
928 * console.log(result.added);
929 * // Index array of values removed in `prevList`
930 * // [5]
931 * console.log(result.removed);
932 * // An array of index pairs of `prevList` and `list` with different indexes from `prevList` and `list`
933 * // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
934 * console.log(result.changed);
935 * // The subset of `changed` and an array of index pairs that moved data directly. Indicate an array of absolute index pairs of `ordered`.(Formatted by: Array<[index of prevList, index of list]>)
936 * // [[4, 3], [3, 4], [2, 6]]
937 * console.log(result.pureChanged);
938 * // An array of index pairs to be `ordered` that can synchronize `list` before adding data. (Formatted by: Array<[prevIndex, nextIndex]>)
939 * // [[4, 1], [4, 2], [4, 3]]
940 * console.log(result.ordered);
941 * // An array of index pairs of `prevList` and `list` that have not been added/removed so data is preserved
942 * // [[0, 2], [4, 3], [3, 4], [2, 6], [1, 7]]
943 * console.log(result.maintained);
944 */
945
946 function diff$1(prevList, list) {
947 return diff(prevList, list, findKeyCallback);
948 }
949
950 /*
951 Copyright (c) 2020-present NAVER Corp.
952 name: @egjs/imready
953 license: MIT
954 author: NAVER Corp.
955 repository: https://github.com/naver/egjs-imready
956 version: 1.3.0
957 */
958
959 /*! *****************************************************************************
960 Copyright (c) Microsoft Corporation.
961
962 Permission to use, copy, modify, and/or distribute this software for any
963 purpose with or without fee is hereby granted.
964
965 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
966 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
967 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
968 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
969 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
970 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
971 PERFORMANCE OF THIS SOFTWARE.
972 ***************************************************************************** */
973
974 /* global Reflect, Promise */
975 var extendStatics$1 = function (d, b) {
976 extendStatics$1 = Object.setPrototypeOf || {
977 __proto__: []
978 } instanceof Array && function (d, b) {
979 d.__proto__ = b;
980 } || function (d, b) {
981 for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
982 };
983
984 return extendStatics$1(d, b);
985 };
986
987 function __extends$1(d, b) {
988 extendStatics$1(d, b);
989
990 function __() {
991 this.constructor = d;
992 }
993
994 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
995 }
996 var __assign$1 = function () {
997 __assign$1 = Object.assign || function __assign(t) {
998 for (var s, i = 1, n = arguments.length; i < n; i++) {
999 s = arguments[i];
1000
1001 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
1002 }
1003
1004 return t;
1005 };
1006
1007 return __assign$1.apply(this, arguments);
1008 };
1009 function __spreadArrays$1() {
1010 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
1011
1012 for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j];
1013
1014 return r;
1015 }
1016
1017 /*
1018 egjs-imready
1019 Copyright (c) 2020-present NAVER Corp.
1020 MIT license
1021 */
1022 var isWindow = typeof window !== "undefined";
1023 var ua = isWindow ? window.navigator.userAgent : "";
1024 var SUPPORT_COMPUTEDSTYLE = isWindow ? !!("getComputedStyle" in window) : false;
1025 var IS_IE = /MSIE|Trident|Windows Phone|Edge/.test(ua);
1026 var SUPPORT_ADDEVENTLISTENER = isWindow ? !!("addEventListener" in document) : false;
1027 var WIDTH = "width";
1028 var HEIGHT = "height";
1029
1030 function getAttribute(el, name) {
1031 return el.getAttribute(name) || "";
1032 }
1033 function toArray(arr) {
1034 return [].slice.call(arr);
1035 }
1036 function hasSizeAttribute(target, prefix) {
1037 if (prefix === void 0) {
1038 prefix = "data-";
1039 }
1040
1041 return !!target.getAttribute(prefix + "width");
1042 }
1043 function hasLoadingAttribute(target, prefix) {
1044 if (prefix === void 0) {
1045 prefix = "data-";
1046 }
1047
1048 return "loading" in target && target.getAttribute("loading") === "lazy" || !!target.getAttribute(prefix + "lazy");
1049 }
1050 function hasSkipAttribute(target, prefix) {
1051 if (prefix === void 0) {
1052 prefix = "data-";
1053 }
1054
1055 return !!target.getAttribute(prefix + "skip");
1056 }
1057 function addEvent(element, type, handler) {
1058 if (SUPPORT_ADDEVENTLISTENER) {
1059 element.addEventListener(type, handler, false);
1060 } else if (element.attachEvent) {
1061 element.attachEvent("on" + type, handler);
1062 } else {
1063 element["on" + type] = handler;
1064 }
1065 }
1066 function removeEvent(element, type, handler) {
1067 if (element.removeEventListener) {
1068 element.removeEventListener(type, handler, false);
1069 } else if (element.detachEvent) {
1070 element.detachEvent("on" + type, handler);
1071 } else {
1072 element["on" + type] = null;
1073 }
1074 }
1075 function innerWidth(el) {
1076 return getSize(el, "Width");
1077 }
1078 function innerHeight(el) {
1079 return getSize(el, "Height");
1080 }
1081 function getStyles(el) {
1082 return (SUPPORT_COMPUTEDSTYLE ? window.getComputedStyle(el) : el.currentStyle) || {};
1083 }
1084
1085 function getSize(el, name) {
1086 var size = el["client" + name] || el["offset" + name];
1087 return parseFloat(size || getStyles(el)[name.toLowerCase()]) || 0;
1088 }
1089
1090 function getContentElements(element, tags, prefix) {
1091 var skipElements = toArray(element.querySelectorAll(__spreadArrays$1(["[" + prefix + "skip] [" + prefix + "width]"], tags.map(function (tag) {
1092 return ["[" + prefix + "skip] " + tag, tag + "[" + prefix + "skip]", "[" + prefix + "width] " + tag].join(", ");
1093 })).join(", ")));
1094 return toArray(element.querySelectorAll("[" + prefix + "width], " + tags.join(", "))).filter(function (el) {
1095 return skipElements.indexOf(el) === -1;
1096 });
1097 }
1098
1099 /*
1100 egjs-imready
1101 Copyright (c) 2020-present NAVER Corp.
1102 MIT license
1103 */
1104 var elements = [];
1105 function addAutoSizer(element, prefix) {
1106 !elements.length && addEvent(window, "resize", resizeAllAutoSizers);
1107 element.__PREFIX__ = prefix;
1108 elements.push(element);
1109 resize(element);
1110 }
1111 function removeAutoSizer(element, prefix) {
1112 var index = elements.indexOf(element);
1113
1114 if (index < 0) {
1115 return;
1116 }
1117
1118 var fixed = getAttribute(element, prefix + "fixed");
1119 delete element.__PREFIX__;
1120 element.style[fixed === HEIGHT ? WIDTH : HEIGHT] = "";
1121 elements.splice(index, 1);
1122 !elements.length && removeEvent(window, "resize", resizeAllAutoSizers);
1123 }
1124
1125 function resize(element, prefix) {
1126 if (prefix === void 0) {
1127 prefix = "data-";
1128 }
1129
1130 var elementPrefix = element.__PREFIX__ || prefix;
1131 var dataWidth = parseInt(getAttribute(element, "" + elementPrefix + WIDTH), 10) || 0;
1132 var dataHeight = parseInt(getAttribute(element, "" + elementPrefix + HEIGHT), 10) || 0;
1133 var fixed = getAttribute(element, elementPrefix + "fixed");
1134
1135 if (fixed === HEIGHT) {
1136 var size = innerHeight(element) || dataHeight;
1137 element.style[WIDTH] = dataWidth / dataHeight * size + "px";
1138 } else {
1139 var size = innerWidth(element) || dataWidth;
1140 element.style[HEIGHT] = dataHeight / dataWidth * size + "px";
1141 }
1142 }
1143
1144 function resizeAllAutoSizers() {
1145 elements.forEach(function (element) {
1146 resize(element);
1147 });
1148 }
1149
1150 var Loader =
1151 /*#__PURE__*/
1152 function (_super) {
1153 __extends$1(Loader, _super);
1154
1155 function Loader(element, options) {
1156 if (options === void 0) {
1157 options = {};
1158 }
1159
1160 var _this = _super.call(this) || this;
1161
1162 _this.isReady = false;
1163 _this.isPreReady = false;
1164 _this.hasDataSize = false;
1165 _this.hasLoading = false;
1166 _this.isSkip = false;
1167
1168 _this.onCheck = function (e) {
1169 _this.clear();
1170
1171 if (e && e.type === "error") {
1172 _this.onError(_this.element);
1173 }
1174
1175 if (_this.hasLoading && _this.checkElement()) {
1176 // I'm not ready
1177 return;
1178 } // I'm pre-ready and ready!
1179
1180
1181 var withPreReady = !_this.hasDataSize && !_this.hasLoading;
1182
1183 _this.onReady(withPreReady);
1184 };
1185
1186 _this.options = __assign$1({
1187 prefix: "data-"
1188 }, options);
1189 _this.element = element;
1190 var prefix = _this.options.prefix;
1191 _this.hasDataSize = hasSizeAttribute(element, prefix);
1192 _this.isSkip = hasSkipAttribute(element, prefix);
1193 _this.hasLoading = hasLoadingAttribute(element, prefix);
1194 return _this;
1195 }
1196
1197 var __proto = Loader.prototype;
1198
1199 __proto.check = function () {
1200 if (this.isSkip || !this.checkElement()) {
1201 // I'm Ready
1202 this.onAlreadyReady(true);
1203 return false;
1204 }
1205
1206 if (this.hasDataSize) {
1207 addAutoSizer(this.element, this.options.prefix);
1208 }
1209
1210 if (this.hasDataSize || this.hasLoading) {
1211 // I'm Pre Ready
1212 this.onAlreadyPreReady();
1213 } // Wati Pre Ready, Ready
1214
1215
1216 return true;
1217 };
1218
1219 __proto.addEvents = function () {
1220 var _this = this;
1221
1222 var element = this.element;
1223 this.constructor.EVENTS.forEach(function (name) {
1224 addEvent(element, name, _this.onCheck);
1225 });
1226 };
1227
1228 __proto.clear = function () {
1229 var _this = this;
1230
1231 var element = this.element;
1232 this.constructor.EVENTS.forEach(function (name) {
1233 removeEvent(element, name, _this.onCheck);
1234 });
1235 this.removeAutoSizer();
1236 };
1237
1238 __proto.destroy = function () {
1239 this.clear();
1240 this.off();
1241 };
1242
1243 __proto.removeAutoSizer = function () {
1244 if (this.hasDataSize) {
1245 // I'm already ready.
1246 var prefix = this.options.prefix;
1247 removeAutoSizer(this.element, prefix);
1248 }
1249 };
1250
1251 __proto.onError = function (target) {
1252 this.trigger("error", {
1253 element: this.element,
1254 target: target
1255 });
1256 };
1257
1258 __proto.onPreReady = function () {
1259 if (this.isPreReady) {
1260 return;
1261 }
1262
1263 this.isPreReady = true;
1264 this.trigger("preReady", {
1265 element: this.element,
1266 hasLoading: this.hasLoading,
1267 isSkip: this.isSkip
1268 });
1269 };
1270
1271 __proto.onReady = function (withPreReady) {
1272 if (this.isReady) {
1273 return;
1274 }
1275
1276 withPreReady = !this.isPreReady && withPreReady;
1277
1278 if (withPreReady) {
1279 this.isPreReady = true;
1280 }
1281
1282 this.removeAutoSizer();
1283 this.isReady = true;
1284 this.trigger("ready", {
1285 element: this.element,
1286 withPreReady: withPreReady,
1287 hasLoading: this.hasLoading,
1288 isSkip: this.isSkip
1289 });
1290 };
1291
1292 __proto.onAlreadyError = function (target) {
1293 var _this = this;
1294
1295 setTimeout(function () {
1296 _this.onError(target);
1297 });
1298 };
1299
1300 __proto.onAlreadyPreReady = function () {
1301 var _this = this;
1302
1303 setTimeout(function () {
1304 _this.onPreReady();
1305 });
1306 };
1307
1308 __proto.onAlreadyReady = function (withPreReady) {
1309 var _this = this;
1310
1311 setTimeout(function () {
1312 _this.onReady(withPreReady);
1313 });
1314 };
1315
1316 Loader.EVENTS = [];
1317 return Loader;
1318 }(Component);
1319
1320 var ElementLoader =
1321 /*#__PURE__*/
1322 function (_super) {
1323 __extends$1(ElementLoader, _super);
1324
1325 function ElementLoader() {
1326 return _super !== null && _super.apply(this, arguments) || this;
1327 }
1328
1329 var __proto = ElementLoader.prototype;
1330
1331 __proto.setHasLoading = function (hasLoading) {
1332 this.hasLoading = hasLoading;
1333 };
1334
1335 __proto.check = function () {
1336 if (this.isSkip) {
1337 // I'm Ready
1338 this.onAlreadyReady(true);
1339 return false;
1340 }
1341
1342 if (this.hasDataSize) {
1343 addAutoSizer(this.element, this.options.prefix);
1344 this.onAlreadyPreReady();
1345 } else {
1346 // has not data size
1347 this.trigger("requestChildren");
1348 }
1349
1350 return true;
1351 };
1352
1353 __proto.checkElement = function () {
1354 return true;
1355 };
1356
1357 __proto.destroy = function () {
1358 this.clear();
1359 this.trigger("requestDestroy");
1360 this.off();
1361 };
1362
1363 __proto.onAlreadyPreReady = function () {
1364 // has data size
1365 _super.prototype.onAlreadyPreReady.call(this);
1366
1367 this.trigger("reqeustReadyChildren");
1368 };
1369
1370 ElementLoader.EVENTS = [];
1371 return ElementLoader;
1372 }(Loader);
1373
1374 /**
1375 * @alias eg.ImReady
1376 * @extends eg.Component
1377 */
1378
1379 var ImReadyManager =
1380 /*#__PURE__*/
1381 function (_super) {
1382 __extends$1(ImReadyManager, _super);
1383 /**
1384 * @param - ImReady's options
1385 */
1386
1387
1388 function ImReadyManager(options) {
1389 if (options === void 0) {
1390 options = {};
1391 }
1392
1393 var _this = _super.call(this) || this;
1394
1395 _this.readyCount = 0;
1396 _this.preReadyCount = 0;
1397 _this.totalCount = 0;
1398 _this.totalErrorCount = 0;
1399 _this.isPreReadyOver = true;
1400 _this.elementInfos = [];
1401 _this.options = __assign$1({
1402 loaders: {},
1403 prefix: "data-"
1404 }, options);
1405 return _this;
1406 }
1407 /**
1408 * Checks whether elements are in the ready state.
1409 * @ko 엘리먼트가 준비 상태인지 체크한다.
1410 * @elements - Elements to check ready status. <ko> 준비 상태를 체크할 엘리먼트들.</ko>
1411 * @example
1412 * ```html
1413 * <div>
1414 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
1415 * <img src="./2.jpg" data-width="1280" data-height="853"/>
1416 * <img src="ERR" data-width="1280" data-height="853"/>
1417 * </div>
1418 * ```
1419 * ## Javascript
1420 * ```js
1421 * import ImReady from "@egjs/imready";
1422 *
1423 * const im = new ImReady(); // umd: eg.ImReady
1424 * im.check(document.querySelectorAll("img")).on({
1425 * preReadyElement: e => {
1426 * // 1, 3
1427 * // 2, 3
1428 * // 3, 3
1429 * console.log(e.preReadyCount, e.totalCount),
1430 * },
1431 * });
1432 * ```
1433 */
1434
1435
1436 var __proto = ImReadyManager.prototype;
1437
1438 __proto.check = function (elements) {
1439 var _this = this;
1440
1441 var prefix = this.options.prefix;
1442 this.clear();
1443 this.elementInfos = toArray(elements).map(function (element, index) {
1444 var loader = _this.getLoader(element, {
1445 prefix: prefix
1446 });
1447
1448 loader.check();
1449 loader.on("error", function (e) {
1450 _this.onError(index, e.target);
1451 }).on("preReady", function (e) {
1452 var info = _this.elementInfos[index];
1453 info.hasLoading = e.hasLoading;
1454 info.isSkip = e.isSkip;
1455
1456 var isPreReady = _this.checkPreReady(index);
1457
1458 _this.onPreReadyElement(index);
1459
1460 isPreReady && _this.onPreReady();
1461 }).on("ready", function (_a) {
1462 var withPreReady = _a.withPreReady,
1463 hasLoading = _a.hasLoading,
1464 isSkip = _a.isSkip;
1465 var info = _this.elementInfos[index];
1466 info.hasLoading = hasLoading;
1467 info.isSkip = isSkip;
1468
1469 var isPreReady = withPreReady && _this.checkPreReady(index);
1470
1471 var isReady = _this.checkReady(index); // Pre-ready and ready occur simultaneously
1472
1473
1474 withPreReady && _this.onPreReadyElement(index);
1475
1476 _this.onReadyElement(index);
1477
1478 isPreReady && _this.onPreReady();
1479 isReady && _this.onReady();
1480 });
1481 return {
1482 loader: loader,
1483 element: element,
1484 hasLoading: false,
1485 hasError: false,
1486 isPreReady: false,
1487 isReady: false,
1488 isSkip: false
1489 };
1490 });
1491 var length = this.elementInfos.length;
1492 this.totalCount = length;
1493
1494 if (!length) {
1495 setTimeout(function () {
1496 _this.onPreReady();
1497
1498 _this.onReady();
1499 });
1500 }
1501
1502 return this;
1503 };
1504 /**
1505 * Gets the total count of elements to be checked.
1506 * @ko 체크하는 element의 총 개수를 가져온다.
1507 */
1508
1509
1510 __proto.getTotalCount = function () {
1511 return this.totalCount;
1512 };
1513 /**
1514 * Whether the elements are all pre-ready. (all sizes are known)
1515 * @ko 엘리먼트들이 모두 사전 준비가 됐는지 (사이즈를 전부 알 수 있는지) 여부.
1516 */
1517
1518
1519 __proto.isPreReady = function () {
1520 return this.elementInfos.every(function (info) {
1521 return info.isPreReady;
1522 });
1523 };
1524 /**
1525 * Whether the elements are all ready.
1526 * @ko 엘리먼트들이 모두 준비가 됐는지 여부.
1527 */
1528
1529
1530 __proto.isReady = function () {
1531 return this.elementInfos.every(function (info) {
1532 return info.isReady;
1533 });
1534 };
1535 /**
1536 * Whether an error has occurred in the elements in the current state.
1537 * @ko 현재 상태에서 엘리먼트들이 에러가 발생했는지 여부.
1538 */
1539
1540
1541 __proto.hasError = function () {
1542 return this.totalErrorCount > 0;
1543 };
1544 /**
1545 * Clears events of elements being checked.
1546 * @ko 체크 중인 엘리먼트들의 이벤트를 해제 한다.
1547 */
1548
1549
1550 __proto.clear = function () {
1551 this.isPreReadyOver = false;
1552 this.totalCount = 0;
1553 this.preReadyCount = 0;
1554 this.readyCount = 0;
1555 this.totalErrorCount = 0;
1556 this.elementInfos.forEach(function (info) {
1557 if (!info.isReady && info.loader) {
1558 info.loader.destroy();
1559 }
1560 });
1561 this.elementInfos = [];
1562 };
1563 /**
1564 * Destory all events.
1565 * @ko 모든 이벤트를 해제 한다.
1566 */
1567
1568
1569 __proto.destroy = function () {
1570 this.clear();
1571 this.off();
1572 };
1573
1574 __proto.getLoader = function (element, options) {
1575 var _this = this;
1576
1577 var tagName = element.tagName.toLowerCase();
1578 var loaders = this.options.loaders;
1579 var prefix = options.prefix;
1580 var tags = Object.keys(loaders);
1581
1582 if (loaders[tagName]) {
1583 return new loaders[tagName](element, options);
1584 }
1585
1586 var loader = new ElementLoader(element, options);
1587 var children = toArray(element.querySelectorAll(tags.join(", ")));
1588 loader.setHasLoading(children.some(function (el) {
1589 return hasLoadingAttribute(el, prefix);
1590 }));
1591 var withPreReady = false;
1592 var childrenImReady = this.clone().on("error", function (e) {
1593 loader.onError(e.target);
1594 }).on("ready", function () {
1595 loader.onReady(withPreReady);
1596 });
1597 loader.on("requestChildren", function () {
1598 // has not data size
1599 var contentElements = getContentElements(element, tags, _this.options.prefix);
1600 childrenImReady.check(contentElements).on("preReady", function (e) {
1601 withPreReady = e.isReady;
1602
1603 if (!withPreReady) {
1604 loader.onPreReady();
1605 }
1606 });
1607 }).on("reqeustReadyChildren", function () {
1608 // has data size
1609 // loader call preReady
1610 // check only video, image elements
1611 childrenImReady.check(children);
1612 }).on("requestDestroy", function () {
1613 childrenImReady.destroy();
1614 });
1615 return loader;
1616 };
1617
1618 __proto.clone = function () {
1619 return new ImReadyManager(__assign$1({}, this.options));
1620 };
1621
1622 __proto.checkPreReady = function (index) {
1623 this.elementInfos[index].isPreReady = true;
1624 ++this.preReadyCount;
1625
1626 if (this.preReadyCount < this.totalCount) {
1627 return false;
1628 }
1629
1630 return true;
1631 };
1632
1633 __proto.checkReady = function (index) {
1634 this.elementInfos[index].isReady = true;
1635 ++this.readyCount;
1636
1637 if (this.readyCount < this.totalCount) {
1638 return false;
1639 }
1640
1641 return true;
1642 };
1643
1644 __proto.onError = function (index, target) {
1645 var info = this.elementInfos[index];
1646 info.hasError = true;
1647 /**
1648 * An event occurs if the image, video fails to load.
1649 * @ko 이미지, 비디오가 로딩에 실패하면 이벤트가 발생한다.
1650 * @event eg.ImReady#error
1651 * @param {eg.ImReady.OnError} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
1652 * @example
1653 * ```html
1654 * <div>
1655 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
1656 * <img src="./2.jpg"/>
1657 * <img src="ERR"/>
1658 * </div>
1659 * ```
1660 * ## Javascript
1661 * ```js
1662 * import ImReady from "@egjs/imready";
1663 *
1664 * const im = new ImReady(); // umd: eg.ImReady
1665 * im.check([document.querySelector("div")]).on({
1666 * error: e => {
1667 * // <div>...</div>, 0, <img src="ERR"/>
1668 * console.log(e.element, e.index, e.target),
1669 * },
1670 * });
1671 * ```
1672 */
1673
1674 this.trigger(new ComponentEvent$1("error", {
1675 element: info.element,
1676 index: index,
1677 target: target,
1678 errorCount: this.getErrorCount(),
1679 totalErrorCount: ++this.totalErrorCount
1680 }));
1681 };
1682
1683 __proto.onPreReadyElement = function (index) {
1684 var info = this.elementInfos[index];
1685 /**
1686 * An event occurs when the element is pre-ready (when the loading attribute is applied or the size is known)
1687 * @ko 해당 엘리먼트가 사전 준비되었을 때(loading 속성이 적용되었거나 사이즈를 알 수 있을 때) 이벤트가 발생한다.
1688 * @event eg.ImReady#preReadyElement
1689 * @param {eg.ImReady.OnPreReadyElement} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
1690 * @example
1691 * ```html
1692 * <div>
1693 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
1694 * <img src="./2.jpg" data-width="1280" data-height="853"/>
1695 * <img src="ERR" data-width="1280" data-height="853"/>
1696 * </div>
1697 * ```
1698 * ## Javascript
1699 * ```js
1700 * import ImReady from "@egjs/imready";
1701 *
1702 * const im = new ImReady(); // umd: eg.ImReady
1703 * im.check(document.querySelectorAll("img")).on({
1704 * preReadyElement: e => {
1705 * // 1, 3
1706 * // 2, 3
1707 * // 3, 3
1708 * console.log(e.preReadyCount, e.totalCount),
1709 * },
1710 * });
1711 * ```
1712 */
1713
1714 this.trigger(new ComponentEvent$1("preReadyElement", {
1715 element: info.element,
1716 index: index,
1717 preReadyCount: this.preReadyCount,
1718 readyCount: this.readyCount,
1719 totalCount: this.totalCount,
1720 isPreReady: this.isPreReady(),
1721 isReady: this.isReady(),
1722 hasLoading: info.hasLoading,
1723 isSkip: info.isSkip
1724 }));
1725 };
1726
1727 __proto.onPreReady = function () {
1728 this.isPreReadyOver = true;
1729 /**
1730 * An event occurs when all element are pre-ready (When all elements have the loading attribute applied or the size is known)
1731 * @ko 모든 엘리먼트들이 사전 준비된 경우 (모든 엘리먼트들이 loading 속성이 적용되었거나 사이즈를 알 수 있는 경우) 이벤트가 발생한다.
1732 * @event eg.ImReady#preReady
1733 * @param {eg.ImReady.OnPreReady} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
1734 * @example
1735 * ```html
1736 * <div>
1737 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
1738 * <img src="./2.jpg" data-width="1280" data-height="853"/>
1739 * <img src="ERR" data-width="1280" data-height="853"/>
1740 * </div>
1741 * ```
1742 * ## Javascript
1743 * ```js
1744 * import ImReady from "@egjs/imready";
1745 *
1746 * const im = new ImReady(); // umd: eg.ImReady
1747 * im.check(document.querySelectorAll("img")).on({
1748 * preReady: e => {
1749 * // 0, 3
1750 * console.log(e.readyCount, e.totalCount),
1751 * },
1752 * });
1753 * ```
1754 */
1755
1756 this.trigger(new ComponentEvent$1("preReady", {
1757 readyCount: this.readyCount,
1758 totalCount: this.totalCount,
1759 isReady: this.isReady(),
1760 hasLoading: this.hasLoading()
1761 }));
1762 };
1763
1764 __proto.onReadyElement = function (index) {
1765 var info = this.elementInfos[index];
1766 /**
1767 * An event occurs when the element is ready
1768 * @ko 해당 엘리먼트가 준비가 되었을 때 이벤트가 발생한다.
1769 * @event eg.ImReady#readyElement
1770 * @param {eg.ImReady.OnReadyElement} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
1771 * @example
1772 * ```html
1773 * <div>
1774 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
1775 * <img src="./2.jpg" data-width="1280" data-height="853"/>
1776 * <img src="ERR" data-width="1280" data-height="853"/>
1777 * </div>
1778 * ```
1779 * ## Javascript
1780 * ```js
1781 * import ImReady from "@egjs/imready";
1782 *
1783 * const im = new ImReady(); // umd: eg.ImReady
1784 * im.check(document.querySelectorAll("img")).on({
1785 * readyElement: e => {
1786 * // 1, 0, false, 3
1787 * // 2, 1, false, 3
1788 * // 3, 2, true, 3
1789 * console.log(e.readyCount, e.index, e.hasError, e.totalCount),
1790 * },
1791 * });
1792 * ```
1793 */
1794
1795 this.trigger(new ComponentEvent$1("readyElement", {
1796 index: index,
1797 element: info.element,
1798 hasError: info.hasError,
1799 errorCount: this.getErrorCount(),
1800 totalErrorCount: this.totalErrorCount,
1801 preReadyCount: this.preReadyCount,
1802 readyCount: this.readyCount,
1803 totalCount: this.totalCount,
1804 isPreReady: this.isPreReady(),
1805 isReady: this.isReady(),
1806 hasLoading: info.hasLoading,
1807 isPreReadyOver: this.isPreReadyOver,
1808 isSkip: info.isSkip
1809 }));
1810 };
1811
1812 __proto.onReady = function () {
1813 /**
1814 * An event occurs when all element are ready
1815 * @ko 모든 엘리먼트들이 준비된 경우 이벤트가 발생한다.
1816 * @event eg.ImReady#ready
1817 * @param {eg.ImReady.OnReady} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
1818 * @example
1819 * ```html
1820 * <div>
1821 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
1822 * <img src="./2.jpg" data-width="1280" data-height="853"/>
1823 * <img src="ERR" data-width="1280" data-height="853"/>
1824 * </div>
1825 * ```
1826 * ## Javascript
1827 * ```js
1828 * import ImReady from "@egjs/imready";
1829 *
1830 * const im = new ImReady(); // umd: eg.ImReady
1831 * im.check(document.querySelectorAll("img")).on({
1832 * preReady: e => {
1833 * // 0, 3
1834 * console.log(e.readyCount, e.totalCount),
1835 * },
1836 * ready: e => {
1837 * // 1, 3
1838 * console.log(e.errorCount, e.totalCount),
1839 * },
1840 * });
1841 * ```
1842 */
1843 this.trigger(new ComponentEvent$1("ready", {
1844 errorCount: this.getErrorCount(),
1845 totalErrorCount: this.totalErrorCount,
1846 totalCount: this.totalCount
1847 }));
1848 };
1849
1850 __proto.getErrorCount = function () {
1851 return this.elementInfos.filter(function (info) {
1852 return info.hasError;
1853 }).length;
1854 };
1855
1856 __proto.hasLoading = function () {
1857 return this.elementInfos.some(function (info) {
1858 return info.hasLoading;
1859 });
1860 };
1861
1862 return ImReadyManager;
1863 }(Component);
1864
1865 var ImageLoader =
1866 /*#__PURE__*/
1867 function (_super) {
1868 __extends$1(ImageLoader, _super);
1869
1870 function ImageLoader() {
1871 return _super !== null && _super.apply(this, arguments) || this;
1872 }
1873
1874 var __proto = ImageLoader.prototype;
1875
1876 __proto.checkElement = function () {
1877 var element = this.element;
1878 var src = element.getAttribute("src");
1879
1880 if (element.complete) {
1881 if (src) {
1882 // complete
1883 if (!element.naturalWidth) {
1884 this.onAlreadyError(element);
1885 }
1886
1887 return false;
1888 } else {
1889 // Using an external lazy loading module
1890 this.onAlreadyPreReady();
1891 }
1892 }
1893
1894 this.addEvents();
1895 IS_IE && element.setAttribute("src", src);
1896 return true;
1897 };
1898
1899 ImageLoader.EVENTS = ["load", "error"];
1900 return ImageLoader;
1901 }(Loader);
1902
1903 var VideoLoader =
1904 /*#__PURE__*/
1905 function (_super) {
1906 __extends$1(VideoLoader, _super);
1907
1908 function VideoLoader() {
1909 return _super !== null && _super.apply(this, arguments) || this;
1910 }
1911
1912 var __proto = VideoLoader.prototype;
1913
1914 __proto.checkElement = function () {
1915 var element = this.element; // HAVE_NOTHING: 0, no information whether or not the audio/video is ready
1916 // HAVE_METADATA: 1, HAVE_METADATA - metadata for the audio/video is ready
1917 // HAVE_CURRENT_DATA: 2, data for the current playback position is available, but not enough data to play next frame/millisecond
1918 // HAVE_FUTURE_DATA: 3, data for the current and at least the next frame is available
1919 // HAVE_ENOUGH_DATA: 4, enough data available to start playing
1920
1921 if (element.readyState >= 1) {
1922 return false;
1923 }
1924
1925 if (element.error) {
1926 this.onAlreadyError(element);
1927 return false;
1928 }
1929
1930 this.addEvents();
1931 return true;
1932 };
1933
1934 VideoLoader.EVENTS = ["loadedmetadata", "error"];
1935 return VideoLoader;
1936 }(Loader);
1937
1938 var ImReady =
1939 /*#__PURE__*/
1940 function (_super) {
1941 __extends$1(ImReady, _super);
1942
1943 function ImReady(options) {
1944 if (options === void 0) {
1945 options = {};
1946 }
1947
1948 return _super.call(this, __assign$1({
1949 loaders: {
1950 img: ImageLoader,
1951 video: VideoLoader
1952 }
1953 }, options)) || this;
1954 }
1955
1956 return ImReady;
1957 }(ImReadyManager);
1958
1959 /*
1960 Copyright (c) 2021-present NAVER Corp.
1961 name: @egjs/grid
1962 license: MIT
1963 author: NAVER Corp.
1964 repository: https://github.com/naver/egjs-grid
1965 version: 1.11.0
1966 */
1967
1968 /*! *****************************************************************************
1969 Copyright (c) Microsoft Corporation.
1970
1971 Permission to use, copy, modify, and/or distribute this software for any
1972 purpose with or without fee is hereby granted.
1973
1974 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1975 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1976 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1977 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1978 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1979 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1980 PERFORMANCE OF THIS SOFTWARE.
1981 ***************************************************************************** */
1982
1983 /* global Reflect, Promise */
1984 var extendStatics$2 = function (d, b) {
1985 extendStatics$2 = Object.setPrototypeOf || {
1986 __proto__: []
1987 } instanceof Array && function (d, b) {
1988 d.__proto__ = b;
1989 } || function (d, b) {
1990 for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
1991 };
1992
1993 return extendStatics$2(d, b);
1994 };
1995
1996 function __extends$2(d, b) {
1997 if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
1998 extendStatics$2(d, b);
1999
2000 function __() {
2001 this.constructor = d;
2002 }
2003
2004 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
2005 }
2006 var __assign$2 = function () {
2007 __assign$2 = Object.assign || function __assign(t) {
2008 for (var s, i = 1, n = arguments.length; i < n; i++) {
2009 s = arguments[i];
2010
2011 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
2012 }
2013
2014 return t;
2015 };
2016
2017 return __assign$2.apply(this, arguments);
2018 };
2019 function __decorate$1(decorators, target, key, desc) {
2020 var c = arguments.length,
2021 r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
2022 d;
2023 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2024 return c > 3 && r && Object.defineProperty(target, key, r), r;
2025 }
2026 function __spreadArray(to, from) {
2027 for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i];
2028
2029 return to;
2030 }
2031
2032 var DEFAULT_GRID_OPTIONS = {
2033 horizontal: false,
2034 useTransform: false,
2035 percentage: false,
2036 isEqualSize: false,
2037 isConstantSize: false,
2038 gap: 0,
2039 attributePrefix: "data-grid-",
2040 resizeDebounce: 100,
2041 maxResizeDebounce: 0,
2042 autoResize: true,
2043 preserveUIOnDestroy: false,
2044 defaultDirection: "end",
2045 externalContainerManager: null,
2046 externalItemRenderer: null,
2047 renderOnPropertyChange: true,
2048 useFit: true,
2049 outlineLength: 0,
2050 outlineSize: 0,
2051 useRoundedSize: true,
2052 useResizeObserver: false,
2053 observeChildren: false
2054 };
2055 var PROPERTY_TYPE;
2056
2057 (function (PROPERTY_TYPE) {
2058 PROPERTY_TYPE[PROPERTY_TYPE["PROPERTY"] = 1] = "PROPERTY";
2059 PROPERTY_TYPE[PROPERTY_TYPE["RENDER_PROPERTY"] = 2] = "RENDER_PROPERTY";
2060 })(PROPERTY_TYPE || (PROPERTY_TYPE = {}));
2061
2062 var MOUNT_STATE;
2063
2064 (function (MOUNT_STATE) {
2065 MOUNT_STATE[MOUNT_STATE["UNCHECKED"] = 1] = "UNCHECKED";
2066 MOUNT_STATE[MOUNT_STATE["UNMOUNTED"] = 2] = "UNMOUNTED";
2067 MOUNT_STATE[MOUNT_STATE["MOUNTED"] = 3] = "MOUNTED";
2068 })(MOUNT_STATE || (MOUNT_STATE = {}));
2069
2070 var UPDATE_STATE;
2071
2072 (function (UPDATE_STATE) {
2073 UPDATE_STATE[UPDATE_STATE["NEED_UPDATE"] = 1] = "NEED_UPDATE";
2074 UPDATE_STATE[UPDATE_STATE["WAIT_LOADING"] = 2] = "WAIT_LOADING";
2075 UPDATE_STATE[UPDATE_STATE["UPDATED"] = 3] = "UPDATED";
2076 })(UPDATE_STATE || (UPDATE_STATE = {}));
2077
2078 var GRID_PROPERTY_TYPES = {
2079 gap: PROPERTY_TYPE.RENDER_PROPERTY,
2080 defaultDirection: PROPERTY_TYPE.PROPERTY,
2081 renderOnPropertyChange: PROPERTY_TYPE.PROPERTY,
2082 preserveUIOnDestroy: PROPERTY_TYPE.PROPERTY,
2083 useFit: PROPERTY_TYPE.PROPERTY,
2084 outlineSize: PROPERTY_TYPE.RENDER_PROPERTY,
2085 outlineLength: PROPERTY_TYPE.RENDER_PROPERTY
2086 };
2087 var RECT_NAMES = {
2088 horizontal: {
2089 inlinePos: "top",
2090 contentPos: "left",
2091 inlineSize: "height",
2092 contentSize: "width"
2093 },
2094 vertical: {
2095 inlinePos: "left",
2096 contentPos: "top",
2097 inlineSize: "width",
2098 contentSize: "height"
2099 }
2100 };
2101
2102 function getKeys(obj) {
2103 return Object.keys(obj);
2104 }
2105 function getUpdatedItems(items, entries) {
2106 var mountedItems = getMountedItems(items);
2107 return diff$1(entries.map(function (entry) {
2108 return entry.target;
2109 }), mountedItems.map(function (item) {
2110 return item.element;
2111 })).maintained.filter(function (_a) {
2112 var prevIndex = _a[0],
2113 nextIndex = _a[1];
2114 var entrySize = entries[prevIndex].size;
2115 var item = items[nextIndex];
2116 return entrySize.inlineSize !== item.computedInlineSize || entrySize.blockSize !== item.computedContentSize;
2117 }).map(function (_a) {
2118 var nextIndex = _a[1];
2119 return items[nextIndex];
2120 });
2121 }
2122 function getMountedItems(items) {
2123 return items.filter(function (item) {
2124 return item.element;
2125 });
2126 }
2127 function getMountedElements(items) {
2128 return getMountedItems(items).map(function (item) {
2129 return item.element;
2130 });
2131 }
2132 function isString(val) {
2133 return typeof val === "string";
2134 }
2135 function isObject(val) {
2136 return typeof val === "object";
2137 }
2138 function isNumber(val) {
2139 return typeof val === "number";
2140 }
2141 function camelize(str) {
2142 return str.replace(/[\s-_]([a-z])/g, function (all, letter) {
2143 return letter.toUpperCase();
2144 });
2145 }
2146 function getDataAttributes(element, attributePrefix) {
2147 var dataAttributes = {};
2148 var attributes = element.attributes;
2149 var length = attributes.length;
2150
2151 for (var i = 0; i < length; ++i) {
2152 var attribute = attributes[i];
2153 var name = attribute.name,
2154 value = attribute.value;
2155
2156 if (name.indexOf(attributePrefix) === -1) {
2157 continue;
2158 }
2159
2160 dataAttributes[camelize(name.replace(attributePrefix, ""))] = value;
2161 }
2162
2163 return dataAttributes;
2164 }
2165 /* Class Decorator */
2166
2167 function GetterSetter(component) {
2168 var prototype = component.prototype,
2169 propertyTypes = component.propertyTypes;
2170
2171 var _loop_1 = function (name) {
2172 var shouldRender = propertyTypes[name] === PROPERTY_TYPE.RENDER_PROPERTY;
2173 var descriptor = Object.getOwnPropertyDescriptor(prototype, name) || {};
2174
2175 var getter = descriptor.get || function get() {
2176 return this.options[name];
2177 };
2178
2179 var setter = descriptor.set || function set(value) {
2180 var options = this.options;
2181 var prevValue = options[name];
2182
2183 if (prevValue === value) {
2184 return;
2185 }
2186
2187 options[name] = value;
2188
2189 if (shouldRender && options.renderOnPropertyChange) {
2190 this.scheduleRender();
2191 }
2192 };
2193
2194 var attributes = {
2195 enumerable: true,
2196 configurable: true,
2197 get: getter,
2198 set: setter
2199 };
2200 Object.defineProperty(prototype, name, attributes);
2201 };
2202
2203 for (var name in propertyTypes) {
2204 _loop_1(name);
2205 }
2206 }
2207 function withMethods(methods) {
2208 return function (prototype, memberName) {
2209 methods.forEach(function (name) {
2210 if (name in prototype) {
2211 return;
2212 }
2213
2214 prototype[name] = function () {
2215 var _a;
2216
2217 var args = [];
2218
2219 for (var _i = 0; _i < arguments.length; _i++) {
2220 args[_i] = arguments[_i];
2221 }
2222
2223 var result = (_a = this[memberName])[name].apply(_a, args); // fix `this` type to return your own `class` instance to the instance using the decorator.
2224
2225
2226 if (result === this[memberName]) {
2227 return this;
2228 } else {
2229 return result;
2230 }
2231 };
2232 });
2233 };
2234 }
2235 function range(length) {
2236 var arr = [];
2237
2238 for (var i = 0; i < length; ++i) {
2239 arr.push(i);
2240 }
2241
2242 return arr;
2243 }
2244 function getRangeCost(value, valueRange) {
2245 return Math.max(value - valueRange[1], valueRange[0] - value, 0) + 1;
2246 }
2247
2248 var ResizeWatcher =
2249 /*#__PURE__*/
2250 function () {
2251 function ResizeWatcher(container, options) {
2252 var _this = this;
2253
2254 if (options === void 0) {
2255 options = {};
2256 }
2257
2258 this._resizeTimer = 0;
2259 this._maxResizeDebounceTimer = 0;
2260 this.rect = {
2261 width: 0,
2262 height: 0
2263 };
2264 this._updatedEntries = [];
2265
2266 this._onWindowResize = function () {
2267 _this._scheduleResize([{
2268 target: _this.container
2269 }]);
2270 };
2271
2272 this._onObserve = function (entries) {
2273 var options = _this._options;
2274 var container = _this.container;
2275 var containerRectBox = options.rectBox;
2276 var childrenRectBox = options.childrenRectBox;
2277
2278 _this._scheduleResize(entries.map(function (entry) {
2279 var target = entry.target;
2280 var rectBox = target === container ? containerRectBox : childrenRectBox;
2281 var sizes = rectBox === "border-box" ? entry.borderBoxSize : entry.contentBoxSize;
2282 return {
2283 // not array in old browser
2284 size: sizes[0] || sizes,
2285 target: entry.target
2286 };
2287 }));
2288 };
2289
2290 this._scheduleResize = function (entries) {
2291 var _a = _this._options,
2292 resizeDebounce = _a.resizeDebounce,
2293 maxResizeDebounce = _a.maxResizeDebounce;
2294 var updatedEntries = _this._updatedEntries;
2295 updatedEntries.push.apply(updatedEntries, entries);
2296 _this._updatedEntries = updatedEntries.filter(function (entry, index) {
2297 return updatedEntries.lastIndexOf(entry) === index;
2298 });
2299
2300 if (!_this._maxResizeDebounceTimer && maxResizeDebounce >= resizeDebounce) {
2301 _this._maxResizeDebounceTimer = window.setTimeout(_this._onResize, maxResizeDebounce);
2302 }
2303
2304 if (_this._resizeTimer) {
2305 clearTimeout(_this._resizeTimer);
2306 _this._resizeTimer = 0;
2307 }
2308
2309 _this._resizeTimer = window.setTimeout(_this._onResize, resizeDebounce);
2310 };
2311
2312 this._onResize = function () {
2313 clearTimeout(_this._resizeTimer);
2314 clearTimeout(_this._maxResizeDebounceTimer);
2315 _this._maxResizeDebounceTimer = 0;
2316 _this._resizeTimer = 0;
2317 var updated = _this._updatedEntries;
2318 var container = _this.container;
2319 var containerEntry;
2320 var childEntries = updated.filter(function (entry) {
2321 if (entry.target === container) {
2322 containerEntry = entry;
2323 return false;
2324 } else {
2325 return true;
2326 }
2327 });
2328 var isResizeChildren = childEntries.length > 0;
2329 var isResizeContainer = !!containerEntry;
2330
2331 if (isResizeContainer) {
2332 var watchDirection = _this._options.watchDirection;
2333 var prevRect = _this.rect;
2334 var containerEntrySize = containerEntry.size;
2335
2336 if (containerEntrySize) {
2337 // ResizeObserver
2338 _this.setRect({
2339 width: containerEntrySize.inlineSize,
2340 height: containerEntrySize.blockSize
2341 });
2342 } else {
2343 // window's resize event
2344 _this.resize();
2345 }
2346
2347 var rect = _this.rect;
2348 var isWatchWidth = watchDirection === "box" || watchDirection === "width";
2349 var isWatchHeight = watchDirection === "box" || watchDirection === "height";
2350 isResizeContainer = !watchDirection || isWatchWidth && prevRect.width !== rect.width || isWatchHeight && prevRect.height !== rect.height;
2351 }
2352
2353 _this._updatedEntries = [];
2354
2355 if (isResizeContainer || isResizeChildren) {
2356 _this._emitter.trigger("resize", {
2357 isResizeContainer: isResizeContainer,
2358 childEntries: childEntries
2359 });
2360 }
2361 };
2362
2363 this._options = __assign$2({
2364 resizeDebounce: 100,
2365 maxResizeDebounce: 0,
2366 useResizeObserver: false,
2367 useWindowResize: true,
2368 watchDirection: false,
2369 rectBox: "content-box",
2370 childrenRectBox: "border-box"
2371 }, options);
2372 this.container = isString(container) ? document.querySelector(container) : container;
2373
2374 this._init();
2375 }
2376
2377 var __proto = ResizeWatcher.prototype;
2378
2379 __proto.getRect = function () {
2380 return this.rect;
2381 };
2382
2383 __proto.setRect = function (rect) {
2384 this.rect = __assign$2({}, rect);
2385 };
2386
2387 __proto.resize = function () {
2388 var container = this.container;
2389 this.setRect(this._options.rectBox === "border-box" ? {
2390 width: container.offsetWidth,
2391 height: container.offsetHeight
2392 } : {
2393 width: container.clientWidth,
2394 height: container.clientHeight
2395 });
2396 };
2397
2398 __proto.observeChildren = function (children) {
2399 var observer = this._observer;
2400
2401 if (!observer) {
2402 return;
2403 }
2404
2405 var box = this._options.childrenRectBox;
2406 children.forEach(function (element) {
2407 observer.observe(element, {
2408 box: box
2409 });
2410 });
2411 };
2412
2413 __proto.unobserveChildren = function (children) {
2414 var observer = this._observer;
2415
2416 if (!observer) {
2417 return;
2418 }
2419
2420 children.forEach(function (element) {
2421 observer.unobserve(element);
2422 });
2423 };
2424
2425 __proto.listen = function (callback) {
2426 this._emitter.on("resize", callback);
2427
2428 return this;
2429 };
2430
2431 __proto.destroy = function () {
2432 var _a;
2433
2434 (_a = this._observer) === null || _a === void 0 ? void 0 : _a.disconnect();
2435
2436 if (this._options.useWindowResize) {
2437 window.removeEventListener("resize", this._onWindowResize);
2438 }
2439 };
2440
2441 __proto._init = function () {
2442 var container = this.container;
2443 var options = this._options;
2444 this._emitter = new Component();
2445
2446 if (options.useResizeObserver && !!window.ResizeObserver) {
2447 this._observer = new window.ResizeObserver(this._onObserve);
2448
2449 this._observer.observe(container, {
2450 box: options.rectBox
2451 });
2452 }
2453
2454 if (options.useWindowResize) {
2455 window.addEventListener("resize", this._onWindowResize);
2456 }
2457
2458 this.resize();
2459 };
2460
2461 return ResizeWatcher;
2462 }();
2463
2464 var ContainerManager =
2465 /*#__PURE__*/
2466 function (_super) {
2467 __extends$2(ContainerManager, _super);
2468
2469 function ContainerManager(container, options) {
2470 var _this = _super.call(this) || this;
2471
2472 _this.container = container;
2473
2474 _this._onResize = function (e) {
2475 _this.trigger("resize", e);
2476 };
2477
2478 _this.options = __assign$2({
2479 horizontal: DEFAULT_GRID_OPTIONS.horizontal,
2480 autoResize: DEFAULT_GRID_OPTIONS.autoResize,
2481 resizeDebounce: DEFAULT_GRID_OPTIONS.resizeDebounce,
2482 maxResizeDebounce: DEFAULT_GRID_OPTIONS.maxResizeDebounce,
2483 useResizeObserver: DEFAULT_GRID_OPTIONS.useResizeObserver
2484 }, options);
2485
2486 _this._init();
2487
2488 return _this;
2489 }
2490
2491 var __proto = ContainerManager.prototype;
2492
2493 __proto.resize = function () {
2494 var container = this.container;
2495 this.setRect({
2496 width: container.clientWidth,
2497 height: container.clientHeight
2498 });
2499 };
2500
2501 __proto.getRect = function () {
2502 return this._watcher.getRect();
2503 };
2504
2505 __proto.observeChildren = function (children) {
2506 this._watcher.observeChildren(children);
2507 };
2508
2509 __proto.unobserveChildren = function (children) {
2510 this._watcher.unobserveChildren(children);
2511 };
2512
2513 __proto.setRect = function (rect) {
2514 this._watcher.setRect(rect);
2515 };
2516
2517 __proto.getInlineSize = function () {
2518 return this.getRect()[this._names.inlineSize];
2519 };
2520
2521 __proto.getContentSize = function () {
2522 return this.getRect()[this._names.contentSize];
2523 };
2524
2525 __proto.getStatus = function () {
2526 return {
2527 rect: this._watcher.getRect()
2528 };
2529 };
2530
2531 __proto.setStatus = function (status) {
2532 this.setRect(status.rect);
2533 this.setContentSize(this.getContentSize());
2534 };
2535
2536 __proto.setContentSize = function (size) {
2537 var _a;
2538
2539 var sizeName = this.options.horizontal ? "width" : "height";
2540 this.setRect(__assign$2(__assign$2({}, this.getRect()), (_a = {}, _a[sizeName] = size, _a)));
2541 this.container.style[sizeName] = size + "px";
2542 };
2543
2544 __proto.destroy = function (options) {
2545 if (options === void 0) {
2546 options = {};
2547 }
2548
2549 this._watcher.destroy();
2550
2551 if (!options.preserveUI) {
2552 this.container.style.cssText = this.orgCSSText;
2553 }
2554 };
2555
2556 __proto._init = function () {
2557 var container = this.container;
2558 var style = window.getComputedStyle(container);
2559 this.orgCSSText = container.style.cssText;
2560
2561 if (style.position === "static") {
2562 container.style.position = "relative";
2563 }
2564
2565 var options = this.options;
2566 this._watcher = new ResizeWatcher(container, {
2567 useWindowResize: options.autoResize,
2568 useResizeObserver: options.useResizeObserver,
2569 resizeDebounce: options.resizeDebounce,
2570 maxResizeDebounce: options.maxResizeDebounce,
2571 watchDirection: options.useResizeObserver ? this._names.inlineSize : false
2572 }).listen(this._onResize);
2573 };
2574
2575 Object.defineProperty(__proto, "_names", {
2576 get: function () {
2577 return RECT_NAMES[this.options.horizontal ? "horizontal" : "vertical"];
2578 },
2579 enumerable: false,
2580 configurable: true
2581 });
2582 return ContainerManager;
2583 }(Component);
2584
2585 var ItemRenderer =
2586 /*#__PURE__*/
2587 function () {
2588 function ItemRenderer(options) {
2589 this.initialRect = null;
2590 this.sizePercetage = false;
2591 this.posPercetage = false;
2592 this.options = __assign$2({
2593 attributePrefix: DEFAULT_GRID_OPTIONS.attributePrefix,
2594 useTransform: DEFAULT_GRID_OPTIONS.useTransform,
2595 horizontal: DEFAULT_GRID_OPTIONS.horizontal,
2596 percentage: DEFAULT_GRID_OPTIONS.percentage,
2597 isEqualSize: DEFAULT_GRID_OPTIONS.isEqualSize,
2598 isConstantSize: DEFAULT_GRID_OPTIONS.isConstantSize,
2599 useRoundedSize: DEFAULT_GRID_OPTIONS.useRoundedSize
2600 }, options);
2601
2602 this._init();
2603 }
2604
2605 var __proto = ItemRenderer.prototype;
2606
2607 __proto.resize = function () {
2608 this.initialRect = null;
2609 };
2610
2611 __proto.renderItems = function (items) {
2612 var _this = this;
2613
2614 items.forEach(function (item) {
2615 _this._renderItem(item);
2616 });
2617 };
2618
2619 __proto.getInlineSize = function () {
2620 return this.containerRect[this.options.horizontal ? "height" : "width"];
2621 };
2622
2623 __proto.setContainerRect = function (rect) {
2624 this.containerRect = rect;
2625 };
2626
2627 __proto.updateItems = function (items) {
2628 var _this = this;
2629
2630 items.forEach(function (item) {
2631 _this._updateItem(item);
2632 });
2633 };
2634
2635 __proto.getStatus = function () {
2636 return {
2637 initialRect: this.initialRect
2638 };
2639 };
2640
2641 __proto.setStatus = function (status) {
2642 this.initialRect = status.initialRect;
2643 };
2644
2645 __proto._init = function () {
2646 var percentage = this.options.percentage;
2647 var sizePercentage = false;
2648 var posPercentage = false;
2649
2650 if (percentage === true) {
2651 sizePercentage = true;
2652 posPercentage = true;
2653 } else if (percentage) {
2654 if (percentage.indexOf("position") > -1) {
2655 posPercentage = true;
2656 }
2657
2658 if (percentage.indexOf("size") > -1) {
2659 sizePercentage = true;
2660 }
2661 }
2662
2663 this.posPercetage = posPercentage;
2664 this.sizePercetage = sizePercentage;
2665 };
2666
2667 __proto._updateItem = function (item) {
2668 var _a = this.options,
2669 isEqualSize = _a.isEqualSize,
2670 isConstantSize = _a.isConstantSize,
2671 useRoundedSize = _a.useRoundedSize;
2672 var initialRect = this.initialRect;
2673 var orgRect = item.orgRect,
2674 element = item.element;
2675 var isLoading = item.updateState === UPDATE_STATE.WAIT_LOADING;
2676 var hasOrgSize = orgRect && orgRect.width && orgRect.height;
2677 var rect;
2678
2679 if (isEqualSize && initialRect) {
2680 rect = initialRect;
2681 } else if (isConstantSize && hasOrgSize && !isLoading) {
2682 rect = orgRect;
2683 } else if (!element) {
2684 return;
2685 } else {
2686 rect = {
2687 left: element.offsetLeft,
2688 top: element.offsetTop,
2689 width: 0,
2690 height: 0
2691 };
2692
2693 if (useRoundedSize) {
2694 rect.width = element.offsetWidth;
2695 rect.height = element.offsetHeight;
2696 } else {
2697 var clientRect = element.getBoundingClientRect();
2698 rect.width = clientRect.width;
2699 rect.height = clientRect.height;
2700 }
2701 }
2702
2703 if (!item.isFirstUpdate || !hasOrgSize) {
2704 item.orgRect = __assign$2({}, rect);
2705 }
2706
2707 item.rect = __assign$2({}, rect);
2708
2709 if (item.element) {
2710 item.mountState = MOUNT_STATE.MOUNTED;
2711 }
2712
2713 if (item.updateState === UPDATE_STATE.NEED_UPDATE) {
2714 item.updateState = UPDATE_STATE.UPDATED;
2715 item.isFirstUpdate = true;
2716 }
2717
2718 item.attributes = element ? getDataAttributes(element, this.options.attributePrefix) : {};
2719
2720 if (!isLoading && !this.initialRect) {
2721 this.initialRect = __assign$2({}, rect);
2722 }
2723
2724 return rect;
2725 };
2726
2727 __proto._renderItem = function (item) {
2728 var element = item.element;
2729 var cssRect = item.cssRect;
2730
2731 if (!element || !cssRect) {
2732 return;
2733 }
2734
2735 var _a = this.options,
2736 horizontal = _a.horizontal,
2737 useTransform = _a.useTransform;
2738 var posPercentage = this.posPercetage;
2739 var sizePercentage = this.sizePercetage;
2740 var cssTexts = ["position: absolute;"];
2741 var _b = RECT_NAMES[horizontal ? "horizontal" : "vertical"],
2742 sizeName = _b.inlineSize,
2743 posName = _b.inlinePos;
2744 var inlineSize = this.getInlineSize();
2745 var keys = getKeys(cssRect);
2746
2747 if (useTransform) {
2748 keys = keys.filter(function (key) {
2749 return key !== "top" && key !== "left";
2750 });
2751 cssTexts.push("transform: " + ("translate(" + (cssRect.left || 0) + "px, " + (cssRect.top || 0) + "px);"));
2752 }
2753
2754 cssTexts.push.apply(cssTexts, keys.map(function (name) {
2755 var value = cssRect[name];
2756
2757 if (name === sizeName && sizePercentage || name === posName && posPercentage) {
2758 return name + ": " + value / inlineSize * 100 + "%;";
2759 }
2760
2761 return name + ": " + value + "px;";
2762 }));
2763 element.style.cssText += cssTexts.join("");
2764 };
2765
2766 return ItemRenderer;
2767 }();
2768
2769 /**
2770 * @memberof Grid
2771 * @implements Grid.GridItem.GridItemStatus
2772 */
2773
2774 var GridItem =
2775 /*#__PURE__*/
2776 function () {
2777 /**
2778 * @constructor
2779 * @param horizontal - Direction of the scroll movement. (true: horizontal, false: vertical) <ko>스크롤 이동 방향. (true: 가로방향, false: 세로방향)</ko>
2780 * @param itemStatus - Default status object of GridItem module. <ko>GridItem 모듈의 기본 status 객체.</ko>
2781 */
2782 function GridItem(horizontal, itemStatus) {
2783 if (itemStatus === void 0) {
2784 itemStatus = {};
2785 }
2786
2787 var _a;
2788
2789 this.horizontal = horizontal;
2790 this.isUpdate = false;
2791 this.hasTransition = false;
2792 this.transitionDuration = "";
2793 var element = itemStatus.element;
2794
2795 var status = __assign$2({
2796 key: "",
2797 orgRect: {
2798 left: 0,
2799 top: 0,
2800 width: 0,
2801 height: 0
2802 },
2803 rect: {
2804 left: 0,
2805 top: 0,
2806 width: 0,
2807 height: 0
2808 },
2809 cssRect: {},
2810 attributes: {},
2811 data: {},
2812 isFirstUpdate: false,
2813 mountState: MOUNT_STATE.UNCHECKED,
2814 updateState: UPDATE_STATE.NEED_UPDATE,
2815 element: element || null,
2816 orgCSSText: (_a = element === null || element === void 0 ? void 0 : element.style.cssText) !== null && _a !== void 0 ? _a : "",
2817 gridData: {}
2818 }, itemStatus);
2819
2820 for (var name in status) {
2821 this[name] = status[name];
2822 }
2823 }
2824
2825 var __proto = GridItem.prototype;
2826 Object.defineProperty(__proto, "orgInlineSize", {
2827 /**
2828 * The size in inline direction before first rendering. "width" if horizontal is false, "height" otherwise.
2829 * @ko 첫 렌더링 되기 전의 inline 방향의 사이즈. horizontal이 false면 "width", 아니면 "height".
2830 * @member Grid.GridItem#orgInlineSize
2831 */
2832 get: function () {
2833 var name = this._names.inlineSize;
2834 return this.orgRect[name] || this.rect[name];
2835 },
2836 enumerable: false,
2837 configurable: true
2838 });
2839 Object.defineProperty(__proto, "orgContentSize", {
2840 /**
2841 * The size in content direction before first rendering. "height" if horizontal is false, "width" otherwise.
2842 * @ko 첫 렌더링 되기 전의 content 방향의 사이즈. horizontal이 false면 "height", 아니면 "width".
2843 * @member Grid.GridItem#orgContentSize
2844 */
2845 get: function () {
2846 var name = this._names.contentSize;
2847 return this.orgRect[name] || this.rect[name];
2848 },
2849 enumerable: false,
2850 configurable: true
2851 });
2852 Object.defineProperty(__proto, "inlineSize", {
2853 /**
2854 * The size in inline direction. "width" if horizontal is false, "height" otherwise.
2855 * @ko inline 방향의 사이즈. horizontal이 false면 "width", 아니면 "height".
2856 * @member Grid.GridItem#inlineSize
2857 */
2858 get: function () {
2859 return this.rect[this._names.inlineSize];
2860 },
2861 enumerable: false,
2862 configurable: true
2863 });
2864 Object.defineProperty(__proto, "contentSize", {
2865 /**
2866 * The size in content direction. "height" if horizontal is false, "width" otherwise.
2867 * @ko content 방향의 사이즈. horizontal이 false면 "height", 아니면 "width".
2868 * @member Grid.GridItem#contentSize
2869 */
2870 get: function () {
2871 return this.rect[this._names.contentSize];
2872 },
2873 enumerable: false,
2874 configurable: true
2875 });
2876 Object.defineProperty(__proto, "cssInlineSize", {
2877 /**
2878 * The CSS size in inline direction applied to the Grid. "width" if horizontal is false, "height" otherwise.
2879 * @ko Grid에 적용된 inline 방향의 CSS 사이즈. horizontal이 false면 "width", 아니면 "height".
2880 * @member Grid.GridItem#cssInlineSize
2881 */
2882 get: function () {
2883 return this.cssRect[this._names.inlineSize];
2884 },
2885 set: function (inlineSize) {
2886 this.cssRect[this._names.inlineSize] = inlineSize;
2887 },
2888 enumerable: false,
2889 configurable: true
2890 });
2891 Object.defineProperty(__proto, "cssContentSize", {
2892 /**
2893 * The CSS size in content direction applied to the Grid. "height" if horizontal is false, "width" otherwise.
2894 * @ko Grid에 적용된 content 방향의 CSS 사이즈. horizontal이 false면 "height", 아니면 "width".
2895 * @member Grid.GridItem#cssContentSize
2896 */
2897 get: function () {
2898 return this.cssRect[this._names.contentSize];
2899 },
2900 set: function (contentSize) {
2901 this.cssRect[this._names.contentSize] = contentSize;
2902 },
2903 enumerable: false,
2904 configurable: true
2905 });
2906 Object.defineProperty(__proto, "cssInlinePos", {
2907 /**
2908 * The CSS pos in inline direction applied to the Grid. "left" if horizontal is false, "top" otherwise.
2909 * @ko Grid에 적용된 inline 방향의 CSS 포지션. horizontal이 false면 "left", 아니면 "top".
2910 * @member Grid.GridItem#cssInlinePos
2911 */
2912 get: function () {
2913 return this.cssRect[this._names.inlinePos];
2914 },
2915 set: function (inlinePos) {
2916 this.cssRect[this._names.inlinePos] = inlinePos;
2917 },
2918 enumerable: false,
2919 configurable: true
2920 });
2921 Object.defineProperty(__proto, "cssContentPos", {
2922 /**
2923 * The CSS pos in content direction applied to the Grid. "top" if horizontal is false, "left" otherwise.
2924 * @ko Grid에 적용된 content 방향의 CSS 포지션. horizontal이 false면 "top", 아니면 "left".
2925 * @member Grid.GridItem#cssContentPos
2926 */
2927 get: function () {
2928 return this.cssRect[this._names.contentPos];
2929 },
2930 set: function (contentPos) {
2931 this.cssRect[this._names.contentPos] = contentPos;
2932 },
2933 enumerable: false,
2934 configurable: true
2935 });
2936 Object.defineProperty(__proto, "computedInlineSize", {
2937 /**
2938 * Calculated size in the direction of the inline applied to the grid. "width" if horizontal is false, "height" otherwise.
2939 * @ko Grid에 적용된 inline 방향의 계산된 사이즈. horizontal이 false면 "width", 아니면 "height".
2940 * @member Grid.GridItem#computedInlineSize
2941 */
2942 get: function () {
2943 var name = this._names.inlineSize;
2944 return this.cssRect[name] || this.rect[name] || this.orgRect[name];
2945 },
2946 enumerable: false,
2947 configurable: true
2948 });
2949 Object.defineProperty(__proto, "computedContentSize", {
2950 /**
2951 * Calculated size in the direction of the content applied to the grid. "height" if horizontal is false, "width" otherwise.
2952 * @ko Grid에 적용된 content 방향의 계산된 사이즈. horizontal이 false면 "height", 아니면 "width".
2953 * @member Grid.GridItem#computedContentSize
2954 */
2955 get: function () {
2956 var name = this._names.contentSize;
2957 return this.cssRect[name] || this.rect[name] || this.orgRect[name];
2958 },
2959 enumerable: false,
2960 configurable: true
2961 });
2962 Object.defineProperty(__proto, "computedInlinePos", {
2963 /**
2964 * Calculated position in the direction of the inline applied to the grid. "left" if horizontal is false, "top" otherwise.
2965 * @ko Grid에 적용된 content 방향의 계산된 포지션. horizontal이 false면 "left", 아니면 "top".
2966 * @member Grid.GridItem#computedInlinePos
2967 */
2968 get: function () {
2969 var _a;
2970
2971 var name = this._names.inlinePos;
2972 return (_a = this.cssRect[name]) !== null && _a !== void 0 ? _a : this.rect[name];
2973 },
2974 enumerable: false,
2975 configurable: true
2976 });
2977 Object.defineProperty(__proto, "computedContentPos", {
2978 /**
2979 * Calculated position in the direction of the content applied to the grid. "top" if horizontal is false, "left" otherwise.
2980 * @ko Grid에 적용된 content 방향의 계산된 포지션. horizontal이 false면 "top", 아니면 "left".
2981 * @member Grid.GridItem#computedContentPos
2982 */
2983 get: function () {
2984 var _a;
2985
2986 var name = this._names.contentPos;
2987 return (_a = this.cssRect[name]) !== null && _a !== void 0 ? _a : this.rect[name];
2988 },
2989 enumerable: false,
2990 configurable: true
2991 });
2992 /**
2993 * Set CSS Rect through GridRect.
2994 * @ko GridRect을 통해 CSS Rect를 설정한다.
2995 * @param - The style for setting CSS rect. <ko>CSS rect를 설정하기 위한 스타일.</ko>
2996 */
2997
2998 __proto.setCSSGridRect = function (gridRect) {
2999 var names = RECT_NAMES[this.horizontal ? "horizontal" : "vertical"];
3000 var rect = {};
3001
3002 for (var name in gridRect) {
3003 rect[names[name]] = gridRect[name];
3004 }
3005
3006 this.cssRect = rect;
3007 };
3008 /**
3009 * Returns the status of the item.
3010 * @ko 아이템의 상태를 반환한다.
3011 */
3012
3013
3014 __proto.getStatus = function () {
3015 return {
3016 mountState: this.mountState,
3017 updateState: this.updateState,
3018 attributes: this.attributes,
3019 orgCSSText: this.orgCSSText,
3020 isFirstUpdate: this.isFirstUpdate,
3021 element: null,
3022 key: this.key,
3023 orgRect: this.orgRect,
3024 rect: this.rect,
3025 cssRect: this.cssRect,
3026 gridData: this.gridData,
3027 data: this.data
3028 };
3029 };
3030 /**
3031 * Returns minimized status of the item.
3032 * @ko 아이템의 간소화된 상태를 반환한다.
3033 */
3034
3035
3036 __proto.getMinimizedStatus = function () {
3037 var status = {
3038 orgRect: this.orgRect,
3039 rect: this.rect,
3040 cssRect: this.cssRect,
3041 attributes: this.attributes,
3042 gridData: this.gridData
3043 };
3044
3045 var _a = this,
3046 key = _a.key,
3047 mountState = _a.mountState,
3048 updateState = _a.updateState,
3049 isFirstUpdate = _a.isFirstUpdate,
3050 orgCSSText = _a.orgCSSText;
3051
3052 if (typeof key !== "undefined") {
3053 status.key = key;
3054 }
3055
3056 if (mountState !== MOUNT_STATE.UNCHECKED) {
3057 status.mountState = mountState;
3058 }
3059
3060 if (updateState !== UPDATE_STATE.NEED_UPDATE) {
3061 status.updateState = updateState;
3062 }
3063
3064 if (isFirstUpdate) {
3065 status.isFirstUpdate = true;
3066 }
3067
3068 if (orgCSSText) {
3069 status.orgCSSText = orgCSSText;
3070 }
3071
3072 return status;
3073 };
3074
3075 Object.defineProperty(__proto, "_names", {
3076 get: function () {
3077 return this.horizontal ? RECT_NAMES.horizontal : RECT_NAMES.vertical;
3078 },
3079 enumerable: false,
3080 configurable: true
3081 });
3082 return GridItem;
3083 }();
3084
3085 /**
3086 * @extends eg.Component
3087 */
3088
3089 var Grid =
3090 /*#__PURE__*/
3091 function (_super) {
3092 __extends$2(Grid, _super);
3093 /**
3094 * @param - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
3095 * @param - The option object of the Grid module <ko>Grid 모듈의 옵션 객체</ko>
3096 */
3097
3098
3099 function Grid(containerElement, options) {
3100 if (options === void 0) {
3101 options = {};
3102 }
3103
3104 var _this = _super.call(this) || this;
3105
3106 _this.items = [];
3107 _this.outlines = {
3108 start: [],
3109 end: []
3110 };
3111 _this._renderTimer = 0;
3112
3113 _this._onResize = function (e) {
3114 if (e.isResizeContainer) {
3115 _this._renderItems({
3116 useResize: true
3117 }, true);
3118 } else {
3119 var updatedItems = getUpdatedItems(_this.items, e.childEntries);
3120
3121 if (updatedItems.length > 0) {
3122 _this.updateItems(updatedItems);
3123 }
3124 }
3125 };
3126
3127 _this.options = __assign$2(__assign$2({}, _this.constructor.defaultOptions), options);
3128 _this.containerElement = isString(containerElement) ? document.querySelector(containerElement) : containerElement;
3129 var _a = _this.options,
3130 isEqualSize = _a.isEqualSize,
3131 isConstantSize = _a.isConstantSize,
3132 useTransform = _a.useTransform,
3133 horizontal = _a.horizontal,
3134 percentage = _a.percentage,
3135 externalContainerManager = _a.externalContainerManager,
3136 externalItemRenderer = _a.externalItemRenderer,
3137 resizeDebounce = _a.resizeDebounce,
3138 maxResizeDebounce = _a.maxResizeDebounce,
3139 autoResize = _a.autoResize,
3140 useRoundedSize = _a.useRoundedSize,
3141 useResizeObserver = _a.useResizeObserver; // TODO: 테스트용 설정
3142
3143 _this.containerManager = externalContainerManager || new ContainerManager(_this.containerElement, {
3144 horizontal: horizontal,
3145 resizeDebounce: resizeDebounce,
3146 maxResizeDebounce: maxResizeDebounce,
3147 autoResize: autoResize,
3148 useResizeObserver: useResizeObserver
3149 }).on("resize", _this._onResize);
3150 _this.itemRenderer = externalItemRenderer || new ItemRenderer({
3151 useTransform: useTransform,
3152 isEqualSize: isEqualSize,
3153 isConstantSize: isConstantSize,
3154 percentage: percentage,
3155 useRoundedSize: useRoundedSize
3156 });
3157
3158 _this._init();
3159
3160 return _this;
3161 }
3162
3163 var __proto = Grid.prototype;
3164 Grid_1 = Grid;
3165 /**
3166 * Return Container Element.
3167 * @ko 컨테이너 엘리먼트를 반환한다.
3168 */
3169
3170 __proto.getContainerElement = function () {
3171 return this.containerElement;
3172 };
3173 /**
3174 * Return items.
3175 * @ko 아이템들을 반환한다.
3176 */
3177
3178
3179 __proto.getItems = function () {
3180 return this.items;
3181 };
3182 /**
3183 * Returns the children of the container element.
3184 * @ko 컨테이너 엘리먼트의 children을 반환한다.
3185 */
3186
3187
3188 __proto.getChildren = function () {
3189 return [].slice.call(this.containerElement.children);
3190 };
3191 /**
3192 * Set items.
3193 * @ko 아이템들을 설정한다.
3194 * @param items - The items to set. <ko>설정할 아이템들</ko>
3195 */
3196
3197
3198 __proto.setItems = function (items) {
3199 var options = this.options;
3200
3201 if (options.useResizeObserver && options.observeChildren) {
3202 var containerManager = this.containerManager;
3203 containerManager.unobserveChildren(getMountedElements(this.items));
3204 containerManager.observeChildren(getMountedElements(items));
3205 }
3206
3207 this.items = items;
3208 return this;
3209 };
3210 /**
3211 * Gets the container's inline size. ("width" if horizontal is false, otherwise "height")
3212 * @ko container의 inline 사이즈를 가져온다. (horizontal이 false면 "width", 아니면 "height")
3213 */
3214
3215
3216 __proto.getContainerInlineSize = function () {
3217 return this.containerManager.getInlineSize();
3218 };
3219 /**
3220 * Returns the outlines of the start and end of the Grid.
3221 * @ko Grid의 처음과 끝의 outline을 반환한다.
3222 */
3223
3224
3225 __proto.getOutlines = function () {
3226 return this.outlines;
3227 };
3228 /**
3229 * Set outlines.
3230 * @ko 아웃라인을 설정한다.
3231 * @param outlines - The outlines to set. <ko>설정할 아웃라인.</ko>
3232 */
3233
3234
3235 __proto.setOutlines = function (outlines) {
3236 this.outlines = outlines;
3237 return this;
3238 };
3239 /**
3240 * When elements change, it synchronizes and renders items.
3241 * @ko elements가 바뀐 경우 동기화를 하고 렌더링을 한다.
3242 * @param - Options for rendering. <ko>렌더링을 하기 위한 옵션.</ko>
3243 */
3244
3245
3246 __proto.syncElements = function (options) {
3247 if (options === void 0) {
3248 options = {};
3249 }
3250
3251 var items = this.items;
3252 var horizontal = this.options.horizontal;
3253 var elements = this.getChildren();
3254
3255 var _a = diff$1(this.items.map(function (item) {
3256 return item.element;
3257 }), elements),
3258 added = _a.added,
3259 maintained = _a.maintained,
3260 changed = _a.changed,
3261 removed = _a.removed;
3262
3263 var nextItems = [];
3264 maintained.forEach(function (_a) {
3265 var beforeIndex = _a[0],
3266 afterIndex = _a[1];
3267 nextItems[afterIndex] = items[beforeIndex];
3268 });
3269 added.forEach(function (index) {
3270 nextItems[index] = new GridItem(horizontal, {
3271 element: elements[index]
3272 });
3273 });
3274 this.setItems(nextItems);
3275
3276 if (added.length || removed.length || changed.length) {
3277 this.renderItems(options);
3278 }
3279
3280 return this;
3281 };
3282 /**
3283 * Update the size of the items and render them.
3284 * @ko 아이템들의 사이즈를 업데이트하고 렌더링을 한다.
3285 * @param - Items to be updated. <ko>업데이트할 아이템들.</ko>
3286 * @param - Options for rendering. <ko>렌더링을 하기 위한 옵션.</ko>
3287 */
3288
3289
3290 __proto.updateItems = function (items, options) {
3291 if (items === void 0) {
3292 items = this.items;
3293 }
3294
3295 if (options === void 0) {
3296 options = {};
3297 }
3298
3299 var useOrgResize = options.useOrgResize;
3300 items.forEach(function (item) {
3301 if (useOrgResize) {
3302 var orgRect = item.orgRect;
3303 orgRect.width = 0;
3304 orgRect.height = 0;
3305 }
3306
3307 item.updateState = UPDATE_STATE.NEED_UPDATE;
3308 });
3309 this.checkReady(options);
3310 return this;
3311 };
3312 /**
3313 * Rearrange items to fit the grid and render them. When rearrange is complete, the `renderComplete` event is fired.
3314 * @ko grid에 맞게 아이템을 재배치하고 렌더링을 한다. 배치가 완료되면 `renderComplete` 이벤트가 발생한다.
3315 * @param - Options for rendering. <ko>렌더링을 하기 위한 옵션.</ko>
3316 * @example
3317 * ```js
3318 * import { MasonryGrid } from "@egjs/grid";
3319 * const grid = new MasonryGrid();
3320 *
3321 * grid.on("renderComplete", e => {
3322 * console.log(e);
3323 * });
3324 * grid.renderItems();
3325 * ```
3326 */
3327
3328
3329 __proto.renderItems = function (options) {
3330 if (options === void 0) {
3331 options = {};
3332 }
3333
3334 this._renderItems(options);
3335
3336 return this;
3337 };
3338 /**
3339 * Returns current status such as item's position, size. The returned status can be restored with the setStatus() method.
3340 * @ko 아이템의 위치, 사이즈 등 현재 상태를 반환한다. 반환한 상태는 setStatus() 메서드로 복원할 수 있다.
3341 * @param - Whether to minimize the status of the item. (default: false) <ko>item의 status를 최소화할지 여부. (default: false)</ko>
3342 */
3343
3344
3345 __proto.getStatus = function (minimize) {
3346 return {
3347 outlines: this.outlines,
3348 items: this.items.map(function (item) {
3349 return minimize ? item.getMinimizedStatus() : item.getStatus();
3350 }),
3351 containerManager: this.containerManager.getStatus(),
3352 itemRenderer: this.itemRenderer.getStatus()
3353 };
3354 };
3355 /**
3356 * Set status of the Grid module with the status returned through a call to the getStatus() method.
3357 * @ko getStatus() 메서드에 대한 호출을 통해 반환된 상태로 Grid 모듈의 상태를 설정한다.
3358 */
3359
3360
3361 __proto.setStatus = function (status) {
3362 var _this = this;
3363
3364 var horizontal = this.options.horizontal;
3365 var containerManager = this.containerManager;
3366 var prevInlineSize = containerManager.getInlineSize();
3367 var children = this.getChildren();
3368 this.itemRenderer.setStatus(status.itemRenderer);
3369 containerManager.setStatus(status.containerManager);
3370 this.outlines = status.outlines;
3371 this.items = status.items.map(function (item, i) {
3372 return new GridItem(horizontal, __assign$2(__assign$2({}, item), {
3373 element: children[i]
3374 }));
3375 });
3376 this.itemRenderer.renderItems(this.items);
3377
3378 if (prevInlineSize !== containerManager.getInlineSize()) {
3379 this.renderItems({
3380 useResize: true
3381 });
3382 } else {
3383 window.setTimeout(function () {
3384 _this._renderComplete({
3385 direction: _this.defaultDirection,
3386 mounted: _this.items,
3387 updated: [],
3388 isResize: false
3389 });
3390 });
3391 }
3392
3393 return this;
3394 };
3395 /**
3396 * Get the inline size corresponding to outline.
3397 * @ko outline에 해당하는 inline 사이즈를 구한다.
3398 * @param items - Items to get outline size. <ko>outline 사이즈를 구하기 위한 아이템들.</ko>
3399 */
3400 // eslint-disable-next-line @typescript-eslint/no-unused-vars
3401
3402
3403 __proto.getComputedOutlineSize = function (items) {
3404 if (items === void 0) {
3405 items = this.items;
3406 }
3407
3408 return this.options.outlineSize || this.getContainerInlineSize();
3409 };
3410 /**
3411 * Get the length corresponding to outline.
3412 * @ko outline에 해당하는 length를 가져온다.
3413 * @param items - Items to get outline length. <ko>outline length를 구하기 위한 아이템들.</ko>
3414 */
3415 // eslint-disable-next-line @typescript-eslint/no-unused-vars
3416
3417
3418 __proto.getComputedOutlineLength = function (items) {
3419 if (items === void 0) {
3420 items = this.items;
3421 }
3422
3423 return this.options.outlineLength || 1;
3424 };
3425 /**
3426 * Releases the instnace and events and returns the CSS of the container and elements.
3427 * @ko 인스턴스와 이벤트를 해제하고 컨테이너와 엘리먼트들의 CSS를 되돌린다.
3428 * @param Options for destroy. <ko>destory()를 위한 옵션</ko>
3429 */
3430
3431
3432 __proto.destroy = function (options) {
3433 var _a;
3434
3435 if (options === void 0) {
3436 options = {};
3437 }
3438
3439 var _b = options.preserveUI,
3440 preserveUI = _b === void 0 ? this.options.preserveUIOnDestroy : _b;
3441 this.containerManager.destroy({
3442 preserveUI: preserveUI
3443 });
3444
3445 if (!preserveUI) {
3446 this.items.forEach(function (_a) {
3447 var element = _a.element,
3448 orgCSSText = _a.orgCSSText;
3449
3450 if (element) {
3451 element.style.cssText = orgCSSText;
3452 }
3453 });
3454 }
3455
3456 (_a = this._im) === null || _a === void 0 ? void 0 : _a.destroy();
3457 };
3458
3459 __proto.checkReady = function (options) {
3460 var _this = this;
3461
3462 var _a;
3463
3464 if (options === void 0) {
3465 options = {};
3466 } // Grid: renderItems => checkReady => readyItems => applyGrid
3467
3468
3469 var items = this.items;
3470 var updated = items.filter(function (item) {
3471 var _a;
3472
3473 return ((_a = item.element) === null || _a === void 0 ? void 0 : _a.parentNode) && item.updateState !== UPDATE_STATE.UPDATED;
3474 });
3475 var mounted = items.filter(function (item) {
3476 var _a;
3477
3478 return ((_a = item.element) === null || _a === void 0 ? void 0 : _a.parentNode) && item.mountState !== MOUNT_STATE.MOUNTED;
3479 });
3480 var moreUpdated = [];
3481 mounted.filter(function (item) {
3482 if (item.hasTransition) {
3483 return true;
3484 } else {
3485 var element = item.element;
3486 var transitionDuration = parseFloat(getComputedStyle(element).transitionDuration);
3487
3488 if (transitionDuration > 0) {
3489 item.hasTransition = true;
3490 item.transitionDuration = element.style.transitionDuration;
3491 return true;
3492 }
3493 }
3494
3495 return false;
3496 }).forEach(function (item) {
3497 item.element.style.transitionDuration = "0s";
3498 });
3499 (_a = this._im) === null || _a === void 0 ? void 0 : _a.destroy();
3500 this._im = new ImReady({
3501 prefix: this.options.attributePrefix
3502 }).on("preReadyElement", function (e) {
3503 updated[e.index].updateState = UPDATE_STATE.WAIT_LOADING;
3504 }).on("preReady", function () {
3505 // reset org size
3506 updated.forEach(function (item) {
3507 var hasOrgSize = item.orgRect.width && item.orgRect.height;
3508 var hasCSSSize = item.cssRect.width || item.cssRect.height;
3509
3510 if (!hasOrgSize && hasCSSSize) {
3511 item.element.style.cssText = item.orgCSSText;
3512 }
3513 });
3514
3515 _this.itemRenderer.updateItems(updated);
3516
3517 _this.readyItems(mounted, updated, options);
3518 }).on("readyElement", function (e) {
3519 var item = updated[e.index];
3520 item.updateState = UPDATE_STATE.NEED_UPDATE; // after preReady
3521
3522 if (e.isPreReadyOver) {
3523 item.element.style.cssText = item.orgCSSText;
3524
3525 _this.itemRenderer.updateItems([item]);
3526
3527 _this.readyItems([], [item], options);
3528 }
3529 }).on("error", function (e) {
3530 var item = updated[e.index];
3531 /**
3532 * This event is fired when an error occurs in the content.
3533 * @ko 콘텐츠 로드에 에러가 날 때 발생하는 이벤트.
3534 * @event Grid#contentError
3535 * @param {Grid.OnContentError} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
3536 * @example
3537 * ```js
3538 * grid.on("contentError", e => {
3539 * e.update();
3540 * });
3541 * ```
3542 */
3543
3544 _this.trigger("contentError", {
3545 element: e.element,
3546 target: e.target,
3547 item: item,
3548 update: function () {
3549 moreUpdated.push(item);
3550 }
3551 });
3552 }).on("ready", function () {
3553 if (moreUpdated.length) {
3554 _this.updateItems(moreUpdated);
3555 }
3556 }).check(updated.map(function (item) {
3557 return item.element;
3558 }));
3559 };
3560
3561 __proto.scheduleRender = function () {
3562 var _this = this;
3563
3564 this._clearRenderTimer();
3565
3566 this._renderTimer = window.setTimeout(function () {
3567 _this.renderItems();
3568 });
3569 };
3570
3571 __proto.fitOutlines = function (useFit) {
3572 if (useFit === void 0) {
3573 useFit = this.useFit;
3574 }
3575
3576 var outlines = this.outlines;
3577 var startOutline = outlines.start;
3578 var endOutline = outlines.end;
3579 var outlineOffset = startOutline.length ? Math.min.apply(Math, startOutline) : 0; // If the outline is less than 0, a fit occurs forcibly.
3580
3581 if (!useFit && outlineOffset > 0) {
3582 return;
3583 }
3584
3585 outlines.start = startOutline.map(function (point) {
3586 return point - outlineOffset;
3587 });
3588 outlines.end = endOutline.map(function (point) {
3589 return point - outlineOffset;
3590 });
3591 this.items.forEach(function (item) {
3592 var contentPos = item.cssContentPos;
3593
3594 if (!isNumber(contentPos)) {
3595 return;
3596 }
3597
3598 item.cssContentPos = contentPos - outlineOffset;
3599 });
3600 };
3601
3602 __proto.readyItems = function (mounted, updated, options) {
3603 var prevOutlines = this.outlines;
3604 var direction = options.direction || this.options.defaultDirection;
3605 var prevOutline = options.outline || prevOutlines[direction === "end" ? "start" : "end"];
3606 var items = this.items;
3607 var nextOutlines = {
3608 start: __spreadArray([], prevOutline),
3609 end: __spreadArray([], prevOutline)
3610 };
3611 mounted.forEach(function (item) {
3612 item.mountState = MOUNT_STATE.MOUNTED;
3613 });
3614 updated.forEach(function (item) {
3615 item.isUpdate = true;
3616 });
3617
3618 if (items.length) {
3619 nextOutlines = this.applyGrid(this.items, direction, prevOutline);
3620 }
3621
3622 updated.forEach(function (item) {
3623 item.isUpdate = false;
3624 });
3625 this.setOutlines(nextOutlines);
3626 this.fitOutlines();
3627 this.itemRenderer.renderItems(this.items);
3628
3629 this._refreshContainerContentSize();
3630
3631 var transitionMounted = mounted.filter(function (item) {
3632 return item.hasTransition;
3633 });
3634
3635 if (transitionMounted.length) {
3636 this.containerManager.resize();
3637 transitionMounted.forEach(function (item) {
3638 var element = item.element;
3639 element.style.transitionDuration = item.transitionDuration;
3640 });
3641 }
3642
3643 this._renderComplete({
3644 direction: direction,
3645 mounted: mounted,
3646 updated: updated,
3647 isResize: !!options.useResize
3648 });
3649 };
3650
3651 __proto._renderComplete = function (e) {
3652 /**
3653 * This event is fired when the Grid has completed rendering.
3654 * @ko Grid가 렌더링이 완료됐을 때 발생하는 이벤트이다.
3655 * @event Grid#renderComplete
3656 * @param {Grid.OnRenderComplete} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
3657 * @example
3658 * ```js
3659 * grid.on("renderComplete", e => {
3660 * console.log(e.mounted, e.updated, e.useResize);
3661 * });
3662 * ```
3663 */
3664 this.trigger("renderComplete", e);
3665 };
3666
3667 __proto._clearRenderTimer = function () {
3668 clearTimeout(this._renderTimer);
3669 this._renderTimer = 0;
3670 };
3671
3672 __proto._refreshContainerContentSize = function () {
3673 var _a = this.outlines,
3674 startOutline = _a.start,
3675 endOutline = _a.end;
3676 var gap = this.options.gap;
3677 var endPoint = endOutline.length ? Math.max.apply(Math, endOutline) : 0;
3678 var startPoint = startOutline.length ? Math.max.apply(Math, startOutline) : 0;
3679 var contentSize = Math.max(startPoint, endPoint - gap);
3680 this.containerManager.setContentSize(contentSize);
3681 };
3682
3683 __proto._resizeContainer = function () {
3684 this.containerManager.resize();
3685 this.itemRenderer.setContainerRect(this.containerManager.getRect());
3686 };
3687
3688 __proto._init = function () {
3689 this._resizeContainer();
3690 };
3691
3692 __proto._renderItems = function (options, isTrusted) {
3693 if (options === void 0) {
3694 options = {};
3695 }
3696
3697 this._clearRenderTimer();
3698
3699 var isResize = options.useResize || options.useOrgResize;
3700
3701 if (isResize && !isTrusted) {
3702 // Resize container
3703 // isTrusted has already been resized internally.
3704 this._resizeContainer();
3705
3706 this.itemRenderer.resize();
3707 }
3708
3709 if (!this.getItems().length && this.getChildren().length) {
3710 this.syncElements(options);
3711 } else if (isResize) {
3712 // Update all items
3713 this.updateItems(this.items, options);
3714 } else {
3715 // Update only items that need to be updated.
3716 this.checkReady(options);
3717 }
3718 };
3719
3720 var Grid_1;
3721 Grid.defaultOptions = DEFAULT_GRID_OPTIONS;
3722 Grid.propertyTypes = GRID_PROPERTY_TYPES;
3723 Grid = Grid_1 = __decorate$1([GetterSetter], Grid);
3724 return Grid;
3725 }(Component);
3726 /**
3727 * Gap used to create space around items.
3728 * @ko 아이템들 사이의 공간.
3729 * @name Grid#gap
3730 * @type {$ts:Grid.GridOptions["gap"]}
3731 * @default 0
3732 * @example
3733 * ```js
3734 * import { MasonryGrid } from "@egjs/grid";
3735 *
3736 * const grid = new MasonryGrid(container, {
3737 * gap: 0,
3738 * });
3739 *
3740 * grid.gap = 5;
3741 * ```
3742 */
3743
3744 /**
3745 * The default direction value when direction is not set in the render option.
3746 * @ko render옵션에서 direction을 미설정시의 기본 방향값.
3747 * @name Grid#defaultDirection
3748 * @type {$ts:Grid.GridOptions["defaultDirection"]}
3749 * @default "end"
3750 * @example
3751 * ```js
3752 * import { MasonryGrid } from "@egjs/grid";
3753 *
3754 * const grid = new MasonryGrid(container, {
3755 * defaultDirection: "end",
3756 * });
3757 *
3758 * grid.defaultDirection = "start";
3759 * ```
3760 */
3761
3762 /**
3763 * Whether to move the outline to 0 when the top is empty when rendering. However, if it overflows above the top, the outline is forced to 0. (default: true)
3764 * @ko 렌더링시 상단이 비어있을 때 아웃라인을 0으로 이동시킬지 여부. 하지만 상단보다 넘치는 경우 아웃라인을 0으로 강제 이동한다. (default: true)
3765 * @name Grid#useFit
3766 * @type {$ts:Grid.GridOptions["useFit"]}
3767 * @default true
3768 * @example
3769 * ```js
3770 * import { MasonryGrid } from "@egjs/grid";
3771 *
3772 * const grid = new MasonryGrid(container, {
3773 * useFit: true,
3774 * });
3775 *
3776 * grid.useFit = false;
3777 * ```
3778 */
3779
3780 /**
3781 * Whether to preserve the UI of the existing container or item when destroying.
3782 * @ko destroy 시 기존 컨테이너, 아이템의 UI를 보존할지 여부.
3783 * @name Grid#preserveUIOnDestroy
3784 * @type {$ts:Grid.GridOptions["preserveUIOnDestroy"]}
3785 * @default false
3786 * @example
3787 * ```js
3788 * import { MasonryGrid } from "@egjs/grid";
3789 *
3790 * const grid = new MasonryGrid(container, {
3791 * preserveUIOnDestroy: false,
3792 * });
3793 *
3794 * grid.preserveUIOnDestroy = true;
3795 * ```
3796 */
3797
3798 /**
3799 * The number of outlines. If the number of outlines is 0, it is calculated according to the type of grid.
3800 * @ko outline의 개수. 아웃라인의 개수가 0이라면 grid의 종류에 따라 계산이 된다.
3801 * @name Grid#outlineLength
3802 * @type {$ts:Grid.GridOptions["outlineLength"]}
3803 * @default 0
3804 * @example
3805 * ```js
3806 * import { MasonryGrid } from "@egjs/grid";
3807 *
3808 * const grid = new MasonryGrid(container, {
3809 * outlineLength: 0,
3810 * outlineSize: 0,
3811 * });
3812 *
3813 * grid.outlineLength = 3;
3814 * ```
3815 */
3816
3817 /**
3818 * The size of the outline. If the outline size is 0, it is calculated according to the grid type.
3819 * @ko outline의 사이즈. 만약 outline의 사이즈가 0이면, grid의 종류에 따라 계산이 된다.
3820 * @name Grid#outlineSize
3821 * @type {$ts:Grid.GridOptions["outlineSize"]}
3822 * @default 0
3823 * @example
3824 * ```js
3825 * import { MasonryGrid } from "@egjs/grid";
3826 *
3827 * const grid = new MasonryGrid(container, {
3828 * outlineLength: 0,
3829 * outlineSize: 0,
3830 * });
3831 *
3832 * grid.outlineSize = 300;
3833 * ```
3834 */
3835
3836 function getColumnPoint(outline, columnIndex, columnCount, pointCaculationName) {
3837 return Math[pointCaculationName].apply(Math, outline.slice(columnIndex, columnIndex + columnCount));
3838 }
3839
3840 function getColumnIndex(outline, columnCount, nearestCalculationName) {
3841 var length = outline.length - columnCount + 1;
3842 var pointCaculationName = nearestCalculationName === "max" ? "min" : "max";
3843 var indexCaculationName = nearestCalculationName === "max" ? "lastIndexOf" : "indexOf";
3844 var points = range(length).map(function (index) {
3845 return getColumnPoint(outline, index, columnCount, pointCaculationName);
3846 });
3847 return points[indexCaculationName](Math[nearestCalculationName].apply(Math, points));
3848 }
3849 /**
3850 * MasonryGrid is a grid that stacks items with the same width as a stack of bricks. Adjust the width of all images to the same size, find the lowest height column, and insert a new item.
3851 * @ko MasonryGrid는 벽돌을 쌓아 올린 모양처럼 동일한 너비를 가진 아이템를 쌓는 레이아웃이다. 모든 이미지의 너비를 동일한 크기로 조정하고, 가장 높이가 낮은 열을 찾아 새로운 이미지를 삽입한다. 따라서 배치된 아이템 사이에 빈 공간이 생기지는 않지만 배치된 레이아웃의 아래쪽은 울퉁불퉁해진다.
3852 * @memberof Grid
3853 * @param {HTMLElement | string} container - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
3854 * @param {Grid.MasonryGrid.MasonryGridOptions} options - The option object of the MasonryGrid module <ko>MasonryGrid 모듈의 옵션 객체</ko>
3855 */
3856
3857
3858 var MasonryGrid =
3859 /*#__PURE__*/
3860 function (_super) {
3861 __extends$2(MasonryGrid, _super);
3862
3863 function MasonryGrid() {
3864 return _super !== null && _super.apply(this, arguments) || this;
3865 }
3866
3867 var __proto = MasonryGrid.prototype;
3868
3869 __proto.applyGrid = function (items, direction, outline) {
3870 var columnSize = this.getComputedOutlineSize(items);
3871 var column = this.getComputedOutlineLength(items);
3872 var _a = this.options,
3873 gap = _a.gap,
3874 align = _a.align,
3875 columnSizeRatio = _a.columnSizeRatio;
3876 var outlineLength = outline.length;
3877 var itemsLength = items.length;
3878
3879 var alignPoses = this._getAlignPoses(column, columnSize);
3880
3881 var isEndDirection = direction === "end";
3882 var nearestCalculationName = isEndDirection ? "min" : "max";
3883 var pointCalculationName = isEndDirection ? "max" : "min";
3884 var startOutline = [0];
3885
3886 if (outlineLength === column) {
3887 startOutline = outline.slice();
3888 } else {
3889 var point_1 = outlineLength ? Math[pointCalculationName].apply(Math, outline) : 0;
3890 startOutline = range(column).map(function () {
3891 return point_1;
3892 });
3893 }
3894
3895 var endOutline = startOutline.slice();
3896 var columnDist = column > 1 ? alignPoses[1] - alignPoses[0] : 0;
3897 var isStretch = align === "stretch";
3898
3899 var _loop_1 = function (i) {
3900 var item = items[isEndDirection ? i : itemsLength - 1 - i];
3901 var columnAttribute = parseInt(item.attributes.column || "1", 10);
3902 var maxColumnAttribute = parseInt(item.attributes.maxColumn || "1", 10);
3903 var contentSize = item.contentSize;
3904 var columnCount = Math.min(column, columnAttribute || Math.max(1, Math.ceil((item.inlineSize + gap) / columnDist)));
3905 var maxColumnCount = Math.min(column, Math.max(columnCount, maxColumnAttribute));
3906 var columnIndex = getColumnIndex(endOutline, columnCount, nearestCalculationName);
3907 var contentPos = getColumnPoint(endOutline, columnIndex, columnCount, pointCalculationName);
3908
3909 while (columnCount < maxColumnCount) {
3910 var nextEndColumnIndex = columnIndex + columnCount;
3911 var nextColumnIndex = columnIndex - 1;
3912
3913 if (isEndDirection && (nextEndColumnIndex >= column || endOutline[nextEndColumnIndex] > contentPos)) {
3914 break;
3915 }
3916
3917 if (!isEndDirection && (nextColumnIndex < 0 || endOutline[nextColumnIndex]) < contentPos) {
3918 break;
3919 }
3920
3921 if (!isEndDirection) {
3922 --columnIndex;
3923 }
3924
3925 ++columnCount;
3926 }
3927
3928 columnIndex = Math.max(0, columnIndex);
3929 columnCount = Math.min(column - columnIndex, columnCount); // stretch mode or data-grid-column > "1"
3930
3931 if (columnAttribute > 0 && columnCount > 1 || isStretch) {
3932 item.cssInlineSize = (columnCount - 1) * columnDist + columnSize;
3933 }
3934
3935 if (columnSizeRatio > 0) {
3936 contentSize = item.computedInlineSize / columnSizeRatio;
3937 item.cssContentSize = contentSize;
3938 }
3939
3940 var inlinePos = alignPoses[columnIndex];
3941 contentPos = isEndDirection ? contentPos : contentPos - gap - contentSize;
3942 item.cssInlinePos = inlinePos;
3943 item.cssContentPos = contentPos;
3944 var nextOutlinePoint = isEndDirection ? contentPos + contentSize + gap : contentPos;
3945 range(columnCount).forEach(function (indexOffset) {
3946 endOutline[columnIndex + indexOffset] = nextOutlinePoint;
3947 });
3948 };
3949
3950 for (var i = 0; i < itemsLength; ++i) {
3951 _loop_1(i);
3952 } // if end items, startOutline is low, endOutline is high
3953 // if start items, startOutline is high, endOutline is low
3954
3955
3956 return {
3957 start: isEndDirection ? startOutline : endOutline,
3958 end: isEndDirection ? endOutline : startOutline
3959 };
3960 };
3961
3962 __proto.getComputedOutlineSize = function (items) {
3963 if (items === void 0) {
3964 items = this.items;
3965 }
3966
3967 var _a = this.options,
3968 gap = _a.gap,
3969 align = _a.align;
3970 var containerInlineSize = this.getContainerInlineSize();
3971 var columnSizeOption = this.columnSize || this.outlineSize;
3972 var columnOption = this.column || this.outlineLength;
3973 var column = columnOption || 1;
3974 var columnSize = 0;
3975
3976 if (align === "stretch") {
3977 if (!columnOption) {
3978 var maxStretchColumnSize = this.maxStretchColumnSize || Infinity;
3979 column = Math.max(1, Math.ceil((containerInlineSize + gap) / (maxStretchColumnSize + gap)));
3980 }
3981
3982 columnSize = (containerInlineSize + gap) / (column || 1) - gap;
3983 } else if (columnSizeOption) {
3984 columnSize = columnSizeOption;
3985 } else if (items.length) {
3986 var checkedItem = items[0];
3987
3988 for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
3989 var item = items_1[_i];
3990 var attributes = item.attributes;
3991
3992 if (item.updateState !== UPDATE_STATE.UPDATED || !item.inlineSize || attributes.column || attributes.maxColumnCount) {
3993 continue;
3994 }
3995
3996 checkedItem = item;
3997 break;
3998 }
3999
4000 var inlineSize = checkedItem.inlineSize || 0;
4001 columnSize = inlineSize;
4002 } else {
4003 columnSize = containerInlineSize;
4004 }
4005
4006 return columnSize || 0;
4007 };
4008
4009 __proto.getComputedOutlineLength = function (items) {
4010 if (items === void 0) {
4011 items = this.items;
4012 }
4013
4014 var gap = this.gap;
4015 var columnOption = this.column || this.outlineLength;
4016 var columnCalculationThreshold = this.columnCalculationThreshold;
4017 var column = 1;
4018
4019 if (columnOption) {
4020 column = columnOption;
4021 } else {
4022 var columnSize = this.getComputedOutlineSize(items);
4023 column = Math.min(items.length, Math.max(1, Math.floor((this.getContainerInlineSize() + gap) / (columnSize - columnCalculationThreshold + gap))));
4024 }
4025
4026 return column;
4027 };
4028
4029 __proto._getAlignPoses = function (column, columnSize) {
4030 var _a = this.options,
4031 align = _a.align,
4032 gap = _a.gap;
4033 var containerSize = this.getContainerInlineSize();
4034 var indexes = range(column);
4035 var offset = 0;
4036 var dist = 0;
4037
4038 if (align === "justify" || align === "stretch") {
4039 var countDist = column - 1;
4040 dist = countDist ? Math.max((containerSize - columnSize) / countDist, columnSize + gap) : 0;
4041 offset = Math.min(0, containerSize / 2 - (countDist * dist + columnSize) / 2);
4042 } else {
4043 dist = columnSize + gap;
4044 var totalColumnSize = (column - 1) * dist + columnSize;
4045
4046 if (align === "center") {
4047 offset = (containerSize - totalColumnSize) / 2;
4048 } else if (align === "end") {
4049 offset = containerSize - totalColumnSize;
4050 }
4051 }
4052
4053 return indexes.map(function (i) {
4054 return offset + i * dist;
4055 });
4056 };
4057
4058 MasonryGrid.propertyTypes = __assign$2(__assign$2({}, Grid.propertyTypes), {
4059 column: PROPERTY_TYPE.RENDER_PROPERTY,
4060 columnSize: PROPERTY_TYPE.RENDER_PROPERTY,
4061 columnSizeRatio: PROPERTY_TYPE.RENDER_PROPERTY,
4062 align: PROPERTY_TYPE.RENDER_PROPERTY,
4063 columnCalculationThreshold: PROPERTY_TYPE.RENDER_PROPERTY,
4064 maxStretchColumnSize: PROPERTY_TYPE.RENDER_PROPERTY
4065 });
4066 MasonryGrid.defaultOptions = __assign$2(__assign$2({}, Grid.defaultOptions), {
4067 align: "justify",
4068 column: 0,
4069 columnSize: 0,
4070 columnSizeRatio: 0,
4071 columnCalculationThreshold: 0.5,
4072 maxStretchColumnSize: Infinity
4073 });
4074 MasonryGrid = __decorate$1([GetterSetter], MasonryGrid);
4075 return MasonryGrid;
4076 }(Grid);
4077 /**
4078 * Align of the position of the items. If you want to use `stretch`, be sure to set `column` or `columnSize` option. ("start", "center", "end", "justify", "stretch")
4079 * @ko 아이템들의 위치의 정렬. `stretch`를 사용하고 싶다면 `column` 또는 `columnSize` 옵션을 설정해라. ("start", "center", "end", "justify", "stretch")
4080 * @name Grid.MasonryGrid#align
4081 * @type {$ts:Grid.MasonryGrid.MasonryGridOptions["align"]}
4082 * @default "justify"
4083 * @example
4084 * ```js
4085 * import { MasonryGrid } from "@egjs/grid";
4086 *
4087 * const grid = new MasonryGrid(container, {
4088 * align: "start",
4089 * });
4090 *
4091 * grid.align = "justify";
4092 * ```
4093 */
4094
4095 /**
4096 * The number of columns. If the number of columns is 0, it is automatically calculated according to the size of the container. Can be used instead of outlineLength.
4097 * @ko 열의 개수. 열의 개수가 0이라면, 컨테이너의 사이즈에 의해 계산이 된다. outlineLength 대신 사용할 수 있다.
4098 * @name Grid.MasonryGrid#column
4099 * @type {$ts:Grid.MasonryGrid.MasonryGridOptions["column"]}
4100 * @default 0
4101 * @example
4102 * ```js
4103 * import { MasonryGrid } from "@egjs/grid";
4104 *
4105 * const grid = new MasonryGrid(container, {
4106 * column: 0,
4107 * });
4108 *
4109 * grid.column = 4;
4110 * ```
4111 */
4112
4113 /**
4114 * The size of the columns. If it is 0, it is calculated as the size of the first item in items. Can be used instead of outlineSize.
4115 * @ko 열의 사이즈. 만약 열의 사이즈가 0이면, 아이템들의 첫번째 아이템의 사이즈로 계산이 된다. outlineSize 대신 사용할 수 있다.
4116 * @name Grid.MasonryGrid#columnSize
4117 * @type {$ts:Grid.MasonryGrid.MasonryGridOptions["columnSize"]}
4118 * @default 0
4119 * @example
4120 * ```js
4121 * import { MasonryGrid } from "@egjs/grid";
4122 *
4123 * const grid = new MasonryGrid(container, {
4124 * columnSize: 0,
4125 * });
4126 *
4127 * grid.columnSize = 200;
4128 * ```
4129 */
4130
4131 /**
4132 * The size ratio(inlineSize / contentSize) of the columns. 0 is not set.
4133 * @ko 열의 사이즈 비율(inlineSize / contentSize). 0은 미설정이다.
4134 * @name Grid.MasonryGrid#columnSizeRatio
4135 * @type {$ts:Grid.MasonryGrid.MasonryGridOptions["columnSizeRatio"]}
4136 * @default 0
4137 * @example
4138 * ```js
4139 * import { MasonryGrid } from "@egjs/grid";
4140 *
4141 * const grid = new MasonryGrid(container, {
4142 * columnSizeRatio: 0,
4143 * });
4144 *
4145 * grid.columnSizeRatio = 0.5;
4146 * ```
4147 */
4148
4149 /**
4150 * If stretch is used, the column can be automatically calculated by setting the maximum size of the column that can be stretched.
4151 * @ko stretch를 사용한 경우 최대로 늘릴 수 있는 column의 사이즈를 설정하여 column을 자동 계산할 수 있다.
4152 * @name Grid.MasonryGrid#maxStretchColumnSize
4153 * @type {$ts:Grid.MasonryGrid.MasonryGridOptions["maxStretchColumnSize"]}
4154 * @default Infinity
4155 * @example
4156 * ```js
4157 * import { MasonryGrid } from "@egjs/grid";
4158 *
4159 * const grid = new MasonryGrid(container, {
4160 * align: "stretch",
4161 * maxStretchColumnSize: 0,
4162 * });
4163 *
4164 * grid.maxStretchColumnSize = 400;
4165 * ```
4166 */
4167
4168 /* eslint-disable */
4169
4170 /******************************************************************************
4171 * Created 2008-08-19.
4172 *
4173 * Dijkstra path-finding functions. Adapted from the Dijkstar Python project.
4174 *
4175 * Copyright (C) 2008
4176 * Wyatt Baldwin <self@wyattbaldwin.com>
4177 * All rights reserved
4178 *
4179 * Licensed under the MIT license.
4180 *
4181 * http://www.opensource.org/licenses/mit-license.php
4182 *
4183 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4184 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4185 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4186 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4187 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4188 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4189 * THE SOFTWARE.
4190 *****************************************************************************/
4191 function single_source_shortest_paths(graph, s, d) {
4192 // Predecessor map for each node that has been encountered.
4193 // node ID => predecessor node ID
4194 var predecessors = {}; // Costs of shortest paths from s to all nodes encountered.
4195 // node ID => cost
4196
4197 var costs = {};
4198 costs[s] = 0; // Costs of shortest paths from s to all nodes encountered; differs from
4199 // `costs` in that it provides easy access to the node that currently has
4200 // the known shortest path from s.
4201 // XXX: Do we actually need both `costs` and `open`?
4202
4203 var open = new BinaryHeap(function (x) {
4204 return x.cost;
4205 });
4206 open.push({
4207 value: s,
4208 cost: 0
4209 });
4210 var closest;
4211 var u;
4212 var cost_of_s_to_u;
4213 var adjacent_nodes;
4214 var cost_of_e;
4215 var cost_of_s_to_u_plus_cost_of_e;
4216 var cost_of_s_to_v;
4217 var first_visit;
4218
4219 while (open.size()) {
4220 // In the nodes remaining in graph that have a known cost from s,
4221 // find the node, u, that currently has the shortest path from s.
4222 closest = open.pop();
4223 u = closest.value;
4224 cost_of_s_to_u = closest.cost; // Get nodes adjacent to u...
4225
4226 adjacent_nodes = graph(u) || {}; // ...and explore the edges that connect u to those nodes, updating
4227 // the cost of the shortest paths to any or all of those nodes as
4228 // necessary. v is the node across the current edge from u.
4229
4230 for (var v in adjacent_nodes) {
4231 // Get the cost of the edge running from u to v.
4232 cost_of_e = adjacent_nodes[v]; // Cost of s to u plus the cost of u to v across e--this is *a*
4233 // cost from s to v that may or may not be less than the current
4234 // known cost to v.
4235
4236 cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e; // If we haven't visited v yet OR if the current known cost from s to
4237 // v is greater than the new cost we just found (cost of s to u plus
4238 // cost of u to v across e), update v's cost in the cost list and
4239 // update v's predecessor in the predecessor list (it's now u).
4240
4241 cost_of_s_to_v = costs[v];
4242 first_visit = typeof costs[v] === "undefined";
4243
4244 if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) {
4245 costs[v] = cost_of_s_to_u_plus_cost_of_e;
4246 open.push({
4247 value: v,
4248 cost: cost_of_s_to_u_plus_cost_of_e
4249 });
4250 predecessors[v] = u;
4251 }
4252 }
4253 }
4254
4255 if (typeof costs[d] === "undefined") {
4256 var msg = ["Could not find a path from ", s, " to ", d, "."].join("");
4257 throw new Error(msg);
4258 }
4259
4260 return predecessors;
4261 }
4262
4263 function extract_shortest_path_from_predecessor_list(predecessors, d) {
4264 var nodes = [];
4265 var u = d;
4266
4267 while (u) {
4268 nodes.push(u);
4269 u = predecessors[u];
4270 }
4271
4272 nodes.reverse();
4273 return nodes;
4274 }
4275
4276 function find_path(graph, s, d) {
4277 var predecessors = single_source_shortest_paths(graph, s, d);
4278 return extract_shortest_path_from_predecessor_list(predecessors, d);
4279 }
4280
4281 var BinaryHeap =
4282 /*#__PURE__*/
4283 function () {
4284 function BinaryHeap(scoreFunction) {
4285 this.content = [];
4286 this.scoreFunction = scoreFunction;
4287 }
4288
4289 var __proto = BinaryHeap.prototype;
4290
4291 __proto.push = function (element) {
4292 // Add the new element to the end of the array.
4293 this.content.push(element); // Allow it to bubble up.
4294
4295 this.bubbleUp(this.content.length - 1);
4296 };
4297
4298 __proto.pop = function () {
4299 // Store the first element so we can return it later.
4300 var result = this.content[0]; // Get the element at the end of the array.
4301
4302 var end = this.content.pop(); // If there are any elements left, put the end element at the
4303 // start, and let it sink down.
4304
4305 if (this.content.length > 0) {
4306 this.content[0] = end;
4307 this.sinkDown(0);
4308 }
4309
4310 return result;
4311 };
4312
4313 __proto.size = function () {
4314 return this.content.length;
4315 };
4316
4317 __proto.bubbleUp = function (_n) {
4318 var n = _n; // Fetch the element that has to be moved.
4319
4320 var element = this.content[n]; // When at 0, an element can not go up any further.
4321
4322 while (n > 0) {
4323 // Compute the parent element's index, and fetch it.
4324 var parentN = Math.floor((n + 1) / 2) - 1;
4325 var parent = this.content[parentN]; // Swap the elements if the parent is greater.
4326
4327 if (this.scoreFunction(element) < this.scoreFunction(parent)) {
4328 this.content[parentN] = element;
4329 this.content[n] = parent; // Update 'n' to continue at the new position.
4330
4331 n = parentN;
4332 } else {
4333 // Found a parent that is less, no need to move it further.
4334 break;
4335 }
4336 }
4337 };
4338
4339 __proto.sinkDown = function (n) {
4340 // Look up the target element and its score.
4341 var length = this.content.length;
4342 var element = this.content[n];
4343 var elemScore = this.scoreFunction(element);
4344 var child1Score;
4345
4346 while (true) {
4347 // Compute the indices of the child elements.
4348 var child2N = (n + 1) * 2;
4349 var child1N = child2N - 1; // This is used to store the new position of the element,
4350 // if any.
4351
4352 var swap = null; // If the first child exists (is inside the array)...
4353
4354 if (child1N < length) {
4355 // Look it up and compute its score.
4356 var child1 = this.content[child1N];
4357 child1Score = this.scoreFunction(child1); // If the score is less than our element's, we need to swap.
4358
4359 if (child1Score < elemScore) {
4360 swap = child1N;
4361 }
4362 } // Do the same checks for the other child.
4363
4364
4365 if (child2N < length) {
4366 var child2 = this.content[child2N];
4367 var child2Score = this.scoreFunction(child2);
4368
4369 if (child2Score < (swap == null ? elemScore : child1Score)) {
4370 swap = child2N;
4371 }
4372 } // If the element needs to be moved, swap it, and continue.
4373
4374
4375 if (swap !== null) {
4376 this.content[n] = this.content[swap];
4377 this.content[swap] = element;
4378 n = swap;
4379 } else {
4380 // Otherwise, we are done.
4381 break;
4382 }
4383 }
4384 };
4385
4386 return BinaryHeap;
4387 }();
4388
4389 function splitItems(items, path) {
4390 var length = path.length;
4391 var groups = [];
4392
4393 for (var i = 0; i < length - 1; ++i) {
4394 var path1 = parseInt(path[i], 10);
4395 var path2 = parseInt(path[i + 1], 10);
4396 groups.push(items.slice(path1, path2));
4397 }
4398
4399 return groups;
4400 }
4401
4402 function getExpectedColumnSize(item, rowSize) {
4403 var inlineSize = item.orgInlineSize;
4404 var contentSize = item.orgContentSize;
4405
4406 if (!inlineSize || !contentSize) {
4407 return rowSize;
4408 }
4409
4410 var inlineOffset = parseFloat(item.gridData.inlineOffset) || 0;
4411 var contentOffset = parseFloat(item.gridData.contentOffset) || 0;
4412 var ratio = contentSize <= contentOffset ? 1 : (inlineSize - inlineOffset) / (contentSize - contentOffset);
4413 return ratio * (rowSize - contentOffset) + inlineOffset;
4414 }
4415 /**
4416 * 'justified' is a printing term with the meaning that 'it fits in one row wide'. JustifiedGrid is a grid that the item is filled up on the basis of a line given a size.
4417 * If 'data-grid-inline-offset' or 'data-grid-content-offset' are set for item element, the ratio is maintained except for the offset value.
4418 * If 'data-grid-maintained-target' is set for an element whose ratio is to be maintained, the item is rendered while maintaining the ratio of the element.
4419 * @ko 'justified'는 '1행의 너비에 맞게 꼭 들어찬'이라는 의미를 가진 인쇄 용어다. JustifiedGrid는 용어의 의미대로 너비가 주어진 사이즈를 기준으로 아이템가 가득 차도록 배치하는 Grid다.
4420 * 아이템 엘리먼트에 'data-grid-inline-offset' 또는 'data-grid-content-offset'를 설정하면 offset 값을 제외하고 비율을 유지한다.
4421 * 비율을 유지하고 싶은 엘리먼트에 'data-grid-maintained-target'을 설정한다면 해당 엘리먼트의 비율을 유지하면서 아이템이 렌더링이 된다.
4422 * @memberof Grid
4423 * @param {HTMLElement | string} container - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
4424 * @param {Grid.JustifiedGrid.JustifiedGridOptions} options - The option object of the JustifiedGrid module <ko>JustifiedGrid 모듈의 옵션 객체</ko>
4425 */
4426
4427
4428 var JustifiedGrid =
4429 /*#__PURE__*/
4430 function (_super) {
4431 __extends$2(JustifiedGrid, _super);
4432
4433 function JustifiedGrid() {
4434 return _super !== null && _super.apply(this, arguments) || this;
4435 }
4436
4437 var __proto = JustifiedGrid.prototype;
4438
4439 __proto.applyGrid = function (items, direction, outline) {
4440 var _a = this.options,
4441 attributePrefix = _a.attributePrefix,
4442 horizontal = _a.horizontal;
4443 items.forEach(function (item) {
4444 if (!item.isUpdate) {
4445 return;
4446 }
4447
4448 var element = item.element;
4449 var attributes = item.attributes;
4450 var gridData = item.gridData;
4451 var inlineOffset = parseFloat(attributes.inlineOffset) || gridData.inlineOffset || 0;
4452 var contentOffset = parseFloat(attributes.contentOffset) || gridData.contentOffset | 0;
4453
4454 if (element && !("inlineOffset" in attributes) && !("contentOffset" in attributes) && item.mountState === MOUNT_STATE.MOUNTED) {
4455 var maintainedTarget = element.querySelector("[" + attributePrefix + "maintained-target]");
4456
4457 if (maintainedTarget) {
4458 var widthOffset = element.offsetWidth - element.clientWidth + element.scrollWidth - maintainedTarget.clientWidth;
4459 var heightOffset = element.offsetHeight - element.clientHeight + element.scrollHeight - maintainedTarget.clientHeight;
4460
4461 if (horizontal) {
4462 inlineOffset = heightOffset;
4463 contentOffset = widthOffset;
4464 } else {
4465 inlineOffset = widthOffset;
4466 contentOffset = heightOffset;
4467 }
4468 }
4469 }
4470
4471 gridData.inlineOffset = inlineOffset;
4472 gridData.contentOffset = contentOffset;
4473 });
4474 var rowRange = this.options.rowRange;
4475 var path = [];
4476
4477 if (items.length) {
4478 path = rowRange ? this._getRowPath(items) : this._getPath(items);
4479 }
4480
4481 return this._setStyle(items, path, outline, direction === "end");
4482 };
4483
4484 __proto._getRowPath = function (items) {
4485 var _a;
4486
4487 var columnRange = this._getColumnRange();
4488
4489 var rowRange = this._getRowRange();
4490
4491 var pathLink = this._getRowLink(items, {
4492 path: [0],
4493 cost: 0,
4494 length: 0,
4495 currentNode: 0
4496 }, columnRange, rowRange);
4497
4498 return (_a = pathLink === null || pathLink === void 0 ? void 0 : pathLink.path.map(function (node) {
4499 return "" + node;
4500 })) !== null && _a !== void 0 ? _a : [];
4501 };
4502
4503 __proto._getRowLink = function (items, currentLink, columnRange, rowRange) {
4504 var minColumn = columnRange[0];
4505 var minRow = rowRange[0],
4506 maxRow = rowRange[1];
4507 var lastNode = items.length;
4508 var path = currentLink.path,
4509 pathLength = currentLink.length,
4510 cost = currentLink.cost,
4511 currentNode = currentLink.currentNode; // not reached lastNode but path is exceed or the number of remaining nodes is less than minColumn.
4512
4513 if (currentNode < lastNode && (maxRow <= pathLength || currentNode + minColumn > lastNode)) {
4514 var rangeCost = getRangeCost(lastNode - currentNode, columnRange);
4515 var lastCost = rangeCost * Math.abs(this._getCost(items, currentNode, lastNode));
4516 return __assign$2(__assign$2({}, currentLink), {
4517 length: pathLength + 1,
4518 path: __spreadArray(__spreadArray([], path), [lastNode]),
4519 currentNode: lastNode,
4520 cost: cost + lastCost,
4521 isOver: true
4522 });
4523 } else if (currentNode >= lastNode) {
4524 return __assign$2(__assign$2({}, currentLink), {
4525 currentNode: lastNode,
4526 isOver: minRow > pathLength || maxRow < pathLength
4527 });
4528 } else {
4529 return this._searchRowLink(items, currentLink, lastNode, columnRange, rowRange);
4530 }
4531 };
4532
4533 __proto._searchRowLink = function (items, currentLink, lastNode, columnRange, rowRange) {
4534 var minColumn = columnRange[0],
4535 maxColumn = columnRange[1];
4536 var currentNode = currentLink.currentNode,
4537 path = currentLink.path,
4538 pathLength = currentLink.length,
4539 cost = currentLink.cost;
4540 var length = Math.min(lastNode, currentNode + maxColumn);
4541 var links = [];
4542
4543 for (var nextNode = currentNode + minColumn; nextNode <= length; ++nextNode) {
4544 if (nextNode === currentNode) {
4545 continue;
4546 }
4547
4548 var nextCost = Math.abs(this._getCost(items, currentNode, nextNode));
4549
4550 var nextLink = this._getRowLink(items, {
4551 path: __spreadArray(__spreadArray([], path), [nextNode]),
4552 length: pathLength + 1,
4553 cost: cost + nextCost,
4554 currentNode: nextNode
4555 }, columnRange, rowRange);
4556
4557 if (nextLink) {
4558 links.push(nextLink);
4559 }
4560 }
4561
4562 links.sort(function (a, b) {
4563 var aIsOver = a.isOver;
4564 var bIsOver = b.isOver;
4565
4566 if (aIsOver !== bIsOver) {
4567 // If it is over, the cost is high.
4568 return aIsOver ? 1 : -1;
4569 }
4570
4571 var aRangeCost = getRangeCost(a.length, rowRange);
4572 var bRangeCost = getRangeCost(b.length, rowRange);
4573 return aRangeCost - bRangeCost || a.cost - b.cost;
4574 }); // It returns the lowest cost link.
4575
4576 return links[0];
4577 };
4578
4579 __proto._getExpectedRowSize = function (items) {
4580 var gap = this.options.gap;
4581 var containerInlineSize = this.getContainerInlineSize() - gap * (items.length - 1);
4582 var ratioSum = 0;
4583 var inlineSum = 0;
4584 items.forEach(function (item) {
4585 var inlineSize = item.orgInlineSize;
4586 var contentSize = item.orgContentSize;
4587
4588 if (!inlineSize || !contentSize) {
4589 ratioSum += 1;
4590 return;
4591 } // sum((expect - offset) * ratio) = container inline size
4592
4593
4594 var inlineOffset = parseFloat(item.gridData.inlineOffset) || 0;
4595 var contentOffset = parseFloat(item.gridData.contentOffset) || 0;
4596 var maintainedRatio = contentSize <= contentOffset ? 1 : (inlineSize - inlineOffset) / (contentSize - contentOffset);
4597 ratioSum += maintainedRatio;
4598 inlineSum += contentOffset * maintainedRatio;
4599 containerInlineSize -= inlineOffset;
4600 });
4601 return ratioSum ? (containerInlineSize + inlineSum) / ratioSum : 0;
4602 };
4603
4604 __proto._getExpectedInlineSize = function (items, rowSize) {
4605 var gap = this.options.gap;
4606 var size = items.reduce(function (sum, item) {
4607 return sum + getExpectedColumnSize(item, rowSize);
4608 }, 0);
4609 return size ? size + gap * (items.length - 1) : 0;
4610 };
4611
4612 __proto._getCost = function (items, i, j) {
4613 var lineItems = items.slice(i, j);
4614
4615 var rowSize = this._getExpectedRowSize(lineItems);
4616
4617 var _a = this._getSizeRange(),
4618 minSize = _a[0],
4619 maxSize = _a[1];
4620
4621 if (this.isCroppedSize) {
4622 if (minSize <= rowSize && rowSize <= maxSize) {
4623 return 0;
4624 }
4625
4626 var expectedInlineSize = this._getExpectedInlineSize(lineItems, rowSize < minSize ? minSize : maxSize);
4627
4628 return Math.pow(expectedInlineSize - this.getContainerInlineSize(), 2);
4629 }
4630
4631 if (isFinite(maxSize)) {
4632 // if this size is not in range, the cost increases sharply.
4633 if (rowSize < minSize) {
4634 return Math.pow(rowSize - minSize, 2) + Math.pow(maxSize, 2);
4635 } else if (rowSize > maxSize) {
4636 return Math.pow(rowSize - maxSize, 2) + Math.pow(maxSize, 2);
4637 }
4638 } else if (rowSize < minSize) {
4639 return Math.max(Math.pow(minSize, 2), Math.pow(rowSize, 2)) + Math.pow(maxSize, 2);
4640 } // if this size in range, the cost is row
4641
4642
4643 return rowSize - minSize;
4644 };
4645
4646 __proto._getPath = function (items) {
4647 var _this = this;
4648
4649 var lastNode = items.length;
4650 var columnRangeOption = this.options.columnRange;
4651
4652 var _a = isObject(columnRangeOption) ? columnRangeOption : [columnRangeOption, columnRangeOption],
4653 minColumn = _a[0],
4654 maxColumn = _a[1];
4655
4656 var graph = function (nodeKey) {
4657 var results = {};
4658 var currentNode = parseInt(nodeKey, 10);
4659
4660 for (var nextNode = Math.min(currentNode + minColumn, lastNode); nextNode <= lastNode; ++nextNode) {
4661 if (nextNode - currentNode > maxColumn) {
4662 break;
4663 }
4664
4665 var cost = _this._getCost(items, currentNode, nextNode);
4666
4667 if (cost < 0 && nextNode === lastNode) {
4668 cost = 0;
4669 }
4670
4671 results["" + nextNode] = Math.pow(cost, 2);
4672 }
4673
4674 return results;
4675 }; // shortest path for items' total height.
4676
4677
4678 return find_path(graph, "0", "" + lastNode);
4679 };
4680
4681 __proto._setStyle = function (items, path, outline, isEndDirection) {
4682 var _this = this;
4683
4684 if (outline === void 0) {
4685 outline = [];
4686 }
4687
4688 var _a = this.options,
4689 gap = _a.gap,
4690 isCroppedSize = _a.isCroppedSize,
4691 displayedRow = _a.displayedRow;
4692
4693 var sizeRange = this._getSizeRange();
4694
4695 var startPoint = outline[0] || 0;
4696 var containerInlineSize = this.getContainerInlineSize();
4697 var groups = splitItems(items, path);
4698 var contentPos = startPoint;
4699 var displayedSize = 0;
4700 groups.forEach(function (groupItems, rowIndex) {
4701 var length = groupItems.length;
4702
4703 var rowSize = _this._getExpectedRowSize(groupItems);
4704
4705 if (isCroppedSize) {
4706 rowSize = Math.max(sizeRange[0], Math.min(rowSize, sizeRange[1]));
4707 }
4708
4709 var expectedInlineSize = _this._getExpectedInlineSize(groupItems, rowSize);
4710
4711 var allGap = gap * (length - 1);
4712 var scale = (containerInlineSize - allGap) / (expectedInlineSize - allGap);
4713 groupItems.forEach(function (item, i) {
4714 var columnSize = getExpectedColumnSize(item, rowSize);
4715 var prevItem = groupItems[i - 1];
4716 var inlinePos = prevItem ? prevItem.cssInlinePos + prevItem.cssInlineSize + gap : 0;
4717
4718 if (isCroppedSize) {
4719 columnSize *= scale;
4720 }
4721
4722 item.setCSSGridRect({
4723 inlinePos: inlinePos,
4724 contentPos: contentPos,
4725 inlineSize: columnSize,
4726 contentSize: rowSize
4727 });
4728 });
4729 contentPos += gap + rowSize;
4730
4731 if (displayedRow < 0 || rowIndex < displayedRow) {
4732 displayedSize = contentPos;
4733 }
4734 });
4735
4736 if (isEndDirection) {
4737 // previous group's end outline is current group's start outline
4738 return {
4739 start: [startPoint],
4740 end: [displayedSize]
4741 };
4742 } // always start is lower than end.
4743 // contentPos is endPoinnt
4744
4745
4746 var height = contentPos - startPoint;
4747 items.forEach(function (item) {
4748 item.cssContentPos -= height;
4749 });
4750 return {
4751 start: [startPoint - height],
4752 end: [startPoint] // endPoint - height = startPoint
4753
4754 };
4755 };
4756
4757 __proto.getComputedOutlineLength = function () {
4758 return 1;
4759 };
4760
4761 __proto.getComputedOutlineSize = function () {
4762 return this.getContainerInlineSize();
4763 };
4764
4765 __proto._getRowRange = function () {
4766 var rowRange = this.rowRange;
4767 return isObject(rowRange) ? rowRange : [rowRange, rowRange];
4768 };
4769
4770 __proto._getColumnRange = function () {
4771 var columnRange = this.columnRange;
4772 return isObject(columnRange) ? columnRange : [columnRange, columnRange];
4773 };
4774
4775 __proto._getSizeRange = function () {
4776 var sizeRange = this.sizeRange;
4777 return isObject(sizeRange) ? sizeRange : [sizeRange, sizeRange];
4778 };
4779
4780 JustifiedGrid.propertyTypes = __assign$2(__assign$2({}, Grid.propertyTypes), {
4781 columnRange: PROPERTY_TYPE.RENDER_PROPERTY,
4782 rowRange: PROPERTY_TYPE.RENDER_PROPERTY,
4783 sizeRange: PROPERTY_TYPE.RENDER_PROPERTY,
4784 isCroppedSize: PROPERTY_TYPE.RENDER_PROPERTY,
4785 displayedRow: PROPERTY_TYPE.RENDER_PROPERTY
4786 });
4787 JustifiedGrid.defaultOptions = __assign$2(__assign$2({}, Grid.defaultOptions), {
4788 columnRange: [1, 8],
4789 rowRange: 0,
4790 sizeRange: [0, Infinity],
4791 displayedRow: -1,
4792 isCroppedSize: false
4793 });
4794 JustifiedGrid = __decorate$1([GetterSetter], JustifiedGrid);
4795 return JustifiedGrid;
4796 }(Grid);
4797 /**
4798 * The minimum and maximum number of items per line.
4799 * @ko 한 줄에 들어가는 아이템의 최소, 최대 개수.
4800 * @name Grid.JustifiedGrid#columnRange
4801 * @type {$ts:Grid.JustifiedGrid.JustifiedGridOptions["columnRange"]}
4802 * @default [1, 8]
4803 * @example
4804 * ```js
4805 * import { JustifiedGrid } from "@egjs/grid";
4806 *
4807 * const grid = new JustifiedGrid(container, {
4808 * columnRange: [1, 8],
4809 * });
4810 *
4811 * grid.columnRange = [3, 6];
4812 * ```
4813 */
4814
4815 /**
4816 * The minimum and maximum number of rows in a group, 0 is not set.
4817 * @ko 한 그룹에 들어가는 행의 최소, 최대 개수, 0은 미설정이다.
4818 * @name Grid.JustifiedGrid#rowRange
4819 * @type {$ts:Grid.JustifiedGrid.JustifiedGridOptions["rowRange"]}
4820 * @default 0
4821 * @example
4822 * ```js
4823 * import { JustifiedGrid } from "@egjs/grid";
4824 *
4825 * const grid = new JustifiedGrid(container, {
4826 * rowRange: 0,
4827 * });
4828 *
4829 * grid.rowRange = [3, 4];
4830 * ```
4831 */
4832
4833 /**
4834 * The minimum and maximum size by which the item is adjusted. If it is not calculated, it may deviate from the minimum and maximum sizes.
4835 * @ko 아이템이 조정되는 최소, 최대 사이즈. 계산이 되지 않는 경우 최소, 최대 사이즈를 벗어날 수 있다.
4836 * @name Grid.JustifiedGrid#sizeRange
4837 * @type {$ts:Grid.JustifiedGrid.JustifiedGridOptions["sizeRange"]}
4838 * @default [0, Infinity]
4839 * @example
4840 * ```js
4841 * import { JustifiedGrid } from "@egjs/grid";
4842 *
4843 * const grid = new JustifiedGrid(container, {
4844 * sizeRange: [0, Infinity],
4845 * });
4846 *
4847 * grid.sizeRange = [200, 800];
4848 * ```
4849 */
4850
4851 /**
4852 * Maximum number of rows to be counted for container size. You can hide it on the screen by setting overflow: hidden. -1 is not set.
4853 * @ko - 컨테이너 크기에 계산될 최대 row 개수. overflow: hidden을 설정하면 화면에 가릴 수 있다. -1은 미설정이다.
4854 * @name Grid.JustifiedGrid#displayedRow
4855 * @type {$ts:Grid.JustifiedGrid.JustifiedGridOptions["displayedRow"]}
4856 * @default -1
4857 * @example
4858 * ```js
4859 * import { JustifiedGrid } from "@egjs/grid";
4860 *
4861 * const grid = new JustifiedGrid(container, {
4862 * displayedRow: -1,
4863 * });
4864 *
4865 * grid.displayedRow = 3;
4866 * ```
4867 */
4868
4869 /**
4870 * Whether to crop when the row size is out of sizeRange. If set to true, this ratio can be broken.
4871 * @ko - row 사이즈가 sizeRange에 벗어나면 크롭할지 여부. true로 설정하면 비율이 깨질 수 있다.
4872 * @name Grid.JustifiedGrid#isCroppedSize
4873 * @type {$ts:Grid.JustifiedGrid.JustifiedGridOptions["isCroppedSize"]}
4874 * @default false
4875 * @example
4876 * ```js
4877 * import { JustifiedGrid } from "@egjs/grid";
4878 *
4879 * const grid = new JustifiedGrid(container, {
4880 * sizeRange: [200, 250],
4881 * isCroppedSize: false,
4882 * });
4883 *
4884 * grid.isCroppedSize = true;
4885 * ```
4886 */
4887
4888 function getMaxPoint(outline) {
4889 var maxPoint = -Infinity;
4890 outline.forEach(function (point) {
4891 if (isFinite(point)) {
4892 maxPoint = Math.max(maxPoint, point);
4893 }
4894 });
4895 return isFinite(maxPoint) ? maxPoint : 0;
4896 }
4897
4898 function getMinPoint(outline) {
4899 var minPoint = Infinity;
4900 outline.forEach(function (point) {
4901 if (isFinite(point)) {
4902 minPoint = Math.min(minPoint, point);
4903 }
4904 });
4905 return isFinite(minPoint) ? minPoint : 0;
4906 }
4907
4908 function getOutlinePoint(startOutline, frameOutline, useFrameFill) {
4909 return getMaxPoint(startOutline) + getOutlineDist(startOutline, frameOutline, useFrameFill);
4910 }
4911
4912 function getOutlineDist(startOutline, endOutline, useFrameFill) {
4913 var length = startOutline.length;
4914
4915 if (!length) {
4916 return 0;
4917 }
4918
4919 var minEndPoint = getMinPoint(endOutline);
4920 var maxStartPoint = getMaxPoint(startOutline);
4921 var frameDist = 0;
4922
4923 if (!useFrameFill) {
4924 return 0;
4925 }
4926
4927 for (var outlineIndex = 0; outlineIndex < length; ++outlineIndex) {
4928 var startPoint = startOutline[outlineIndex];
4929 var endPoint = endOutline[outlineIndex];
4930
4931 if (!isFinite(startPoint) || !isFinite(endPoint)) {
4932 continue;
4933 }
4934
4935 var startPos = startPoint - maxStartPoint;
4936 var endPos = endPoint - minEndPoint; // Fill empty block.
4937
4938 frameDist = outlineIndex ? Math.max(frameDist, frameDist + startPos - endPos) : startPos - endPos;
4939 }
4940
4941 return frameDist;
4942 }
4943
4944 function fillOutlines(startOutline, endOutline, rect) {
4945 var inlinePos = rect.inlinePos,
4946 inlineSize = rect.inlineSize,
4947 contentPos = rect.contentPos,
4948 contentSize = rect.contentSize;
4949
4950 for (var outlineIndex = inlinePos; outlineIndex < inlinePos + inlineSize; ++outlineIndex) {
4951 startOutline[outlineIndex] = Math.min(startOutline[outlineIndex], contentPos);
4952 endOutline[outlineIndex] = Math.max(endOutline[outlineIndex], contentPos + contentSize);
4953 }
4954 }
4955 /**
4956 * 'Frame' is a printing term with the meaning that 'it fits in one row wide'. FrameGrid is a grid that the item is filled up on the basis of a line given a size.
4957 * @ko 'Frame'는 '1행의 너비에 맞게 꼭 들어찬'이라는 의미를 가진 인쇄 용어다. FrameGrid는 용어의 의미대로 너비가 주어진 사이즈를 기준으로 아이템이 가득 차도록 배치하는 Grid다.
4958 * @memberof Grid
4959 * @param {HTMLElement | string} container - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
4960 * @param {Grid.FrameGrid.FrameGridOptions} options - The option object of the FrameGrid module <ko>FrameGrid 모듈의 옵션 객체</ko>
4961 */
4962
4963
4964 var FrameGrid =
4965 /*#__PURE__*/
4966 function (_super) {
4967 __extends$2(FrameGrid, _super);
4968
4969 function FrameGrid() {
4970 return _super !== null && _super.apply(this, arguments) || this;
4971 }
4972
4973 var __proto = FrameGrid.prototype;
4974
4975 __proto.applyGrid = function (items, direction, outline) {
4976 var frame = this._getFrame();
4977
4978 var frameInlineSize = frame.inlineSize,
4979 frameContentSize = frame.contentSize,
4980 frameRects = frame.rects;
4981 var _a = this.options,
4982 gap = _a.gap,
4983 useFrameFill = _a.useFrameFill;
4984
4985 var _b = this.getRectSize(frameInlineSize),
4986 rectInlineSize = _b.inlineSize,
4987 rectContentSize = _b.contentSize;
4988
4989 var itemsLength = items.length;
4990
4991 if (!itemsLength || !frameInlineSize || !frameContentSize) {
4992 return {
4993 start: outline,
4994 end: outline
4995 };
4996 }
4997
4998 var rectsLength = frameRects.length;
4999 var startOutline = range(frameInlineSize).map(function () {
5000 return Infinity;
5001 });
5002 var endOutline = range(frameInlineSize).map(function () {
5003 return -Infinity;
5004 });
5005 var frameOutline = frame.outline.map(function (point) {
5006 return point * (rectContentSize + gap);
5007 });
5008
5009 for (var startIndex = 0; startIndex < itemsLength; startIndex += rectsLength) {
5010 // Compare group's startOutline and startOutline of rect
5011 var startPoint = getOutlinePoint(endOutline, frameOutline, useFrameFill);
5012
5013 for (var rectIndex = 0; rectIndex < rectsLength && startIndex + rectIndex < itemsLength; ++rectIndex) {
5014 var item = items[startIndex + rectIndex];
5015 var _c = frameRects[rectIndex],
5016 frameRectContentPos = _c.contentPos,
5017 frameRectInlinePos = _c.inlinePos,
5018 frameRectContentSize = _c.contentSize,
5019 frameRectInlineSize = _c.inlineSize;
5020 var contentPos = startPoint + frameRectContentPos * (rectContentSize + gap);
5021 var inlinePos = frameRectInlinePos * (rectInlineSize + gap);
5022 var contentSize = frameRectContentSize * (rectContentSize + gap) - gap;
5023 var inlineSize = frameRectInlineSize * (rectInlineSize + gap) - gap;
5024 fillOutlines(startOutline, endOutline, {
5025 inlinePos: frameRectInlinePos,
5026 inlineSize: frameRectInlineSize,
5027 contentPos: contentPos,
5028 contentSize: contentSize + gap
5029 });
5030 item.setCSSGridRect({
5031 inlinePos: inlinePos,
5032 contentPos: contentPos,
5033 inlineSize: inlineSize,
5034 contentSize: contentSize
5035 });
5036 }
5037 }
5038
5039 var isDirectionEnd = direction === "end";
5040 var gridOutline = outline.length ? outline : [0];
5041
5042 if (gridOutline.length !== frameInlineSize) {
5043 var point_1 = isDirectionEnd ? Math.max.apply(Math, gridOutline) : Math.min.apply(Math, gridOutline);
5044 gridOutline = range(frameInlineSize).map(function () {
5045 return point_1;
5046 });
5047 }
5048
5049 startOutline = startOutline.map(function (point) {
5050 return isFinite(point) ? point : 0;
5051 });
5052 endOutline = endOutline.map(function (point) {
5053 return isFinite(point) ? point : 0;
5054 });
5055 var outlineDist = isDirectionEnd ? getOutlinePoint(gridOutline, startOutline, useFrameFill) : getOutlinePoint(endOutline, gridOutline, useFrameFill);
5056 items.forEach(function (item) {
5057 item.cssContentPos += outlineDist;
5058 });
5059 return {
5060 start: startOutline.map(function (point) {
5061 return point + outlineDist;
5062 }),
5063 end: endOutline.map(function (point) {
5064 return point + outlineDist;
5065 })
5066 };
5067 };
5068
5069 __proto.getComputedOutlineLength = function () {
5070 var frame = this.options.frame;
5071 return frame.length ? frame[0].length : 0;
5072 };
5073
5074 __proto.getComputedOutlineSize = function () {
5075 var _a = this.options,
5076 gap = _a.gap,
5077 rectSizeOption = _a.rectSize;
5078
5079 if (typeof rectSizeOption === "object") {
5080 return rectSizeOption.inlineSize;
5081 }
5082
5083 return rectSizeOption || (this.getContainerInlineSize() + gap) / this.getComputedOutlineLength() - gap;
5084 };
5085
5086 __proto.getRectSize = function (frameInlineSize) {
5087 var _a = this.options,
5088 gap = _a.gap,
5089 rectSizeOption = _a.rectSize;
5090
5091 if (typeof rectSizeOption === "object") {
5092 return rectSizeOption;
5093 }
5094
5095 var rectSizeValue = rectSizeOption ? rectSizeOption : (this.getContainerInlineSize() + gap) / frameInlineSize - gap;
5096 return {
5097 inlineSize: rectSizeValue,
5098 contentSize: rectSizeValue
5099 };
5100 };
5101
5102 __proto._getFrame = function () {
5103 var frame = this.options.frame;
5104 var frameContentSize = frame.length;
5105 var frameInlineSize = frameContentSize ? frame[0].length : 0;
5106 var rects = [];
5107 var passMap = {};
5108 var startOutline = range(frameInlineSize).map(function () {
5109 return Infinity;
5110 });
5111 var endOutline = range(frameInlineSize).map(function () {
5112 return -Infinity;
5113 });
5114
5115 for (var y1 = 0; y1 < frameContentSize; ++y1) {
5116 for (var x1 = 0; x1 < frameInlineSize; ++x1) {
5117 var type = frame[y1][x1];
5118
5119 if (!type) {
5120 continue;
5121 }
5122
5123 if (passMap[y1 + "," + x1]) {
5124 continue;
5125 }
5126
5127 var rect = this._findRect(passMap, type, y1, x1, frameInlineSize, frameContentSize);
5128
5129 fillOutlines(startOutline, endOutline, rect);
5130 rects.push(rect);
5131 }
5132 }
5133
5134 rects.sort(function (a, b) {
5135 return a.type < b.type ? -1 : 1;
5136 });
5137 return {
5138 rects: rects,
5139 inlineSize: frameInlineSize,
5140 contentSize: frameContentSize,
5141 outline: startOutline
5142 };
5143 };
5144
5145 __proto._findRect = function (passMap, type, y1, x1, frameInlineSize, frameContentSize) {
5146 var frame = this.options.frame;
5147 var contentSize = 1;
5148 var inlineSize = 1; // find rect
5149
5150 for (var x2 = x1; x2 < frameInlineSize; ++x2) {
5151 if (frame[y1][x2] === type) {
5152 inlineSize = x2 - x1 + 1;
5153 continue;
5154 }
5155
5156 break;
5157 }
5158
5159 for (var y2 = y1; y2 < frameContentSize; ++y2) {
5160 if (frame[y2][x1] === type) {
5161 contentSize = y2 - y1 + 1;
5162 continue;
5163 }
5164
5165 break;
5166 } // pass rect
5167
5168
5169 for (var y = y1; y < y1 + contentSize; ++y) {
5170 for (var x = x1; x < x1 + inlineSize; ++x) {
5171 passMap[y + "," + x] = true;
5172 }
5173 }
5174
5175 var rect = {
5176 type: type,
5177 inlinePos: x1,
5178 contentPos: y1,
5179 inlineSize: inlineSize,
5180 contentSize: contentSize
5181 };
5182 return rect;
5183 };
5184
5185 FrameGrid.propertyTypes = __assign$2(__assign$2({}, Grid.propertyTypes), {
5186 frame: PROPERTY_TYPE.RENDER_PROPERTY,
5187 useFrameFill: PROPERTY_TYPE.RENDER_PROPERTY,
5188 rectSize: PROPERTY_TYPE.RENDER_PROPERTY
5189 });
5190 FrameGrid.defaultOptions = __assign$2(__assign$2({}, Grid.defaultOptions), {
5191 frame: [],
5192 rectSize: 0,
5193 useFrameFill: true
5194 });
5195 FrameGrid = __decorate$1([GetterSetter], FrameGrid);
5196 return FrameGrid;
5197 }(Grid);
5198 /**
5199 * The shape of the grid. You can set the shape and order of items with a 2d array ([contentPos][inlinePos]). You can place items as many times as you fill the array with numbers, and zeros and spaces are empty spaces. The order of the items is arranged in ascending order of the numeric values that fill the array.
5200 * @ko Grid의 모양. 2d 배열([contentPos][inlinePos])로 아이템의 모양과 순서를 설정할 수 있다. 숫자로 배열을 채운만큼 아이템을 배치할 수 있으며 0과 공백은 빈 공간이다. 아이템들의 순서는 배열을 채운 숫자값의 오름차순대로 배치가 된다.
5201 * @name Grid.FrameGrid#frame
5202 * @type {$ts:Grid.FrameGrid.FrameGridOptions["frame"]}
5203 * @default []
5204 * @example
5205 * ```js
5206 * import { FrameGrid } from "@egjs/grid";
5207 *
5208 * // Item 1 : 2 x 2
5209 * // Item 2 : 1 x 1
5210 * // Item 3 : 1 x 2
5211 * // Item 4 : 1 x 1
5212 * // Item 5 : 2 x 1
5213 * const grid = new FrameGrid(container, {
5214 * frame: [
5215 * [1, 1, 0, 0, 2, 3],
5216 * [1, 1, 0, 4, 5, 5],
5217 * ],
5218 * });
5219 *
5220 * // Item 1 : 2 x 2
5221 * // Item 2 : 2 x 2
5222 * grid.frame = [
5223 * [1, 1, 0, 0, 2, 2],
5224 * [1, 1, 0, 0, 2, 2],
5225 * ];
5226 * ```
5227 */
5228
5229 /**
5230 * Make sure that the frame can be attached after the previous frame.
5231 * @ko 다음 프레임이 전 프레임에 이어 붙일 수 있는지 있는지 확인한다.
5232 * @name Grid.FrameGrid#useFrameFill
5233 * @type {$ts:Grid.FrameGrid.FrameGridOptions["useFrameFill"]}
5234 * @default true
5235 * @example
5236 * ```js
5237 * import { FrameGrid } from "@egjs/grid";
5238 *
5239 * const grid = new FrameGrid(container, {
5240 * useFrameFill: true,
5241 * });
5242 *
5243 * grid.useFrameFill = false;
5244 * ```
5245 */
5246
5247 /**
5248 * 1x1 rect size. If it is 0, it is determined by the number of columns in the frame. (default: 0)
5249 * @ko 1x1 직사각형 크기. 0이면 frame의 column의 개수에 의해 결정된다. (default: 0)
5250 * @name Grid.FrameGrid#rectSize
5251 * @type {$ts:Grid.FrameGrid.FrameGridOptions["rectSize"]}
5252 * @example
5253 * ```js
5254 * import { FrameGrid } from "@egjs/grid";
5255 *
5256 * const grid = new FrameGrid(container, {
5257 * rectSize: 0,
5258 * });
5259 *
5260 * grid.rectSize = { inlineSize: 100, contentSize: 150 };
5261 * ```
5262 */
5263
5264 var BoxModel =
5265 /*#__PURE__*/
5266 function () {
5267 function BoxModel(status) {
5268 var boxStatus = __assign$2({
5269 orgInlineSize: 0,
5270 orgContentSize: 0,
5271 inlineSize: 0,
5272 contentSize: 0,
5273 inlinePos: 0,
5274 contentPos: 0,
5275 items: []
5276 }, status);
5277
5278 for (var name in boxStatus) {
5279 this[name] = boxStatus[name];
5280 }
5281 }
5282
5283 var __proto = BoxModel.prototype;
5284
5285 __proto.scaleTo = function (inlineSize, contentSize) {
5286 var scaleX = this.inlineSize ? inlineSize / this.inlineSize : 0;
5287 var scaleY = this.contentSize ? contentSize / this.contentSize : 0;
5288 this.items.forEach(function (item) {
5289 if (scaleX !== 0) {
5290 item.inlinePos *= scaleX;
5291 item.inlineSize *= scaleX;
5292 }
5293
5294 if (scaleY !== 0) {
5295 item.contentPos *= scaleY;
5296 item.contentSize *= scaleY;
5297 }
5298 });
5299 this.inlineSize = inlineSize;
5300 this.contentSize = contentSize;
5301 };
5302
5303 __proto.push = function (item) {
5304 this.items.push(item);
5305 };
5306
5307 __proto.getOrgSizeWeight = function () {
5308 return this.orgInlineSize * this.orgContentSize;
5309 };
5310
5311 __proto.getSize = function () {
5312 return this.inlineSize * this.contentSize;
5313 };
5314
5315 __proto.getOrgRatio = function () {
5316 return this.orgContentSize === 0 ? 0 : this.orgInlineSize / this.orgContentSize;
5317 };
5318
5319 __proto.getRatio = function () {
5320 return this.contentSize === 0 ? 0 : this.inlineSize / this.contentSize;
5321 };
5322
5323 return BoxModel;
5324 }();
5325
5326 function getCost(originLength, length) {
5327 var cost = originLength / length;
5328
5329 if (cost < 1) {
5330 cost = 1 / cost;
5331 }
5332
5333 return cost - 1;
5334 }
5335
5336 function fitArea(item, bestFitArea, itemFitSize, containerFitSize, isContentDirection) {
5337 item.contentSize = itemFitSize.contentSize;
5338 item.inlineSize = itemFitSize.inlineSize;
5339 bestFitArea.contentSize = containerFitSize.contentSize;
5340 bestFitArea.inlineSize = containerFitSize.inlineSize;
5341
5342 if (isContentDirection) {
5343 item.contentPos = bestFitArea.contentPos + bestFitArea.contentSize;
5344 item.inlinePos = bestFitArea.inlinePos;
5345 } else {
5346 item.inlinePos = bestFitArea.inlinePos + bestFitArea.inlineSize;
5347 item.contentPos = bestFitArea.contentPos;
5348 }
5349 }
5350 /**
5351 * The PackingGrid is a grid that shows the important items bigger without sacrificing the weight of the items.
5352 * Rows and columns are separated so that items are dynamically placed within the horizontal and vertical space rather than arranged in an orderly fashion.
5353 * If `sizeWeight` is higher than `ratioWeight`, the size of items is preserved as much as possible.
5354 * Conversely, if `ratioWeight` is higher than `sizeWeight`, the ratio of items is preserved as much as possible.
5355 * @ko PackingGrid는 아이템의 본래 크기에 따른 비중을 해치지 않으면서 중요한 카드는 더 크게 보여 주는 레이아웃이다.
5356 * 행과 열이 구분돼 아이템을 정돈되게 배치하는 대신 가로세로 일정 공간 내에서 동적으로 아이템을 배치한다.
5357 * `sizeWeight`가 `ratioWeight`보다 높으면 아이템들의 size가 최대한 보존이 된다.
5358 * 반대로 `ratioWeight`가 `sizeWeight`보다 높으면 아이템들의 비율이 최대한 보존이 된다.
5359 * @memberof Grid
5360 * @param {HTMLElement | string} container - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
5361 * @param {Grid.PackingGrid.PackingGridOptions} options - The option object of the PackingGrid module <ko>PackingGrid 모듈의 옵션 객체</ko>
5362 */
5363
5364
5365 var PackingGrid =
5366 /*#__PURE__*/
5367 function (_super) {
5368 __extends$2(PackingGrid, _super);
5369
5370 function PackingGrid() {
5371 return _super !== null && _super.apply(this, arguments) || this;
5372 }
5373
5374 var __proto = PackingGrid.prototype;
5375
5376 __proto.applyGrid = function (items, direction, outline) {
5377 var _this = this;
5378
5379 var _a = this.options,
5380 aspectRatio = _a.aspectRatio,
5381 gap = _a.gap;
5382 var containerInlineSize = this.getContainerInlineSize();
5383 var containerContentSize = containerInlineSize / aspectRatio;
5384 var prevOutline = outline.length ? outline : [0];
5385 var startPoint = direction === "end" ? Math.max.apply(Math, prevOutline) : Math.min.apply(Math, prevOutline) - containerContentSize - gap;
5386 var endPoint = startPoint + containerContentSize + gap;
5387 var container = new BoxModel({});
5388 items.forEach(function (item) {
5389 var model = new BoxModel({
5390 inlineSize: item.orgInlineSize,
5391 contentSize: item.orgContentSize,
5392 orgInlineSize: item.orgInlineSize,
5393 orgContentSize: item.orgContentSize
5394 });
5395
5396 _this._findBestFitArea(container, model);
5397
5398 container.push(model);
5399 container.scaleTo(containerInlineSize + gap, containerContentSize + gap);
5400 });
5401 items.forEach(function (item, i) {
5402 var boxItem = container.items[i];
5403 var inlineSize = boxItem.inlineSize - gap;
5404 var contentSize = boxItem.contentSize - gap;
5405 var contentPos = startPoint + boxItem.contentPos;
5406 var inlinePos = boxItem.inlinePos;
5407 item.setCSSGridRect({
5408 inlinePos: inlinePos,
5409 contentPos: contentPos,
5410 inlineSize: inlineSize,
5411 contentSize: contentSize
5412 });
5413 });
5414 return {
5415 start: [startPoint],
5416 end: [endPoint]
5417 };
5418 };
5419
5420 __proto._findBestFitArea = function (container, item) {
5421 if (container.getRatio() === 0) {
5422 // 아이템 최초 삽입시 전체영역 지정
5423 container.orgInlineSize = item.inlineSize;
5424 container.orgContentSize = item.contentSize;
5425 container.inlineSize = item.inlineSize;
5426 container.contentSize = item.contentSize;
5427 return;
5428 }
5429
5430 var bestFitArea;
5431 var minCost = Infinity;
5432 var isContentDirection = false;
5433 var itemFitSize = {
5434 inlineSize: 0,
5435 contentSize: 0
5436 };
5437 var containerFitSize = {
5438 inlineSize: 0,
5439 contentSize: 0
5440 };
5441
5442 var sizeWeight = this._getWeight("size");
5443
5444 var ratioWeight = this._getWeight("ratio");
5445
5446 container.items.forEach(function (child) {
5447 var containerSizeCost = getCost(child.getOrgSizeWeight(), child.getSize()) * sizeWeight;
5448 var containerRatioCost = getCost(child.getOrgRatio(), child.getRatio()) * ratioWeight;
5449 var inlineSize = child.inlineSize;
5450 var contentSize = child.contentSize;
5451
5452 for (var i = 0; i < 2; ++i) {
5453 var itemInlineSize = void 0;
5454 var itemContentSize = void 0;
5455 var containerInlineSize = void 0;
5456 var containerContentSize = void 0;
5457
5458 if (i === 0) {
5459 // add item to content pos (top, bottom)
5460 itemInlineSize = inlineSize;
5461 itemContentSize = contentSize * (item.contentSize / (child.orgContentSize + item.contentSize));
5462 containerInlineSize = inlineSize;
5463 containerContentSize = contentSize - itemContentSize;
5464 } else {
5465 // add item to inline pos (left, right)
5466 itemContentSize = contentSize;
5467 itemInlineSize = inlineSize * (item.inlineSize / (child.orgInlineSize + item.inlineSize));
5468 containerContentSize = contentSize;
5469 containerInlineSize = inlineSize - itemInlineSize;
5470 }
5471
5472 var itemSize = itemInlineSize * itemContentSize;
5473 var itemRatio = itemInlineSize / itemContentSize;
5474 var containerSize = containerInlineSize * containerContentSize;
5475 var containerRatio = containerContentSize / containerContentSize;
5476 var cost = getCost(item.getSize(), itemSize) * sizeWeight;
5477 cost += getCost(item.getRatio(), itemRatio) * ratioWeight;
5478 cost += getCost(child.getOrgSizeWeight(), containerSize) * sizeWeight - containerSizeCost;
5479 cost += getCost(child.getOrgRatio(), containerRatio) * ratioWeight - containerRatioCost;
5480
5481 if (cost === Math.min(cost, minCost)) {
5482 minCost = cost;
5483 bestFitArea = child;
5484 isContentDirection = i === 0;
5485 itemFitSize.inlineSize = itemInlineSize;
5486 itemFitSize.contentSize = itemContentSize;
5487 containerFitSize.inlineSize = containerInlineSize;
5488 containerFitSize.contentSize = containerContentSize;
5489 }
5490 }
5491 });
5492 fitArea(item, bestFitArea, itemFitSize, containerFitSize, isContentDirection);
5493 };
5494
5495 __proto.getComputedOutlineLength = function () {
5496 return 1;
5497 };
5498
5499 __proto.getComputedOutlineSize = function () {
5500 return this.getContainerInlineSize();
5501 };
5502
5503 __proto._getWeight = function (type) {
5504 var options = this.options;
5505 var weightPriority = options.weightPriority;
5506
5507 if (weightPriority === type) {
5508 return 100;
5509 } else if (weightPriority === "custom") {
5510 return options[type + "Weight"];
5511 }
5512
5513 return 1;
5514 };
5515
5516 PackingGrid.propertyTypes = __assign$2(__assign$2({}, Grid.propertyTypes), {
5517 aspectRatio: PROPERTY_TYPE.RENDER_PROPERTY,
5518 sizeWeight: PROPERTY_TYPE.RENDER_PROPERTY,
5519 ratioWeight: PROPERTY_TYPE.RENDER_PROPERTY,
5520 weightPriority: PROPERTY_TYPE.RENDER_PROPERTY
5521 });
5522 PackingGrid.defaultOptions = __assign$2(__assign$2({}, Grid.defaultOptions), {
5523 aspectRatio: 1,
5524 sizeWeight: 1,
5525 ratioWeight: 1,
5526 weightPriority: "custom"
5527 });
5528 PackingGrid = __decorate$1([GetterSetter], PackingGrid);
5529 return PackingGrid;
5530 }(Grid);
5531
5532 var ua$1 = typeof window !== "undefined" ? window.navigator.userAgent : "";
5533 var IS_IOS = /iPhone|iPad/.test(ua$1);
5534 var CONTAINER_CLASS_NAME = "infinitegrid-container";
5535 var IGNORE_PROPERITES_MAP = {
5536 renderOnPropertyChange: true,
5537 useFit: true,
5538 autoResize: true
5539 };
5540 var INFINITEGRID_PROPERTY_TYPES = __assign({}, GRID_PROPERTY_TYPES);
5541 var DIRECTION = {
5542 START: "start",
5543 END: "end",
5544 NONE: ""
5545 };
5546 var INFINITEGRID_EVENTS = {
5547 CHANGE_SCROLL: "changeScroll",
5548 REQUEST_APPEND: "requestAppend",
5549 REQUEST_PREPEND: "requestPrepend",
5550 RENDER_COMPLETE: "renderComplete",
5551 CONTENT_ERROR: "contentError"
5552 }; // type?: ITEM_TYPE;
5553 // groupKey?: string | number;
5554 // key?: string | number;
5555 // element?: HTMLElement | null;
5556 // html?: string;
5557 // data?: Record<string, any>;
5558
5559 var ITEM_INFO_PROPERTIES = {
5560 type: true,
5561 groupKey: true,
5562 key: true,
5563 element: true,
5564 html: true,
5565 data: true
5566 };
5567 var INFINITEGRID_METHODS = ["insertByGroupIndex", "updateItems", "getItems", "getVisibleItems", "getGroups", "getVisibleGroups", "renderItems", "getContainerElement", "getScrollContainerElement", "getWrapperElement", "setStatus", "getStatus", "removePlaceholders", "prependPlaceholders", "appendPlaceholders", "getStartCursor", "getEndCursor", "setCursors"];
5568 var GROUP_TYPE;
5569
5570 (function (GROUP_TYPE) {
5571 GROUP_TYPE[GROUP_TYPE["NORMAL"] = 0] = "NORMAL";
5572 GROUP_TYPE[GROUP_TYPE["VIRTUAL"] = 1] = "VIRTUAL";
5573 GROUP_TYPE[GROUP_TYPE["LOADING"] = 2] = "LOADING";
5574 })(GROUP_TYPE || (GROUP_TYPE = {}));
5575
5576 var ITEM_TYPE;
5577
5578 (function (ITEM_TYPE) {
5579 ITEM_TYPE[ITEM_TYPE["NORMAL"] = 0] = "NORMAL";
5580 ITEM_TYPE[ITEM_TYPE["VIRTUAL"] = 1] = "VIRTUAL";
5581 ITEM_TYPE[ITEM_TYPE["LOADING"] = 2] = "LOADING";
5582 })(ITEM_TYPE || (ITEM_TYPE = {}));
5583
5584 var STATUS_TYPE;
5585
5586 (function (STATUS_TYPE) {
5587 // does not remove anything.
5588 STATUS_TYPE[STATUS_TYPE["NOT_REMOVE"] = 0] = "NOT_REMOVE"; // Minimize information on invisible items
5589
5590 STATUS_TYPE[STATUS_TYPE["MINIMIZE_INVISIBLE_ITEMS"] = 1] = "MINIMIZE_INVISIBLE_ITEMS"; // Minimize information on invisible groups
5591
5592 STATUS_TYPE[STATUS_TYPE["MINIMIZE_INVISIBLE_GROUPS"] = 2] = "MINIMIZE_INVISIBLE_GROUPS"; // remove invisible groups
5593
5594 STATUS_TYPE[STATUS_TYPE["REMOVE_INVISIBLE_GROUPS"] = 3] = "REMOVE_INVISIBLE_GROUPS";
5595 })(STATUS_TYPE || (STATUS_TYPE = {}));
5596
5597 var INVISIBLE_POS = -9999;
5598
5599 /**
5600 * @extends Grid.GridItem
5601 */
5602
5603 var InfiniteGridItem =
5604 /*#__PURE__*/
5605 function (_super) {
5606 __extends(InfiniteGridItem, _super);
5607
5608 function InfiniteGridItem(horizontal, itemStatus) {
5609 var _this = _super.call(this, horizontal, __assign({
5610 html: "",
5611 type: ITEM_TYPE.NORMAL,
5612 cssRect: {
5613 top: INVISIBLE_POS,
5614 left: INVISIBLE_POS
5615 }
5616 }, itemStatus)) || this;
5617
5618 if (_this.type === ITEM_TYPE.VIRTUAL) {
5619 if (_this.rect.width || _this.rect.height) {
5620 _this.mountState = MOUNT_STATE.UNMOUNTED;
5621 }
5622
5623 var orgRect = _this.orgRect;
5624 var rect = _this.rect;
5625 var cssRect = _this.cssRect;
5626
5627 if (cssRect.width) {
5628 rect.width = cssRect.width;
5629 } else if (orgRect.width) {
5630 rect.width = orgRect.width;
5631 }
5632
5633 if (cssRect.height) {
5634 rect.height = cssRect.height;
5635 } else if (orgRect.height) {
5636 rect.height = orgRect.height;
5637 }
5638 }
5639
5640 return _this;
5641 }
5642
5643 var __proto = InfiniteGridItem.prototype;
5644
5645 __proto.getVirtualStatus = function () {
5646 return {
5647 type: ITEM_TYPE.VIRTUAL,
5648 groupKey: this.groupKey,
5649 key: this.key,
5650 orgRect: this.orgRect,
5651 rect: this.rect,
5652 cssRect: this.cssRect,
5653 attributes: this.attributes
5654 };
5655 };
5656
5657 __proto.getMinimizedStatus = function () {
5658 var status = __assign(__assign({}, _super.prototype.getMinimizedStatus.call(this)), {
5659 type: ITEM_TYPE.NORMAL,
5660 groupKey: this.groupKey
5661 });
5662
5663 if (this.html) {
5664 status.html = this.html;
5665 }
5666
5667 return status;
5668 };
5669
5670 return InfiniteGridItem;
5671 }(GridItem);
5672
5673 var LOADING_GROUP_KEY = "__INFINITEGRID__LOADING_GRID";
5674 var LOADING_ITEM_KEY = "__INFINITEGRID__LOADING_ITEM";
5675
5676 var LoadingGrid =
5677 /*#__PURE__*/
5678 function (_super) {
5679 __extends(LoadingGrid, _super);
5680
5681 function LoadingGrid() {
5682 var _this = _super !== null && _super.apply(this, arguments) || this;
5683
5684 _this.type = "";
5685 return _this;
5686 }
5687
5688 var __proto = LoadingGrid.prototype;
5689
5690 __proto.getLoadingItem = function () {
5691 return this.items[0] || null;
5692 };
5693
5694 __proto.setLoadingItem = function (item) {
5695 if (item) {
5696 var loadingItem = this.getLoadingItem();
5697
5698 if (!loadingItem) {
5699 this.items = [new InfiniteGridItem(this.options.horizontal, __assign(__assign({}, item), {
5700 type: ITEM_TYPE.LOADING,
5701 key: LOADING_ITEM_KEY
5702 }))];
5703 } else {
5704 for (var name in item) {
5705 loadingItem[name] = item[name];
5706 }
5707 }
5708 } else {
5709 this.items = [];
5710 }
5711 };
5712
5713 __proto.applyGrid = function (items, direction, outline) {
5714 if (!items.length) {
5715 return {
5716 start: outline,
5717 end: outline
5718 };
5719 }
5720
5721 var nextOutline = outline.length ? __spreadArrays(outline) : [0];
5722 var item = items[0];
5723 var offset = item.contentSize + this.gap;
5724 item.cssInlinePos = this.getContainerInlineSize() / 2 - item.inlineSize / 2;
5725
5726 if (direction === "end") {
5727 var maxPos = Math.max.apply(Math, nextOutline);
5728 item.cssContentPos = maxPos;
5729 return {
5730 start: nextOutline,
5731 end: nextOutline.map(function (pos) {
5732 return pos + offset;
5733 })
5734 };
5735 } else {
5736 var minPos = Math.min.apply(Math, nextOutline);
5737 item.cssContentPos = minPos - offset;
5738 return {
5739 start: nextOutline.map(function (pos) {
5740 return pos - offset;
5741 }),
5742 end: nextOutline
5743 };
5744 }
5745 };
5746
5747 return LoadingGrid;
5748 }(Grid);
5749
5750 function isWindow$1(el) {
5751 return el === window;
5752 }
5753 function isNumber$1(val) {
5754 return typeof val === "number";
5755 }
5756 function isString$1(val) {
5757 return typeof val === "string";
5758 }
5759 function isObject$1(val) {
5760 return typeof val === "object";
5761 }
5762 function flat(arr) {
5763 return arr.reduce(function (prev, cur) {
5764 return __spreadArrays(prev, cur);
5765 }, []);
5766 }
5767 function splitOptions(options) {
5768 var gridOptions = options.gridOptions,
5769 otherOptions = __rest(options, ["gridOptions"]);
5770
5771 return __assign(__assign({}, splitGridOptions(gridOptions)), otherOptions);
5772 }
5773 function splitGridOptions(options) {
5774 var nextOptions = {};
5775 var gridOptions = {};
5776 var defaultOptions = Grid.defaultOptions;
5777
5778 for (var name in options) {
5779 var value = options[name];
5780
5781 if (!(name in IGNORE_PROPERITES_MAP)) {
5782 gridOptions[name] = value;
5783 }
5784
5785 if (name in defaultOptions) {
5786 nextOptions[name] = value;
5787 }
5788 }
5789
5790 return __assign(__assign({}, nextOptions), {
5791 gridOptions: gridOptions
5792 });
5793 }
5794 function categorize(items) {
5795 var groups = [];
5796 var groupKeys = {};
5797 var registeredGroupKeys = {};
5798 items.filter(function (item) {
5799 return item.groupKey != null;
5800 }).forEach(function (_a) {
5801 var groupKey = _a.groupKey;
5802 registeredGroupKeys[groupKey] = true;
5803 });
5804 var generatedGroupKey;
5805 var isContinuousGroupKey = false;
5806 items.forEach(function (item) {
5807 if (item.groupKey != null) {
5808 isContinuousGroupKey = false;
5809 } else {
5810 if (!isContinuousGroupKey) {
5811 generatedGroupKey = makeKey(registeredGroupKeys);
5812 isContinuousGroupKey = true;
5813 registeredGroupKeys[generatedGroupKey] = true;
5814 }
5815
5816 item.groupKey = generatedGroupKey;
5817 }
5818
5819 var groupKey = item.groupKey;
5820 var group = groupKeys[groupKey];
5821
5822 if (!group) {
5823 group = {
5824 groupKey: groupKey,
5825 items: []
5826 };
5827 groupKeys[groupKey] = group;
5828 groups.push(group);
5829 }
5830
5831 group.items.push(item);
5832 });
5833 return groups;
5834 }
5835 function getNextCursors(prevKeys, nextKeys, prevStartCursor, prevEndCursor) {
5836 var result = diff(prevKeys, nextKeys, function (key) {
5837 return key;
5838 });
5839 var nextStartCursor = -1;
5840 var nextEndCursor = -1; // sync cursors
5841
5842 result.maintained.forEach(function (_a) {
5843 var prevIndex = _a[0],
5844 nextIndex = _a[1];
5845
5846 if (prevStartCursor <= prevIndex && prevIndex <= prevEndCursor) {
5847 if (nextStartCursor === -1) {
5848 nextStartCursor = nextIndex;
5849 nextEndCursor = nextIndex;
5850 } else {
5851 nextStartCursor = Math.min(nextStartCursor, nextIndex);
5852 nextEndCursor = Math.max(nextEndCursor, nextIndex);
5853 }
5854 }
5855 });
5856 return {
5857 startCursor: nextStartCursor,
5858 endCursor: nextEndCursor
5859 };
5860 }
5861 function splitVirtualGroups(groups, direction, nextGroups) {
5862 var virtualGroups = [];
5863
5864 if (direction === "start") {
5865 var index = findIndex(groups, function (group) {
5866 return group.type === GROUP_TYPE.NORMAL;
5867 });
5868
5869 if (index === -1) {
5870 return [];
5871 } // Get the virtual group maintained in the group from the next group.
5872
5873
5874 var endMaintainedIndex = findIndex(groups, function (group) {
5875 return findIndex(nextGroups, function (nextGroup) {
5876 return nextGroup.groupKey === group.groupKey;
5877 }) >= 0;
5878 });
5879 var endIndex = endMaintainedIndex >= 0 ? Math.min(index, endMaintainedIndex) : index;
5880 virtualGroups = groups.slice(0, endIndex);
5881 } else {
5882 var index = findLastIndex(groups, function (group) {
5883 return group.type === GROUP_TYPE.NORMAL;
5884 });
5885
5886 if (index === -1) {
5887 return [];
5888 }
5889
5890 var startMaintainedIndex = findLastIndex(groups, function (group) {
5891 return findIndex(nextGroups, function (nextGroup) {
5892 return nextGroup.groupKey === group.groupKey;
5893 }) >= 0;
5894 });
5895 var startIndex = startMaintainedIndex >= 0 ? Math.max(index, startMaintainedIndex) : index;
5896 virtualGroups = groups.slice(startIndex + 1);
5897 }
5898
5899 return virtualGroups;
5900 }
5901 function getFirstRenderingItems(nextItems, horizontal) {
5902 var groups = categorize(nextItems);
5903
5904 if (!groups[0]) {
5905 return [];
5906 }
5907
5908 return groups[0].items.map(function (item) {
5909 return new InfiniteGridItem(horizontal, __assign({}, item));
5910 });
5911 }
5912 function getRenderingItemsByStatus(groupManagerStatus, nextItems, usePlaceholder, horizontal) {
5913 var prevGroups = groupManagerStatus.groups;
5914 var groups = categorize(nextItems);
5915 var startVirtualGroups = splitVirtualGroups(prevGroups, "start", groups);
5916 var endVirtualGroups = splitVirtualGroups(prevGroups, "end", groups);
5917
5918 var nextGroups = __spreadArrays(startVirtualGroups, groups, endVirtualGroups);
5919
5920 var _a = getNextCursors(prevGroups.map(function (group) {
5921 return group.groupKey;
5922 }), nextGroups.map(function (group) {
5923 return group.groupKey;
5924 }), groupManagerStatus.cursors[0], groupManagerStatus.cursors[1]),
5925 startCursor = _a.startCursor,
5926 endCursor = _a.endCursor;
5927
5928 var nextVisibleItems = flat(nextGroups.slice(startCursor, endCursor + 1).map(function (group) {
5929 return group.items.map(function (item) {
5930 return new InfiniteGridItem(horizontal, __assign({}, item));
5931 });
5932 }));
5933
5934 if (!usePlaceholder) {
5935 nextVisibleItems = nextVisibleItems.filter(function (item) {
5936 return item.type !== ITEM_TYPE.VIRTUAL;
5937 });
5938 }
5939
5940 return nextVisibleItems;
5941 }
5942 function mountRenderingItems(items, options) {
5943 var grid = options.grid,
5944 usePlaceholder = options.usePlaceholder,
5945 useLoading = options.useLoading,
5946 useFirstRender = options.useFirstRender,
5947 status = options.status;
5948
5949 if (!grid) {
5950 return;
5951 }
5952
5953 if (usePlaceholder) {
5954 grid.setPlaceholder({});
5955 }
5956
5957 if (useLoading) {
5958 grid.setLoading({});
5959 }
5960
5961 if (status) {
5962 grid.setStatus(status, true);
5963 }
5964
5965 grid.syncItems(items);
5966
5967 if (useFirstRender && !status && grid.getGroups().length) {
5968 grid.setCursors(0, 0, true);
5969 }
5970 }
5971 function getRenderingItems(items, options) {
5972 var status = options.status,
5973 usePlaceholder = options.usePlaceholder,
5974 useLoading = options.useLoading,
5975 horizontal = options.horizontal,
5976 useFirstRender = options.useFirstRender,
5977 grid = options.grid;
5978 var visibleItems = [];
5979
5980 if (grid) {
5981 grid.setPlaceholder(usePlaceholder ? {} : null);
5982 grid.setLoading(useLoading ? {} : null);
5983 grid.syncItems(items);
5984 visibleItems = grid.getRenderingItems();
5985 } else if (status) {
5986 visibleItems = getRenderingItemsByStatus(status.groupManager, items, !!usePlaceholder, !!horizontal);
5987 } else if (useFirstRender) {
5988 visibleItems = getFirstRenderingItems(items, !!horizontal);
5989 }
5990
5991 return visibleItems;
5992 }
5993 /* Class Decorator */
5994
5995 function InfiniteGridGetterSetter(component) {
5996 var prototype = component.prototype,
5997 propertyTypes = component.propertyTypes;
5998
5999 var _loop_1 = function (name) {
6000 var attributes = {
6001 enumerable: true,
6002 configurable: true,
6003 get: function () {
6004 var options = this.groupManager.options;
6005
6006 if (name in options) {
6007 return options[name];
6008 } else {
6009 return options.gridOptions[name];
6010 }
6011 },
6012 set: function (value) {
6013 var _a;
6014
6015 var prevValue = this.groupManager[name];
6016
6017 if (prevValue === value) {
6018 return;
6019 }
6020
6021 this.groupManager.gridOptions = (_a = {}, _a[name] = value, _a);
6022 }
6023 };
6024 Object.defineProperty(prototype, name, attributes);
6025 };
6026
6027 for (var name in propertyTypes) {
6028 _loop_1(name);
6029 }
6030 }
6031 function makeKey(registeredKeys) {
6032 var index = 0; // eslint-disable-next-line no-constant-condition
6033
6034 while (true) {
6035 var key = "infinitegrid_" + index++;
6036
6037 if (!(key in registeredKeys)) {
6038 return key;
6039 }
6040 }
6041 }
6042 function convertHTMLtoElement(html) {
6043 var dummy = document.createElement("div");
6044 dummy.innerHTML = html;
6045 return toArray$1(dummy.children);
6046 }
6047 function convertInsertedItems(items, groupKey) {
6048 var insertedItems;
6049
6050 if (isString$1(items)) {
6051 insertedItems = convertHTMLtoElement(items);
6052 } else {
6053 insertedItems = items;
6054 }
6055
6056 return insertedItems.map(function (item) {
6057 var element;
6058 var html = "";
6059 var key;
6060
6061 if (isString$1(item)) {
6062 html = item;
6063 } else if ("parentNode" in item) {
6064 element = item;
6065 html = item.outerHTML;
6066 } else {
6067 return __assign({
6068 groupKey: groupKey
6069 }, item);
6070 }
6071
6072 return {
6073 key: key,
6074 groupKey: groupKey,
6075 html: html,
6076 element: element
6077 };
6078 });
6079 }
6080 function toArray$1(nodes) {
6081 var array = [];
6082
6083 if (nodes) {
6084 var length = nodes.length;
6085
6086 for (var i = 0; i < length; i++) {
6087 array.push(nodes[i]);
6088 }
6089 }
6090
6091 return array;
6092 }
6093 function findIndex(arr, callback) {
6094 var length = arr.length;
6095
6096 for (var i = 0; i < length; ++i) {
6097 if (callback(arr[i], i)) {
6098 return i;
6099 }
6100 }
6101
6102 return -1;
6103 }
6104 function findLastIndex(arr, callback) {
6105 var length = arr.length;
6106
6107 for (var i = length - 1; i >= 0; --i) {
6108 if (callback(arr[i], i)) {
6109 return i;
6110 }
6111 }
6112
6113 return -1;
6114 }
6115 function getItemInfo(info) {
6116 var nextInfo = {};
6117
6118 for (var name in info) {
6119 if (name in ITEM_INFO_PROPERTIES) {
6120 nextInfo[name] = info[name];
6121 }
6122 }
6123
6124 return nextInfo;
6125 }
6126 function setPlaceholder(item, info) {
6127 for (var name in info) {
6128 var value = info[name];
6129
6130 if (isObject$1(value)) {
6131 item[name] = __assign(__assign({}, item[name]), value);
6132 } else {
6133 item[name] = info[name];
6134 }
6135 }
6136 }
6137 function isFlatOutline(start, end) {
6138 return start.length === end.length && start.every(function (pos, i) {
6139 return end[i] === pos;
6140 });
6141 }
6142 function range$1(length) {
6143 var arr = [];
6144
6145 for (var i = 0; i < length; ++i) {
6146 arr.push(i);
6147 }
6148
6149 return arr;
6150 }
6151 function flatGroups(groups) {
6152 return flat(groups.map(function (_a) {
6153 var grid = _a.grid;
6154 return grid.getItems();
6155 }));
6156 }
6157 function filterVirtuals(items, includePlaceholders) {
6158 if (includePlaceholders) {
6159 return items;
6160 } else {
6161 return items.filter(function (item) {
6162 return item.type !== ITEM_TYPE.VIRTUAL;
6163 });
6164 }
6165 }
6166 /**
6167 * Decorator that makes the method of InfiniteGrid available in the framework.
6168 * @ko 프레임워크에서 InfiniteGrid의 메소드를 사용할 수 있게 하는 데코레이터.
6169 * @private
6170 * @example
6171 * ```js
6172 * import { withInfiniteGridMethods } from "@egjs/infinitegrid";
6173 *
6174 * class Grid extends React.Component<Partial<InfiniteGridProps & InfiniteGridOptions>> {
6175 * &#64;withInfiniteGridMethods
6176 * private grid: NativeGrid;
6177 * }
6178 * ```
6179 */
6180
6181 var withInfiniteGridMethods = withMethods(INFINITEGRID_METHODS);
6182
6183 var GroupManager =
6184 /*#__PURE__*/
6185 function (_super) {
6186 __extends(GroupManager, _super);
6187
6188 function GroupManager(container, options) {
6189 var _this = _super.call(this, container, splitOptions(options)) || this;
6190
6191 _this.groupItems = [];
6192 _this.groups = [];
6193 _this.itemKeys = {};
6194 _this.groupKeys = {};
6195 _this.startCursor = 0;
6196 _this.endCursor = 0;
6197 _this._placeholder = null;
6198 _this._loadingGrid = new LoadingGrid(container, {
6199 externalContainerManager: _this.containerManager,
6200 useFit: false,
6201 autoResize: false,
6202 renderOnPropertyChange: false,
6203 gap: _this.gap
6204 });
6205 _this._mainGrid = _this._makeGrid();
6206 return _this;
6207 }
6208
6209 var __proto = GroupManager.prototype;
6210 Object.defineProperty(__proto, "gridOptions", {
6211 set: function (options) {
6212 var _a = splitGridOptions(options),
6213 gridOptions = _a.gridOptions,
6214 otherOptions = __rest(_a, ["gridOptions"]);
6215
6216 var shouldRender = this._checkShouldRender(options);
6217
6218 this.options.gridOptions = __assign(__assign({}, this.options.gridOptions), gridOptions);
6219
6220 __spreadArrays([this._mainGrid], this.groups.map(function (_a) {
6221 var grid = _a.grid;
6222 return grid;
6223 })).forEach(function (grid) {
6224 for (var name in options) {
6225 grid[name] = options[name];
6226 }
6227 });
6228
6229 for (var name in otherOptions) {
6230 this[name] = otherOptions[name];
6231 }
6232
6233 this._loadingGrid.gap = this.gap;
6234
6235 if (shouldRender) {
6236 this.scheduleRender();
6237 }
6238 },
6239 enumerable: false,
6240 configurable: true
6241 });
6242
6243 __proto.getItemByKey = function (key) {
6244 return this.itemKeys[key] || null;
6245 };
6246
6247 __proto.getGroupItems = function (includePlaceholders) {
6248 return filterVirtuals(this.groupItems, includePlaceholders);
6249 };
6250
6251 __proto.getVisibleItems = function (includePlaceholders) {
6252 return filterVirtuals(this.items, includePlaceholders);
6253 };
6254
6255 __proto.getRenderingItems = function () {
6256 if (this.hasPlaceholder()) {
6257 return this.items;
6258 } else {
6259 return this.items.filter(function (item) {
6260 return item.type !== ITEM_TYPE.VIRTUAL;
6261 });
6262 }
6263 };
6264
6265 __proto.getGroups = function (includePlaceholders) {
6266 return filterVirtuals(this.groups, includePlaceholders);
6267 };
6268
6269 __proto.hasVisibleVirtualGroups = function () {
6270 return this.getVisibleGroups(true).some(function (group) {
6271 return group.type === GROUP_TYPE.VIRTUAL;
6272 });
6273 };
6274
6275 __proto.hasPlaceholder = function () {
6276 return !!this._placeholder;
6277 };
6278
6279 __proto.hasLoadingItem = function () {
6280 return !!this._getLoadingItem();
6281 };
6282
6283 __proto.updateItems = function (items, options) {
6284 if (items === void 0) {
6285 items = this.groupItems;
6286 }
6287
6288 return _super.prototype.updateItems.call(this, items, options);
6289 };
6290
6291 __proto.setPlaceholder = function (placeholder) {
6292 this._placeholder = placeholder;
6293
6294 this._updatePlaceholder();
6295 };
6296
6297 __proto.getLoadingType = function () {
6298 return this._loadingGrid.type;
6299 };
6300
6301 __proto.startLoading = function (type) {
6302 this._loadingGrid.type = type;
6303 this.items = this._getRenderingItems();
6304 return true;
6305 };
6306
6307 __proto.endLoading = function () {
6308 var prevType = this._loadingGrid.type;
6309 this._loadingGrid.type = "";
6310 this.items = this._getRenderingItems();
6311 return !!prevType;
6312 };
6313
6314 __proto.setLoading = function (loading) {
6315 this._loadingGrid.setLoadingItem(loading);
6316
6317 this.items = this._getRenderingItems();
6318 };
6319
6320 __proto.getVisibleGroups = function (includePlaceholders) {
6321 var groups = this.groups.slice(this.startCursor, this.endCursor + 1);
6322 return filterVirtuals(groups, includePlaceholders);
6323 };
6324
6325 __proto.getComputedOutlineLength = function (items) {
6326 if (items === void 0) {
6327 items = this.items;
6328 }
6329
6330 return this._mainGrid.getComputedOutlineLength(items);
6331 };
6332
6333 __proto.getComputedOutlineSize = function (items) {
6334 if (items === void 0) {
6335 items = this.items;
6336 }
6337
6338 return this._mainGrid.getComputedOutlineSize(items);
6339 };
6340
6341 __proto.applyGrid = function (items, direction, outline) {
6342 var _this = this;
6343
6344 var renderingGroups = this.groups.slice();
6345
6346 if (!renderingGroups.length) {
6347 return {
6348 start: [],
6349 end: []
6350 };
6351 }
6352
6353 var loadingGrid = this._loadingGrid;
6354
6355 if (loadingGrid.getLoadingItem()) {
6356 if (loadingGrid.type === "start") {
6357 renderingGroups.unshift(this._getLoadingGroup());
6358 } else if (loadingGrid.type === "end") {
6359 renderingGroups.push(this._getLoadingGroup());
6360 }
6361 }
6362
6363 var groups = renderingGroups.slice();
6364 var nextOutline = outline;
6365
6366 if (direction === "start") {
6367 groups.reverse();
6368 }
6369
6370 var groupItems = this.groupItems;
6371 var outlineLength = this.getComputedOutlineLength(groupItems);
6372 var outlineSize = this.getComputedOutlineSize(groupItems);
6373 groups.forEach(function (group) {
6374 var grid = group.grid;
6375 var gridItems = grid.getItems();
6376 var isVirtual = group.type === GROUP_TYPE.VIRTUAL && !gridItems[0];
6377 var appliedItems = gridItems.filter(function (item) {
6378 return item.mountState !== MOUNT_STATE.UNCHECKED && item.rect.width;
6379 });
6380 var gridOutlines;
6381 grid.outlineLength = outlineLength;
6382 grid.outlineSize = outlineSize;
6383
6384 if (isVirtual) {
6385 gridOutlines = _this._applyVirtualGrid(grid, direction, nextOutline);
6386 } else if (appliedItems.length) {
6387 gridOutlines = grid.applyGrid(appliedItems, direction, nextOutline);
6388 } else {
6389 gridOutlines = {
6390 start: __spreadArrays(nextOutline),
6391 end: __spreadArrays(nextOutline)
6392 };
6393 }
6394
6395 grid.setOutlines(gridOutlines);
6396 nextOutline = gridOutlines[direction];
6397 });
6398 return {
6399 start: renderingGroups[0].grid.getOutlines().start,
6400 end: renderingGroups[renderingGroups.length - 1].grid.getOutlines().end
6401 };
6402 };
6403
6404 __proto.syncItems = function (nextItemInfos) {
6405 var _this = this;
6406
6407 var prevItemKeys = this.itemKeys;
6408 this.itemKeys = {};
6409
6410 var nextItems = this._syncItemInfos(nextItemInfos.map(function (info) {
6411 return getItemInfo(info);
6412 }), prevItemKeys);
6413
6414 var prevGroupKeys = this.groupKeys;
6415 var nextManagerGroups = categorize(nextItems);
6416
6417 var startVirtualGroups = this._splitVirtualGroups("start", nextManagerGroups);
6418
6419 var endVirtualGroups = this._splitVirtualGroups("end", nextManagerGroups);
6420
6421 nextManagerGroups = __spreadArrays(startVirtualGroups, this._mergeVirtualGroups(nextManagerGroups), endVirtualGroups);
6422 var nextGroups = nextManagerGroups.map(function (_a) {
6423 var _b, _c;
6424
6425 var groupKey = _a.groupKey,
6426 items = _a.items;
6427 var isVirtual = !items[0] || items[0].type === ITEM_TYPE.VIRTUAL;
6428 var grid = (_c = (_b = prevGroupKeys[groupKey]) === null || _b === void 0 ? void 0 : _b.grid) !== null && _c !== void 0 ? _c : _this._makeGrid();
6429 var gridItems = isVirtual ? items : items.filter(function (_a) {
6430 var type = _a.type;
6431 return type === ITEM_TYPE.NORMAL;
6432 });
6433 grid.setItems(gridItems);
6434 return {
6435 type: isVirtual ? GROUP_TYPE.VIRTUAL : GROUP_TYPE.NORMAL,
6436 groupKey: groupKey,
6437 grid: grid,
6438 items: gridItems,
6439 renderItems: items
6440 };
6441 });
6442
6443 this._registerGroups(nextGroups);
6444 };
6445
6446 __proto.renderItems = function (options) {
6447 if (options === void 0) {
6448 options = {};
6449 }
6450
6451 if (options.useResize) {
6452 this.groupItems.forEach(function (item) {
6453 item.updateState = UPDATE_STATE.NEED_UPDATE;
6454 });
6455
6456 var loadingItem = this._getLoadingItem();
6457
6458 if (loadingItem) {
6459 loadingItem.updateState = UPDATE_STATE.NEED_UPDATE;
6460 }
6461 }
6462
6463 return _super.prototype.renderItems.call(this, options);
6464 };
6465
6466 __proto.setCursors = function (startCursor, endCursor) {
6467 this.startCursor = startCursor;
6468 this.endCursor = endCursor;
6469 this.items = this._getRenderingItems();
6470 };
6471
6472 __proto.getStartCursor = function () {
6473 return this.startCursor;
6474 };
6475
6476 __proto.getEndCursor = function () {
6477 return this.endCursor;
6478 };
6479
6480 __proto.getGroupStatus = function (type, includePlaceholders) {
6481 var orgStartCursor = this.startCursor;
6482 var orgEndCursor = this.endCursor;
6483 var orgGroups = this.groups;
6484 var startGroup = orgGroups[orgStartCursor];
6485 var endGroup = orgGroups[orgEndCursor];
6486 var startCursor = orgStartCursor;
6487 var endCursor = orgEndCursor;
6488 var isMinimizeItems = type === STATUS_TYPE.MINIMIZE_INVISIBLE_ITEMS;
6489 var isMinimizeGroups = type === STATUS_TYPE.MINIMIZE_INVISIBLE_GROUPS;
6490 var groups;
6491
6492 if (type === STATUS_TYPE.REMOVE_INVISIBLE_GROUPS) {
6493 groups = this.getVisibleGroups(includePlaceholders);
6494 endCursor = groups.length - 1;
6495 startCursor = 0;
6496 } else {
6497 groups = this.getGroups(includePlaceholders);
6498
6499 if (!includePlaceholders) {
6500 startCursor = -1;
6501 endCursor = -1;
6502
6503 for (var orgIndex = orgStartCursor; orgIndex <= orgEndCursor; ++orgIndex) {
6504 var orgGroup = orgGroups[orgIndex];
6505
6506 if (orgGroup && orgGroup.type !== GROUP_TYPE.VIRTUAL) {
6507 startCursor = groups.indexOf(orgGroup);
6508 break;
6509 }
6510 }
6511
6512 for (var orgIndex = orgEndCursor; orgIndex >= orgStartCursor; --orgIndex) {
6513 var orgGroup = orgGroups[orgIndex];
6514
6515 if (orgGroup && orgGroup.type !== GROUP_TYPE.VIRTUAL) {
6516 endCursor = groups.lastIndexOf(orgGroup);
6517 break;
6518 }
6519 }
6520 }
6521 }
6522
6523 var groupStatus = groups.map(function (_a, i) {
6524 var grid = _a.grid,
6525 groupKey = _a.groupKey;
6526 var isOutsideCursor = i < startCursor || endCursor < i;
6527 var isVirtualItems = isMinimizeItems && isOutsideCursor;
6528 var isVirtualGroup = isMinimizeGroups && isOutsideCursor;
6529 var gridItems = grid.getItems();
6530 var items = isVirtualGroup ? [] : gridItems.map(function (item) {
6531 return isVirtualItems ? item.getVirtualStatus() : item.getMinimizedStatus();
6532 });
6533 return {
6534 type: isVirtualGroup || isVirtualItems ? GROUP_TYPE.VIRTUAL : GROUP_TYPE.NORMAL,
6535 groupKey: groupKey,
6536 outlines: grid.getOutlines(),
6537 items: items
6538 };
6539 });
6540 var totalItems = this.getGroupItems();
6541 var itemStartCursor = totalItems.indexOf(startGroup === null || startGroup === void 0 ? void 0 : startGroup.items[0]);
6542 var itemEndCursor = totalItems.indexOf(endGroup === null || endGroup === void 0 ? void 0 : endGroup.items.slice().reverse()[0]);
6543 return {
6544 cursors: [startCursor, endCursor],
6545 orgCursors: [orgStartCursor, orgEndCursor],
6546 itemCursors: [itemStartCursor, itemEndCursor],
6547 startGroupKey: startGroup === null || startGroup === void 0 ? void 0 : startGroup.groupKey,
6548 endGroupKey: endGroup === null || endGroup === void 0 ? void 0 : endGroup.groupKey,
6549 groups: groupStatus,
6550 outlines: this.outlines
6551 };
6552 };
6553
6554 __proto.fitOutlines = function (useFit) {
6555 if (useFit === void 0) {
6556 useFit = this.useFit;
6557 }
6558
6559 var groups = this.groups;
6560 var firstGroup = groups[0];
6561
6562 if (!firstGroup) {
6563 return;
6564 }
6565
6566 var outlines = firstGroup.grid.getOutlines();
6567 var startOutline = outlines.start;
6568 var outlineOffset = startOutline.length ? Math.min.apply(Math, startOutline) : 0; // If the outline is less than 0, a fit occurs forcibly.
6569
6570 if (!useFit && outlineOffset > 0) {
6571 return;
6572 }
6573
6574 groups.forEach(function (_a) {
6575 var grid = _a.grid;
6576
6577 var _b = grid.getOutlines(),
6578 start = _b.start,
6579 end = _b.end;
6580
6581 grid.setOutlines({
6582 start: start.map(function (point) {
6583 return point - outlineOffset;
6584 }),
6585 end: end.map(function (point) {
6586 return point - outlineOffset;
6587 })
6588 });
6589 });
6590 this.groupItems.forEach(function (item) {
6591 var contentPos = item.cssContentPos;
6592
6593 if (!isNumber$1(contentPos)) {
6594 return;
6595 }
6596
6597 item.cssContentPos = contentPos - outlineOffset;
6598 });
6599 };
6600
6601 __proto.setGroupStatus = function (status) {
6602 var _this = this;
6603
6604 this.itemKeys = {};
6605 this.groupItems = [];
6606 this.items = [];
6607 var prevGroupKeys = this.groupKeys;
6608 var nextGroups = status.groups.map(function (_a) {
6609 var _b, _c;
6610
6611 var type = _a.type,
6612 groupKey = _a.groupKey,
6613 items = _a.items,
6614 outlines = _a.outlines;
6615
6616 var nextItems = _this._syncItemInfos(items);
6617
6618 var grid = (_c = (_b = prevGroupKeys[groupKey]) === null || _b === void 0 ? void 0 : _b.grid) !== null && _c !== void 0 ? _c : _this._makeGrid();
6619 grid.setOutlines(outlines);
6620 grid.setItems(nextItems);
6621 return {
6622 type: type,
6623 groupKey: groupKey,
6624 grid: grid,
6625 items: nextItems,
6626 renderItems: nextItems
6627 };
6628 });
6629 this.setOutlines(status.outlines);
6630
6631 this._registerGroups(nextGroups);
6632
6633 this._updatePlaceholder();
6634
6635 this.setCursors(status.cursors[0], status.cursors[1]);
6636 };
6637
6638 __proto.appendPlaceholders = function (items, groupKey) {
6639 return this.insertPlaceholders("end", items, groupKey);
6640 };
6641
6642 __proto.prependPlaceholders = function (items, groupKey) {
6643 return this.insertPlaceholders("start", items, groupKey);
6644 };
6645
6646 __proto.removePlaceholders = function (type) {
6647 var groups = this.groups;
6648 var length = groups.length;
6649
6650 if (type === "start") {
6651 var index = findIndex(groups, function (group) {
6652 return group.type === GROUP_TYPE.NORMAL;
6653 });
6654 groups.splice(0, index);
6655 } else if (type === "end") {
6656 var index = findLastIndex(groups, function (group) {
6657 return group.type === GROUP_TYPE.NORMAL;
6658 });
6659 groups.splice(index + 1, length - index - 1);
6660 } else {
6661 var groupKey_1 = type.groupKey;
6662 var index = findIndex(groups, function (group) {
6663 return group.groupKey === groupKey_1;
6664 });
6665
6666 if (index > -1) {
6667 groups.splice(index, 1);
6668 }
6669 }
6670
6671 this.syncItems(flatGroups(this.getGroups()));
6672 };
6673
6674 __proto.insertPlaceholders = function (direction, items, groupKey) {
6675 var _a, _b;
6676
6677 if (groupKey === void 0) {
6678 groupKey = makeKey(this.groupKeys);
6679 }
6680
6681 var infos = [];
6682
6683 if (isNumber$1(items)) {
6684 infos = range$1(items).map(function () {
6685 return {
6686 type: ITEM_TYPE.VIRTUAL,
6687 groupKey: groupKey
6688 };
6689 });
6690 } else if (Array.isArray(items)) {
6691 infos = items.map(function (status) {
6692 return __assign(__assign({
6693 groupKey: groupKey
6694 }, status), {
6695 type: ITEM_TYPE.VIRTUAL
6696 });
6697 });
6698 }
6699
6700 var grid = this._makeGrid();
6701
6702 var nextItems = this._syncItemInfos(infos, this.itemKeys);
6703
6704 this._updatePlaceholder(nextItems);
6705
6706 grid.setItems(nextItems);
6707 var group = {
6708 type: GROUP_TYPE.VIRTUAL,
6709 groupKey: groupKey,
6710 grid: grid,
6711 items: nextItems,
6712 renderItems: nextItems
6713 };
6714 this.groupKeys[groupKey] = group;
6715
6716 if (direction === "end") {
6717 this.groups.push(group);
6718
6719 (_a = this.groupItems).push.apply(_a, nextItems);
6720 } else {
6721 this.groups.splice(0, 0, group);
6722
6723 (_b = this.groupItems).splice.apply(_b, __spreadArrays([0, 0], nextItems));
6724
6725 if (this.startCursor > -1) {
6726 ++this.startCursor;
6727 ++this.endCursor;
6728 }
6729 }
6730
6731 return {
6732 group: group,
6733 items: nextItems
6734 };
6735 };
6736
6737 __proto.shouldRerenderItems = function () {
6738 var isRerender = false;
6739 this.getVisibleGroups().forEach(function (group) {
6740 var items = group.items;
6741
6742 if (items.length === group.renderItems.length || items.every(function (item) {
6743 return item.mountState === MOUNT_STATE.UNCHECKED;
6744 })) {
6745 return;
6746 }
6747
6748 isRerender = true;
6749 group.renderItems = __spreadArrays(items);
6750 });
6751
6752 if (isRerender) {
6753 this.items = this._getRenderingItems();
6754 }
6755
6756 return isRerender;
6757 };
6758
6759 __proto._getGroupItems = function () {
6760 return flatGroups(this.getGroups(true));
6761 };
6762
6763 __proto._getRenderingItems = function () {
6764 var items = flat(this.getVisibleGroups(true).map(function (item) {
6765 return item.renderItems;
6766 }));
6767 var loadingGrid = this._loadingGrid;
6768 var loadingItem = loadingGrid.getLoadingItem();
6769
6770 if (loadingItem) {
6771 if (loadingGrid.type === "end") {
6772 items.push(loadingItem);
6773 } else if (loadingGrid.type === "start") {
6774 items.unshift(loadingItem);
6775 }
6776 }
6777
6778 return items;
6779 };
6780
6781 __proto._checkShouldRender = function (options) {
6782 var GridConstructor = this.options.gridConstructor;
6783 var prevOptions = this.gridOptions;
6784 var propertyTypes = GridConstructor.propertyTypes;
6785
6786 for (var name in prevOptions) {
6787 if (!(name in options) && propertyTypes[name] === PROPERTY_TYPE.RENDER_PROPERTY) {
6788 return true;
6789 }
6790 }
6791
6792 for (var name in options) {
6793 if (prevOptions[name] !== options[name] && propertyTypes[name] === PROPERTY_TYPE.RENDER_PROPERTY) {
6794 return true;
6795 }
6796 }
6797
6798 return false;
6799 };
6800
6801 __proto._applyVirtualGrid = function (grid, direction, outline) {
6802 var startOutline = outline.length ? __spreadArrays(outline) : [0];
6803 var prevOutlines = grid.getOutlines();
6804 var prevOutline = prevOutlines[direction === "end" ? "start" : "end"];
6805
6806 if (prevOutline.length !== startOutline.length || prevOutline.some(function (value, i) {
6807 return value !== startOutline[i];
6808 })) {
6809 return {
6810 start: __spreadArrays(startOutline),
6811 end: __spreadArrays(startOutline)
6812 };
6813 }
6814
6815 return prevOutlines;
6816 };
6817
6818 __proto._syncItemInfos = function (nextItemInfos, prevItemKeys) {
6819 if (prevItemKeys === void 0) {
6820 prevItemKeys = {};
6821 }
6822
6823 var horizontal = this.options.horizontal;
6824 var nextItemKeys = this.itemKeys;
6825 nextItemInfos.filter(function (info) {
6826 return info.key != null;
6827 }).forEach(function (info) {
6828 var key = info.key;
6829 var prevItem = prevItemKeys[key];
6830
6831 if (!prevItem) {
6832 nextItemKeys[key] = new InfiniteGridItem(horizontal, __assign({}, info));
6833 } else if (prevItem.type === ITEM_TYPE.VIRTUAL && info.type !== ITEM_TYPE.VIRTUAL) {
6834 nextItemKeys[key] = new InfiniteGridItem(horizontal, __assign({
6835 orgRect: prevItem.orgRect,
6836 rect: prevItem.rect
6837 }, info));
6838 } else {
6839 if (info.data) {
6840 prevItem.data = info.data;
6841 }
6842
6843 nextItemKeys[key] = prevItem;
6844 }
6845 });
6846 var nextItems = nextItemInfos.map(function (info) {
6847 var key = info.key;
6848
6849 if (info.key == null) {
6850 key = makeKey(nextItemKeys);
6851 }
6852
6853 var item = nextItemKeys[key];
6854
6855 if (!item) {
6856 var prevItem = prevItemKeys[key];
6857
6858 if (prevItem) {
6859 item = prevItem;
6860
6861 if (info.data) {
6862 item.data = info.data;
6863 }
6864 } else {
6865 item = new InfiniteGridItem(horizontal, __assign(__assign({}, info), {
6866 key: key
6867 }));
6868 }
6869
6870 nextItemKeys[key] = item;
6871 }
6872
6873 return item;
6874 });
6875 return nextItems;
6876 };
6877
6878 __proto._registerGroups = function (groups) {
6879 var nextGroupKeys = {};
6880 groups.forEach(function (group) {
6881 nextGroupKeys[group.groupKey] = group;
6882 });
6883 this.groups = groups;
6884 this.groupKeys = nextGroupKeys;
6885 this.groupItems = this._getGroupItems();
6886 };
6887
6888 __proto._splitVirtualGroups = function (direction, nextGroups) {
6889 var groups = splitVirtualGroups(this.groups, direction, nextGroups);
6890 var itemKeys = this.itemKeys;
6891 groups.forEach(function (_a) {
6892 var renderItems = _a.renderItems;
6893 renderItems.forEach(function (item) {
6894 itemKeys[item.key] = item;
6895 });
6896 });
6897 return groups;
6898 };
6899
6900 __proto._mergeVirtualGroups = function (groups) {
6901 var itemKeys = this.itemKeys;
6902 var groupKeys = this.groupKeys;
6903 groups.forEach(function (group) {
6904 var prevGroup = groupKeys[group.groupKey];
6905
6906 if (!prevGroup) {
6907 return;
6908 }
6909
6910 var items = group.items;
6911
6912 if (items.every(function (item) {
6913 return item.mountState === MOUNT_STATE.UNCHECKED;
6914 })) {
6915 prevGroup.renderItems.forEach(function (item) {
6916 if (item.type === ITEM_TYPE.VIRTUAL && !itemKeys[item.key]) {
6917 items.push(item);
6918 itemKeys[item.key] = item;
6919 }
6920 });
6921 }
6922 });
6923 return groups;
6924 };
6925
6926 __proto._updatePlaceholder = function (items) {
6927 if (items === void 0) {
6928 items = this.groupItems;
6929 }
6930
6931 var placeholder = this._placeholder;
6932
6933 if (!placeholder) {
6934 return;
6935 }
6936
6937 items.filter(function (item) {
6938 return item.type === ITEM_TYPE.VIRTUAL;
6939 }).forEach(function (item) {
6940 setPlaceholder(item, placeholder);
6941 });
6942 };
6943
6944 __proto._makeGrid = function () {
6945 var GridConstructor = this.options.gridConstructor;
6946 var gridOptions = this.gridOptions;
6947 var container = this.containerElement;
6948 return new GridConstructor(container, __assign(__assign({}, gridOptions), {
6949 useFit: false,
6950 autoResize: false,
6951 useResizeObserver: false,
6952 observeChildren: false,
6953 renderOnPropertyChange: false,
6954 externalContainerManager: this.containerManager,
6955 externalItemRenderer: this.itemRenderer
6956 }));
6957 };
6958
6959 __proto._getLoadingGroup = function () {
6960 var loadingGrid = this._loadingGrid;
6961 var items = loadingGrid.getItems();
6962 return {
6963 groupKey: LOADING_GROUP_KEY,
6964 type: GROUP_TYPE.NORMAL,
6965 grid: loadingGrid,
6966 items: items,
6967 renderItems: items
6968 };
6969 };
6970
6971 __proto._getLoadingItem = function () {
6972 return this._loadingGrid.getLoadingItem();
6973 };
6974
6975 GroupManager.defaultOptions = __assign(__assign({}, Grid.defaultOptions), {
6976 gridConstructor: null,
6977 gridOptions: {}
6978 });
6979 GroupManager.propertyTypes = __assign(__assign({}, Grid.propertyTypes), {
6980 gridConstructor: PROPERTY_TYPE.PROPERTY,
6981 gridOptions: PROPERTY_TYPE.PROPERTY
6982 });
6983 GroupManager = __decorate([GetterSetter], GroupManager);
6984 return GroupManager;
6985 }(Grid);
6986
6987 var Infinite =
6988 /*#__PURE__*/
6989 function (_super) {
6990 __extends(Infinite, _super);
6991
6992 function Infinite(options) {
6993 var _this = _super.call(this) || this;
6994
6995 _this.startCursor = -1;
6996 _this.endCursor = -1;
6997 _this.size = 0;
6998 _this.items = [];
6999 _this.itemKeys = {};
7000 _this.options = __assign({
7001 threshold: 0,
7002 useRecycle: true,
7003 defaultDirection: "end"
7004 }, options);
7005 return _this;
7006 }
7007
7008 var __proto = Infinite.prototype;
7009
7010 __proto.scroll = function (scrollPos) {
7011 var _a, _b;
7012
7013 var prevStartCursor = this.startCursor;
7014 var prevEndCursor = this.endCursor;
7015 var items = this.items;
7016 var length = items.length;
7017 var size = this.size;
7018 var _c = this.options,
7019 defaultDirection = _c.defaultDirection,
7020 threshold = _c.threshold,
7021 useRecycle = _c.useRecycle;
7022 var isDirectionEnd = defaultDirection === "end";
7023
7024 if (!length) {
7025 this.trigger(isDirectionEnd ? "requestAppend" : "requestPrepend", {
7026 key: undefined,
7027 isVirtual: false
7028 });
7029 return;
7030 } else if (prevStartCursor === -1 || prevEndCursor === -1) {
7031 var nextCursor = isDirectionEnd ? 0 : length - 1;
7032 this.trigger("change", {
7033 prevStartCursor: prevStartCursor,
7034 prevEndCursor: prevEndCursor,
7035 nextStartCursor: nextCursor,
7036 nextEndCursor: nextCursor
7037 });
7038 return;
7039 }
7040
7041 var endScrollPos = scrollPos + size;
7042 var startEdgePos = Math.max.apply(Math, items[prevStartCursor].startOutline);
7043 var endEdgePos = Math.min.apply(Math, items[prevEndCursor].endOutline);
7044 var visibles = items.map(function (item) {
7045 var startOutline = item.startOutline,
7046 endOutline = item.endOutline;
7047
7048 if (!startOutline.length || !endOutline.length) {
7049 return false;
7050 }
7051
7052 var startPos = Math.min.apply(Math, startOutline);
7053 var endPos = Math.max.apply(Math, endOutline);
7054
7055 if (startPos - threshold <= endScrollPos && scrollPos <= endPos + threshold) {
7056 return true;
7057 }
7058
7059 return false;
7060 });
7061 var hasStartItems = 0 < prevStartCursor;
7062 var hasEndItems = prevEndCursor < length - 1;
7063 var isStart = scrollPos <= startEdgePos + threshold;
7064 var isEnd = endScrollPos >= endEdgePos - threshold;
7065 var nextStartCursor = visibles.indexOf(true);
7066 var nextEndCursor = visibles.lastIndexOf(true);
7067
7068 if (nextStartCursor === -1) {
7069 nextStartCursor = prevStartCursor;
7070 nextEndCursor = prevEndCursor;
7071 }
7072
7073 if (!useRecycle) {
7074 nextStartCursor = Math.min(nextStartCursor, prevStartCursor);
7075 nextEndCursor = Math.max(nextEndCursor, prevEndCursor);
7076 }
7077
7078 if (nextStartCursor === prevStartCursor && hasStartItems && isStart) {
7079 nextStartCursor -= 1;
7080 }
7081
7082 if (nextEndCursor === prevEndCursor && hasEndItems && isEnd) {
7083 nextEndCursor += 1;
7084 }
7085
7086 var nextVisibleItems = items.slice(nextStartCursor, nextEndCursor + 1); // It must contain no virtual items.
7087
7088 if (nextVisibleItems.every(function (item) {
7089 return item.isVirtual === true;
7090 })) {
7091 // The real item can be in either the start or end direction.
7092 var hasRealItem = false;
7093
7094 for (var i = nextStartCursor - 1; i >= 0; --i) {
7095 if (!items[i].isVirtual) {
7096 nextStartCursor = i;
7097 hasRealItem = true;
7098 break;
7099 }
7100 }
7101
7102 if (!hasRealItem) {
7103 for (var i = nextEndCursor + 1; i < length; ++i) {
7104 if (!items[i].isVirtual) {
7105 nextEndCursor = i;
7106 hasRealItem = true;
7107 break;
7108 }
7109 }
7110 }
7111
7112 if (hasRealItem) {
7113 nextVisibleItems = items.slice(nextStartCursor, nextEndCursor + 1);
7114 }
7115 }
7116
7117 var hasVirtualItems = nextVisibleItems.some(function (item) {
7118 return item.isVirtual === true;
7119 });
7120
7121 if (prevStartCursor !== nextStartCursor || prevEndCursor !== nextEndCursor) {
7122 this.trigger("change", {
7123 prevStartCursor: prevStartCursor,
7124 prevEndCursor: prevEndCursor,
7125 nextStartCursor: nextStartCursor,
7126 nextEndCursor: nextEndCursor
7127 });
7128
7129 if (!hasVirtualItems) {
7130 return;
7131 }
7132 } // If a virtual item is included, a requestPrepend (or requestAppend) event is triggered.
7133
7134
7135 if (hasVirtualItems) {
7136 var isStartVirtual = (_a = nextVisibleItems[0]) === null || _a === void 0 ? void 0 : _a.isVirtual;
7137 var isEndVirtual = (_b = nextVisibleItems[nextVisibleItems.length - 1]) === null || _b === void 0 ? void 0 : _b.isVirtual;
7138
7139 if ((!isDirectionEnd || !isEnd) && isStartVirtual) {
7140 var realItemIndex = findIndex(nextVisibleItems, function (item) {
7141 return !item.isVirtual;
7142 });
7143 var endVirtualItemIndex = (realItemIndex === -1 ? nextVisibleItems.length : realItemIndex) - 1;
7144
7145 if (nextVisibleItems[endVirtualItemIndex]) {
7146 this.trigger("requestPrepend", {
7147 key: nextVisibleItems[realItemIndex].key,
7148 nextKey: nextVisibleItems[endVirtualItemIndex].key,
7149 nextKeys: nextVisibleItems.slice(0, endVirtualItemIndex + 1).map(function (item) {
7150 return item.key;
7151 }),
7152 isVirtual: true
7153 });
7154 }
7155 } else if ((isDirectionEnd || !isStart) && isEndVirtual) {
7156 var realItemIndex = findLastIndex(nextVisibleItems, function (item) {
7157 return !item.isVirtual;
7158 });
7159 var startVirtualItemIndex = realItemIndex + 1;
7160
7161 if (nextVisibleItems[startVirtualItemIndex]) {
7162 this.trigger("requestAppend", {
7163 key: nextVisibleItems[realItemIndex].key,
7164 nextKey: nextVisibleItems[startVirtualItemIndex].key,
7165 nextKeys: nextVisibleItems.slice(startVirtualItemIndex).map(function (item) {
7166 return item.key;
7167 }),
7168 isVirtual: true
7169 });
7170 }
7171 }
7172 } else if (!this._requestVirtualItems()) {
7173 if ((!isDirectionEnd || !isEnd) && isStart) {
7174 this.trigger("requestPrepend", {
7175 key: items[prevStartCursor].key,
7176 isVirtual: false
7177 });
7178 } else if ((isDirectionEnd || !isStart) && isEnd) {
7179 this.trigger("requestAppend", {
7180 key: items[prevEndCursor].key,
7181 isVirtual: false
7182 });
7183 }
7184 }
7185 };
7186 /**
7187 * Call the requestAppend or requestPrepend event to fill the virtual items.
7188 * @ko virtual item을 채우기 위해 requestAppend 또는 requestPrepend 이벤트를 호출합니다.
7189 * @return - Whether the event is called. <ko>이벤트를 호출했는지 여부.</ko>
7190 */
7191
7192
7193 __proto._requestVirtualItems = function () {
7194 var isDirectionEnd = this.options.defaultDirection === "end";
7195 var items = this.items;
7196 var totalVisibleItems = this.getVisibleItems();
7197 var visibleItems = totalVisibleItems.filter(function (item) {
7198 return !item.isVirtual;
7199 });
7200 var totalVisibleLength = totalVisibleItems.length;
7201 var visibleLength = visibleItems.length;
7202 var startCursor = this.getStartCursor();
7203 var endCursor = this.getEndCursor();
7204
7205 if (visibleLength === totalVisibleLength) {
7206 return false;
7207 } else if (visibleLength) {
7208 var startKey_1 = visibleItems[0].key;
7209 var endKey_1 = visibleItems[visibleLength - 1].key;
7210 var startIndex = findIndex(items, function (item) {
7211 return item.key === startKey_1;
7212 }) - 1;
7213 var endIndex = findIndex(items, function (item) {
7214 return item.key === endKey_1;
7215 }) + 1;
7216 var isEnd = endIndex <= endCursor;
7217 var isStart = startIndex >= startCursor; // Fill the placeholder with the original item.
7218
7219 if ((isDirectionEnd || !isStart) && isEnd) {
7220 this.trigger("requestAppend", {
7221 key: endKey_1,
7222 nextKey: items[endIndex].key,
7223 isVirtual: true
7224 });
7225 return true;
7226 } else if ((!isDirectionEnd || !isEnd) && isStart) {
7227 this.trigger("requestPrepend", {
7228 key: startKey_1,
7229 nextKey: items[startIndex].key,
7230 isVirtual: true
7231 });
7232 return true;
7233 }
7234 } else if (totalVisibleLength) {
7235 var lastItem = totalVisibleItems[totalVisibleLength - 1];
7236
7237 if (isDirectionEnd) {
7238 this.trigger("requestAppend", {
7239 nextKey: totalVisibleItems[0].key,
7240 isVirtual: true
7241 });
7242 } else {
7243 this.trigger("requestPrepend", {
7244 nextKey: lastItem.key,
7245 isVirtual: true
7246 });
7247 }
7248
7249 return true;
7250 }
7251
7252 return false;
7253 };
7254
7255 __proto.setCursors = function (startCursor, endCursor) {
7256 this.startCursor = startCursor;
7257 this.endCursor = endCursor;
7258 };
7259
7260 __proto.setSize = function (size) {
7261 this.size = size;
7262 };
7263
7264 __proto.getStartCursor = function () {
7265 return this.startCursor;
7266 };
7267
7268 __proto.getEndCursor = function () {
7269 return this.endCursor;
7270 };
7271
7272 __proto.isLoading = function (direction) {
7273 var startCursor = this.startCursor;
7274 var endCursor = this.endCursor;
7275 var items = this.items;
7276 var firstItem = items[startCursor];
7277 var lastItem = items[endCursor];
7278 var length = items.length;
7279
7280 if (direction === DIRECTION.END && endCursor > -1 && endCursor < length - 1 && !lastItem.isVirtual && !isFlatOutline(lastItem.startOutline, lastItem.endOutline)) {
7281 return false;
7282 }
7283
7284 if (direction === DIRECTION.START && startCursor > 0 && !firstItem.isVirtual && !isFlatOutline(firstItem.startOutline, firstItem.endOutline)) {
7285 return false;
7286 }
7287
7288 return true;
7289 };
7290
7291 __proto.setItems = function (nextItems) {
7292 this.items = nextItems;
7293 var itemKeys = {};
7294 nextItems.forEach(function (item) {
7295 itemKeys[item.key] = item;
7296 });
7297 this.itemKeys = itemKeys;
7298 };
7299
7300 __proto.syncItems = function (nextItems) {
7301 var prevItems = this.items;
7302 var prevStartCursor = this.startCursor;
7303 var prevEndCursor = this.endCursor;
7304
7305 var _a = getNextCursors(this.items.map(function (item) {
7306 return item.key;
7307 }), nextItems.map(function (item) {
7308 return item.key;
7309 }), prevStartCursor, prevEndCursor),
7310 nextStartCursor = _a.startCursor,
7311 nextEndCursor = _a.endCursor; // sync items between cursors
7312
7313
7314 var isChange = nextEndCursor - nextStartCursor !== prevEndCursor - prevStartCursor || prevStartCursor === -1 || nextStartCursor === -1;
7315
7316 if (!isChange) {
7317 var prevVisibleItems = prevItems.slice(prevStartCursor, prevEndCursor + 1);
7318 var nextVisibleItems = nextItems.slice(nextStartCursor, nextEndCursor + 1);
7319 var visibleResult = diff(prevVisibleItems, nextVisibleItems, function (item) {
7320 return item.key;
7321 });
7322 isChange = visibleResult.added.length > 0 || visibleResult.removed.length > 0 || visibleResult.changed.length > 0;
7323 }
7324
7325 this.setItems(nextItems);
7326 this.setCursors(nextStartCursor, nextEndCursor);
7327 return isChange;
7328 };
7329
7330 __proto.getItems = function () {
7331 return this.items;
7332 };
7333
7334 __proto.getVisibleItems = function () {
7335 var startCursor = this.startCursor;
7336 var endCursor = this.endCursor;
7337
7338 if (startCursor === -1) {
7339 return [];
7340 }
7341
7342 return this.items.slice(startCursor, endCursor + 1);
7343 };
7344
7345 __proto.getItemByKey = function (key) {
7346 return this.itemKeys[key];
7347 };
7348
7349 __proto.getRenderedVisibleItems = function () {
7350 var items = this.getVisibleItems();
7351 var rendered = items.map(function (_a) {
7352 var startOutline = _a.startOutline,
7353 endOutline = _a.endOutline;
7354 var length = startOutline.length;
7355
7356 if (length === 0 || length !== endOutline.length) {
7357 return false;
7358 }
7359
7360 return startOutline.some(function (pos, i) {
7361 return endOutline[i] !== pos;
7362 });
7363 });
7364 var startIndex = rendered.indexOf(true);
7365 var endIndex = rendered.lastIndexOf(true);
7366 return endIndex === -1 ? [] : items.slice(startIndex, endIndex + 1);
7367 };
7368
7369 __proto.destroy = function () {
7370 this.off();
7371 this.startCursor = -1;
7372 this.endCursor = -1;
7373 this.items = [];
7374 this.size = 0;
7375 };
7376
7377 return Infinite;
7378 }(Component);
7379
7380 var Renderer =
7381 /*#__PURE__*/
7382 function (_super) {
7383 __extends(Renderer, _super);
7384
7385 function Renderer() {
7386 var _this = _super !== null && _super.apply(this, arguments) || this;
7387
7388 _this.items = [];
7389 _this.container = null;
7390 _this.rendererKey = 0;
7391 _this._updateTimer = 0;
7392 _this._state = {};
7393 _this._isItemChanged = false;
7394 return _this;
7395 }
7396
7397 var __proto = Renderer.prototype;
7398
7399 __proto.updateKey = function () {
7400 this.rendererKey = Date.now();
7401 };
7402
7403 __proto.getItems = function () {
7404 return this.items;
7405 };
7406
7407 __proto.setContainer = function (container) {
7408 this.container = container;
7409 };
7410
7411 __proto.render = function (nextItems, state) {
7412 return this.syncItems(nextItems, state);
7413 };
7414
7415 __proto.update = function (state) {
7416 var _this = this;
7417
7418 if (state === void 0) {
7419 state = {};
7420 }
7421
7422 this._state = __assign(__assign({}, this._state), state);
7423 this.trigger("update", {
7424 state: state
7425 });
7426 clearTimeout(this._updateTimer);
7427 this._updateTimer = window.setTimeout(function () {
7428 _this.trigger("requestUpdate", {
7429 state: state
7430 });
7431 });
7432 };
7433
7434 __proto.updated = function (nextElements) {
7435 var _a, _b;
7436
7437 if (nextElements === void 0) {
7438 nextElements = (_b = (_a = this.container) === null || _a === void 0 ? void 0 : _a.children) !== null && _b !== void 0 ? _b : [];
7439 }
7440
7441 var diffResult = this._diffResult;
7442 var isChanged = !!(diffResult.added.length || diffResult.removed.length || diffResult.changed.length);
7443 var state = this._state;
7444 var isItemChanged = this._isItemChanged;
7445 var nextItems = diffResult.list;
7446 this._isItemChanged = false;
7447 this._state = {};
7448 this.items = nextItems;
7449 nextItems.forEach(function (item, i) {
7450 item.element = nextElements[i];
7451 });
7452 this.trigger("updated", {
7453 items: nextItems,
7454 elements: toArray$1(nextElements),
7455 diffResult: this._diffResult,
7456 state: state,
7457 isItemChanged: isItemChanged,
7458 isChanged: isChanged
7459 });
7460 return isChanged;
7461 };
7462
7463 __proto.syncItems = function (items, state) {
7464 if (state === void 0) {
7465 state = {};
7466 }
7467
7468 var rendererKey = this.rendererKey;
7469 var prevItems = this.items;
7470 var nextItems = items.map(function (item) {
7471 return __assign(__assign({}, item), {
7472 renderKey: rendererKey + "_" + item.key
7473 });
7474 });
7475 var result = diff(prevItems, nextItems, function (item) {
7476 return item.renderKey;
7477 });
7478 this._isItemChanged = !!result.added.length || !!result.removed.length || !!result.changed.length;
7479 this._state = __assign(__assign({}, this._state), state);
7480 this._diffResult = result;
7481 return result;
7482 };
7483
7484 __proto.destroy = function () {
7485 this.off();
7486 };
7487
7488 return Renderer;
7489 }(Component);
7490
7491 var VanillaRenderer =
7492 /*#__PURE__*/
7493 function (_super) {
7494 __extends(VanillaRenderer, _super);
7495
7496 function VanillaRenderer() {
7497 return _super !== null && _super.apply(this, arguments) || this;
7498 }
7499
7500 var __proto = VanillaRenderer.prototype;
7501
7502 __proto.render = function (nextItems, state) {
7503 var container = this.container;
7504
7505 var result = _super.prototype.render.call(this, nextItems, state);
7506
7507 var prevList = result.prevList,
7508 removed = result.removed,
7509 ordered = result.ordered,
7510 added = result.added,
7511 list = result.list;
7512
7513 var diffList = __spreadArrays(prevList);
7514
7515 removed.forEach(function (index) {
7516 diffList.splice(index, 1);
7517 container.removeChild(prevList[index].element);
7518 });
7519 ordered.forEach(function (_a) {
7520 var _b, _c;
7521
7522 var prevIndex = _a[0],
7523 nextIndex = _a[1];
7524 var item = diffList.splice(prevIndex, 1)[0];
7525 diffList.splice(nextIndex, 0, item);
7526 container.insertBefore(item.element, (_c = (_b = diffList[nextIndex + 1]) === null || _b === void 0 ? void 0 : _b.element) !== null && _c !== void 0 ? _c : null);
7527 });
7528 added.forEach(function (index) {
7529 var _a, _b;
7530
7531 var item = list[index];
7532 diffList.splice(index, 0, item);
7533 container.insertBefore(item.element, (_b = (_a = diffList[index + 1]) === null || _a === void 0 ? void 0 : _a.element) !== null && _b !== void 0 ? _b : null);
7534 });
7535 this.updated(container.children);
7536 return result;
7537 };
7538
7539 return VanillaRenderer;
7540 }(Renderer);
7541
7542 var VanillaGridRenderer =
7543 /*#__PURE__*/
7544 function (_super) {
7545 __extends(VanillaGridRenderer, _super);
7546
7547 function VanillaGridRenderer() {
7548 return _super !== null && _super.apply(this, arguments) || this;
7549 }
7550
7551 var __proto = VanillaGridRenderer.prototype;
7552
7553 __proto.syncItems = function (nextItems) {
7554 var result = _super.prototype.syncItems.call(this, nextItems);
7555
7556 var added = result.added,
7557 list = result.list;
7558 added.forEach(function (index) {
7559 var orgItem = nextItems[index].orgItem;
7560
7561 if (orgItem.html && !orgItem.element) {
7562 orgItem.element = convertHTMLtoElement(orgItem.html)[0];
7563 }
7564
7565 list[index].element = orgItem.element;
7566 });
7567 return result;
7568 };
7569
7570 return VanillaGridRenderer;
7571 }(VanillaRenderer);
7572
7573 var ScrollManager =
7574 /*#__PURE__*/
7575 function (_super) {
7576 __extends(ScrollManager, _super);
7577
7578 function ScrollManager(wrapper, options) {
7579 var _this = _super.call(this) || this;
7580
7581 _this.wrapper = wrapper;
7582 _this.prevScrollPos = null;
7583 _this.scrollOffset = 0;
7584 _this.contentSize = 0;
7585 _this._isScrollIssue = IS_IOS;
7586
7587 _this._onCheck = function () {
7588 var prevScrollPos = _this.getScrollPos();
7589
7590 var nextScrollPos = _this.getOrgScrollPos();
7591
7592 _this.setScrollPos(nextScrollPos);
7593
7594 if (prevScrollPos === null || _this._isScrollIssue && nextScrollPos === 0 || prevScrollPos === nextScrollPos) {
7595 nextScrollPos && (_this._isScrollIssue = false);
7596 return;
7597 }
7598
7599 _this._isScrollIssue = false;
7600
7601 _this.trigger(new ComponentEvent$1("scroll", {
7602 direction: prevScrollPos < nextScrollPos ? "end" : "start",
7603 scrollPos: nextScrollPos,
7604 relativeScrollPos: _this.getRelativeScrollPos()
7605 }));
7606 };
7607
7608 _this.options = __assign({
7609 container: false,
7610 containerTag: "div",
7611 horizontal: false
7612 }, options);
7613
7614 _this._init();
7615
7616 return _this;
7617 }
7618
7619 var __proto = ScrollManager.prototype;
7620
7621 __proto.getWrapper = function () {
7622 return this.wrapper;
7623 };
7624
7625 __proto.getContainer = function () {
7626 return this.container;
7627 };
7628
7629 __proto.getScrollContainer = function () {
7630 return this.scrollContainer;
7631 };
7632
7633 __proto.getScrollOffset = function () {
7634 return this.scrollOffset;
7635 };
7636
7637 __proto.getContentSize = function () {
7638 return this.contentSize;
7639 };
7640
7641 __proto.getRelativeScrollPos = function () {
7642 return (this.prevScrollPos || 0) - this.scrollOffset;
7643 };
7644
7645 __proto.getScrollPos = function () {
7646 return this.prevScrollPos;
7647 };
7648
7649 __proto.setScrollPos = function (pos) {
7650 this.prevScrollPos = pos;
7651 };
7652
7653 __proto.getOrgScrollPos = function () {
7654 var eventTarget = this.eventTarget;
7655 var horizontal = this.options.horizontal;
7656 var prop = "scroll" + (horizontal ? "Left" : "Top");
7657
7658 if (isWindow$1(eventTarget)) {
7659 return window[horizontal ? "pageXOffset" : "pageYOffset"] || document.documentElement[prop] || document.body[prop];
7660 } else {
7661 return eventTarget[prop];
7662 }
7663 };
7664
7665 __proto.setStatus = function (status) {
7666 this.contentSize = status.contentSize;
7667 this.scrollOffset = status.scrollOffset;
7668 this.prevScrollPos = status.prevScrollPos;
7669 this.scrollTo(this.prevScrollPos);
7670 };
7671
7672 __proto.getStatus = function () {
7673 return {
7674 contentSize: this.contentSize,
7675 scrollOffset: this.scrollOffset,
7676 prevScrollPos: this.prevScrollPos
7677 };
7678 };
7679
7680 __proto.scrollTo = function (pos) {
7681 var eventTarget = this.eventTarget;
7682 var horizontal = this.options.horizontal;
7683
7684 var _a = horizontal ? [pos, 0] : [0, pos],
7685 x = _a[0],
7686 y = _a[1];
7687
7688 if (isWindow$1(eventTarget)) {
7689 eventTarget.scroll(x, y);
7690 } else {
7691 eventTarget.scrollLeft = x;
7692 eventTarget.scrollTop = y;
7693 }
7694 };
7695
7696 __proto.scrollBy = function (pos) {
7697 if (!pos) {
7698 return;
7699 }
7700
7701 var eventTarget = this.eventTarget;
7702 var horizontal = this.options.horizontal;
7703
7704 var _a = horizontal ? [pos, 0] : [0, pos],
7705 x = _a[0],
7706 y = _a[1];
7707
7708 this.prevScrollPos += pos;
7709
7710 if (isWindow$1(eventTarget)) {
7711 eventTarget.scrollBy(x, y);
7712 } else {
7713 eventTarget.scrollLeft += x;
7714 eventTarget.scrollTop += y;
7715 }
7716 };
7717
7718 __proto.resize = function () {
7719 var scrollContainer = this.scrollContainer;
7720 var horizontal = this.options.horizontal;
7721 var isBody = scrollContainer === document.body;
7722 var scrollContainerRect = isBody ? {
7723 top: 0,
7724 left: 0
7725 } : scrollContainer.getBoundingClientRect();
7726 var containerRect = this.container.getBoundingClientRect();
7727 this.scrollOffset = (this.prevScrollPos || 0) + (horizontal ? containerRect.left - scrollContainerRect.left : containerRect.top - scrollContainerRect.top);
7728
7729 if (isBody) {
7730 this.contentSize = horizontal ? window.innerWidth : window.innerHeight;
7731 } else {
7732 this.contentSize = horizontal ? scrollContainer.offsetWidth : scrollContainer.offsetHeight;
7733 }
7734 };
7735
7736 __proto.destroy = function () {
7737 var container = this.container;
7738 this.eventTarget.removeEventListener("scroll", this._onCheck);
7739
7740 if (this._isCreateElement) {
7741 var scrollContainer = this.scrollContainer;
7742 var fragment_1 = document.createDocumentFragment();
7743 var childNodes = toArray$1(container.childNodes);
7744 scrollContainer.removeChild(container);
7745 childNodes.forEach(function (childNode) {
7746 fragment_1.appendChild(childNode);
7747 });
7748 scrollContainer.appendChild(fragment_1);
7749 } else if (this.options.container) {
7750 container.style.cssText = this._orgCSSText;
7751 }
7752 };
7753
7754 __proto._init = function () {
7755 var _a;
7756
7757 var _b = this.options,
7758 containerOption = _b.container,
7759 containerTag = _b.containerTag,
7760 horizontal = _b.horizontal;
7761 var wrapper = this.wrapper;
7762 var scrollContainer = wrapper;
7763 var container = wrapper;
7764 var containerCSSText = "";
7765
7766 if (!containerOption) {
7767 scrollContainer = document.body;
7768 containerCSSText = container.style.cssText;
7769 } else {
7770 if (containerOption instanceof HTMLElement) {
7771 // Container that already exists
7772 container = containerOption;
7773 } else if (containerOption === true) {
7774 // Create Container
7775 container = document.createElement(containerTag);
7776 container.style.position = "relative";
7777 container.className = CONTAINER_CLASS_NAME;
7778 var childNodes = toArray$1(scrollContainer.childNodes);
7779 childNodes.forEach(function (childNode) {
7780 container.appendChild(childNode);
7781 });
7782 scrollContainer.appendChild(container);
7783 this._isCreateElement = true;
7784 } else {
7785 // Find Container by Selector
7786 container = scrollContainer.querySelector(containerOption);
7787 }
7788
7789 containerCSSText = container.style.cssText;
7790 var style = scrollContainer.style;
7791 _a = horizontal ? ["scroll", "hidden"] : ["hidden", "scroll"], style.overflowX = _a[0], style.overflowY = _a[1];
7792
7793 if (horizontal) {
7794 container.style.height = "100%";
7795 }
7796 }
7797
7798 var eventTarget = scrollContainer === document.body ? window : scrollContainer;
7799 eventTarget.addEventListener("scroll", this._onCheck);
7800 this._orgCSSText = containerCSSText;
7801 this.container = container;
7802 this.scrollContainer = scrollContainer;
7803 this.eventTarget = eventTarget;
7804 this.resize();
7805 this.setScrollPos(this.getOrgScrollPos());
7806 };
7807
7808 return ScrollManager;
7809 }(Component);
7810
7811 /**
7812 * A module used to arrange items including content infinitely according to layout type. With this module, you can implement various layouts composed of different items whose sizes vary. It guarantees performance by maintaining the number of DOMs the module is handling under any circumstance
7813 * @ko 콘텐츠가 있는 아이템을 레이아웃 타입에 따라 무한으로 배치하는 모듈. 다양한 크기의 아이템을 다양한 레이아웃으로 배치할 수 있다. 아이템의 개수가 계속 늘어나도 모듈이 처리하는 DOM의 개수를 일정하게 유지해 최적의 성능을 보장한다
7814 * @extends Component
7815 * @support {"ie": "9+(with polyfill)", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "4.X+"}
7816 * @example
7817 ```html
7818 <ul id="grid">
7819 <li class="card">
7820 <div>test1</div>
7821 </li>
7822 <li class="card">
7823 <div>test2</div>
7824 </li>
7825 <li class="card">
7826 <div>test3</div>
7827 </li>
7828 <li class="card">
7829 <div>test4</div>
7830 </li>
7831 <li class="card">
7832 <div>test5</div>
7833 </li>
7834 <li class="card">
7835 <div>test6</div>
7836 </li>
7837 </ul>
7838 <script>
7839 import { MasonryInfiniteGrid } from "@egjs/infinitegrid";
7840 var some = new MasonryInfiniteGrid("#grid").on("renderComplete", function(e) {
7841 // ...
7842 });
7843 // If you already have items in the container, call "layout" method.
7844 some.renderItems();
7845 </script>
7846 ```
7847 */
7848
7849 var InfiniteGrid =
7850 /*#__PURE__*/
7851 function (_super) {
7852 __extends(InfiniteGrid, _super);
7853 /**
7854 * @param - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
7855 * @param - The option object of the InfiniteGrid module <ko>eg.InfiniteGrid 모듈의 옵션 객체</ko>
7856 */
7857
7858
7859 function InfiniteGrid(wrapper, options) {
7860 var _this = _super.call(this) || this;
7861
7862 _this._waitType = "";
7863
7864 _this._onScroll = function (_a) {
7865 var direction = _a.direction,
7866 scrollPos = _a.scrollPos,
7867 relativeScrollPos = _a.relativeScrollPos;
7868
7869 _this._scroll();
7870 /**
7871 * This event is fired when scrolling.
7872 * @ko 스크롤하면 발생하는 이벤트이다.
7873 * @event InfiniteGrid#changeScroll
7874 * @param {InfiniteGrid.OnChangeScroll} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
7875 */
7876
7877
7878 _this.trigger(new ComponentEvent$1(INFINITEGRID_EVENTS.CHANGE_SCROLL, {
7879 direction: direction,
7880 scrollPos: scrollPos,
7881 relativeScrollPos: relativeScrollPos
7882 }));
7883 };
7884
7885 _this._onChange = function (e) {
7886 _this.setCursors(e.nextStartCursor, e.nextEndCursor);
7887 };
7888
7889 _this._onRendererUpdated = function (e) {
7890 if (!e.isChanged) {
7891 _this._checkEndLoading();
7892
7893 _this._scroll();
7894
7895 return;
7896 }
7897
7898 var renderedItems = e.items;
7899 var _a = e.diffResult,
7900 added = _a.added,
7901 removed = _a.removed,
7902 prevList = _a.prevList,
7903 list = _a.list;
7904 removed.forEach(function (index) {
7905 var orgItem = prevList[index].orgItem;
7906
7907 if (orgItem.mountState !== MOUNT_STATE.UNCHECKED) {
7908 orgItem.mountState = MOUNT_STATE.UNMOUNTED;
7909 }
7910 });
7911 renderedItems.forEach(function (item) {
7912 // set grid element
7913 var gridItem = item.orgItem;
7914 gridItem.element = item.element;
7915 });
7916 var horizontal = _this.options.horizontal;
7917 var addedItems = added.map(function (index) {
7918 var gridItem = list[index].orgItem;
7919 var element = gridItem.element;
7920
7921 if (gridItem.type === ITEM_TYPE.VIRTUAL) {
7922 var cssRect = __assign({}, gridItem.cssRect);
7923
7924 var rect = gridItem.rect;
7925
7926 if (!cssRect.width && rect.width) {
7927 cssRect.width = rect.width;
7928 }
7929
7930 if (!cssRect.height && rect.height) {
7931 cssRect.height = rect.height;
7932 } // virtual item
7933
7934
7935 return new GridItem(horizontal, {
7936 element: element,
7937 cssRect: cssRect
7938 });
7939 }
7940
7941 return gridItem;
7942 });
7943 var containerManager = _this.containerManager;
7944
7945 if (_this.options.observeChildren) {
7946 containerManager.observeChildren(added.map(function (index) {
7947 return list[index].element;
7948 }));
7949 containerManager.unobserveChildren(removed.map(function (index) {
7950 return prevList[index].element;
7951 }));
7952 }
7953
7954 var _b = e.state,
7955 isRestore = _b.isRestore,
7956 isResize = _b.isResize;
7957
7958 _this.itemRenderer.renderItems(addedItems);
7959
7960 if (isRestore) {
7961 _this._onRenderComplete({
7962 mounted: added.map(function (index) {
7963 return list[index].orgItem;
7964 }),
7965 updated: [],
7966 isResize: false,
7967 direction: _this.defaultDirection
7968 });
7969 }
7970
7971 if (!isRestore || isResize || e.isItemChanged) {
7972 _this.groupManager.renderItems();
7973 }
7974 };
7975
7976 _this._onResize = function (e) {
7977 if (e.isResizeContainer) {
7978 _this._renderItems({
7979 useResize: true
7980 }, true);
7981 } else {
7982 var updatedItems = getUpdatedItems(_this.getVisibleItems(), e.childEntries);
7983
7984 if (updatedItems.length > 0) {
7985 _this.updateItems(updatedItems);
7986 }
7987 }
7988 };
7989
7990 _this._onRequestAppend = function (e) {
7991 /**
7992 * The event is fired when scrolling reaches the end or when data for a virtual group is required.
7993 * @ko 스크롤이 끝에 도달하거나 virtual 그룹에 대한 데이터가 필요한 경우 이벤트가 발생한다.
7994 * @event InfiniteGrid#requestAppend
7995 * @param {InfiniteGrid.OnRequestAppend} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
7996 */
7997 _this._onRequestInsert(DIRECTION.END, INFINITEGRID_EVENTS.REQUEST_APPEND, e);
7998 };
7999
8000 _this._onRequestPrepend = function (e) {
8001 /**
8002 * The event is fired when scrolling reaches the start or when data for a virtual group is required.
8003 * @ko 스크롤이 끝에 도달하거나 virtual 그룹에 대한 데이터가 필요한 경우 이벤트가 발생한다.
8004 * @event InfiniteGrid#requestPrepend
8005 * @param {InfiniteGrid.OnRequestPrepend} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
8006 */
8007 _this._onRequestInsert(DIRECTION.START, INFINITEGRID_EVENTS.REQUEST_PREPEND, e);
8008 };
8009
8010 _this._onContentError = function (_a) {
8011 var element = _a.element,
8012 target = _a.target,
8013 item = _a.item,
8014 update = _a.update;
8015 /**
8016 * The event is fired when scrolling reaches the start or when data for a virtual group is required.
8017 * @ko 스크롤이 끝에 도달하거나 virtual 그룹에 대한 데이터가 필요한 경우 이벤트가 발생한다.
8018 * @event InfiniteGrid#contentError
8019 * @param {InfiniteGrid.OnContentError} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
8020 */
8021
8022 _this.trigger(new ComponentEvent$1(INFINITEGRID_EVENTS.CONTENT_ERROR, {
8023 element: element,
8024 target: target,
8025 item: item,
8026 update: update,
8027 remove: function () {
8028 _this.removeByKey(item.key);
8029 }
8030 }));
8031 };
8032
8033 _this._onRenderComplete = function (_a) {
8034 var isResize = _a.isResize,
8035 mounted = _a.mounted,
8036 updated = _a.updated,
8037 direction = _a.direction;
8038 var infinite = _this.infinite;
8039 var prevRenderedGroups = infinite.getRenderedVisibleItems();
8040 var length = prevRenderedGroups.length;
8041 var isDirectionEnd = direction === DIRECTION.END;
8042
8043 _this._syncInfinite();
8044
8045 if (length) {
8046 var prevStandardGroup = prevRenderedGroups[isDirectionEnd ? 0 : length - 1];
8047 var nextStandardGroup = infinite.getItemByKey(prevStandardGroup.key);
8048 var offset = isDirectionEnd ? Math.min.apply(Math, nextStandardGroup.startOutline) - Math.min.apply(Math, prevStandardGroup.startOutline) : Math.max.apply(Math, nextStandardGroup.endOutline) - Math.max.apply(Math, prevStandardGroup.endOutline);
8049
8050 _this.scrollManager.scrollBy(offset);
8051 }
8052 /**
8053 * This event is fired when the InfiniteGrid has completed rendering.
8054 * @ko InfiniteGrid가 렌더링이 완료됐을 때 이벤트가 발생한다.
8055 * @event InfiniteGrid#renderComplete
8056 * @param {InfiniteGrid.OnRenderComplete} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
8057 */
8058
8059
8060 _this.trigger(new ComponentEvent$1(INFINITEGRID_EVENTS.RENDER_COMPLETE, {
8061 isResize: isResize,
8062 direction: direction,
8063 mounted: mounted.filter(function (item) {
8064 return item.type !== ITEM_TYPE.LOADING;
8065 }),
8066 updated: updated.filter(function (item) {
8067 return item.type !== ITEM_TYPE.LOADING;
8068 }),
8069 startCursor: _this.getStartCursor(),
8070 endCursor: _this.getEndCursor(),
8071 items: _this.getVisibleItems(true),
8072 groups: _this.getVisibleGroups(true)
8073 }));
8074
8075 if (_this.groupManager.shouldRerenderItems()) {
8076 _this._update();
8077 } else {
8078 _this._checkEndLoading();
8079
8080 _this._scroll();
8081 }
8082 };
8083
8084 _this.options = __assign(__assign(__assign({}, _this.constructor.defaultOptions), {
8085 renderer: new VanillaGridRenderer().on("requestUpdate", function () {
8086 return _this._render();
8087 })
8088 }), options);
8089
8090 var _a = _this.options,
8091 gridConstructor = _a.gridConstructor,
8092 containerTag = _a.containerTag,
8093 container = _a.container,
8094 renderer = _a.renderer,
8095 threshold = _a.threshold,
8096 useRecycle = _a.useRecycle,
8097 gridOptions = __rest(_a, ["gridConstructor", "containerTag", "container", "renderer", "threshold", "useRecycle"]); // options.container === false, wrapper = container, scrollContainer = document.body
8098 // options.container === true, wrapper = scrollContainer, container = wrapper's child
8099 // options.container === string,
8100
8101
8102 var horizontal = gridOptions.horizontal,
8103 attributePrefix = gridOptions.attributePrefix,
8104 useTransform = gridOptions.useTransform,
8105 percentage = gridOptions.percentage,
8106 isConstantSize = gridOptions.isConstantSize,
8107 isEqualSize = gridOptions.isEqualSize,
8108 autoResize = gridOptions.autoResize,
8109 useResizeObserver = gridOptions.useResizeObserver,
8110 resizeDebounce = gridOptions.resizeDebounce,
8111 maxResizeDebounce = gridOptions.maxResizeDebounce,
8112 defaultDirection = gridOptions.defaultDirection;
8113 var wrapperElement = isString$1(wrapper) ? document.querySelector(wrapper) : wrapper;
8114 var scrollManager = new ScrollManager(wrapperElement, {
8115 container: container,
8116 containerTag: containerTag,
8117 horizontal: horizontal
8118 }).on({
8119 scroll: _this._onScroll
8120 });
8121 var containerElement = scrollManager.getContainer();
8122 var containerManager = new ContainerManager(containerElement, {
8123 horizontal: horizontal,
8124 autoResize: autoResize,
8125 resizeDebounce: resizeDebounce,
8126 maxResizeDebounce: maxResizeDebounce,
8127 useResizeObserver: useResizeObserver
8128 }).on("resize", _this._onResize);
8129 var itemRenderer = new ItemRenderer({
8130 attributePrefix: attributePrefix,
8131 horizontal: horizontal,
8132 useTransform: useTransform,
8133 percentage: percentage,
8134 isEqualSize: isEqualSize,
8135 isConstantSize: isConstantSize
8136 });
8137 var infinite = new Infinite({
8138 defaultDirection: defaultDirection,
8139 useRecycle: useRecycle,
8140 threshold: threshold
8141 }).on({
8142 "change": _this._onChange,
8143 "requestAppend": _this._onRequestAppend,
8144 "requestPrepend": _this._onRequestPrepend
8145 });
8146 infinite.setSize(scrollManager.getContentSize());
8147 var groupManager = new GroupManager(containerElement, {
8148 gridConstructor: gridConstructor,
8149 externalItemRenderer: itemRenderer,
8150 externalContainerManager: containerManager,
8151 gridOptions: gridOptions
8152 });
8153 groupManager.on({
8154 "renderComplete": _this._onRenderComplete,
8155 "contentError": _this._onContentError
8156 });
8157 renderer.setContainer(containerElement);
8158 renderer.on("updated", _this._onRendererUpdated);
8159 _this.itemRenderer = itemRenderer;
8160 _this.groupManager = groupManager;
8161 _this.wrapperElement = wrapperElement;
8162 _this.scrollManager = scrollManager;
8163 _this.containerManager = containerManager;
8164 _this.infinite = infinite;
8165
8166 _this.containerManager.resize();
8167
8168 return _this;
8169 }
8170
8171 var __proto = InfiniteGrid.prototype;
8172 InfiniteGrid_1 = InfiniteGrid;
8173 /**
8174 * Rearrange items to fit the grid and render them. When rearrange is complete, the `renderComplete` event is fired.
8175 * @ko grid에 맞게 아이템을 재배치하고 렌더링을 한다. 배치가 완료되면 `renderComplete` 이벤트가 발생한다.
8176 * @param - Options for rendering. <ko>렌더링을 하기 위한 옵션.</ko>
8177 * @example
8178 * ```ts
8179 * import { MasonryInfiniteGrid } from "@egjs/infinitegrid";
8180 * const grid = new MasonryInfiniteGrid();
8181 *
8182 * grid.on("renderComplete", e => {
8183 * console.log(e);
8184 * });
8185 * grid.renderItems();
8186 * ```
8187 */
8188
8189 __proto.renderItems = function (options) {
8190 if (options === void 0) {
8191 options = {};
8192 }
8193
8194 this._renderItems(options);
8195
8196 return this;
8197 };
8198 /**
8199 * Returns the wrapper element specified by the user.
8200 * @ko 컨테이너 엘리먼트를 반환한다.
8201 */
8202
8203
8204 __proto.getWrapperElement = function () {
8205 return this.scrollManager.getWrapper();
8206 };
8207 /**
8208 * Returns the container element corresponding to the scroll area.
8209 * @ko 스크롤 영역에 해당하는 컨테이너 엘리먼트를 반환한다.
8210 */
8211
8212
8213 __proto.getScrollContainerElement = function () {
8214 return this.scrollManager.getScrollContainer();
8215 };
8216 /**
8217 * Returns the container element containing item elements.
8218 * @ko 아이템 엘리먼트들을 담긴 컨테이너 엘리먼트를 반환한다.
8219 */
8220
8221
8222 __proto.getContainerElement = function () {
8223 return this.scrollManager.getContainer();
8224 };
8225 /**
8226 * When items change, it synchronizes and renders items.
8227 * @ko items가 바뀐 경우 동기화를 하고 렌더링을 한다.
8228 * @param - Options for rendering. <ko>렌더링을 하기 위한 옵션.</ko>
8229 */
8230
8231
8232 __proto.syncItems = function (items) {
8233 this.groupManager.syncItems(items);
8234
8235 this._syncGroups();
8236
8237 return this;
8238 };
8239 /**
8240 * Change the currently visible groups.
8241 * @ko 현재 보이는 그룹들을 바꾼다.
8242 * @param - first index of visible groups. <ko>보이는 그룹의 첫번째 index.</ko>
8243 * @param - last index of visible groups. <ko>보이는 그룹의 마지막 index.</ko>
8244 * @param - Whether the first rendering has already been done. <ko>첫 렌더링이 이미 되어있는지 여부.</ko>
8245 */
8246
8247
8248 __proto.setCursors = function (startCursor, endCursor, useFirstRender) {
8249 this.groupManager.setCursors(startCursor, endCursor);
8250 this.infinite.setCursors(startCursor, endCursor);
8251
8252 if (useFirstRender) {
8253 this._syncItems();
8254 } else {
8255 this._update();
8256
8257 this._checkEndLoading();
8258 }
8259
8260 return this;
8261 };
8262 /**
8263 * Returns the first index of visible groups.
8264 * @ko 보이는 그룹들의 첫번째 index를 반환한다.
8265 */
8266
8267
8268 __proto.getStartCursor = function () {
8269 return this.infinite.getStartCursor();
8270 };
8271 /**
8272 * Returns the last index of visible groups.
8273 * @ko 보이는 그룹들의 마지막 index를 반환한다.
8274 */
8275
8276
8277 __proto.getEndCursor = function () {
8278 return this.infinite.getEndCursor();
8279 };
8280 /**
8281 * Add items at the bottom(right) of the grid.
8282 * @ko 아이템들을 grid 아래(오른쪽)에 추가한다.
8283 * @param - items to be added <ko>추가할 아이템들</ko>
8284 * @param - The group key to be configured in items. It is automatically generated by default. <ko>추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.</ko>
8285 * @return - An instance of a module itself<ko>모듈 자신의 인스턴스</ko>
8286 * @example
8287 * ```js
8288 * ig.append(`<div class="item">test1</div><div class="item">test2</div>`);
8289 * ig.append([`<div class="item">test1</div>`, `<div class="item">test2</div>`]);
8290 * ig.append([HTMLElement1, HTMLElement2]);
8291 * ```
8292 */
8293
8294
8295 __proto.append = function (items, groupKey) {
8296 return this.insert(-1, items, groupKey);
8297 };
8298 /**
8299 * Add items at the top(left) of the grid.
8300 * @ko 아이템들을 grid 위(왼쪽)에 추가한다.
8301 * @param - items to be added <ko>추가할 아이템들</ko>
8302 * @param - The group key to be configured in items. It is automatically generated by default. <ko>추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.</ko>
8303 * @return - An instance of a module itself<ko>모듈 자신의 인스턴스</ko>
8304 * @example
8305 * ```ts
8306 * ig.prepend(`<div class="item">test1</div><div class="item">test2</div>`);
8307 * ig.prepend([`<div class="item">test1</div>`, `<div class="item">test2</div>`]);
8308 * ig.prepend([HTMLElement1, HTMLElement2]);
8309 * ```
8310 */
8311
8312
8313 __proto.prepend = function (items, groupKey) {
8314 return this.insert(0, items, groupKey);
8315 };
8316 /**
8317 * Add items to a specific index.
8318 * @ko 아이템들을 특정 index에 추가한다.
8319 * @param - index to add <ko>추가하기 위한 index</ko>
8320 * @param - items to be added <ko>추가할 아이템들</ko>
8321 * @param - The group key to be configured in items. It is automatically generated by default. <ko>추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.</ko>
8322 * @return - An instance of a module itself<ko>모듈 자신의 인스턴스</ko>
8323 * @example
8324 * ```ts
8325 * ig.insert(2, `<div class="item">test1</div><div class="item">test2</div>`);
8326 * ig.insert(3, [`<div class="item">test1</div>`, `<div class="item">test2</div>`]);
8327 * ig.insert(4, [HTMLElement1, HTMLElement2]);
8328 * ```
8329 */
8330
8331
8332 __proto.insert = function (index, items, groupKey) {
8333 var nextItemInfos = this.groupManager.getGroupItems();
8334 var itemInfos = convertInsertedItems(items, groupKey);
8335
8336 if (index === -1) {
8337 nextItemInfos.push.apply(nextItemInfos, itemInfos);
8338 } else {
8339 nextItemInfos.splice.apply(nextItemInfos, __spreadArrays([index, 0], itemInfos));
8340 }
8341
8342 return this.syncItems(nextItemInfos);
8343 };
8344 /**
8345 * Add items based on group index.
8346 * @ko group의 index 기준으로 item들을 추가한다.
8347 * @param - group index to add <ko>추가하기 위한 group의 index</ko>
8348 * @param - items to be added <ko>추가할 아이템들</ko>
8349 * @param - The group key to be configured in items. It is automatically generated by default. <ko>추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.</ko>
8350 * @return - An instance of a module itself<ko>모듈 자신의 인스턴스</ko>
8351 * @example
8352 * ```ts
8353 * ig.insertByGroupIndex(2, `<div class="item">test1</div><div class="item">test2</div>`);
8354 * ig.insertByGroupIndex(3, [`<div class="item">test1</div>`, `<div class="item">test2</div>`]);
8355 * ig.insertByGroupIndex(4, [HTMLElement1, HTMLElement2]);
8356 * ```
8357 */
8358
8359
8360 __proto.insertByGroupIndex = function (groupIndex, items, groupKey) {
8361 var nextGroupInfos = this.groupManager.getGroups();
8362 var rightGroup = nextGroupInfos[groupIndex];
8363
8364 if (!rightGroup) {
8365 return this.append(items, groupKey);
8366 }
8367
8368 var nextItemInfos = this.groupManager.getGroupItems();
8369 var rightGroupKey = rightGroup.groupKey;
8370 var rightItemIndex = findIndex(nextItemInfos, function (item) {
8371 return item.groupKey === rightGroupKey;
8372 });
8373 return this.insert(rightItemIndex, items, groupKey);
8374 };
8375 /**
8376 * Returns the current state of a module such as location information. You can use the setStatus() method to restore the information returned through a call to this method.
8377 * @ko 아이템의 위치 정보 등 모듈의 현재 상태 정보를 반환한다. 이 메서드가 반환한 정보를 저장해 두었다가 setStatus() 메서드로 복원할 수 있다
8378 * @param - STATUS_TYPE.NOT_REMOVE = Get all information about items. STATUS_TYPE.REMOVE_INVISIBLE_ITEMS = Get information on visible items only. STATUS_TYPE.MINIMIZE_INVISIBLE_ITEMS = Compress invisible items. You can replace it with a placeholder. STATUS_TYPE.MINIMIZE_INVISIBLE_GROUPS = Compress invisible groups. <ko> STATUS_TYPE.NOT_REMOVE = 모든 아이템들의 정보를 가져온다. STATUS_TYPE.REMOVE_INVISIBLE_ITEMS = 보이는 아이템들의 정보만 가져온다. STATUS_TYPE.MINIMIZE_INVISIBLE_ITEMS = 안보이는 아이템들을 압축한다. placeholder로 대체가 가능하다. STATUS_TYPE.MINIMIZE_INVISIBLE_GROUPS = 안보이는 그룹을 압축한다.</ko>
8379 * @param - Whether to include items corresponding to placeholders. <ko>placeholder에 해당하는 아이템들을 포함할지 여부.</ko>
8380 */
8381
8382
8383 __proto.getStatus = function (type, includePlaceholders) {
8384 return {
8385 containerManager: this.containerManager.getStatus(),
8386 itemRenderer: this.itemRenderer.getStatus(),
8387 groupManager: this.groupManager.getGroupStatus(type, includePlaceholders),
8388 scrollManager: this.scrollManager.getStatus()
8389 };
8390 };
8391 /**
8392 * You can set placeholders to restore status or wait for items to be added.
8393 * @ko status 복구 또는 아이템 추가 대기를 위한 placeholder를 설정할 수 있다.
8394 * @param - The placeholder status. <ko>placeholder의 status</ko>
8395 */
8396
8397
8398 __proto.setPlaceholder = function (info) {
8399 this.groupManager.setPlaceholder(info);
8400 return this;
8401 };
8402 /**
8403 * You can set placeholders to restore status or wait for items to be added.
8404 * @ko status 복구 또는 아이템 추가 대기를 위한 placeholder를 설정할 수 있다.
8405 * @param - The placeholder status. <ko>placeholder의 status</ko>
8406 */
8407
8408
8409 __proto.setLoading = function (info) {
8410 this.groupManager.setLoading(info);
8411 return this;
8412 };
8413 /**
8414 * Add the placeholder at the end.
8415 * @ko placeholder들을 마지막에 추가한다.
8416 * @param - Items that correspond to placeholders. If it is a number, it duplicates the number of copies. <ko>placeholder에 해당하는 아이템들. 숫자면 갯수만큼 복제를 한다.</ko>
8417 * @param - The group key to be configured in items. It is automatically generated by default. <ko>추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.</ko>
8418 */
8419
8420
8421 __proto.appendPlaceholders = function (items, groupKey) {
8422 var _this = this;
8423
8424 var result = this.groupManager.appendPlaceholders(items, groupKey);
8425
8426 this._syncGroups(true);
8427
8428 return __assign(__assign({}, result), {
8429 remove: function () {
8430 _this.removePlaceholders({
8431 groupKey: result.group.groupKey
8432 });
8433 }
8434 });
8435 };
8436 /**
8437 * Add the placeholder at the start.
8438 * @ko placeholder들을 처음에 추가한다.
8439 * @param - Items that correspond to placeholders. If it is a number, it duplicates the number of copies. <ko>placeholder에 해당하는 아이템들. 숫자면 갯수만큼 복제를 한다.</ko>
8440 * @param - The group key to be configured in items. It is automatically generated by default. <ko>추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.</ko>
8441 */
8442
8443
8444 __proto.prependPlaceholders = function (items, groupKey) {
8445 var _this = this;
8446
8447 var result = this.groupManager.prependPlaceholders(items, groupKey);
8448
8449 this._syncGroups(true);
8450
8451 return __assign(__assign({}, result), {
8452 remove: function () {
8453 _this.removePlaceholders({
8454 groupKey: result.group.groupKey
8455 });
8456 }
8457 });
8458 };
8459 /**
8460 * Remove placeholders
8461 * @ko placeholder들을 삭제한다.
8462 * @param type - Remove the placeholders corresponding to the groupkey. When "start" or "end", remove all placeholders in that direction. <ko>groupkey에 해당하는 placeholder들을 삭제한다. "start" 또는 "end" 일 때 해당 방향의 모든 placeholder들을 삭제한다.</ko>
8463 */
8464
8465
8466 __proto.removePlaceholders = function (type) {
8467 this.groupManager.removePlaceholders(type);
8468
8469 this._syncGroups(true);
8470 };
8471 /**
8472 * Sets the status of the InfiniteGrid module with the information returned through a call to the getStatus() method.
8473 * @ko getStatus() 메서드가 저장한 정보로 InfiniteGrid 모듈의 상태를 설정한다.
8474 * @param - status object of the InfiniteGrid module. <ko>InfiniteGrid 모듈의 status 객체.</ko>
8475 * @param - Whether the first rendering has already been done. <ko>첫 렌더링이 이미 되어있는지 여부.</ko>
8476 */
8477
8478
8479 __proto.setStatus = function (status, useFirstRender) {
8480 this.itemRenderer.setStatus(status.itemRenderer);
8481 this.containerManager.setStatus(status.containerManager);
8482 this.scrollManager.setStatus(status.scrollManager);
8483 var groupManager = this.groupManager;
8484 var prevInlineSize = this.containerManager.getInlineSize();
8485 groupManager.setGroupStatus(status.groupManager);
8486
8487 this._syncInfinite();
8488
8489 this.infinite.setCursors(groupManager.getStartCursor(), groupManager.getEndCursor());
8490
8491 this._getRenderer().updateKey();
8492
8493 var state = {
8494 isResize: this.containerManager.getInlineSize() !== prevInlineSize,
8495 isRestore: true
8496 };
8497
8498 if (useFirstRender) {
8499 this._syncItems(state);
8500 } else {
8501 this._update(state);
8502 }
8503
8504 return this;
8505 };
8506 /**
8507 * Removes the group corresponding to index.
8508 * @ko index에 해당하는 그룹을 제거 한다.
8509 */
8510
8511
8512 __proto.removeGroupByIndex = function (index) {
8513 var nextGroups = this.getGroups();
8514 return this.removeGroupByKey(nextGroups[index].groupKey);
8515 };
8516 /**
8517 * Removes the group corresponding to key.
8518 * @ko key에 해당하는 그룹을 제거 한다.
8519 */
8520
8521
8522 __proto.removeGroupByKey = function (key) {
8523 var nextItemInfos = this.getItems();
8524 var firstIndex = findIndex(nextItemInfos, function (item) {
8525 return item.groupKey === key;
8526 });
8527 var lastIndex = findLastIndex(nextItemInfos, function (item) {
8528 return item.groupKey === key;
8529 });
8530
8531 if (firstIndex === -1) {
8532 return this;
8533 }
8534
8535 nextItemInfos.splice(firstIndex, lastIndex - firstIndex + 1);
8536 return this.syncItems(nextItemInfos);
8537 };
8538 /**
8539 * Removes the item corresponding to index.
8540 * @ko index에 해당하는 아이템을 제거 한다.
8541 */
8542
8543
8544 __proto.removeByIndex = function (index) {
8545 var nextItemInfos = this.getItems(true);
8546 nextItemInfos.splice(index, 1);
8547 return this.syncItems(nextItemInfos);
8548 };
8549 /**
8550 * Removes the item corresponding to key.
8551 * @ko key에 해당하는 아이템을 제거 한다.
8552 */
8553
8554
8555 __proto.removeByKey = function (key) {
8556 var nextItemInfos = this.getItems(true);
8557 var index = findIndex(nextItemInfos, function (item) {
8558 return item.key === key;
8559 });
8560 return this.removeByIndex(index);
8561 };
8562 /**
8563 * Update the size of the items and render them.
8564 * @ko 아이템들의 사이즈를 업데이트하고 렌더링을 한다.
8565 * @param - Items to be updated. <ko>업데이트할 아이템들.</ko>
8566 * @param - Options for rendering. <ko>렌더링을 하기 위한 옵션.</ko>
8567 */
8568
8569
8570 __proto.updateItems = function (items, options) {
8571 if (options === void 0) {
8572 options = {};
8573 }
8574
8575 this.groupManager.updateItems(items, options);
8576 return this;
8577 };
8578 /**
8579 * Return all items of InfiniteGrid.
8580 * @ko InfiniteGrid의 모든 아이템들을 반환한다.
8581 * @param - Whether to include items corresponding to placeholders. <ko>placeholder에 해당하는 아이템들을 포함할지 여부.</ko>
8582 */
8583
8584
8585 __proto.getItems = function (includePlaceholders) {
8586 return this.groupManager.getGroupItems(includePlaceholders);
8587 };
8588 /**
8589 * Return visible items of InfiniteGrid.
8590 * @ko InfiniteGrid의 보이는 아이템들을 반환한다.
8591 * @param - Whether to include items corresponding to placeholders. <ko>placeholder에 해당하는 아이템들을 포함할지 여부.</ko>
8592 */
8593
8594
8595 __proto.getVisibleItems = function (includePlaceholders) {
8596 return this.groupManager.getVisibleItems(includePlaceholders);
8597 };
8598 /**
8599 * Return rendering items of InfiniteGrid.
8600 * @ko InfiniteGrid의 렌더링 아이템들을 반환한다.
8601 */
8602
8603
8604 __proto.getRenderingItems = function () {
8605 return this.groupManager.getRenderingItems();
8606 };
8607 /**
8608 * Return all groups of InfiniteGrid.
8609 * @ko InfiniteGrid의 모든 그룹들을 반환한다.
8610 * @param - Whether to include groups corresponding to placeholders. <ko>placeholder에 해당하는 그룹들을 포함할지 여부.</ko>
8611 */
8612
8613
8614 __proto.getGroups = function (includePlaceholders) {
8615 return this.groupManager.getGroups(includePlaceholders);
8616 };
8617 /**
8618 * Return visible groups of InfiniteGrid.
8619 * @ko InfiniteGrid의 보이는 그룹들을 반환한다.
8620 * @param - Whether to include groups corresponding to placeholders. <ko>placeholder에 해당하는 그룹들을 포함할지 여부.</ko>
8621 */
8622
8623
8624 __proto.getVisibleGroups = function (includePlaceholders) {
8625 return this.groupManager.getVisibleGroups(includePlaceholders);
8626 };
8627 /**
8628 * Set to wait to request data.
8629 * @ko 데이터를 요청하기 위해 대기 상태로 설정한다.
8630 * @param direction - direction in which data will be added. <ko>데이터를 추가하기 위한 방향.</ko>
8631 */
8632
8633
8634 __proto.wait = function (direction) {
8635 if (direction === void 0) {
8636 direction = DIRECTION.END;
8637 }
8638
8639 this._waitType = direction;
8640
8641 this._checkStartLoading(direction);
8642 };
8643 /**
8644 * When the data request is complete, it is set to ready state.
8645 * @ko 데이터 요청이 끝났다면 준비 상태로 설정한다.
8646 */
8647
8648
8649 __proto.ready = function () {
8650 this._waitType = "";
8651 };
8652 /**
8653 * Returns whether it is set to wait to request data.
8654 * @ko 데이터를 요청하기 위해 대기 상태로 설정되어 있는지 여부를 반환한다.
8655 */
8656
8657
8658 __proto.isWait = function () {
8659 return !!this._waitType;
8660 };
8661 /**
8662 * Releases the instnace and events and returns the CSS of the container and elements.
8663 * @ko 인스턴스와 이벤트를 해제하고 컨테이너와 엘리먼트들의 CSS를 되돌린다.
8664 */
8665
8666
8667 __proto.destroy = function () {
8668 this.off();
8669
8670 this._getRenderer().destroy();
8671
8672 this.containerManager.destroy();
8673 this.groupManager.destroy();
8674 this.scrollManager.destroy();
8675 this.infinite.destroy();
8676 };
8677
8678 __proto._getRenderer = function () {
8679 return this.options.renderer;
8680 };
8681
8682 __proto._getRendererItems = function () {
8683 return this.getRenderingItems().map(function (item) {
8684 return {
8685 element: item.element,
8686 key: item.type + "_" + item.key,
8687 orgItem: item
8688 };
8689 });
8690 };
8691
8692 __proto._syncItems = function (state) {
8693 this._getRenderer().syncItems(this._getRendererItems(), state);
8694 };
8695
8696 __proto._render = function (state) {
8697 this._getRenderer().render(this._getRendererItems(), state);
8698 };
8699
8700 __proto._update = function (state) {
8701 if (state === void 0) {
8702 state = {};
8703 }
8704
8705 this._getRenderer().update(state);
8706 };
8707
8708 __proto._resizeScroll = function () {
8709 var scrollManager = this.scrollManager;
8710 scrollManager.resize();
8711 this.infinite.setSize(scrollManager.getContentSize());
8712 };
8713
8714 __proto._syncGroups = function (isUpdate) {
8715 var infinite = this.infinite;
8716 var scrollManager = this.scrollManager;
8717
8718 if (!scrollManager.getContentSize()) {
8719 this._resizeScroll();
8720 }
8721
8722 this._syncInfinite();
8723
8724 this.groupManager.setCursors(infinite.getStartCursor(), infinite.getEndCursor());
8725
8726 if (isUpdate) {
8727 this._update();
8728 } else {
8729 this._render();
8730 }
8731 };
8732
8733 __proto._syncInfinite = function () {
8734 this.infinite.syncItems(this.getGroups(true).map(function (_a) {
8735 var groupKey = _a.groupKey,
8736 grid = _a.grid,
8737 type = _a.type;
8738 var outlines = grid.getOutlines();
8739 return {
8740 key: groupKey,
8741 isVirtual: type === GROUP_TYPE.VIRTUAL,
8742 startOutline: outlines.start,
8743 endOutline: outlines.end
8744 };
8745 }));
8746 };
8747
8748 __proto._scroll = function () {
8749 this.infinite.scroll(this.scrollManager.getRelativeScrollPos());
8750 };
8751
8752 __proto._onRequestInsert = function (direction, eventType, e) {
8753 var _this = this;
8754
8755 if (this._waitType) {
8756 this._checkStartLoading(this._waitType);
8757
8758 return;
8759 }
8760
8761 this.trigger(new ComponentEvent$1(eventType, {
8762 groupKey: e.key,
8763 nextGroupKey: e.nextKey,
8764 nextGroupKeys: e.nextKeys || [],
8765 isVirtual: e.isVirtual,
8766 wait: function () {
8767 _this.wait(direction);
8768 },
8769 ready: function () {
8770 _this.ready();
8771 }
8772 }));
8773 };
8774
8775 __proto._renderItems = function (options, isTrusted) {
8776 if (options === void 0) {
8777 options = {};
8778 }
8779
8780 if (!isTrusted && options.useResize) {
8781 this.containerManager.resize();
8782 }
8783
8784 this._resizeScroll();
8785
8786 if (!this.getRenderingItems().length) {
8787 var children = toArray$1(this.getContainerElement().children);
8788
8789 if (children.length > 0) {
8790 // no items, but has children
8791 this.groupManager.syncItems(convertInsertedItems(children));
8792
8793 this._syncInfinite();
8794
8795 this.setCursors(0, 0, true);
8796
8797 this._getRenderer().updated();
8798 } else {
8799 this.infinite.scroll(0);
8800 }
8801
8802 return this;
8803 }
8804
8805 if (!this.getVisibleGroups(true).length) {
8806 this.setCursors(0, 0);
8807 } else {
8808 this.groupManager.renderItems(options);
8809 }
8810
8811 return this;
8812 };
8813
8814 __proto._checkStartLoading = function (direction) {
8815 var groupManager = this.groupManager;
8816 var infinite = this.infinite;
8817
8818 if (!groupManager.getLoadingType() && infinite.isLoading(direction) && groupManager.startLoading(direction) && groupManager.hasLoadingItem()) {
8819 this._update();
8820 }
8821 };
8822
8823 __proto._checkEndLoading = function () {
8824 var groupManager = this.groupManager;
8825 var loadingType = this.groupManager.getLoadingType();
8826
8827 if (loadingType && (!this._waitType || !this.infinite.isLoading(loadingType)) && groupManager.endLoading() && groupManager.hasLoadingItem()) {
8828 this._update();
8829 }
8830 };
8831
8832 var InfiniteGrid_1;
8833 InfiniteGrid.defaultOptions = __assign(__assign({}, DEFAULT_GRID_OPTIONS), {
8834 container: false,
8835 containerTag: "div",
8836 renderer: null,
8837 threshold: 100,
8838 useRecycle: true
8839 });
8840 InfiniteGrid.propertyTypes = INFINITEGRID_PROPERTY_TYPES;
8841 InfiniteGrid = InfiniteGrid_1 = __decorate([InfiniteGridGetterSetter], InfiniteGrid);
8842 return InfiniteGrid;
8843 }(Component);
8844
8845 /**
8846 * MasonryInfiniteGrid is a grid that stacks items with the same width as a stack of bricks. Adjust the width of all images to the same size, find the lowest height column, and insert a new item.
8847 * @ko MasonryInfiniteGrid는 벽돌을 쌓아 올린 모양처럼 동일한 너비를 가진 아이템을 쌓는 레이아웃이다. 모든 이미지의 너비를 동일한 크기로 조정하고, 가장 높이가 낮은 열을 찾아 새로운 이미지를 삽입한다. 따라서 배치된 아이템 사이에 빈 공간이 생기지는 않지만 배치된 레이아웃의 아래쪽은 울퉁불퉁해진다.
8848 * @param {HTMLElement | string} container - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
8849 * @param {MasonryInfiniteGridOptions} options - The option object of the MasonryInfiniteGrid module <ko>MasonryInfiniteGrid 모듈의 옵션 객체</ko>
8850 */
8851
8852 var MasonryInfiniteGrid =
8853 /*#__PURE__*/
8854 function (_super) {
8855 __extends(MasonryInfiniteGrid, _super);
8856
8857 function MasonryInfiniteGrid() {
8858 return _super !== null && _super.apply(this, arguments) || this;
8859 }
8860
8861 MasonryInfiniteGrid.propertyTypes = __assign(__assign({}, InfiniteGrid.propertyTypes), MasonryGrid.propertyTypes);
8862 MasonryInfiniteGrid.defaultOptions = __assign(__assign(__assign({}, InfiniteGrid.defaultOptions), MasonryGrid.defaultOptions), {
8863 gridConstructor: MasonryGrid
8864 });
8865 MasonryInfiniteGrid = __decorate([InfiniteGridGetterSetter], MasonryInfiniteGrid);
8866 return MasonryInfiniteGrid;
8867 }(InfiniteGrid);
8868
8869 /**
8870 * 'justified' is a printing term with the meaning that 'it fits in one row wide'. JustifiedInfiniteGrid is a grid that the item is filled up on the basis of a line given a size.
8871 * If 'data-grid-inline-offset' or 'data-grid-content-offset' are set for item element, the ratio is maintained except for the offset value.
8872 * If 'data-grid-maintained-target' is set for an element whose ratio is to be maintained, the item is rendered while maintaining the ratio of the element.
8873 * @ko 'justified'는 '1행의 너비에 맞게 꼭 들어찬'이라는 의미를 가진 인쇄 용어다. JustifiedInfiniteGrid는 용어의 의미대로 너비가 주어진 사이즈를 기준으로 아이템가 가득 차도록 배치하는 Grid다.
8874 * 아이템 엘리먼트에 'data-grid-inline-offset' 또는 'data-grid-content-offset'를 설정하면 offset 값을 제외하고 비율을 유지한다.
8875 * 비율을 유지하고 싶은 엘리먼트에 'data-grid-maintained-target'을 설정한다면 해당 엘리먼트의 비율을 유지하면서 아이템이 렌더링이 된다.
8876 * @param {HTMLElement | string} container - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
8877 * @param {JustifiedInfiniteGridOptions} options - The option object of the JustifiedInfiniteGrid module <ko>JustifiedInfiniteGrid 모듈의 옵션 객체</ko>
8878 */
8879
8880 var JustifiedInfiniteGrid =
8881 /*#__PURE__*/
8882 function (_super) {
8883 __extends(JustifiedInfiniteGrid, _super);
8884
8885 function JustifiedInfiniteGrid() {
8886 return _super !== null && _super.apply(this, arguments) || this;
8887 }
8888
8889 JustifiedInfiniteGrid.propertyTypes = __assign(__assign({}, InfiniteGrid.propertyTypes), JustifiedGrid.propertyTypes);
8890 JustifiedInfiniteGrid.defaultOptions = __assign(__assign(__assign({}, InfiniteGrid.defaultOptions), JustifiedGrid.defaultOptions), {
8891 gridConstructor: JustifiedGrid
8892 });
8893 JustifiedInfiniteGrid = __decorate([InfiniteGridGetterSetter], JustifiedInfiniteGrid);
8894 return JustifiedInfiniteGrid;
8895 }(InfiniteGrid);
8896
8897 /**
8898 * 'Frame' is a printing term with the meaning that 'it fits in one row wide'. FrameInfiniteGrid is a grid that the item is filled up on the basis of a line given a size.
8899 * @ko 'Frame'는 '1행의 너비에 맞게 꼭 들어찬'이라는 의미를 가진 인쇄 용어다. FrameInfiniteGrid는 용어의 의미대로 너비가 주어진 사이즈를 기준으로 아이템이 가득 차도록 배치하는 Grid다.
8900 * @param {HTMLElement | string} container - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
8901 * @param {FrameInfiniteGridOptions} options - The option object of the FrameInfiniteGrid module <ko>FrameGrid 모듈의 옵션 객체</ko>
8902 */
8903
8904 var FrameInfiniteGrid =
8905 /*#__PURE__*/
8906 function (_super) {
8907 __extends(FrameInfiniteGrid, _super);
8908
8909 function FrameInfiniteGrid() {
8910 return _super !== null && _super.apply(this, arguments) || this;
8911 }
8912
8913 FrameInfiniteGrid.propertyTypes = __assign(__assign({}, InfiniteGrid.propertyTypes), FrameGrid.propertyTypes);
8914 FrameInfiniteGrid.defaultOptions = __assign(__assign(__assign({}, InfiniteGrid.defaultOptions), FrameGrid.defaultOptions), {
8915 gridConstructor: FrameGrid
8916 });
8917 FrameInfiniteGrid = __decorate([InfiniteGridGetterSetter], FrameInfiniteGrid);
8918 return FrameInfiniteGrid;
8919 }(InfiniteGrid);
8920
8921 /**
8922 * The PackingInfiniteGrid is a grid that shows the important items bigger without sacrificing the weight of the items.
8923 * Rows and columns are separated so that items are dynamically placed within the horizontal and vertical space rather than arranged in an orderly fashion.
8924 * If `sizeWeight` is higher than `ratioWeight`, the size of items is preserved as much as possible.
8925 * Conversely, if `ratioWeight` is higher than `sizeWeight`, the ratio of items is preserved as much as possible.
8926 * @ko PackingInfiniteGrid는 아이템의 본래 크기에 따른 비중을 해치지 않으면서 중요한 카드는 더 크게 보여 주는 레이아웃이다.
8927 * 행과 열이 구분돼 아이템을 정돈되게 배치하는 대신 가로세로 일정 공간 내에서 동적으로 아이템을 배치한다.
8928 * `sizeWeight`가 `ratioWeight`보다 높으면 아이템들의 size가 최대한 보존이 된다.
8929 * 반대로 `ratioWeight`가 `sizeWeight`보다 높으면 아이템들의 비율이 최대한 보존이 된다.
8930 * @param {HTMLElement | string} container - A base element for a module <ko>모듈을 적용할 기준 엘리먼트</ko>
8931 * @param {PackingInfiniteGridOptions} options - The option object of the PackingInfiniteGrid module <ko>PackingInfiniteGrid 모듈의 옵션 객체</ko>
8932 */
8933
8934 var PackingInfiniteGrid =
8935 /*#__PURE__*/
8936 function (_super) {
8937 __extends(PackingInfiniteGrid, _super);
8938
8939 function PackingInfiniteGrid() {
8940 return _super !== null && _super.apply(this, arguments) || this;
8941 }
8942
8943 PackingInfiniteGrid.propertyTypes = __assign(__assign({}, InfiniteGrid.propertyTypes), PackingGrid.propertyTypes);
8944 PackingInfiniteGrid.defaultOptions = __assign(__assign(__assign({}, InfiniteGrid.defaultOptions), PackingGrid.defaultOptions), {
8945 gridConstructor: PackingGrid
8946 });
8947 PackingInfiniteGrid = __decorate([InfiniteGridGetterSetter], PackingInfiniteGrid);
8948 return PackingInfiniteGrid;
8949 }(InfiniteGrid);
8950
8951
8952
8953 var modules = {
8954 __proto__: null,
8955 'default': InfiniteGrid,
8956 withInfiniteGridMethods: withInfiniteGridMethods,
8957 getRenderingItems: getRenderingItems,
8958 mountRenderingItems: mountRenderingItems,
8959 InfiniteGridItem: InfiniteGridItem,
8960 MasonryInfiniteGrid: MasonryInfiniteGrid,
8961 JustifiedInfiniteGrid: JustifiedInfiniteGrid,
8962 FrameInfiniteGrid: FrameInfiniteGrid,
8963 PackingInfiniteGrid: PackingInfiniteGrid,
8964 Renderer: Renderer,
8965 IS_IOS: IS_IOS,
8966 CONTAINER_CLASS_NAME: CONTAINER_CLASS_NAME,
8967 IGNORE_PROPERITES_MAP: IGNORE_PROPERITES_MAP,
8968 INFINITEGRID_PROPERTY_TYPES: INFINITEGRID_PROPERTY_TYPES,
8969 DIRECTION: DIRECTION,
8970 INFINITEGRID_EVENTS: INFINITEGRID_EVENTS,
8971 ITEM_INFO_PROPERTIES: ITEM_INFO_PROPERTIES,
8972 INFINITEGRID_METHODS: INFINITEGRID_METHODS,
8973 get GROUP_TYPE () { return GROUP_TYPE; },
8974 get ITEM_TYPE () { return ITEM_TYPE; },
8975 get STATUS_TYPE () { return STATUS_TYPE; },
8976 INVISIBLE_POS: INVISIBLE_POS
8977 };
8978
8979 for (var name in modules) {
8980 InfiniteGrid[name] = modules[name];
8981 }
8982
8983 return InfiniteGrid;
8984
8985})));
8986//# sourceMappingURL=infinitegrid.js.map