{"version":3,"file":"infinitegrid.min.js","sources":["../src/consts.ts","../src/InfiniteGridItem.ts","../src/LoadingGrid.ts","../src/utils.ts","../src/index.umd.ts","../src/GroupManager.ts","../src/Infinite.ts","../src/Renderer/Renderer.ts","../src/Renderer/VanillaGridRenderer.ts","../src/Renderer/VanillaRenderer.ts","../src/ScrollManager.ts","../src/InfiniteGrid.ts","../src/grids/MasonryInfiniteGrid.ts","../src/grids/JustifiedInfiniteGrid.ts","../src/grids/FrameInfiniteGrid.ts","../src/grids/PackingInfiniteGrid.ts"],"sourcesContent":["import { GRID_PROPERTY_TYPES } from \"@egjs/grid\";\n\nconst ua = typeof window !== \"undefined\" ? window.navigator.userAgent : \"\";\n\nexport const IS_IOS = /iPhone|iPad/.test(ua);\nexport const CONTAINER_CLASS_NAME = \"infinitegrid-container\";\nexport const IGNORE_PROPERITES_MAP = {\n renderOnPropertyChange: true,\n useFit: true,\n autoResize: true,\n} as const;\n\n\nexport const INFINITEGRID_PROPERTY_TYPES = {\n ...GRID_PROPERTY_TYPES,\n};\n\nexport const DIRECTION = {\n START: \"start\",\n END: \"end\",\n NONE: \"\",\n} as const;\n\nexport const INFINITEGRID_EVENTS = {\n CHANGE_SCROLL: \"changeScroll\",\n REQUEST_APPEND: \"requestAppend\",\n REQUEST_PREPEND: \"requestPrepend\",\n RENDER_COMPLETE: \"renderComplete\",\n CONTENT_ERROR: \"contentError\",\n} as const;\n\n// type?: ITEM_TYPE;\n// groupKey?: string | number;\n// key?: string | number;\n// element?: HTMLElement | null;\n// html?: string;\n// data?: Record;\nexport const ITEM_INFO_PROPERTIES = {\n type: true,\n groupKey: true,\n key: true,\n element: true,\n html: true,\n data: true,\n};\n\n\nexport const INFINITEGRID_METHODS = [\n \"updateItems\",\n \"getItems\",\n \"getVisibleItems\",\n \"getGroups\",\n \"getVisibleGroups\",\n \"renderItems\",\n \"getContainerElement\",\n \"getScrollContainerElement\",\n \"getWrapperElement\",\n \"setStatus\",\n \"getStatus\",\n \"removePlaceholders\",\n \"prependPlaceholders\",\n \"appendPlaceholders\",\n \"getStartCursor\",\n \"getEndCursor\",\n \"setCursors\",\n] as const;\n\n\nexport enum GROUP_TYPE {\n NORMAL = 0,\n VIRTUAL = 1,\n LOADING = 2,\n}\n\nexport enum ITEM_TYPE {\n NORMAL = 0,\n VIRTUAL = 1,\n LOADING = 2,\n}\n\nexport enum STATUS_TYPE {\n // does not remove anything.\n NOT_REMOVE = 0,\n // Minimize information on invisible items\n MINIMIZE_INVISIBLE_ITEMS = 1,\n // Minimize information on invisible groups\n MINIMIZE_INVISIBLE_GROUPS = 2,\n // remove invisible groups\n REMOVE_INVISIBLE_GROUPS = 3,\n}\n\n\nexport const INVISIBLE_POS = -9999;\n","import { GridItem, GridItemStatus, MOUNT_STATE } from \"@egjs/grid\";\nimport { INVISIBLE_POS, ITEM_TYPE } from \"./consts\";\nimport { InfiniteGridItemInfo } from \"./types\";\n\nexport interface InfiniteGridItemStatus extends GridItemStatus {\n type?: ITEM_TYPE;\n groupKey?: string | number;\n key?: string | number;\n html?: string;\n}\n\nexport class InfiniteGridItem extends GridItem implements Required {\n public groupKey: string | number;\n public readonly html: string;\n constructor(horizontal: boolean, itemStatus?: Partial) {\n super(horizontal, {\n html: \"\",\n type: ITEM_TYPE.NORMAL,\n cssRect: { top: INVISIBLE_POS, left: INVISIBLE_POS },\n ...itemStatus,\n });\n\n if (this.type === ITEM_TYPE.VIRTUAL) {\n if (this.rect.width || this.rect.height) {\n this.mountState = MOUNT_STATE.UNMOUNTED;\n }\n const orgRect = this.orgRect;\n const rect = this.rect;\n const cssRect = this.cssRect;\n\n if (cssRect.width) {\n rect.width = cssRect.width;\n } else if (orgRect.width) {\n rect.width = orgRect.width;\n }\n if (cssRect.height) {\n rect.height = cssRect.height;\n } else if (orgRect.height) {\n rect.height = orgRect.height;\n }\n }\n }\n public getVirtualStatus(): Partial {\n return {\n type: ITEM_TYPE.VIRTUAL,\n groupKey: this.groupKey,\n key: this.key,\n orgRect: this.orgRect,\n rect: this.rect,\n cssRect: this.cssRect,\n attributes: this.attributes,\n };\n }\n public getMinimizedStatus(): Partial {\n const status: Partial = {\n ...super.getStatus(),\n type: ITEM_TYPE.NORMAL,\n groupKey: this.groupKey,\n };\n if (this.html) {\n status.html = this.html;\n }\n return status;\n }\n}\n\nexport interface InfiniteGridItem extends Required {}\n","import Grid, { GridItem, GridOutlines } from \"@egjs/grid\";\nimport { ITEM_TYPE } from \"./consts\";\nimport { InfiniteGridItem, InfiniteGridItemStatus } from \"./InfiniteGridItem\";\n\nexport const LOADING_GROUP_KEY = \"__INFINITEGRID__LOADING_GRID\";\nexport const LOADING_ITEM_KEY = \"__INFINITEGRID__LOADING_ITEM\";\n\nexport class LoadingGrid extends Grid {\n public type: \"start\" | \"end\" | \"\" = \"\";\n public getLoadingItem(): InfiniteGridItem | null {\n return this.items[0] as InfiniteGridItem || null;\n }\n public setLoadingItem(item: Partial | null) {\n if (item) {\n const loadingItem = this.getLoadingItem();\n\n if (!loadingItem) {\n this.items = [new InfiniteGridItem(this.options.horizontal, {\n ...item,\n type: ITEM_TYPE.LOADING,\n key: LOADING_ITEM_KEY,\n })];\n } else {\n for (const name in item) {\n loadingItem[name] = item[name];\n }\n }\n } else {\n this.items = [];\n }\n }\n public applyGrid(items: GridItem[], direction: \"start\" | \"end\", outline: number[]): GridOutlines {\n if (!items.length) {\n return {\n start: outline,\n end: outline,\n };\n }\n const nextOutline = outline.length ? [...outline] : [0];\n const item = items[0];\n const offset = item.contentSize + this.gap;\n\n item.cssInlinePos = this.getContainerInlineSize() / 2 - item.inlineSize / 2;\n\n if (direction === \"end\") {\n const maxPos = Math.max(...nextOutline);\n\n item.cssContentPos = maxPos;\n\n return {\n start: nextOutline,\n end: nextOutline.map((pos) => pos + offset),\n };\n } else {\n const minPos = Math.min(...nextOutline);\n\n item.cssContentPos = minPos - offset;\n\n return {\n start: nextOutline.map((pos) => pos - offset),\n end: nextOutline,\n };\n }\n }\n}\n","import Grid, { GRID_PROPERTY_TYPES, withMethods } from \"@egjs/grid\";\nimport { diff } from \"@egjs/list-differ\";\nimport { GROUP_TYPE, IGNORE_PROPERITES_MAP, INFINITEGRID_METHODS, ITEM_INFO_PROPERTIES, ITEM_TYPE } from \"./consts\";\nimport { GroupManagerStatus, InfiniteGridGroupStatus } from \"./GroupManager\";\nimport InfiniteGrid from \"./InfiniteGrid\";\nimport { InfiniteGridItem, InfiniteGridItemStatus } from \"./InfiniteGridItem\";\nimport {\n CategorizedGroup, InfiniteGridGroup, InfiniteGridInsertedItems,\n InfiniteGridItemInfo,\n RenderingOptions,\n} from \"./types\";\n\nexport function isWindow(el: Window | Element): el is Window {\n return el === window;\n}\n\nexport function isNumber(val: any): val is number {\n return typeof val === \"number\";\n}\n\nexport function isString(val: any): val is string {\n return typeof val === \"string\";\n}\nexport function isObject(val: any): val is object {\n return typeof val === \"object\";\n}\n\nexport function flat(arr: T[][]): T[] {\n return arr.reduce((prev, cur) => {\n return [...prev, ...cur];\n }, []);\n}\nexport function splitOptions(options: Record) {\n const {\n gridOptions,\n ...otherOptions\n } = options;\n\n return {\n ...splitGridOptions(gridOptions),\n ...otherOptions,\n };\n}\nexport function splitGridOptions(options: Record) {\n const nextOptions: Record = {};\n const gridOptions: Record = {};\n const defaultOptions = Grid.defaultOptions;\n\n for (const name in options) {\n const value = options[name];\n\n if (!(name in IGNORE_PROPERITES_MAP)) {\n gridOptions[name] = value;\n }\n\n if (name in defaultOptions) {\n nextOptions[name] = value;\n }\n }\n return {\n ...nextOptions,\n gridOptions,\n };\n}\n\nexport function categorize(items: Item[]) {\n const groups: Array> = [];\n const groupKeys: Record> = {};\n const registeredGroupKeys: Record = {};\n\n items.filter((item) => item.groupKey != null).forEach(({ groupKey }) => {\n registeredGroupKeys[groupKey!] = true;\n });\n\n let generatedGroupKey: number | string;\n let isContinuousGroupKey = false;\n\n items.forEach((item) => {\n if (item.groupKey != null) {\n isContinuousGroupKey = false;\n } else {\n if (!isContinuousGroupKey) {\n generatedGroupKey = makeKey(registeredGroupKeys);\n isContinuousGroupKey = true;\n registeredGroupKeys[generatedGroupKey] = true;\n }\n item.groupKey = generatedGroupKey;\n }\n\n const groupKey = item.groupKey;\n let group = groupKeys[groupKey];\n\n if (!group) {\n group = {\n groupKey,\n items: [],\n };\n groupKeys[groupKey] = group;\n groups.push(group);\n }\n\n group.items.push(item);\n });\n return groups;\n}\n\nexport function getNextCursors(\n prevKeys: Array,\n nextKeys: Array,\n prevStartCursor: number,\n prevEndCursor: number,\n) {\n const result = diff(prevKeys, nextKeys, (key) => key);\n let nextStartCursor = -1;\n let nextEndCursor = -1;\n\n // sync cursors\n result.maintained.forEach(([prevIndex, nextIndex]) => {\n if (prevStartCursor <= prevIndex && prevIndex <= prevEndCursor) {\n if (nextStartCursor === -1) {\n nextStartCursor = nextIndex;\n nextEndCursor = nextIndex;\n } else {\n nextStartCursor = Math.min(nextStartCursor, nextIndex);\n nextEndCursor = Math.max(nextEndCursor, nextIndex);\n }\n }\n });\n return {\n startCursor: nextStartCursor,\n endCursor: nextEndCursor,\n };\n}\nexport function splitVirtualGroups(\n groups: Group[],\n direction: \"start\" | \"end\",\n nextGroups: CategorizedGroup[],\n) {\n let virtualGroups: Group[] = [];\n\n if (direction === \"start\") {\n const index = findIndex(groups, (group) => group.type === GROUP_TYPE.NORMAL);\n\n if (index === -1) {\n return [];\n }\n virtualGroups = groups.slice(0, index);\n } else {\n const index = findLastIndex(groups, (group) => group.type === GROUP_TYPE.NORMAL);\n\n if (index === -1) {\n return [];\n }\n virtualGroups = groups.slice(index + 1);\n }\n\n const nextVirtualGroups = diff<{ groupKey: string | number }>(\n virtualGroups, nextGroups, ({ groupKey }) => groupKey,\n ).removed.map((index) => {\n return virtualGroups[index];\n }).reverse();\n\n return nextVirtualGroups;\n}\n\nexport function getFirstRenderingItems(\n nextItems: InfiniteGridItemStatus[],\n horizontal: boolean,\n) {\n const groups = categorize(nextItems);\n\n if (!groups[0]) {\n return [];\n }\n return groups[0].items.map((item) => {\n return new InfiniteGridItem(horizontal, {\n ...item,\n });\n });\n}\nexport function getRenderingItemsByStatus(\n groupManagerStatus: GroupManagerStatus,\n nextItems: InfiniteGridItemStatus[],\n usePlaceholder: boolean,\n horizontal: boolean,\n) {\n const prevGroups = groupManagerStatus.groups;\n const groups = categorize(nextItems);\n\n const startVirtualGroups = splitVirtualGroups(prevGroups, \"start\", groups);\n const endVirtualGroups = splitVirtualGroups(prevGroups, \"end\", groups);\n const nextGroups = [\n ...startVirtualGroups,\n ...groups,\n ...endVirtualGroups,\n ] as Array>;\n const {\n startCursor,\n endCursor,\n } = getNextCursors(\n prevGroups.map((group) => group.groupKey),\n nextGroups.map((group) => group.groupKey),\n groupManagerStatus.cursors[0],\n groupManagerStatus.cursors[1],\n );\n\n let nextVisibleItems = flat(nextGroups.slice(startCursor, endCursor + 1).map((group) => {\n return group.items.map((item) => {\n return new InfiniteGridItem(horizontal, { ...item });\n });\n }));\n\n if (!usePlaceholder) {\n nextVisibleItems = nextVisibleItems.filter((item) => {\n return item.type !== ITEM_TYPE.VIRTUAL;\n });\n }\n\n return nextVisibleItems;\n}\n\nexport function mountRenderingItems(items: InfiniteGridItemInfo[], options: RenderingOptions) {\n const {\n grid,\n usePlaceholder,\n useLoading,\n useFirstRender,\n status,\n } = options;\n if (!grid) {\n return;\n }\n if (usePlaceholder) {\n grid.setPlaceholder({});\n }\n if (useLoading) {\n grid.setLoading({});\n }\n if (status) {\n grid.setStatus(status, true);\n }\n\n grid.syncItems(items);\n\n if (useFirstRender && !status && grid.getGroups().length) {\n grid.setCursors(0, 0, true);\n }\n}\nexport function getRenderingItems(items: InfiniteGridItemInfo[], options: RenderingOptions) {\n const {\n status,\n usePlaceholder,\n useLoading,\n horizontal,\n useFirstRender,\n grid,\n } = options;\n let visibleItems: InfiniteGridItem[] = [];\n\n if (grid) {\n grid.setPlaceholder(usePlaceholder ? {} : null);\n grid.setLoading(useLoading ? {} : null);\n grid.syncItems(items);\n\n visibleItems = grid.getRenderingItems();\n } else if (status) {\n visibleItems = getRenderingItemsByStatus(status.groupManager, items, !!usePlaceholder, !!horizontal);\n } else if (useFirstRender) {\n visibleItems = getFirstRenderingItems(items, !!horizontal);\n }\n\n return visibleItems;\n}\n\n/* Class Decorator */\nexport function InfiniteGridGetterSetter(component: {\n prototype: InfiniteGrid,\n propertyTypes: typeof GRID_PROPERTY_TYPES,\n}) {\n const {\n prototype,\n propertyTypes,\n } = component;\n for (const name in propertyTypes) {\n const attributes: Record = {\n enumerable: true,\n configurable: true,\n get(this: InfiniteGrid) {\n const options = this.groupManager.options;\n if (name in options) {\n return options[name];\n } else {\n return options.gridOptions[name];\n }\n },\n set(this: InfiniteGrid, value: any) {\n const prevValue = this.groupManager[name];\n\n if (prevValue === value) {\n return;\n }\n this.groupManager.gridOptions = {\n [name]: value,\n };\n },\n };\n Object.defineProperty(prototype, name, attributes);\n }\n}\n\nexport function makeKey(registeredKeys: Record) {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const key = new Date().getTime() + Math.floor(Math.random() * 1000);\n\n if (!(key in registeredKeys)) {\n return key;\n }\n }\n}\n\nexport function convertHTMLtoElement(html: string) {\n const dummy = document.createElement(\"div\");\n\n dummy.innerHTML = html;\n return toArray(dummy.children);\n}\n\nexport function convertInsertedItems(\n items: InfiniteGridInsertedItems,\n groupKey?: string | number,\n): InfiniteGridItemInfo[] {\n let insertedItems: Array;\n\n if (isString(items)) {\n insertedItems = convertHTMLtoElement(items);\n } else {\n insertedItems = items;\n }\n return insertedItems.map((item) => {\n let element!: HTMLElement;\n let html = \"\";\n let key!: string | number;\n\n if (isString(item)) {\n html = item;\n } else if (\"parentNode\" in item) {\n element = item;\n html = item.outerHTML;\n } else {\n return { groupKey, ...item };\n }\n\n return {\n key,\n groupKey,\n html,\n element,\n };\n });\n}\nexport function toArray(nodes: HTMLCollection): HTMLElement[];\nexport function toArray(nodes: { length: number, [key: number]: T }): T[];\nexport function toArray(nodes: { length: number, [key: number]: T }): T[] {\n const array: T[] = [];\n\n if (nodes) {\n const length = nodes.length;\n\n for (let i = 0; i < length; i++) {\n array.push(nodes[i]);\n }\n }\n return array;\n}\n\n\nexport function findIndex(arr: T[], callback: (value: T, index: number) => boolean) {\n const length = arr.length;\n for (let i = 0; i < length; ++i) {\n if (callback(arr[i], i)) {\n return i;\n }\n }\n\n return -1;\n}\n\nexport function findLastIndex(arr: T[], callback: (value: T, index: number) => boolean) {\n const length = arr.length;\n for (let i = length - 1; i >= 0; --i) {\n if (callback(arr[i], i)) {\n return i;\n }\n }\n\n return -1;\n}\n\nexport function getItemInfo(info: InfiniteGridItemInfo) {\n const nextInfo: InfiniteGridItemInfo = {};\n\n for (const name in info) {\n if (name in ITEM_INFO_PROPERTIES) {\n nextInfo[name] = info[name];\n }\n }\n\n return nextInfo;\n}\n\nexport function setPlaceholder(item: InfiniteGridItem, info: InfiniteGridItemStatus) {\n for (const name in info) {\n const value = info[name];\n\n if (isObject(value)) {\n item[name] = {\n ...item[name],\n ...value,\n };\n } else {\n item[name] = info[name];\n }\n }\n}\n\nexport function isFlatOutline(start: number[], end: number[]) {\n return start.length === end.length && start.every((pos, i) => end[i] === pos);\n}\n\nexport function range(length: number): number[] {\n const arr: number[] = [];\n for (let i = 0; i < length; ++i) {\n arr.push(i);\n }\n return arr;\n}\n\nexport function flatGroups(groups: InfiniteGridGroup[]) {\n return flat(groups.map(({ grid }) => grid.getItems() as InfiniteGridItem[]));\n}\n\n\nexport function filterVirtuals(\n items: T[],\n includePlaceholders?: boolean\n): T[] {\n if (includePlaceholders) {\n return items;\n } else {\n return items.filter((item) => item.type !== ITEM_TYPE.VIRTUAL);\n }\n}\n\n/**\n * Decorator that makes the method of InfiniteGrid available in the framework.\n * @ko 프레임워크에서 InfiniteGrid의 메소드를 사용할 수 있게 하는 데코레이터.\n * @memberof InfiniteGrid\n * @private\n * @example\n * ```js\n * import { withInfiniteGridMethods } from \"@egjs/infinitegrid\";\n *\n * class Grid extends React.Component> {\n * @withInfiniteGridMethods\n * private grid: NativeGrid;\n * }\n * ```\n */\nexport const withInfiniteGridMethods = withMethods(INFINITEGRID_METHODS);\n\n","import InfiniteGrid, * as modules from \"./index\";\n\nfor (const name in modules) {\n (InfiniteGrid as any)[name] = (modules as any)[name];\n}\n\nexport default InfiniteGrid;\n","import Grid, {\n GetterSetter,\n GridFunction, GridOptions,\n GridOutlines, MOUNT_STATE, Properties, PROPERTY_TYPE,\n RenderOptions, UPDATE_STATE,\n} from \"@egjs/grid\";\nimport { GROUP_TYPE, ITEM_TYPE, STATUS_TYPE } from \"./consts\";\nimport { InfiniteGridItem, InfiniteGridItemStatus } from \"./InfiniteGridItem\";\nimport { LoadingGrid, LOADING_GROUP_KEY } from \"./LoadingGrid\";\nimport { CategorizedGroup, InfiniteGridGroup, InfiniteGridItemInfo } from \"./types\";\nimport {\n categorize, filterVirtuals, findIndex, findLastIndex,\n flat,\n flatGroups, getItemInfo, isNumber, makeKey,\n range,\n setPlaceholder,\n splitGridOptions, splitOptions, splitVirtualGroups,\n} from \"./utils\";\n\nexport interface InfiniteGridGroupStatus {\n type: GROUP_TYPE;\n groupKey: string | number;\n items: InfiniteGridItemStatus[];\n outlines: GridOutlines;\n}\n\nexport interface GroupManagerOptions extends GridOptions {\n gridConstructor: GridFunction | null;\n gridOptions: Record;\n}\n\nexport interface GroupManagerStatus {\n cursors: [number, number];\n orgCursors: [number, number];\n itemCursors: [number, number];\n startGroupKey: number | string;\n endGroupKey: number | string;\n groups: InfiniteGridGroupStatus[];\n outlines: GridOutlines;\n}\n\n@GetterSetter\nexport class GroupManager extends Grid {\n public static defaultOptions: Required = {\n ...Grid.defaultOptions,\n gridConstructor: null,\n gridOptions: {},\n };\n public static propertyTypes = {\n ...Grid.propertyTypes,\n gridConstructor: PROPERTY_TYPE.PROPERTY,\n gridOptions: PROPERTY_TYPE.PROPERTY,\n } as const;\n protected items: InfiniteGridItem[];\n protected groupItems: InfiniteGridItem[] = [];\n protected groups: InfiniteGridGroup[] = [];\n protected itemKeys: Record = {};\n protected groupKeys: Record = {};\n protected startCursor = 0;\n protected endCursor = 0;\n private _placeholder: Partial | null = null;\n private _loadingGrid!: LoadingGrid;\n\n constructor(container: HTMLElement, options: GroupManagerOptions) {\n super(container, splitOptions(options));\n\n this._loadingGrid = new LoadingGrid(container, {\n externalContainerManager: this.containerManager,\n useFit: false,\n autoResize: false,\n renderOnPropertyChange: false,\n gap: this.gap,\n });\n }\n public set gridOptions(options: Record) {\n const {\n gridOptions,\n ...otherOptions\n } = splitGridOptions(options);\n\n const shouldRender = this._checkShouldRender(options);\n\n this.options.gridOptions = {\n ...this.options.gridOptions,\n ...gridOptions,\n };\n this.groups.forEach(({ grid }) => {\n for (const name in options) {\n (grid as any)[name] = options[name];\n }\n });\n for (const name in otherOptions) {\n this[name] = otherOptions[name];\n }\n\n this._loadingGrid.gap = this.gap;\n if (shouldRender) {\n this.scheduleRender();\n }\n }\n\n public getItemByKey(key: string | number): InfiniteGridItem | null {\n return this.itemKeys[key] || null;\n }\n\n public getGroupItems(includePlaceholders?: boolean) {\n return filterVirtuals(this.groupItems, includePlaceholders);\n }\n public getVisibleItems(includePlaceholders?: boolean) {\n return filterVirtuals(this.items, includePlaceholders);\n }\n\n public getRenderingItems() {\n if (this.hasPlaceholder()) {\n return this.items;\n } else {\n return this.items.filter((item) => item.type !== ITEM_TYPE.VIRTUAL);\n }\n }\n\n public getGroups(includePlaceholders?: boolean): InfiniteGridGroup[] {\n return filterVirtuals(this.groups, includePlaceholders);\n }\n\n public hasVisibleVirtualGroups() {\n return this.getVisibleGroups(true).some((group) => group.type === GROUP_TYPE.VIRTUAL);\n }\n public hasPlaceholder() {\n return !!this._placeholder;\n }\n public hasLoadingItem() {\n return !!this._getLoadingItem();\n }\n\n public setPlaceholder(placeholder: Partial | null) {\n this._placeholder = placeholder;\n this._updatePlaceholder();\n }\n\n public getLoadingType() {\n return this._loadingGrid.type;\n }\n\n public startLoading(type: \"start\" | \"end\") {\n this._loadingGrid.type = type;\n this.items = this._getRenderingItems();\n\n return true;\n }\n\n public endLoading() {\n const prevType = this._loadingGrid.type;\n\n this._loadingGrid.type = \"\";\n this.items = this._getRenderingItems();\n return !!prevType;\n }\n\n public setLoading(loading: Partial | null) {\n this._loadingGrid.setLoadingItem(loading);\n this.items = this._getRenderingItems();\n }\n\n public getVisibleGroups(includePlaceholders?: boolean): InfiniteGridGroup[] {\n const groups = this.groups.slice(this.startCursor, this.endCursor + 1);\n\n return filterVirtuals(groups, includePlaceholders);\n }\n\n\n public applyGrid(items: InfiniteGridItem[], direction: \"end\" | \"start\", outline: number[]): GridOutlines {\n items.forEach((item) => {\n item.mountState = MOUNT_STATE.MOUNTED;\n });\n\n const renderingGroups = this.groups.slice();\n\n if (!renderingGroups.length) {\n return {\n start: [],\n end: [],\n };\n }\n\n\n const loadingGrid = this._loadingGrid;\n\n if (loadingGrid.getLoadingItem()) {\n if (loadingGrid.type === \"start\") {\n renderingGroups.unshift(this._getLoadingGroup());\n } else if (loadingGrid.type === \"end\") {\n renderingGroups.push(this._getLoadingGroup());\n }\n }\n\n const groups = renderingGroups.slice();\n\n let nextOutline = outline;\n\n if (direction === \"start\") {\n groups.reverse();\n }\n groups.forEach((group) => {\n const grid = group.grid;\n const gridItems = grid.getItems();\n const isVirtual = group.type === GROUP_TYPE.VIRTUAL && !gridItems[0];\n const appliedItems = gridItems.filter((item) => item.mountState !== MOUNT_STATE.UNCHECKED && item.rect.width);\n let gridOutlines: GridOutlines;\n\n if (isVirtual) {\n gridOutlines = this._applyVirtualGrid(grid, direction, nextOutline);\n } else if (appliedItems.length) {\n gridOutlines = grid.applyGrid(appliedItems, direction, nextOutline);\n } else {\n gridOutlines = {\n start: [...nextOutline],\n end: [...nextOutline],\n };\n }\n grid.setOutlines(gridOutlines);\n nextOutline = gridOutlines[direction];\n });\n\n return {\n start: renderingGroups[0].grid.getOutlines().start,\n end: renderingGroups[renderingGroups.length - 1].grid.getOutlines().end,\n };\n }\n\n public syncItems(nextItemInfos: InfiniteGridItemInfo[]) {\n const prevItemKeys = this.itemKeys;\n\n this.itemKeys = {};\n const nextItems = this._syncItemInfos(nextItemInfos.map((info) => getItemInfo(info)), prevItemKeys);\n const prevGroupKeys = this.groupKeys;\n let nextManagerGroups = categorize(nextItems);\n\n const startVirtualGroups = this._splitVirtualGroups(\"start\", nextManagerGroups);\n const endVirtualGroups = this._splitVirtualGroups(\"end\", nextManagerGroups);\n nextManagerGroups = [...startVirtualGroups, ...this._mergeVirtualGroups(nextManagerGroups), ...endVirtualGroups];\n\n const nextGroups: InfiniteGridGroup[] = nextManagerGroups.map(({ groupKey, items }) => {\n const isVirtual = !items[0] || items[0].type === ITEM_TYPE.VIRTUAL;\n const grid = prevGroupKeys[groupKey]?.grid ?? this._makeGrid();\n const gridItems = isVirtual ? items : items.filter(({ type }) => type === ITEM_TYPE.NORMAL);\n\n grid.setItems(gridItems);\n\n return {\n type: isVirtual ? GROUP_TYPE.VIRTUAL : GROUP_TYPE.NORMAL,\n groupKey,\n grid,\n items: gridItems,\n renderItems: items,\n };\n });\n\n this._registerGroups(nextGroups);\n }\n\n public renderItems(options: RenderOptions = {}) {\n if (options.useResize) {\n this.groupItems.forEach((item) => {\n item.updateState = UPDATE_STATE.NEED_UPDATE;\n });\n const loadingItem = this._getLoadingItem();\n\n if (loadingItem) {\n loadingItem.updateState = UPDATE_STATE.NEED_UPDATE;\n }\n }\n return super.renderItems(options);\n }\n\n public setCursors(startCursor: number, endCursor: number) {\n this.startCursor = startCursor;\n this.endCursor = endCursor;\n this.items = this._getRenderingItems();\n }\n\n public getStartCursor() {\n return this.startCursor;\n }\n\n public getEndCursor() {\n return this.endCursor;\n }\n\n public getGroupStatus(type?: STATUS_TYPE): GroupManagerStatus {\n const orgStartCursor = this.startCursor;\n const orgEndCursor = this.endCursor;\n const orgGroups = this.groups;\n\n let startCursor = orgStartCursor;\n let endCursor = orgEndCursor;\n\n const isMinimizeItems = type === STATUS_TYPE.MINIMIZE_INVISIBLE_ITEMS;\n const isMinimizeGroups = type === STATUS_TYPE.MINIMIZE_INVISIBLE_GROUPS;\n let groups: InfiniteGridGroup[];\n\n if (type === STATUS_TYPE.REMOVE_INVISIBLE_GROUPS) {\n groups = this.getVisibleGroups();\n endCursor -= startCursor;\n startCursor = 0;\n } else {\n groups = this.getGroups();\n }\n\n const groupStatus: InfiniteGridGroupStatus[] = groups.map(({ grid, groupKey }, i) => {\n const isOutsideCursor = i < startCursor || endCursor < i;\n const isVirtualItems = isMinimizeItems && isOutsideCursor;\n const isVirtualGroup = isMinimizeGroups && isOutsideCursor;\n const gridItems = grid.getItems() as InfiniteGridItem[];\n const items = isVirtualGroup\n ? []\n : gridItems.map((item) => isVirtualItems ? item.getVirtualStatus() : item.getMinimizedStatus());\n\n return {\n type: isVirtualGroup || isVirtualItems ? GROUP_TYPE.VIRTUAL : GROUP_TYPE.NORMAL,\n groupKey: groupKey,\n outlines: grid.getOutlines(),\n items,\n };\n });\n\n const startGroup = orgGroups[orgStartCursor];\n const endGroup = orgGroups[orgEndCursor];\n const totalItems = this.getGroupItems();\n\n const itemStartCursor = totalItems.indexOf(startGroup?.items[0]);\n const itemEndCursor = totalItems.indexOf(endGroup?.items.slice().reverse()[0]);\n\n return {\n cursors: [startCursor, endCursor],\n orgCursors: [orgStartCursor, orgEndCursor],\n itemCursors: [itemStartCursor, itemEndCursor],\n startGroupKey: startGroup?.groupKey,\n endGroupKey: endGroup?.groupKey,\n groups: groupStatus,\n outlines: this.outlines,\n };\n }\n\n public setGroupStatus(status: GroupManagerStatus) {\n this.itemKeys = {};\n this.groupItems = [];\n this.items = [];\n const prevGroupKeys = this.groupKeys;\n\n const nextGroups: InfiniteGridGroup[] = status.groups.map(({\n type,\n groupKey,\n items,\n outlines,\n }) => {\n const nextItems = this._syncItemInfos(items);\n const grid = prevGroupKeys[groupKey]?.grid ?? this._makeGrid();\n\n grid.setOutlines(outlines);\n grid.setItems(nextItems);\n\n return {\n type,\n groupKey,\n grid,\n items: nextItems,\n renderItems: nextItems,\n };\n });\n\n this.setOutlines(status.outlines);\n this._registerGroups(nextGroups);\n this._updatePlaceholder();\n this.setCursors(status.cursors[0], status.cursors[1]);\n }\n public appendPlaceholders(items: number | InfiniteGridItemStatus[], groupKey?: string | number) {\n return this.insertPlaceholders(\"end\", items, groupKey);\n }\n public prependPlaceholders(items: number | InfiniteGridItemStatus[], groupKey?: string | number) {\n return this.insertPlaceholders(\"start\", items, groupKey);\n }\n public removePlaceholders(type: \"start\" | \"end\" | { groupKey: string | number }) {\n const groups = this.groups;\n const length = groups.length;\n\n if (type === \"start\") {\n const index = findIndex(groups, (group) => group.type === GROUP_TYPE.NORMAL);\n\n groups.splice(0, index);\n\n } else if (type === \"end\") {\n const index = findLastIndex(groups, (group) => group.type === GROUP_TYPE.NORMAL);\n\n groups.splice(index + 1, length - index - 1);\n } else {\n const groupKey = type.groupKey;\n\n const index = findIndex(groups, (group) => group.groupKey === groupKey);\n\n if (index > -1) {\n groups.splice(index, 1);\n }\n }\n\n this.syncItems(flatGroups(this.getGroups()));\n }\n public insertPlaceholders(\n direction: \"start\" | \"end\",\n items: number | InfiniteGridItemStatus[],\n groupKey: string | number = makeKey(this.groupKeys),\n ) {\n\n let infos: InfiniteGridItemInfo[] = [];\n\n if (isNumber(items)) {\n infos = range(items).map(() => ({ type: ITEM_TYPE.VIRTUAL, groupKey }));\n } else if (Array.isArray(items)) {\n infos = items.map((status) => ({\n groupKey,\n ...status,\n type: ITEM_TYPE.VIRTUAL,\n }));\n }\n const grid = this._makeGrid();\n const nextItems = this._syncItemInfos(infos, this.itemKeys);\n\n this._updatePlaceholder(nextItems);\n grid.setItems(nextItems);\n\n const group = {\n type: GROUP_TYPE.VIRTUAL,\n groupKey,\n grid,\n items: nextItems,\n renderItems: nextItems,\n };\n if (direction === \"end\") {\n this.groups.push(group);\n this.groupItems.push(...nextItems);\n } else {\n this.groups.splice(0, 0, group);\n this.groupItems.splice(0, 0, ...nextItems);\n if (this.startCursor > -1) {\n ++this.startCursor;\n ++this.endCursor;\n }\n }\n\n\n return {\n group,\n items: nextItems,\n };\n }\n\n public shouldRerenderItems() {\n let isRerender = false;\n\n this.getVisibleGroups().forEach((group) => {\n const items = group.items;\n\n if (\n items.length === group.renderItems.length\n || items.every((item) => item.mountState === MOUNT_STATE.UNCHECKED)\n ) {\n return;\n }\n isRerender = true;\n group.renderItems = [...items];\n });\n\n return isRerender;\n }\n\n private _getGroupItems() {\n return flatGroups(this.getGroups(true));\n }\n\n private _getRenderingItems() {\n const items = flat(this.getVisibleGroups(true).map((item) => item.renderItems));\n\n const loadingGrid = this._loadingGrid;\n const loadingItem = loadingGrid.getLoadingItem();\n\n if (loadingItem) {\n if (loadingGrid.type === \"end\") {\n items.push(loadingItem);\n } else if (loadingGrid.type === \"start\") {\n items.unshift(loadingItem);\n }\n }\n\n return items;\n }\n\n private _checkShouldRender(options: Record) {\n const GridConstructor = this.options.gridConstructor!;\n const prevOptions = this.gridOptions;\n const propertyTypes = GridConstructor.propertyTypes;\n\n for (const name in prevOptions) {\n if (!(name in options) && propertyTypes[name] === PROPERTY_TYPE.RENDER_PROPERTY) {\n return true;\n }\n }\n for (const name in options) {\n if (prevOptions[name] !== options[name] && propertyTypes[name] === PROPERTY_TYPE.RENDER_PROPERTY) {\n return true;\n }\n }\n return false;\n }\n private _applyVirtualGrid(grid: Grid, direction: \"start\" | \"end\", outline: number[]) {\n const startOutline = outline.length ? [...outline] : [0];\n const prevOutlines = grid.getOutlines();\n const prevOutline = prevOutlines[direction === \"end\" ? \"start\" : \"end\"];\n\n if (\n prevOutline.length !== startOutline.length\n || prevOutline.some((value, i) => value !== startOutline[i])\n ) {\n return {\n start: [...startOutline],\n end: [...startOutline],\n };\n }\n return prevOutlines;\n }\n private _syncItemInfos(\n nextItemInfos: InfiniteGridItemStatus[],\n prevItemKeys: Record = {},\n ) {\n const horizontal = this.options.horizontal;\n const nextItemKeys = this.itemKeys;\n\n nextItemInfos.filter((info) => info.key != null).forEach((info) => {\n const key = info.key!;\n const prevItem = prevItemKeys[key];\n\n if (!prevItem) {\n nextItemKeys[key] = new InfiniteGridItem(horizontal, {\n ...info,\n });\n } else if (prevItem.type === ITEM_TYPE.VIRTUAL && info.type !== ITEM_TYPE.VIRTUAL) {\n nextItemKeys[key] = new InfiniteGridItem(horizontal, {\n orgRect: prevItem.orgRect,\n rect: prevItem.rect,\n ...info,\n });\n } else {\n if (info.data) {\n prevItem.data = info.data;\n }\n nextItemKeys[key] = prevItem;\n }\n });\n const nextItems = nextItemInfos.map((info) => {\n let key = info.key!;\n\n if (info.key == null) {\n key = makeKey(nextItemKeys);\n nextItemKeys[key] = new InfiniteGridItem(horizontal, {\n ...info,\n key,\n });\n }\n return nextItemKeys[key];\n });\n return nextItems;\n }\n private _registerGroups(groups: InfiniteGridGroup[]) {\n const nextGroupKeys: Record = {};\n\n groups.forEach((group) => {\n nextGroupKeys[group.groupKey] = group;\n });\n\n this.groups = groups;\n this.groupKeys = nextGroupKeys;\n this.groupItems = this._getGroupItems();\n }\n private _splitVirtualGroups(direction: \"start\" | \"end\", nextGroups: CategorizedGroup[]) {\n const groups = splitVirtualGroups(this.groups, direction, nextGroups);\n const itemKeys = this.itemKeys;\n\n groups.forEach(({ renderItems }) => {\n renderItems.forEach((item) => {\n itemKeys[item.key] = item;\n });\n });\n\n return groups;\n }\n private _mergeVirtualGroups(groups: Array>) {\n const itemKeys = this.itemKeys;\n const groupKeys = this.groupKeys;\n\n groups.forEach((group) => {\n const prevGroup = groupKeys[group.groupKey];\n\n if (!prevGroup) {\n return;\n }\n const items = group.items;\n\n\n if (items.every((item) => item.mountState === MOUNT_STATE.UNCHECKED)) {\n prevGroup.renderItems.forEach((item) => {\n if (item.type === ITEM_TYPE.VIRTUAL && !itemKeys[item.key]) {\n items.push(item);\n itemKeys[item.key] = item;\n }\n });\n }\n });\n return groups;\n }\n\n private _updatePlaceholder(items = this.groupItems) {\n const placeholder = this._placeholder;\n\n if (!placeholder) {\n return;\n }\n\n items.filter((item) => item.type === ITEM_TYPE.VIRTUAL).forEach((item) => {\n setPlaceholder(item, placeholder);\n });\n }\n private _makeGrid() {\n const GridConstructor = this.options.gridConstructor!;\n const gridOptions = this.gridOptions;\n const container = this.containerElement;\n\n return new GridConstructor(container, {\n ...gridOptions,\n useFit: false,\n autoResize: false,\n renderOnPropertyChange: false,\n externalContainerManager: this.containerManager,\n externalItemRenderer: this.itemRenderer,\n });\n }\n private _getLoadingGroup(): InfiniteGridGroup {\n const loadingGrid = this._loadingGrid;\n const items = loadingGrid.getItems() as InfiniteGridItem[];\n\n return {\n groupKey: LOADING_GROUP_KEY,\n type: GROUP_TYPE.NORMAL,\n grid: loadingGrid,\n items,\n renderItems: items,\n };\n }\n private _getLoadingItem() {\n return this._loadingGrid.getLoadingItem();\n }\n}\n\nexport interface GroupManager extends Properties {\n getItems(): InfiniteGridItem[];\n}\n","import Component from \"@egjs/component\";\nimport { diff } from \"@egjs/list-differ\";\nimport { DIRECTION } from \"./consts\";\nimport { findIndex, getNextCursors, isFlatOutline } from \"./utils\";\n\nexport interface OnInfiniteRequestAppend {\n key?: string | number | undefined;\n nextKey?: string | number | undefined;\n isVirtual: boolean;\n}\n\nexport interface OnInfiniteRequestPrepend {\n key?: string | number;\n nextKey?: string | number;\n isVirtual: boolean;\n}\n\nexport interface OnInfiniteChange {\n prevStartCursor: number;\n prevEndCursor: number;\n nextStartCursor: number;\n nextEndCursor: number;\n}\n\nexport interface InfiniteEvents {\n requestAppend: OnInfiniteRequestAppend;\n requestPrepend: OnInfiniteRequestPrepend;\n change: OnInfiniteChange;\n}\n\nexport interface InfiniteOptions {\n useRecycle?: boolean;\n threshold?: number;\n defaultDirection?: \"start\" | \"end\";\n}\n\nexport interface InfiniteItem {\n key: string | number;\n startOutline: number[];\n endOutline: number[];\n isVirtual?: boolean;\n}\n\nexport class Infinite extends Component {\n public options: Required;\n protected startCursor = -1;\n protected endCursor = -1;\n protected size = 0;\n protected items: InfiniteItem[] = [];\n protected itemKeys: Record = {};\n constructor(options: InfiniteOptions) {\n super();\n this.options = {\n threshold: 0,\n useRecycle: true,\n defaultDirection: \"end\",\n ...options,\n };\n }\n public scroll(scrollPos: number) {\n const prevStartCursor = this.startCursor;\n const prevEndCursor = this.endCursor;\n const items = this.items;\n const length = items.length;\n const size = this.size;\n const {\n defaultDirection,\n threshold,\n useRecycle,\n } = this.options;\n const isDirectionEnd = defaultDirection === \"end\";\n\n if (!length) {\n this.trigger(isDirectionEnd ? \"requestAppend\" : \"requestPrepend\", {\n key: undefined,\n isVirtual: false,\n });\n return;\n } else if (prevStartCursor === -1 || prevEndCursor === -1) {\n const nextCursor = isDirectionEnd ? 0 : length - 1;\n this.trigger(\"change\", {\n prevStartCursor,\n prevEndCursor,\n nextStartCursor: nextCursor,\n nextEndCursor: nextCursor,\n });\n return;\n }\n\n const endScrollPos = scrollPos + size;\n const startEdgePos = Math.max(...items[prevStartCursor].startOutline);\n const endEdgePos = Math.min(...items[prevEndCursor].endOutline);\n const visibles = items.map((item) => {\n const {\n startOutline,\n endOutline,\n } = item;\n\n if (!startOutline.length || !endOutline.length) {\n return false;\n }\n const startPos = Math.min(...startOutline);\n const endPos = Math.max(...endOutline);\n\n if (startPos - threshold <= endScrollPos && scrollPos <= endPos + threshold) {\n return true;\n }\n return false;\n });\n const hasStartItems = 0 < prevStartCursor;\n const hasEndItems = prevEndCursor < length - 1;\n const isStart = scrollPos <= startEdgePos + threshold;\n const isEnd = endScrollPos >= endEdgePos - threshold;\n let nextStartCursor = visibles.indexOf(true);\n let nextEndCursor = visibles.lastIndexOf(true);\n\n if (nextStartCursor === -1) {\n nextStartCursor = prevStartCursor;\n nextEndCursor = prevEndCursor;\n }\n\n if (!useRecycle) {\n nextStartCursor = Math.min(nextStartCursor, prevStartCursor);\n nextEndCursor = Math.max(nextEndCursor, prevEndCursor);\n }\n if (nextStartCursor === prevStartCursor && hasStartItems && isStart) {\n nextStartCursor -= 1;\n }\n if (nextEndCursor === prevEndCursor && hasEndItems && isEnd) {\n nextEndCursor += 1;\n }\n if (prevStartCursor !== nextStartCursor || prevEndCursor !== nextEndCursor) {\n this.trigger(\"change\", {\n prevStartCursor,\n prevEndCursor,\n nextStartCursor,\n nextEndCursor,\n });\n return;\n } else if (this._requestVirtualItems()) {\n return;\n } else if ((!isDirectionEnd || !isEnd) && isStart) {\n this.trigger(\"requestPrepend\", {\n key: items[prevStartCursor].key,\n isVirtual: false,\n });\n } else if ((isDirectionEnd || !isStart) && isEnd) {\n this.trigger(\"requestAppend\", {\n key: items[prevEndCursor].key,\n isVirtual: false,\n });\n }\n }\n\n /**\n * @private\n * Call the requestAppend or requestPrepend event to fill the virtual items.\n * @ko virtual item을 채우기 위해 requestAppend 또는 requestPrepend 이벤트를 호출합니다.\n * @return - Whether the event is called. 이벤트를 호출했는지 여부.\n */\n public _requestVirtualItems() {\n const isDirectionEnd = this.options.defaultDirection === \"end\";\n const items = this.items;\n const totalVisibleItems = this.getVisibleItems();\n const visibleItems = totalVisibleItems.filter((item) => !item.isVirtual);\n const totalVisibleLength = totalVisibleItems.length;\n const visibleLength = visibleItems.length;\n const startCursor = this.getStartCursor();\n const endCursor = this.getEndCursor();\n\n\n if (visibleLength === totalVisibleLength) {\n return false;\n } else if (visibleLength) {\n const startKey = visibleItems[0].key;\n const endKey = visibleItems[visibleLength - 1].key;\n const startIndex = findIndex(items, (item) => item.key === startKey) - 1;\n const endIndex = findIndex(items, (item) => item.key === endKey) + 1;\n\n const isEnd = endIndex <= endCursor;\n const isStart = startIndex >= startCursor;\n\n // Fill the placeholder with the original item.\n if ((isDirectionEnd || !isStart) && isEnd) {\n this.trigger(\"requestAppend\", {\n key: endKey,\n nextKey: items[endIndex].key,\n isVirtual: true,\n });\n return true;\n } else if ((!isDirectionEnd || !isEnd) && isStart) {\n this.trigger(\"requestPrepend\", {\n key: startKey,\n nextKey: items[startIndex].key,\n isVirtual: true,\n });\n return true;\n }\n } else if (totalVisibleLength) {\n const lastItem = totalVisibleItems[totalVisibleLength - 1];\n\n if (isDirectionEnd) {\n this.trigger(\"requestAppend\", {\n nextKey: totalVisibleItems[0].key,\n isVirtual: true,\n });\n } else {\n this.trigger(\"requestPrepend\", {\n nextKey: lastItem.key,\n isVirtual: true,\n });\n }\n return true;\n }\n return false;\n }\n public setCursors(startCursor: number, endCursor: number) {\n this.startCursor = startCursor;\n this.endCursor = endCursor;\n }\n public setSize(size: number) {\n this.size = size;\n }\n public getStartCursor() {\n return this.startCursor;\n }\n public getEndCursor() {\n return this.endCursor;\n }\n public isLoading(direction: \"start\" | \"end\") {\n const startCursor = this.startCursor;\n const endCursor = this.endCursor;\n const items = this.items;\n const firstItem = items[startCursor]!;\n const lastItem = items[endCursor]!;\n const length = items.length;\n\n if (\n direction === DIRECTION.END\n && endCursor > -1\n && endCursor < length - 1\n && !lastItem.isVirtual\n && !isFlatOutline(lastItem.startOutline, lastItem.endOutline)\n ) {\n return false;\n }\n if (\n direction === DIRECTION.START\n && startCursor > 0\n && !firstItem.isVirtual\n && !isFlatOutline(firstItem.startOutline, firstItem.endOutline)\n ) {\n return false;\n }\n return true;\n }\n public setItems(nextItems: InfiniteItem[]) {\n this.items = nextItems;\n\n const itemKeys: Record = {};\n\n nextItems.forEach((item) => {\n itemKeys[item.key] = item;\n });\n this.itemKeys = itemKeys;\n }\n public syncItems(nextItems: InfiniteItem[]) {\n const prevItems = this.items;\n const prevStartCursor = this.startCursor;\n const prevEndCursor = this.endCursor;\n const {\n startCursor: nextStartCursor,\n endCursor: nextEndCursor,\n } = getNextCursors(\n this.items.map((item) => item.key),\n nextItems.map((item) => item.key),\n prevStartCursor,\n prevEndCursor,\n );\n // sync items between cursors\n let isChange = nextEndCursor - nextStartCursor !== prevEndCursor - prevStartCursor\n || (prevStartCursor === -1 || nextStartCursor === -1);\n\n if (!isChange) {\n const prevVisibleItems = prevItems.slice(prevStartCursor, prevEndCursor + 1);\n const nextVisibleItems = nextItems.slice(nextStartCursor, nextEndCursor + 1);\n const visibleResult = diff(prevVisibleItems, nextVisibleItems, (item) => item.key);\n\n isChange = visibleResult.added.length > 0\n || visibleResult.removed.length > 0\n || visibleResult.changed.length > 0;\n }\n this.setItems(nextItems);\n this.setCursors(nextStartCursor, nextEndCursor);\n return isChange;\n }\n public getItems() {\n return this.items;\n }\n public getVisibleItems() {\n const startCursor = this.startCursor;\n const endCursor = this.endCursor;\n\n if (startCursor === -1) {\n return [];\n }\n return this.items.slice(startCursor, endCursor + 1);\n }\n public getItemByKey(key: string | number) {\n return this.itemKeys[key];\n }\n public getRenderedVisibleItems() {\n const items = this.getVisibleItems();\n const rendered = items.map(({ startOutline, endOutline }) => {\n const length = startOutline.length;\n\n if (length === 0 || length !== endOutline.length) {\n return false;\n }\n return startOutline.some((pos, i) => endOutline[i] !== pos);\n });\n const startIndex = rendered.indexOf(true);\n const endIndex = rendered.lastIndexOf(true);\n\n return endIndex === -1 ? [] : items.slice(startIndex, endIndex + 1);\n }\n public destroy() {\n this.off();\n this.startCursor = -1;\n this.endCursor = -1;\n this.items = [];\n this.size = 0;\n }\n}\n","import Component from \"@egjs/component\";\nimport { diff, DiffResult } from \"@egjs/list-differ\";\nimport { toArray } from \"../utils\";\n\nexport interface RendererItem {\n key: string | number;\n renderKey?: string;\n element?: Element | null;\n}\n\nexport interface OnRendererUpdated {\n items: T[];\n elements: Element[];\n isChanged: boolean;\n state: Record;\n diffResult: DiffResult;\n}\n\nexport interface OnRendererUpdate {\n state: Record;\n}\nexport interface RendererEvents {\n update: OnRendererUpdate;\n updated: OnRendererUpdated;\n requestUpdate: OnRendererUpdate;\n}\n\nexport class Renderer extends Component {\n protected items: Item[] = [];\n protected container: Element | null = null;\n protected rendererKey = 0;\n private _diffResult: DiffResult;\n private _updateTimer = 0;\n private _state: Record = {};\n\n public updateKey() {\n this.rendererKey = Date.now();\n }\n\n public getItems() {\n return this.items;\n }\n public setContainer(container: Element) {\n this.container = container;\n }\n public render(nextItems: Item[], state?: Record) {\n if (state) {\n this._state = state;\n }\n return this.syncItems(nextItems);\n }\n public update(state: Record = {}) {\n this._state = state;\n this.trigger(\"update\", {\n state,\n });\n\n clearTimeout(this._updateTimer);\n this._updateTimer = window.setTimeout(() => {\n this.trigger(\"requestUpdate\", {\n state,\n });\n });\n }\n public updated(nextElements: ArrayLike = this.container?.children ?? []) {\n const diffResult = this._diffResult;\n const isChanged = !!(diffResult.added.length || diffResult.removed.length || diffResult.changed.length);\n const state = this._state;\n\n this._state = {};\n\n const nextItems = diffResult.list;\n\n this.items = nextItems;\n nextItems.forEach((item, i) => {\n item.element = nextElements[i];\n });\n\n this.trigger(\"updated\", {\n items: nextItems,\n elements: toArray(nextElements),\n diffResult: this._diffResult,\n state,\n isChanged,\n });\n\n return isChanged;\n }\n public destroy() {\n this.off();\n }\n protected syncItems(items: Item[]) {\n const rendererKey = this.rendererKey;\n const prevItems = this.items;\n const nextItems = items.map((item) => ({\n ...item,\n renderKey: `${rendererKey}_${item.key}`,\n }));\n\n const result = diff(prevItems, nextItems, (item) => item.renderKey!);\n\n this._diffResult = result;\n\n return result;\n }\n}\n","import { InfiniteGridItem } from \"../InfiniteGridItem\";\nimport { convertHTMLtoElement } from \"../utils\";\nimport { RendererItem } from \"./Renderer\";\nimport { VanillaRenderer } from \"./VanillaRenderer\";\n\nexport interface GridRendererItem extends RendererItem {\n orgItem: InfiniteGridItem;\n}\n\nexport class VanillaGridRenderer extends VanillaRenderer {\n public syncItems(nextItems: GridRendererItem[]) {\n const result = super.syncItems(nextItems);\n const {\n added,\n list,\n } = result;\n added.forEach((index) => {\n const orgItem = nextItems[index].orgItem;\n\n if (orgItem.html && !orgItem.element) {\n orgItem.element = convertHTMLtoElement(orgItem.html)[0];\n }\n list[index].element = orgItem.element!;\n });\n\n return result;\n }\n}\n","import { Renderer, RendererItem } from \"./Renderer\";\n\nexport class VanillaRenderer extends Renderer {\n public render(nextItems: Item[], state?: Record) {\n const container = this.container!;\n const result = super.render(nextItems, state);\n const {\n prevList,\n removed,\n ordered,\n added,\n list,\n } = result;\n const diffList = [...prevList];\n\n\n removed.forEach((index) => {\n diffList.splice(index, 1);\n container.removeChild(prevList[index].element!);\n });\n ordered.forEach(([prevIndex, nextIndex]) => {\n const item = diffList.splice(prevIndex, 1)[0];\n\n diffList.splice(nextIndex, 0, item);\n container.insertBefore(item.element!, diffList[nextIndex + 1]?.element ?? null);\n });\n added.forEach((index) => {\n const item = list[index];\n\n diffList.splice(index, 0, item);\n container.insertBefore(item.element!, diffList[index + 1]?.element ?? null);\n });\n\n this.updated(container.children);\n return result;\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { CONTAINER_CLASS_NAME, IS_IOS } from \"./consts\";\nimport { OnChangeScroll } from \"./types\";\nimport { isWindow, toArray } from \"./utils\";\n\nexport interface ScrollManagerOptions {\n container?: HTMLElement | boolean | string;\n containerTag?: string;\n horizontal?: boolean;\n}\n\nexport interface ScrollManagerStatus {\n contentSize: number;\n scrollOffset: number;\n prevScrollPos: number;\n}\n\n\nexport interface ScrollManagerEvents {\n scroll: OnChangeScroll;\n}\n\nexport class ScrollManager extends Component {\n public options: Required;\n protected prevScrollPos: number | null = null;\n protected eventTarget: HTMLElement | Window;\n protected scrollOffset = 0;\n protected contentSize = 0;\n protected container: HTMLElement;\n protected scrollContainer: HTMLElement;\n private _orgCSSText: string;\n private _isScrollIssue = IS_IOS;\n private _isCreateElement: boolean;\n\n constructor(\n protected wrapper: HTMLElement,\n options: ScrollManagerOptions,\n ) {\n super();\n this.options = {\n container: false,\n containerTag: \"div\",\n horizontal: false,\n ...options,\n };\n\n this._init();\n }\n public getWrapper() {\n return this.wrapper;\n }\n public getContainer() {\n return this.container;\n }\n public getScrollContainer() {\n return this.scrollContainer;\n }\n public getScrollOffset() {\n return this.scrollOffset;\n }\n public getContentSize() {\n return this.contentSize;\n }\n public getRelativeScrollPos() {\n return (this.prevScrollPos || 0) - this.scrollOffset;\n }\n public getScrollPos() {\n return this.prevScrollPos;\n }\n public setScrollPos(pos: number) {\n this.prevScrollPos = pos;\n }\n public getOrgScrollPos() {\n const eventTarget = this.eventTarget;\n const horizontal = this.options.horizontal;\n\n const prop = `scroll${horizontal ? \"Left\" : \"Top\"}` as \"scrollLeft\" | \"scrollTop\";\n\n if (isWindow(eventTarget)) {\n return window[horizontal ? \"pageXOffset\" : \"pageYOffset\"]\n || document.documentElement[prop] || document.body[prop];\n } else {\n return eventTarget[prop];\n }\n }\n public setStatus(status: ScrollManagerStatus) {\n this.contentSize = status.contentSize;\n this.scrollOffset = status.scrollOffset;\n this.prevScrollPos = status.prevScrollPos;\n\n this.scrollTo(this.prevScrollPos);\n }\n public getStatus(): ScrollManagerStatus {\n return {\n contentSize: this.contentSize,\n scrollOffset: this.scrollOffset,\n prevScrollPos: this.prevScrollPos!,\n };\n }\n public scrollTo(pos: number) {\n const eventTarget = this.eventTarget;\n const horizontal = this.options.horizontal;\n const [x, y] = horizontal ? [pos, 0] : [0, pos];\n\n if (isWindow(eventTarget)) {\n eventTarget.scroll(x, y);\n } else {\n eventTarget.scrollLeft = x;\n eventTarget.scrollTop = y;\n }\n }\n public scrollBy(pos: number) {\n if (!pos) {\n return;\n }\n const eventTarget = this.eventTarget;\n const horizontal = this.options.horizontal;\n const [x, y] = horizontal ? [pos, 0] : [0, pos];\n\n\n this.prevScrollPos! += pos;\n\n if (isWindow(eventTarget)) {\n eventTarget.scrollBy(x, y);\n } else {\n eventTarget.scrollLeft += x;\n eventTarget.scrollTop += y;\n }\n }\n public resize() {\n const scrollContainer = this.scrollContainer;\n const horizontal = this.options.horizontal;\n const scrollContainerRect = scrollContainer === document.body\n ? { top: 0, left: 0 }\n : scrollContainer.getBoundingClientRect();\n const containerRect = this.container.getBoundingClientRect();\n\n this.scrollOffset = (this.prevScrollPos! || 0) + (horizontal\n ? containerRect.left - scrollContainerRect.left\n : containerRect.top - scrollContainerRect.top);\n this.contentSize = horizontal ? scrollContainer.offsetWidth : scrollContainer.offsetHeight;\n }\n public destroy() {\n const container = this.container;\n\n this.eventTarget.removeEventListener(\"scroll\", this._onCheck);\n\n if (this._isCreateElement) {\n const scrollContainer = this.scrollContainer;\n\n const fragment = document.createDocumentFragment();\n const childNodes = toArray(container.childNodes);\n\n scrollContainer.removeChild(container);\n childNodes.forEach((childNode) => {\n fragment.appendChild(childNode);\n });\n scrollContainer.appendChild(fragment);\n } else if (this.options.container) {\n container.style.cssText = this._orgCSSText;\n }\n }\n private _init() {\n const {\n container: containerOption,\n containerTag,\n horizontal,\n } = this.options;\n const wrapper = this.wrapper;\n let scrollContainer = wrapper;\n let container = wrapper;\n\n if (!containerOption) {\n scrollContainer = document.body;\n } else {\n if (containerOption instanceof HTMLElement) {\n // Container that already exists\n container = containerOption;\n } else if (containerOption === true) {\n // Create Container\n container = document.createElement(containerTag) as HTMLElement;\n\n container.style.position = \"relative\";\n container.className = CONTAINER_CLASS_NAME;\n const childNodes = toArray(scrollContainer.childNodes);\n\n childNodes.forEach((childNode) => {\n container.appendChild(childNode);\n });\n scrollContainer.appendChild(container);\n\n this._isCreateElement = true;\n } else {\n // Find Container by Selector\n container = scrollContainer.querySelector(containerOption) as HTMLElement;\n }\n const style = scrollContainer.style;\n\n [style.overflowX, style.overflowY] = horizontal ? [\"scroll\", \"hidden\"] : [\"hidden\", \"scroll\"];\n }\n const eventTarget = scrollContainer === document.body ? window : scrollContainer;\n\n eventTarget.addEventListener(\"scroll\", this._onCheck);\n this._orgCSSText = container.style.cssText;\n this.container = container;\n this.scrollContainer = scrollContainer;\n this.eventTarget = eventTarget;\n this.resize();\n this.setScrollPos(this.getOrgScrollPos());\n }\n private _onCheck = () => {\n const prevScrollPos = this.getScrollPos();\n const nextScrollPos = this.getOrgScrollPos();\n\n this.setScrollPos(nextScrollPos);\n\n if (prevScrollPos === null || (this._isScrollIssue && nextScrollPos === 0) || prevScrollPos === nextScrollPos) {\n nextScrollPos && (this._isScrollIssue = false);\n return;\n }\n this._isScrollIssue = false;\n this.trigger(new ComponentEvent(\"scroll\", {\n direction: prevScrollPos < nextScrollPos ? \"end\" : \"start\",\n scrollPos: nextScrollPos,\n relativeScrollPos: this.getRelativeScrollPos(),\n }));\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport {\n ContainerManager,\n DEFAULT_GRID_OPTIONS,\n Properties,\n RenderOptions,\n MOUNT_STATE,\n OnContentError,\n ItemRenderer,\n GridItem,\n} from \"@egjs/grid\";\nimport {\n DIRECTION,\n GROUP_TYPE,\n INFINITEGRID_EVENTS, INFINITEGRID_PROPERTY_TYPES,\n ITEM_TYPE, STATUS_TYPE,\n} from \"./consts\";\nimport { GroupManager } from \"./GroupManager\";\nimport {\n Infinite,\n OnInfiniteChange,\n OnInfiniteRequestAppend,\n OnInfiniteRequestPrepend,\n} from \"./Infinite\";\nimport { InfiniteGridItem, InfiniteGridItemStatus } from \"./InfiniteGridItem\";\nimport { OnRendererUpdated } from \"./Renderer/Renderer\";\nimport { GridRendererItem, VanillaGridRenderer } from \"./Renderer/VanillaGridRenderer\";\nimport { ScrollManager } from \"./ScrollManager\";\nimport {\n InfiniteGridEvents, InfiniteGridGroup,\n InfiniteGridInsertedItems, InfiniteGridItemInfo,\n InfiniteGridOptions,\n InfiniteGridStatus,\n InsertedPlaceholdersResult,\n OnPickedRenderComplete,\n OnRequestInsert,\n OnChangeScroll,\n} from \"./types\";\nimport {\n InfiniteGridGetterSetter, toArray, convertInsertedItems, findIndex,\n findLastIndex, isString,\n} from \"./utils\";\n\n\n/**\n * 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\n * @ko 콘텐츠가 있는 아이템을 레이아웃 타입에 따라 무한으로 배치하는 모듈. 다양한 크기의 아이템을 다양한 레이아웃으로 배치할 수 있다. 아이템의 개수가 계속 늘어나도 모듈이 처리하는 DOM의 개수를 일정하게 유지해 최적의 성능을 보장한다\n * @extends Component\n * @support {\"ie\": \"9+(with polyfill)\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"4.X+\"}\n * @example\n```html\n
    \n
  • \n
    test1
    \n
  • \n
  • \n
    test2
    \n
  • \n
  • \n
    test3
    \n
  • \n
  • \n
    test4
    \n
  • \n
  • \n
    test5
    \n
  • \n
  • \n
    test6
    \n
  • \n
\n\n```\n */\n@InfiniteGridGetterSetter\nclass InfiniteGrid extends Component {\n public static defaultOptions = {\n ...DEFAULT_GRID_OPTIONS,\n container: false,\n containerTag: \"div\",\n renderer: null,\n threshold: 100,\n useRecycle: true,\n } as Required;\n public static propertyTypes = INFINITEGRID_PROPERTY_TYPES;\n protected wrapperElement: HTMLElement;\n protected scrollManager: ScrollManager;\n protected itemRenderer: ItemRenderer;\n protected containerManager: ContainerManager;\n protected infinite: Infinite;\n protected groupManager: GroupManager;\n protected options: Required;\n private _waitType: \"\" | \"start\" | \"end\" = \"\";\n /**\n * @param - A base element for a module 모듈을 적용할 기준 엘리먼트\n * @param - The option object of the InfiniteGrid module eg.InfiniteGrid 모듈의 옵션 객체\n */\n constructor(wrapper: HTMLElement | string, options: Options) {\n super();\n this.options = {\n ...((this.constructor as typeof InfiniteGrid).defaultOptions as Required),\n renderer: new VanillaGridRenderer().on(\"requestUpdate\", () => this._render()),\n ...options,\n };\n\n const {\n gridConstructor,\n containerTag,\n container,\n renderer,\n threshold,\n useRecycle,\n ...gridOptions\n } = this.options;\n // options.container === false, wrapper = container, scrollContainer = document.body\n // options.container === true, wrapper = scrollContainer, container = wrapper's child\n // options.container === string,\n const {\n horizontal,\n attributePrefix,\n useTransform,\n percentage,\n isConstantSize,\n isEqualSize,\n } = gridOptions;\n const wrapperElement = isString(wrapper) ? document.querySelector(wrapper) as HTMLElement : wrapper;\n const scrollManager = new ScrollManager(wrapperElement, {\n container,\n containerTag,\n horizontal,\n }).on({\n scroll: this._onScroll,\n });\n const containerElement = scrollManager.getContainer();\n const containerManager = new ContainerManager(containerElement, {\n horizontal,\n }).on(\"resize\", this._onResize);\n const itemRenderer = new ItemRenderer({\n attributePrefix,\n horizontal,\n useTransform,\n percentage,\n isEqualSize,\n isConstantSize,\n });\n const infinite = new Infinite({\n useRecycle,\n threshold,\n }).on({\n \"change\": this._onChange,\n \"requestAppend\": this._onRequestAppend,\n \"requestPrepend\": this._onRequestPrepend,\n });\n\n infinite.setSize(scrollManager.getContentSize());\n const groupManager = new GroupManager(containerElement, {\n gridConstructor: gridConstructor!,\n externalItemRenderer: itemRenderer,\n externalContainerManager: containerManager,\n gridOptions,\n });\n\n groupManager.on({\n \"renderComplete\": this._onRenderComplete,\n \"contentError\": this._onContentError,\n });\n\n renderer!.setContainer(containerElement);\n renderer!.on(\"updated\", this._onRendererUpdated);\n\n this.itemRenderer = itemRenderer;\n this.groupManager = groupManager;\n this.wrapperElement = wrapperElement;\n this.scrollManager = scrollManager;\n this.containerManager = containerManager;\n this.infinite = infinite;\n\n this.containerManager.resize();\n }\n /**\n * Rearrange items to fit the grid and render them. When rearrange is complete, the `renderComplete` event is fired.\n * @ko grid에 맞게 아이템을 재배치하고 렌더링을 한다. 배치가 완료되면 `renderComplete` 이벤트가 발생한다.\n * @param - Options for rendering. 렌더링을 하기 위한 옵션.\n * @example\n * import { MasonryGrid } from \"@egjs/infinitegrid\";\n * const grid = new MasonryGrid();\n *\n * grid.on(\"renderComplete\", e => {\n * console.log(e);\n * });\n * grid.renderItems();\n */\n public renderItems(options: RenderOptions = {}) {\n if (options.useResize) {\n this.containerManager.resize();\n }\n this._resizeScroll();\n if (!this.getItems(true).length) {\n const children = toArray(this.getContainerElement().children);\n if (children.length > 0) {\n this.append(children);\n } else {\n this.infinite.scroll(0);\n return this;\n }\n }\n if (!this.getVisibleGroups(true).length) {\n this.setCursors(0, 0);\n } else {\n this.groupManager.renderItems(options);\n }\n return this;\n }\n /**\n * Returns the wrapper element specified by the user.\n * @ko 컨테이너 엘리먼트를 반환한다.\n */\n public getWrapperElement() {\n return this.scrollManager.getWrapper();\n }\n /**\n * Returns the container element corresponding to the scroll area.\n * @ko 스크롤 영역에 해당하는 컨테이너 엘리먼트를 반환한다.\n */\n public getScrollContainerElement() {\n return this.scrollManager.getScrollContainer();\n }\n /**\n * Returns the container element containing item elements.\n * @ko 아이템 엘리먼트들을 담긴 컨테이너 엘리먼트를 반환한다.\n */\n public getContainerElement() {\n return this.scrollManager.getContainer();\n }\n /**\n * When items change, it synchronizes and renders items.\n * @ko items가 바뀐 경우 동기화를 하고 렌더링을 한다.\n * @param - Options for rendering. 렌더링을 하기 위한 옵션.\n */\n public syncItems(items: InfiniteGridItemInfo[]): this {\n this.groupManager.syncItems(items);\n this._syncGroups();\n\n return this;\n }\n /**\n * Change the currently visible groups.\n * @ko 현재 보이는 그룹들을 바꾼다.\n * @param - first index of visible groups. 보이는 그룹의 첫번째 index.\n * @param - last index of visible groups. 보이는 그룹의 마지막 index.\n * @param - Whether the first rendering has already been done. 첫 렌더링이 이미 되어있는지 여부.\n */\n public setCursors(startCursor: number, endCursor: number, useFirstRender?: boolean): this {\n this.groupManager.setCursors(startCursor, endCursor);\n this.infinite.setCursors(startCursor, endCursor);\n\n if (useFirstRender) {\n this._render();\n } else {\n this._update();\n this._checkEndLoading();\n }\n return this;\n }\n /**\n * Returns the first index of visible groups.\n * @ko 보이는 그룹들의 첫번째 index를 반환한다.\n */\n public getStartCursor(): number {\n return this.infinite.getStartCursor();\n }\n /**\n * Returns the last index of visible groups.\n * @ko 보이는 그룹들의 마지막 index를 반환한다.\n */\n public getEndCursor(): number {\n return this.infinite.getEndCursor();\n }\n /**\n * Add items at the bottom(right) of the grid.\n * @ko 아이템들을 grid 아래(오른쪽)에 추가한다.\n * @param - items to be added 추가할 아이템들\n * @param - The group key to be configured in items. It is automatically generated by default.\n * 추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.\n * @return - An instance of a module itself모듈 자신의 인스턴스\n * @example\n * ig.append(\"<div class='item'>test1</div><div class='item'>test2</div>\");\n * ig.append([\"<div class='item'>test1</div>\", \"<div class='item'>test2</div>\"]);\n * ig.append([HTMLElement1, HTMLElement2]);\n */\n public append(items: InfiniteGridInsertedItems, groupKey?: string | number): this {\n return this.insert(-1, items, groupKey);\n }\n /**\n * Add items at the top(left) of the grid.\n * @ko 아이템들을 grid 위(왼쪽)에 추가한다.\n * @param - items to be added 추가할 아이템들\n * @param - The group key to be configured in items. It is automatically generated by default.\n * 추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.\n * @return - An instance of a module itself모듈 자신의 인스턴스\n * @example\n * ig.prepend(\"<div class='item'>test1</div><div class='item'>test2</div>\");\n * ig.prepend([\"<div class='item'>test1</div>\", \"<div class='item'>test2</div>\"]);\n * ig.prepend([HTMLElement1, HTMLElement2]);\n */\n public prepend(items: InfiniteGridInsertedItems, groupKey?: string | number): this {\n return this.insert(0, items, groupKey);\n }\n /**\n * Add items to a specific index.\n * @ko 아이템들을 특정 index에 추가한다.\n * @param - index to add 추가하기 위한 index\n * @param - items to be added 추가할 아이템들\n * @param - The group key to be configured in items. It is automatically generated by default.\n * 추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.\n * @return - An instance of a module itself모듈 자신의 인스턴스\n * @example\n * ig.insert(2, \"<div class='item'>test1</div><div class='item'>test2</div>\");\n * ig.insert(3, [\"<div class='item'>test1</div>\", \"<div class='item'>test2</div>\"]);\n * ig.insert(4, [HTMLElement1, HTMLElement2]);\n */\n public insert(index: number, items: InfiniteGridInsertedItems, groupKey?: string | number): this {\n const nextItemInfos: InfiniteGridItemInfo[] = this.groupManager.getGroupItems();\n const itemInfos = convertInsertedItems(items, groupKey);\n\n if (index === -1) {\n nextItemInfos.push(...itemInfos);\n } else {\n nextItemInfos.splice(index, 0, ...itemInfos);\n }\n return this.syncItems(nextItemInfos);\n }\n /**\n * 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.\n * @ko 아이템의 위치 정보 등 모듈의 현재 상태 정보를 반환한다. 이 메서드가 반환한 정보를 저장해 두었다가 setStatus() 메서드로 복원할 수 있다\n * @param - STATUS_TYPE.NOT_REMOVE = Get all information about items. STATUS_TYPE.REMOVE_INVISIBLE_ITEMS = Get information on visible items only.\n * STATUS_TYPE.MINIMIZE_INVISIBLE_ITEMS = Compress invisible items. You can replace it with a placeholder. STATUS_TYPE.MINIMIZE_INVISIBLE_GROUPS = Compress invisible groups.\n * STATUS_TYPE.NOT_REMOVE = 모든 아이템들의 정보를 가져온다. STATUS_TYPE.REMOVE_INVISIBLE_ITEMS = 보이는 아이템들의 정보만 가져온다.\n * STATUS_TYPE.MINIMIZE_INVISIBLE_ITEMS = 안보이는 아이템들을 압축한다. placeholder로 대체가 가능하다. STATUS_TYPE.MINIMIZE_INVISIBLE_GROUPS = 안보이는 그룹을 압축한다.\n */\n public getStatus(type?: STATUS_TYPE): InfiniteGridStatus {\n return {\n containerManager: this.containerManager.getStatus(),\n itemRenderer: this.itemRenderer.getStatus(),\n groupManager: this.groupManager.getGroupStatus(type),\n scrollManager: this.scrollManager.getStatus(),\n };\n }\n\n /**\n * You can set placeholders to restore status or wait for items to be added.\n * @ko status 복구 또는 아이템 추가 대기를 위한 placeholder를 설정할 수 있다.\n * @param - The placeholder status. placeholder의 status\n */\n public setPlaceholder(info: Partial | null): this {\n this.groupManager.setPlaceholder(info);\n return this;\n }\n /**\n * You can set placeholders to restore status or wait for items to be added.\n * @ko status 복구 또는 아이템 추가 대기를 위한 placeholder를 설정할 수 있다.\n * @param - The placeholder status. placeholder의 status\n */\n public setLoading(info: Partial | null): this {\n this.groupManager.setLoading(info);\n return this;\n }\n /**\n * Add the placeholder at the end.\n * @ko placeholder들을 마지막에 추가한다.\n * @param - Items that correspond to placeholders. If it is a number, it duplicates the number of copies. placeholder에 해당하는 아이템들. 숫자면 갯수만큼 복제를 한다.\n * @param - The group key to be configured in items. It is automatically generated by default.\n * 추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.\n */\n public appendPlaceholders(\n items: number | InfiniteGridItemStatus[],\n groupKey?: string | number,\n ): InsertedPlaceholdersResult {\n const result = this.groupManager.appendPlaceholders(items, groupKey);\n\n this._syncGroups(true);\n return {\n ...result,\n remove: () => {\n this.removePlaceholders({ groupKey: result.group.groupKey });\n },\n };\n }\n /**\n * Add the placeholder at the start.\n * @ko placeholder들을 처음에 추가한다.\n * @param - Items that correspond to placeholders. If it is a number, it duplicates the number of copies. placeholder에 해당하는 아이템들. 숫자면 갯수만큼 복제를 한다.\n * @param - The group key to be configured in items. It is automatically generated by default.\n * 추가할 아이템에 설정할 그룹 키. 생략하면 값이 자동으로 생성된다.\n */\n public prependPlaceholders(\n items: number | InfiniteGridItemStatus[],\n groupKey?: string | number,\n ): InsertedPlaceholdersResult {\n const result = this.groupManager.prependPlaceholders(items, groupKey);\n\n this._syncGroups(true);\n return {\n ...result,\n remove: () => {\n this.removePlaceholders({ groupKey: result.group.groupKey });\n },\n };\n }\n\n /**\n * Remove placeholders\n * @ko placeholder들을 삭제한다.\n * @param type - Remove the placeholders corresponding to the groupkey. When \"start\" or \"end\", remove all placeholders in that direction. groupkey에 해당하는 placeholder들을 삭제한다. \"start\" 또는 \"end\" 일 때 해당 방향의 모든 placeholder들을 삭제한다.\n */\n public removePlaceholders(type: \"start\" | \"end\" | { groupKey: string | number }) {\n this.groupManager.removePlaceholders(type);\n this._syncGroups(true);\n }\n\n /**\n * Sets the status of the InfiniteGrid module with the information returned through a call to the getStatus() method.\n * @ko getStatus() 메서드가 저장한 정보로 InfiniteGrid 모듈의 상태를 설정한다.\n * @param - status object of the InfiniteGrid module. InfiniteGrid 모듈의 status 객체.\n * @param - Whether the first rendering has already been done. 첫 렌더링이 이미 되어있는지 여부.\n */\n public setStatus(status: InfiniteGridStatus, useFirstRender?: boolean): this {\n this.itemRenderer.setStatus(status.itemRenderer);\n this.containerManager.setStatus(status.containerManager);\n this.scrollManager.setStatus(status.scrollManager);\n const groupManager = this.groupManager;\n const prevInlineSize = this.containerManager.getInlineSize();\n\n groupManager.setGroupStatus(status.groupManager);\n this._syncInfinite();\n this.infinite.setCursors(groupManager.getStartCursor(), groupManager.getEndCursor());\n\n this._getRenderer().updateKey();\n\n const state = {\n isReisze: this.containerManager.getInlineSize() !== prevInlineSize,\n isRestore: true,\n };\n\n if (useFirstRender) {\n this._render(state);\n } else {\n this._update(state);\n }\n return this;\n }\n /**\n * Removes the group corresponding to index.\n * @ko index에 해당하는 그룹을 제거 한다.\n */\n public removeGroupByIndex(index: number): this {\n const nextGroups = this.groupManager.getGroups();\n\n return this.removeGroupByKey(nextGroups[index].groupKey);\n }\n /**\n * Removes the group corresponding to key.\n * @ko key에 해당하는 그룹을 제거 한다.\n */\n public removeGroupByKey(key: number | string): this {\n const nextItemInfos = this.groupManager.getItems();\n\n const firstIndex = findIndex(nextItemInfos, (item) => item.groupKey === key);\n const lastIndex = findLastIndex(nextItemInfos, (item) => item.groupKey === key);\n\n if (firstIndex === -1) {\n return this;\n }\n nextItemInfos.splice(firstIndex, lastIndex - firstIndex + 1);\n return this.syncItems(nextItemInfos);\n }\n /**\n * Removes the item corresponding to index.\n * @ko index에 해당하는 아이템을 제거 한다.\n */\n public removeByIndex(index: number): this {\n const nextItemInfos = this.getItems(true);\n\n nextItemInfos.splice(index, 1);\n\n return this.syncItems(nextItemInfos);\n }\n /**\n * Removes the item corresponding to key.\n * @ko key에 해당하는 아이템을 제거 한다.\n */\n public removeByKey(key: string | number): this {\n const nextItemInfos = this.getItems(true);\n const index = findIndex(nextItemInfos, (item) => item.key === key);\n\n return this.removeByIndex(index);\n }\n /**\n * Update the size of the items and render them.\n * @ko 아이템들의 사이즈를 업데이트하고 렌더링을 한다.\n * @param - Items to be updated. 업데이트할 아이템들.\n * @param - Options for rendering. 렌더링을 하기 위한 옵션.\n */\n public updateItems(items?: InfiniteGridItem[], options: RenderOptions = {}) {\n this.groupManager.updateItems(items, options);\n return this;\n }\n /**\n * Return all items of InfiniteGrid.\n * @ko InfiniteGrid의 모든 아이템들을 반환한다.\n * @param - Whether to include items corresponding to placeholders. placeholder에 해당하는 아이템들을 포함할지 여부.\n */\n public getItems(includePlaceholders?: boolean): InfiniteGridItem[] {\n return this.groupManager.getGroupItems(includePlaceholders);\n }\n /**\n * Return visible items of InfiniteGrid.\n * @ko InfiniteGrid의 보이는 아이템들을 반환한다.\n * @param - Whether to include items corresponding to placeholders. placeholder에 해당하는 아이템들을 포함할지 여부.\n */\n public getVisibleItems(includePlaceholders?: boolean): InfiniteGridItem[] {\n return this.groupManager.getVisibleItems(includePlaceholders);\n }\n\n /**\n * Return rendering items of InfiniteGrid.\n * @ko InfiniteGrid의 렌더링 아이템들을 반환한다.\n */\n public getRenderingItems(): InfiniteGridItem[] {\n return this.groupManager.getRenderingItems();\n }\n /**\n * Return all groups of InfiniteGrid.\n * @ko InfiniteGrid의 모든 그룹들을 반환한다.\n * @param - Whether to include groups corresponding to placeholders. placeholder에 해당하는 그룹들을 포함할지 여부.\n */\n public getGroups(includePlaceholders?: boolean): InfiniteGridGroup[] {\n return this.groupManager.getGroups(includePlaceholders);\n }\n /**\n * Return visible groups of InfiniteGrid.\n * @ko InfiniteGrid의 보이는 그룹들을 반환한다.\n * @param - Whether to include groups corresponding to placeholders. placeholder에 해당하는 그룹들을 포함할지 여부.\n */\n public getVisibleGroups(includePlaceholders?: boolean): InfiniteGridGroup[] {\n return this.groupManager.getVisibleGroups(includePlaceholders);\n }\n /**\n * Set to wait to request data.\n * @ko 데이터를 요청하기 위해 대기 상태로 설정한다.\n * @param direction - direction in which data will be added. 데이터를 추가하기 위한 방향.\n */\n public wait(direction: \"start\" | \"end\" = DIRECTION.END) {\n this._waitType = direction;\n this._checkStartLoading(direction);\n }\n /**\n * When the data request is complete, it is set to ready state.\n * @ko 데이터 요청이 끝났다면 준비 상태로 설정한다.\n */\n public ready() {\n this._waitType = \"\";\n }\n /**\n * Returns whether it is set to wait to request data.\n * @ko 데이터를 요청하기 위해 대기 상태로 설정되어 있는지 여부를 반환한다.\n */\n public isWait() {\n return !!this._waitType;\n }\n /**\n * Releases the instnace and events and returns the CSS of the container and elements.\n * @ko 인스턴스와 이벤트를 해제하고 컨테이너와 엘리먼트들의 CSS를 되돌린다.\n */\n public destroy(): void {\n this.off();\n this.groupManager.destroy();\n this.scrollManager.destroy();\n this.infinite.destroy();\n }\n\n private _getRenderer() {\n return this.options.renderer!;\n }\n private _render(state?: Record): void {\n this._getRenderer().render(this.getRenderingItems().map((item) => {\n return {\n element: item.element,\n key: `${item.type}_${item.key}`,\n orgItem: item,\n };\n }), state);\n }\n private _update(state: Record = {}): void {\n this._getRenderer().update(state);\n }\n private _resizeScroll() {\n const scrollManager = this.scrollManager;\n\n scrollManager.resize();\n\n this.infinite.setSize(scrollManager.getContentSize());\n }\n private _syncGroups(isUpdate?: boolean) {\n const infinite = this.infinite;\n\n this._syncInfinite();\n this.groupManager.setCursors(infinite.getStartCursor(), infinite.getEndCursor());\n if (isUpdate) {\n this._update();\n } else {\n this._render();\n }\n }\n private _syncInfinite() {\n this.infinite.syncItems(this.getGroups(true).map(({ groupKey, grid, type }) => {\n const outlines = grid.getOutlines();\n\n return {\n key: groupKey,\n isVirtual: type === GROUP_TYPE.VIRTUAL,\n startOutline: outlines.start,\n endOutline: outlines.end,\n };\n }));\n }\n private _scroll() {\n this.infinite.scroll(this.scrollManager.getRelativeScrollPos());\n }\n private _onScroll = ({ direction, scrollPos, relativeScrollPos }: OnChangeScroll): void => {\n this._scroll();\n /**\n * This event is fired when scrolling.\n * @ko 스크롤하면 발생하는 이벤트이다.\n * @event InfiniteGrid#changeScroll\n * @param {InfiniteGrid.OnChangeScroll} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n */\n this.trigger(new ComponentEvent(INFINITEGRID_EVENTS.CHANGE_SCROLL, {\n direction,\n scrollPos,\n relativeScrollPos,\n }));\n }\n\n private _onChange = (e: OnInfiniteChange): void => {\n this.setCursors(e.nextStartCursor, e.nextEndCursor);\n }\n private _onRendererUpdated = (e: OnRendererUpdated): void => {\n if (!e.isChanged) {\n this._checkEndLoading();\n this._scroll();\n return;\n }\n const renderedItems = e.items;\n\n const {\n added,\n removed,\n prevList,\n list,\n } = e.diffResult;\n\n removed.forEach((index) => {\n const orgItem = prevList[index].orgItem;\n\n if (orgItem.mountState !== MOUNT_STATE.UNCHECKED) {\n orgItem.mountState = MOUNT_STATE.UNMOUNTED;\n }\n });\n\n renderedItems.forEach((item) => {\n // set grid element\n const gridItem = item.orgItem;\n\n gridItem.element = item.element as HTMLElement;\n });\n\n const horizontal = this.options.horizontal;\n const addedItems = added.map((index) => {\n const gridItem = list[index].orgItem;\n const element = gridItem.element!;\n\n if (gridItem.type === ITEM_TYPE.VIRTUAL) {\n const cssRect = { ...gridItem.cssRect };\n const rect = gridItem.rect;\n\n if (!cssRect.width && rect.width) {\n cssRect.width = rect.width;\n }\n if (!cssRect.height && rect.height) {\n cssRect.height = rect.height;\n }\n // virtual item\n return new GridItem(horizontal!, {\n element,\n cssRect,\n });\n }\n return gridItem;\n });\n\n const {\n isRestore,\n isResize,\n } = e.state;\n\n this.itemRenderer.renderItems(addedItems);\n\n if (isRestore) {\n this._onRenderComplete({\n mounted: added.map((index) => list[index].orgItem),\n updated: [],\n isResize: false,\n direction: this.defaultDirection,\n });\n if (isResize) {\n this.groupManager.renderItems();\n }\n } else {\n this.groupManager.renderItems();\n }\n }\n\n private _onResize = () => {\n this.renderItems({ useResize: true });\n }\n\n private _onRequestAppend = (e: OnRequestInsert): void => {\n /**\n * The event is fired when scrolling reaches the end or when data for a virtual group is required.\n * @ko 스크롤이 끝에 도달하거나 virtual 그룹에 대한 데이터가 필요한 경우 이벤트가 발생한다.\n * @event InfiniteGrid#requestAppend\n * @param {InfiniteGrid.OnRequestAppend} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n */\n this._onRequestInsert(DIRECTION.END, INFINITEGRID_EVENTS.REQUEST_APPEND, e);\n }\n\n private _onRequestPrepend = (e: OnInfiniteRequestPrepend): void => {\n /**\n * The event is fired when scrolling reaches the start or when data for a virtual group is required.\n * @ko 스크롤이 끝에 도달하거나 virtual 그룹에 대한 데이터가 필요한 경우 이벤트가 발생한다.\n * @event InfiniteGrid#requestPrepend\n * @param {InfiniteGrid.OnRequestPrepend} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n */\n this._onRequestInsert(DIRECTION.START, INFINITEGRID_EVENTS.REQUEST_PREPEND, e);\n }\n\n private _onRequestInsert(\n direction: \"start\" | \"end\",\n eventType: \"requestAppend\" | \"requestPrepend\",\n e: OnInfiniteRequestAppend | OnInfiniteRequestPrepend,\n ) {\n\n if (this._waitType) {\n this._checkStartLoading(this._waitType);\n return;\n }\n this.trigger(new ComponentEvent(eventType, {\n groupKey: e.key,\n nextGroupKey: e.nextKey,\n isVirtual: e.isVirtual,\n wait: () => {\n this.wait(direction);\n },\n ready: () => {\n this.ready();\n },\n }));\n }\n\n private _onContentError = ({ element, target, item, update }: OnContentError): void => {\n /**\n * The event is fired when scrolling reaches the start or when data for a virtual group is required.\n * @ko 스크롤이 끝에 도달하거나 virtual 그룹에 대한 데이터가 필요한 경우 이벤트가 발생한다.\n * @event InfiniteGrid#contentError\n * @param {InfiniteGrid.OnContentError} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n */\n this.trigger(new ComponentEvent(INFINITEGRID_EVENTS.CONTENT_ERROR, {\n element,\n target,\n item: item as InfiniteGridItem,\n update,\n remove: () => {\n this.removeByKey(item.key!);\n },\n }));\n }\n\n private _onRenderComplete = ({ isResize, mounted, updated, direction }: OnPickedRenderComplete): void => {\n const infinite = this.infinite;\n const prevRenderedGroups = infinite.getRenderedVisibleItems();\n const length = prevRenderedGroups.length;\n const isDirectionEnd = direction === DIRECTION.END;\n\n this._syncInfinite();\n\n if (length) {\n const prevStandardGroup = prevRenderedGroups[isDirectionEnd ? 0 : length - 1];\n const nextStandardGroup = infinite.getItemByKey(prevStandardGroup.key);\n const offset = isDirectionEnd\n ? Math.min(...nextStandardGroup.startOutline) - Math.min(...prevStandardGroup.startOutline)\n : Math.max(...nextStandardGroup.endOutline) - Math.max(...prevStandardGroup.endOutline);\n\n this.scrollManager.scrollBy(offset);\n }\n\n /**\n * This event is fired when the InfiniteGrid has completed rendering.\n * @ko InfiniteGrid가 렌더링이 완료됐을 때 이벤트가 발생한다.\n * @event InfiniteGrid#renderComplete\n * @param {InfiniteGrid.OnRenderComplete} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n */\n this.trigger(new ComponentEvent(INFINITEGRID_EVENTS.RENDER_COMPLETE, {\n isResize,\n direction,\n mounted: (mounted as InfiniteGridItem[]).filter((item) => item.type !== ITEM_TYPE.LOADING),\n updated: (updated as InfiniteGridItem[]).filter((item) => item.type !== ITEM_TYPE.LOADING),\n startCursor: this.getStartCursor(),\n endCursor: this.getEndCursor(),\n items: this.getVisibleItems(true),\n groups: this.getVisibleGroups(true),\n }));\n\n if (this.groupManager.shouldRerenderItems()) {\n this._update();\n } else {\n this._checkEndLoading();\n this._scroll();\n }\n }\n private _checkStartLoading(direction: \"start\" | \"end\") {\n const groupManager = this.groupManager;\n const infinite = this.infinite;\n\n if (\n !groupManager.getLoadingType()\n && infinite.isLoading(direction)\n && groupManager.startLoading(direction)\n && groupManager.hasLoadingItem()\n ) {\n this._update();\n }\n }\n private _checkEndLoading() {\n const groupManager = this.groupManager;\n const loadingType = this.groupManager.getLoadingType();\n\n if (\n loadingType\n && (!this._waitType || !this.infinite.isLoading(loadingType))\n && groupManager.endLoading()\n && groupManager.hasLoadingItem()\n ) {\n this._update();\n }\n }\n}\n\ninterface InfiniteGrid extends Properties { }\n\nexport default InfiniteGrid;\n","import { MasonryGrid, MasonryGridOptions } from \"@egjs/grid\";\nimport InfiniteGrid from \"../InfiniteGrid\";\nimport { InfiniteGridOptions } from \"../types\";\nimport { InfiniteGridGetterSetter } from \"../utils\";\n\n/**\n * @typedef\n * @memberof InfiniteGrid\n * @extends InfiniteGrid.InfiniteGridOptions\n * @extends Grid.MasonryGridOptions\n */\nexport interface MasonryInfiniteGridOptions extends MasonryGridOptions, InfiniteGridOptions {\n}\n\n/**\n * 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.\n *\n * @ko MasonryInfiniteGrid는 벽돌을 쌓아 올린 모양처럼 동일한 너비를 가진 아이템을 쌓는 레이아웃이다. 모든 이미지의 너비를 동일한 크기로 조정하고, 가장 높이가 낮은 열을 찾아 새로운 이미지를 삽입한다. 따라서 배치된 아이템 사이에 빈 공간이 생기지는 않지만 배치된 레이아웃의 아래쪽은 울퉁불퉁해진다.\n * @memberof InfiniteGrid\n * @param {HTMLElement | string} container - A base element for a module 모듈을 적용할 기준 엘리먼트\n * @param {InfiniteGrid.MasonryInfiniteGrid.MasonryInfiniteGridOptions} options - The option object of the MasonryInfiniteGrid module MasonryInfiniteGrid 모듈의 옵션 객체\n */\n@InfiniteGridGetterSetter\nexport class MasonryInfiniteGrid extends InfiniteGrid {\n public static propertyTypes = {\n ...InfiniteGrid.propertyTypes,\n ...MasonryGrid.propertyTypes,\n };\n public static defaultOptions: Required = {\n ...InfiniteGrid.defaultOptions,\n ...MasonryGrid.defaultOptions,\n gridConstructor: MasonryGrid,\n } as const;\n}\n","import { JustifiedGrid, JustifiedGridOptions } from \"@egjs/grid\";\nimport InfiniteGrid from \"../InfiniteGrid\";\nimport { InfiniteGridOptions } from \"../types\";\nimport { InfiniteGridGetterSetter } from \"../utils\";\n\n/**\n * @typedef\n * @memberof InfiniteGrid\n * @extends InfiniteGrid.InfiniteGridOptions\n * @extends Grid.JustifiedGridOptions\n */\nexport interface JustifiedInfiniteGridOptions extends JustifiedGridOptions, InfiniteGridOptions {\n}\n\n/**\n * '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.\n * If 'data-grid-inline-offset' or 'data-grid-content-offset' are set for item element, the ratio is maintained except for the offset value.\n * 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.\n * @ko 'justified'는 '1행의 너비에 맞게 꼭 들어찬'이라는 의미를 가진 인쇄 용어다. JustifiedInfiniteGrid는 용어의 의미대로 너비가 주어진 사이즈를 기준으로 아이템가 가득 차도록 배치하는 Grid다.\n * 아이템 엘리먼트에 'data-grid-inline-offset' 또는 'data-grid-content-offset'를 설정하면 offset 값을 제외하고 비율을 유지한다.\n * 비율을 유지하고 싶은 엘리먼트에 'data-grid-maintained-target'을 설정한다면 해당 엘리먼트의 비율을 유지하면서 아이템이 렌더링이 된다.\n * @memberof InfiniteGrid\n * @param {HTMLElement | string} container - A base element for a module 모듈을 적용할 기준 엘리먼트\n * @param {JustifiedInfiniteGrid.JustifiedInfiniteGridOptions} options - The option object of the JustifiedInfiniteGrid module JustifiedInfiniteGrid 모듈의 옵션 객체\n */\n@InfiniteGridGetterSetter\nexport class JustifiedInfiniteGrid extends InfiniteGrid {\n public static propertyTypes = {\n ...InfiniteGrid.propertyTypes,\n ...JustifiedGrid.propertyTypes,\n };\n public static defaultOptions: Required = {\n ...InfiniteGrid.defaultOptions,\n ...JustifiedGrid.defaultOptions,\n gridConstructor: JustifiedGrid,\n } as const;\n}\n","import { FrameGrid, FrameGridOptions } from \"@egjs/grid\";\nimport InfiniteGrid from \"../InfiniteGrid\";\nimport { InfiniteGridOptions } from \"../types\";\nimport { InfiniteGridGetterSetter } from \"../utils\";\n\n/**\n * @typedef\n * @memberof InfiniteGrid\n * @extends InfiniteGrid.InfiniteGridOptions\n * @extends Grid.FrameGridOptions\n */\nexport interface FrameInfiniteGridOptions extends FrameGridOptions, InfiniteGridOptions {\n}\n\n/**\n * '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.\n * @ko 'Frame'는 '1행의 너비에 맞게 꼭 들어찬'이라는 의미를 가진 인쇄 용어다. FrameInfiniteGrid는 용어의 의미대로 너비가 주어진 사이즈를 기준으로 아이템이 가득 차도록 배치하는 Grid다.\n * @memberof InfiniteGrid\n * @param {HTMLElement | string} container - A base element for a module 모듈을 적용할 기준 엘리먼트\n * @param {InfiniteGrid.FrameInfiniteGrid.FrameInfiniteGridOptions} options - The option object of the FrameInfiniteGrid module FrameGrid 모듈의 옵션 객체\n */\n@InfiniteGridGetterSetter\nexport class FrameInfiniteGrid extends InfiniteGrid {\n public static propertyTypes = {\n ...InfiniteGrid.propertyTypes,\n ...FrameGrid.propertyTypes,\n };\n public static defaultOptions: Required = {\n ...InfiniteGrid.defaultOptions,\n ...FrameGrid.defaultOptions,\n gridConstructor: FrameGrid,\n } as const;\n}\n","import { PackingGrid, PackingGridOptions } from \"@egjs/grid\";\nimport InfiniteGrid from \"../InfiniteGrid\";\nimport { InfiniteGridOptions } from \"../types\";\nimport { InfiniteGridGetterSetter } from \"../utils\";\n\n/**\n * @typedef\n * @memberof InfiniteGrid\n * @extends InfiniteGrid.InfiniteGridOptions\n * @extends Grid.PackingGridOptions\n */\nexport interface PackingInfiniteGridOptions extends PackingGridOptions, InfiniteGridOptions {\n}\n\n/**\n * The PackingInfiniteGrid is a grid that shows the important items bigger without sacrificing the weight of the items.\n * Rows and columns are separated so that items are dynamically placed within the horizontal and vertical space rather than arranged in an orderly fashion.\n * If `sizeWeight` is higher than `ratioWeight`, the size of items is preserved as much as possible.\n * Conversely, if `ratioWeight` is higher than `sizeWeight`, the ratio of items is preserved as much as possible.\n * @ko PackingInfiniteGrid는 아이템의 본래 크기에 따른 비중을 해치지 않으면서 중요한 카드는 더 크게 보여 주는 레이아웃이다.\n * 행과 열이 구분돼 아이템을 정돈되게 배치하는 대신 가로세로 일정 공간 내에서 동적으로 아이템을 배치한다.\n * `sizeWeight`가 `ratioWeight`보다 높으면 아이템들의 size가 최대한 보존이 된다.\n * 반대로 `ratioWeight`가 `sizeWeight`보다 높으면 아이템들의 비율이 최대한 보존이 된다.\n * @memberof Grid\n * @param {HTMLElement | string} container - A base element for a module 모듈을 적용할 기준 엘리먼트\n * @param {Grid.PackingInfiniteGrid.PackingInfiniteGridOptions} options - The option object of the PackingInfiniteGrid module PackingInfiniteGrid 모듈의 옵션 객체\n */\n@InfiniteGridGetterSetter\nexport class PackingInfiniteGrid extends InfiniteGrid {\n public static propertyTypes = {\n ...InfiniteGrid.propertyTypes,\n ...PackingGrid.propertyTypes,\n };\n public static defaultOptions: Required = {\n ...InfiniteGrid.defaultOptions,\n ...PackingGrid.defaultOptions,\n gridConstructor: PackingGrid,\n };\n}\n"],"names":["GROUP_TYPE","ITEM_TYPE","STATUS_TYPE","ua","window","navigator","userAgent","IS_IOS","test","CONTAINER_CLASS_NAME","IGNORE_PROPERITES_MAP","renderOnPropertyChange","useFit","autoResize","INFINITEGRID_PROPERTY_TYPES","GRID_PROPERTY_TYPES","DIRECTION","START","END","NONE","INFINITEGRID_EVENTS","CHANGE_SCROLL","REQUEST_APPEND","REQUEST_PREPEND","RENDER_COMPLETE","CONTENT_ERROR","ITEM_INFO_PROPERTIES","type","groupKey","key","element","html","data","INFINITEGRID_METHODS","horizontal","itemStatus","orgRect","_super","NORMAL","cssRect","top","left","_this","VIRTUAL","rect","width","height","mountState","MOUNT_STATE","UNMOUNTED","__extends","this","attributes","status","getStatus","GridItem","items","item","loadingItem","getLoadingItem","name","InfiniteGridItem","options","LOADING","direction","outline","length","start","end","nextOutline","offset","contentSize","gap","cssInlinePos","getContainerInlineSize","inlineSize","maxPos","Math","max","cssContentPos","map","pos","minPos","min","Grid","isWindow","el","isString","val","flat","arr","reduce","prev","cur","splitGridOptions","nextOptions","gridOptions","defaultOptions","value","categorize","generatedGroupKey","groups","groupKeys","registeredGroupKeys","filter","forEach","_a","isContinuousGroupKey","makeKey","group","push","getNextCursors","prevKeys","nextKeys","prevStartCursor","prevEndCursor","result","diff","nextStartCursor","nextEndCursor","maintained","prevIndex","nextIndex","startCursor","endCursor","splitVirtualGroups","nextGroups","index","virtualGroups","findIndex","slice","findLastIndex","removed","reverse","InfiniteGridGetterSetter","component","prototype","Object","defineProperty","enumerable","configurable","get","groupManager","set","registeredKeys","Date","getTime","floor","random","convertHTMLtoElement","dummy","document","createElement","innerHTML","toArray","children","nodes","array","i","callback","isFlatOutline","every","flatGroups","getItems","filterVirtuals","includePlaceholders","withInfiniteGridMethods","container","otherOptions","_loadingGrid","LoadingGrid","externalContainerManager","containerManager","shouldRender","_checkShouldRender","grid","scheduleRender","itemKeys","groupItems","hasPlaceholder","getVisibleGroups","some","_placeholder","_getLoadingItem","placeholder","_updatePlaceholder","_getRenderingItems","prevType","loading","setLoadingItem","MOUNTED","renderingGroups","loadingGrid","unshift","_getLoadingGroup","gridItems","isVirtual","appliedItems","UNCHECKED","gridOutlines","_applyVirtualGrid","applyGrid","setOutlines","getOutlines","nextItemInfos","prevItemKeys","nextItems","_syncItemInfos","info","nextInfo","prevGroupKeys","nextManagerGroups","startVirtualGroups","_splitVirtualGroups","endVirtualGroups","_mergeVirtualGroups","_makeGrid","setItems","renderItems","_registerGroups","useResize","updateState","UPDATE_STATE","NEED_UPDATE","orgStartCursor","orgEndCursor","orgGroups","isMinimizeItems","MINIMIZE_INVISIBLE_ITEMS","isMinimizeGroups","MINIMIZE_INVISIBLE_GROUPS","REMOVE_INVISIBLE_GROUPS","getGroups","groupStatus","isOutsideCursor","isVirtualItems","isVirtualGroup","getVirtualStatus","getMinimizedStatus","outlines","startGroup","endGroup","totalItems","getGroupItems","itemStartCursor","indexOf","itemEndCursor","cursors","orgCursors","itemCursors","startGroupKey","endGroupKey","setCursors","insertPlaceholders","groupKey_1","splice","syncItems","infos","range","Array","isArray","_b","isRerender","GridConstructor","gridConstructor","prevOptions","propertyTypes","PROPERTY_TYPE","RENDER_PROPERTY","startOutline","prevOutlines","prevOutline","nextItemKeys","prevItem","nextGroupKeys","_getGroupItems","prevGroup","setPlaceholder","containerElement","externalItemRenderer","itemRenderer","GroupManager","__assign","PROPERTY","GetterSetter","threshold","useRecycle","defaultDirection","scrollPos","endScrollPos","isEnd","size","isDirectionEnd","startEdgePos","endEdgePos","endOutline","visibles","startPos","endPos","hasStartItems","hasEndItems","isStart","lastIndexOf","trigger","_requestVirtualItems","nextCursor","undefined","totalVisibleItems","getVisibleItems","visibleItems","totalVisibleLength","visibleLength","getStartCursor","getEndCursor","startKey_1","endKey_1","startIndex","endIndex","nextKey","lastItem","firstItem","prevItems","isChange","visibleResult","added","changed","rendered","off","Component","rendererKey","now","state","_state","clearTimeout","_updateTimer","setTimeout","nextElements","diffResult","_diffResult","isChanged","list","elements","renderKey","orgItem","render","prevList","ordered","diffList","removeChild","insertBefore","updated","Renderer","wrapper","prevScrollPos","getScrollPos","nextScrollPos","getOrgScrollPos","setScrollPos","_isScrollIssue","ComponentEvent","relativeScrollPos","getRelativeScrollPos","containerTag","_init","scrollContainer","scrollOffset","eventTarget","prop","documentElement","body","scrollTo","x","y","scroll","scrollLeft","scrollTop","scrollBy","scrollContainerRect","getBoundingClientRect","containerRect","offsetWidth","offsetHeight","fragment_1","childNodes","removeEventListener","_onCheck","_isCreateElement","createDocumentFragment","childNode","appendChild","style","cssText","_orgCSSText","containerOption","HTMLElement","position","className","querySelector","overflowX","overflowY","addEventListener","resize","_scroll","e","_checkEndLoading","renderedItems","addedItems","gridItem","isRestore","isResize","_onRenderComplete","mounted","_onRequestInsert","target","update","remove","removeByKey","infinite","prevRenderedGroups","getRenderedVisibleItems","_syncInfinite","prevStandardGroup","nextStandardGroup","getItemByKey","scrollManager","shouldRerenderItems","_update","constructor","renderer","VanillaGridRenderer","on","_render","attributePrefix","useTransform","percentage","isConstantSize","isEqualSize","wrapperElement","ScrollManager","_onScroll","getContainer","ContainerManager","_onResize","ItemRenderer","Infinite","_onChange","_onRequestAppend","_onRequestPrepend","setSize","getContentSize","_onContentError","setContainer","_onRendererUpdated","_resizeScroll","getContainerElement","append","getWrapper","getScrollContainer","_syncGroups","useFirstRender","insert","itemInfos","insertedItems","outerHTML","getGroupStatus","setLoading","appendPlaceholders","removePlaceholders","prependPlaceholders","setStatus","prevInlineSize","getInlineSize","setGroupStatus","_getRenderer","updateKey","isReisze","removeGroupByKey","firstIndex","lastIndex","removeByIndex","updateItems","getRenderingItems","_waitType","_checkStartLoading","destroy","isUpdate","eventType","nextGroupKey","wait","ready","getLoadingType","isLoading","startLoading","hasLoadingItem","loadingType","endLoading","InfiniteGrid","DEFAULT_GRID_OPTIONS","usePlaceholder","useLoading","groupManagerStatus","prevGroups","__spreadArrays","nextVisibleItems","MasonryInfiniteGrid","MasonryGrid","JustifiedInfiniteGrid","JustifiedGrid","FrameInfiniteGrid","FrameGrid","PackingInfiniteGrid","PackingGrid","modules"],"mappings":"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"}