UNPKG

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