{"version":3,"file":"infinitegrid.js","sources":["../src/browser.js","../src/consts.js","../src/utils.js","../src/ItemManager.js","../src/DOMRenderer.js","../src/Watcher.js","../src/Infinite.js","../src/AutoSizer.js","../src/ImageLoaded.js","../src/LayoutManager.js","../src/InfiniteGrid.js","../src/layouts/GridLayout.js","../src/layouts/FrameLayout.js","../src/layouts/SquareLayout.js","../src/layouts/lib/BoxModel.js","../src/layouts/PackingLayout.js","../src/layouts/lib/dijkstra.js","../src/layouts/JustifiedLayout.js","../src/index.js","../src/index.umd.js"],"sourcesContent":["/* eslint-disable no-new-func, no-nested-ternary */\n\nlet win;\n\nif (typeof window === \"undefined\") {\n\t// window is undefined in node.js\n\twin = {\n\t\tdocument: {},\n\t\tnavigator: {\n\t\t\tuserAgent: \"\",\n\t\t},\n\t};\n} else {\n\twin = window;\n}\n/* eslint-enable no-new-func, no-nested-ternary */\n\nexport {win as window};\nexport const document = win.document;\n","import {window, document} from \"./browser\";\n\nconst ua = window.navigator.userAgent;\n\nexport const SUPPORT_COMPUTEDSTYLE = !!(\"getComputedStyle\" in window);\nexport const SUPPORT_ADDEVENTLISTENER = !!(\"addEventListener\" in document);\nexport const SUPPORT_PASSIVE = (() => {\n\tlet supportsPassiveOption = false;\n\n\ttry {\n\t\tif (SUPPORT_ADDEVENTLISTENER && Object.defineProperty) {\n\t\t\tdocument.addEventListener(\"test\", null, Object.defineProperty({},\n\t\t\t\t\"passive\", {\n\t\t\t\t\tget() {\n\t\t\t\t\t\tsupportsPassiveOption = true;\n\t\t\t\t\t},\n\t\t\t\t}));\n\t\t}\n\t} catch (e) {}\n\treturn supportsPassiveOption;\n})();\n\nexport const IS_IE = /MSIE|Trident|Windows Phone|Edge/.test(ua);\nexport const IS_IOS = /iPhone|iPad/.test(ua);\nexport const IS_ANDROID2 = /Android 2\\./.test(ua);\nexport const CONTAINER_CLASSNAME = \"_eg-infinitegrid-container_\";\nexport const IGNORE_CLASSNAME = \"_eg-infinitegrid-ignore_\";\nexport const TRANSITION_NAME = \"_INFINITEGRID_TRANSITION\";\n\nexport const APPEND = true;\nexport const PREPEND = false;\nexport const VERTICAL = \"vertical\";\nexport const HORIZONTAL = \"horizontal\";\nexport const CACHE = true;\nexport const NO_CACHE = false;\nexport const TRUSTED = true;\nexport const NO_TRUSTED = false;\nexport const MULTI = true;\nexport const SINGLE = false;\nexport const DUMMY_POSITION = -100000;\nexport const GROUPKEY_ATT = \"data-groupkey\";\n\nexport const DEFAULT_OPTIONS = {\n\thorizontal: false,\n\tmargin: 0,\n};\n\nexport const agent = ua.toLowerCase();\nexport const isMobile = /mobi|ios|android/.test(agent);\n\nexport const ALIGN = {\n\tSTART: \"start\",\n\tCENTER: \"center\",\n\tEND: \"end\",\n\tJUSTIFY: \"justify\",\n};\n\nexport const IDLE = 0;\nexport const LOADING_APPEND = 1;\nexport const LOADING_PREPEND = 2;\nexport const PROCESSING = 4;\n\n\nconst webkit = /applewebkit\\/([\\d|.]*)/g.exec(agent);\n\nexport const WEBKIT_VERSION = (webkit && parseInt(webkit[1], 10)) || 0;\nexport const DEFENSE_BROWSER = (WEBKIT_VERSION && WEBKIT_VERSION < 537);\n\n\nexport const [TRANSFORM, TRANSITION, TRANSITION_END] = (function() {\n\tconst properties = {\n\t\ttransitionend: \"\",\n\t\twebkitTransitionEnd: \"-webkit-\",\n\t\toTransitionEnd: \"-o-\",\n\t\tmozTransitionEnd: \"-moz-\",\n\t};\n\n\tfor (const property in properties) {\n\t\tconst prefix = properties[property];\n\n\t\tif (`on${property.toLowerCase()}` in window) {\n\t\t\treturn [`${prefix}transform`, `${prefix}transition`, property];\n\t\t}\n\t}\n\treturn [];\n})();\n","import {window, document} from \"./browser\";\nimport {\n\tSUPPORT_COMPUTEDSTYLE,\n\tSUPPORT_ADDEVENTLISTENER,\n\tSUPPORT_PASSIVE,\n\tVERTICAL,\n\tHORIZONTAL,\n\tDEFAULT_OPTIONS,\n} from \"./consts\";\n\nexport function toArray(nodes) {\n\t// SCRIPT5014 in IE8\n\tconst array = [];\n\n\tif (nodes) {\n\t\tfor (let i = 0, len = nodes.length; i < len; i++) {\n\t\t\tarray.push(nodes[i]);\n\t\t}\n\t}\n\treturn array;\n}\nexport function matchHTML(html) {\n\treturn html.match(/^<([A-z]+)\\s*([^>]*)>/);\n}\n/**\n * Select or create element\n * @param {String|HTMLElement|jQuery} param\n * when string given is as HTML tag, then create element\n * otherwise it returns selected elements\n * @param {Boolean} multi\n * @returns {HTMLElement}\n */\nexport function $(param, multi = false) {\n\tlet el;\n\n\tif (typeof param === \"string\") { // String (HTML, Selector)\n\t\t// check if string is HTML tag format\n\t\tconst match = matchHTML(param);\n\n\t\t// creating element\n\t\tif (match) { // HTML\n\t\t\tconst dummy = document.createElement(\"div\");\n\n\t\t\tdummy.innerHTML = param;\n\t\t\tel = dummy.childNodes;\n\t\t} else { // Selector\n\t\t\tel = document.querySelectorAll(param);\n\t\t}\n\t\tif (multi) {\n\t\t\tel = toArray(el);\n\t\t} else {\n\t\t\tel = (el && el.length > 0 && el[0]) || undefined;\n\t\t}\n\t} else if (param === window) { // window\n\t\tel = param;\n\t} else if (param.nodeName &&\n\t\t(param.nodeType === 1 || param.nodeType === 9)) { // HTMLElement, Document\n\t\tel = param;\n\t} else if ((typeof window.jQuery === \"function\" && param instanceof window.jQuery) ||\n\t\tparam.constructor.prototype.jquery) { // jQuery\n\t\tel = $(multi ? param.toArray() : param.get(0), multi);\n\t} else if (Array.isArray(param)) {\n\t\tel = param.map(v => $(v));\n\t\tif (!multi) {\n\t\t\tel = el.length >= 1 ? el[0] : undefined;\n\t\t}\n\t}\n\treturn el;\n}\nexport function addEvent(element, type, handler, eventListenerOptions) {\n\tif (SUPPORT_ADDEVENTLISTENER) {\n\t\tlet options = eventListenerOptions || false;\n\n\t\tif (typeof eventListenerOptions === \"object\") {\n\t\t\toptions = SUPPORT_PASSIVE ? eventListenerOptions : false;\n\t\t}\n\t\telement.addEventListener(type, handler, options);\n\t} else if (element.attachEvent) {\n\t\telement.attachEvent(`on${type}`, handler);\n\t} else {\n\t\telement[`on${type}`] = handler;\n\t}\n}\nexport function removeEvent(element, type, handler) {\n\tif (element.removeEventListener) {\n\t\telement.removeEventListener(type, handler, false);\n\t} else if (element.detachEvent) {\n\t\telement.detachEvent(`on${type}`, handler);\n\t} else {\n\t\telement[`on${type}`] = null;\n\t}\n}\nexport function addOnceEvent(element, type, handler, eventListenerOptions) {\n\tconst callback = e => {\n\t\tremoveEvent(element, type, callback);\n\t\thandler(e);\n\t};\n\n\taddEvent(element, type, callback, eventListenerOptions);\n}\nexport function scroll(el, horizontal = false) {\n\tconst prop = `scroll${horizontal ? \"Left\" : \"Top\"}`;\n\n\tif (el === window) {\n\t\treturn window[horizontal ? \"pageXOffset\" : \"pageYOffset\"] || document.body[prop] || document.documentElement[prop];\n\t} else {\n\t\treturn el[prop];\n\t}\n}\nexport function scrollTo(el, x, y) {\n\tif (el === window) {\n\t\tel.scroll(x, y);\n\t} else {\n\t\tel.scrollLeft = x;\n\t\tel.scrollTop = y;\n\t}\n}\nexport function scrollBy(el, x, y) {\n\tif (el === window) {\n\t\tel.scrollBy(x, y);\n\t} else {\n\t\tel.scrollLeft += x;\n\t\tel.scrollTop += y;\n\t}\n}\nexport function getStyles(el) {\n\treturn (SUPPORT_COMPUTEDSTYLE ?\n\t\twindow.getComputedStyle(el) : el.currentStyle) || {};\n}\nfunction _getSize(el, name, isOffset) {\n\tif (el === window) { // WINDOW\n\t\treturn window[`inner${name}`] || document.body[`client${name}`];\n\t} else if (el.nodeType === 9) { // DOCUMENT_NODE\n\t\tconst doc = el.documentElement;\n\n\t\treturn Math.max(\n\t\t\tel.body[`scroll${name}`], doc[`scroll${name}`],\n\t\t\tel.body[`offset${name}`], doc[`offset${name}`],\n\t\t\tdoc[`client${name}`]\n\t\t);\n\t} else { // NODE\n\t\tlet size = 0;\n\n\t\tif (isOffset) {\n\t\t\tconst clientRect = el.getBoundingClientRect();\n\n\t\t\tsize = name === \"Width\" ? clientRect.right - clientRect.left : clientRect.bottom - clientRect.top;\n\t\t} else {\n\t\t\tsize = el[`client${name}`] || el[`offset${name}`];\n\t\t}\n\t\treturn parseFloat(size || getStyles(el)[name.toLowerCase()]) || 0;\n\t}\n}\nexport function innerWidth(el) {\n\treturn _getSize(el, \"Width\", false);\n}\nexport function innerHeight(el) {\n\treturn _getSize(el, \"Height\", false);\n}\nexport function outerWidth(el) {\n\treturn _getSize(el, \"Width\", true);\n}\nexport function outerHeight(el) {\n\treturn _getSize(el, \"Height\", true);\n}\nexport function getSize(el) {\n\treturn {\n\t\twidth: outerWidth(el),\n\t\theight: outerHeight(el),\n\t};\n}\nexport const STYLE = {\n\tvertical: {\n\t\tpos1: \"top\",\n\t\tendPos1: \"bottom\",\n\t\tsize1: \"height\",\n\t\tpos2: \"left\",\n\t\tendPos2: \"right\",\n\t\tsize2: \"width\",\n\t},\n\thorizontal: {\n\t\tpos1: \"left\",\n\t\tendPos1: \"right\",\n\t\tsize1: \"width\",\n\t\tpos2: \"top\",\n\t\tendPos2: \"bottom\",\n\t\tsize2: \"height\",\n\t},\n};\n\nexport function getStyleNames(isHorizontal) {\n\treturn STYLE[isHorizontal ? HORIZONTAL : VERTICAL];\n}\n\nexport function assignOptions(defaultOptions, options) {\n\treturn Object.assign({},\n\t\tDEFAULT_OPTIONS,\n\t\tdefaultOptions,\n\t\toptions);\n}\n\nexport function toZeroArray(outline) {\n\tif (!outline || !outline.length) {\n\t\treturn [0];\n\t}\n\treturn outline;\n}\nexport function cloneItems(items) {\n\treturn items.map(item => Object.assign({}, item));\n}\nexport function isWindow(el) {\n\treturn el === window;\n}\n\nexport function fill(arr, value) {\n\tconst length = arr.length;\n\n\tfor (let i = length - 1; i >= 0; --i) {\n\t\tarr[i] = value;\n\t}\n\n\treturn arr;\n}\n\nexport function isUndefined(target) {\n\treturn typeof target === \"undefined\";\n}\n","import {MULTI, GROUPKEY_ATT, IGNORE_CLASSNAME, DUMMY_POSITION} from \"./consts\";\nimport {$, toArray, isUndefined} from \"./utils\";\n\nexport default class ItemManager {\n\tstatic from(elements, selector, {groupKey, isAppend}) {\n\t\tconst filted = ItemManager.selectItems($(elements, MULTI), selector);\n\n\t\t// Item Structure\n\t\treturn toArray(filted).map(el => ({\n\t\t\tel,\n\t\t\tgroupKey,\n\t\t\tcontent: el.outerHTML,\n\t\t\trect: {\n\t\t\t\ttop: DUMMY_POSITION,\n\t\t\t\tleft: DUMMY_POSITION,\n\t\t\t},\n\t\t}));\n\t}\n\tstatic selectItems(elements, selector) {\n\t\treturn elements.filter(v => {\n\t\t\tconst classNames = v.className.split(\" \");\n\n\t\t\tif (classNames.some(c => c === IGNORE_CLASSNAME)) {\n\t\t\t\treturn false;\n\t\t\t} else if (!selector || selector === \"*\") {\n\t\t\t\treturn v;\n\t\t\t} else {\n\t\t\t\treturn classNames.some(c => c === selector);\n\t\t\t}\n\t\t});\n\t}\n\tstatic pluck(data, property) {\n\t\treturn data.reduce((acc, v) => acc.concat(v[property]), []);\n\t}\n\tconstructor() {\n\t\tthis.clear();\n\t}\n\tgetStatus(startKey, endKey) {\n\t\tconst datas = this._data;\n\t\tconst startIndex = Math.max(this.indexOf(startKey), 0);\n\t\tconst endIndex = this.indexOf(endKey) + 1 || datas.length;\n\n\t\treturn {\n\t\t\t_data: datas.slice(startIndex, endIndex).map(data => {\n\t\t\t\tconst items = data.items.map(item => {\n\t\t\t\t\tconst item2 = Object.assign({}, item);\n\n\t\t\t\t\tdelete item2.el;\n\t\t\t\t\treturn item2;\n\t\t\t\t});\n\t\t\t\tconst data2 = Object.assign({}, data);\n\n\t\t\t\tdata2.items = items;\n\t\t\t\treturn data2;\n\t\t\t}),\n\t\t};\n\t}\n\tsetStatus(status) {\n\t\tconst data = status._data;\n\n\t\tthis.set(data);\n\t}\n\tsize() {\n\t\treturn this._data.length;\n\t}\n\tfit(base, horizontal) {\n\t\tif (!this._data.length) {\n\t\t\treturn;\n\t\t}\n\t\tconst property = horizontal ? \"left\" : \"top\";\n\n\t\tif (base !== 0) {\n\t\t\tthis._data = this._data.map(v => {\n\t\t\t\tv.items = v.items.map(item => {\n\t\t\t\t\titem.rect[property] -= base;\n\t\t\t\t\treturn item;\n\t\t\t\t});\n\t\t\t\tv.outlines.start = v.outlines.start.map(start => start - base);\n\t\t\t\tv.outlines.end = v.outlines.end.map(end => end - base);\n\t\t\t\treturn v;\n\t\t\t});\n\t\t}\n\t}\n\tpluck(property, start, end) {\n\t\tconst data = isUndefined(start) ? this._data :\n\t\t\tthis._data.slice(start, (isUndefined(end) ? start : end) + 1);\n\n\t\treturn ItemManager.pluck(data, property);\n\t}\n\tgetOutline(index, property) {\n\t\tconst data = this._data[index];\n\n\t\treturn data ? data.outlines[property] : [];\n\t}\n\tgetEdgeIndex(cursor, start, end) {\n\t\tconst prop = cursor === \"start\" ? \"min\" : \"max\";\n\t\tlet index = -1;\n\t\tlet targetValue = cursor === \"start\" ? Infinity : -Infinity;\n\n\t\tfor (let i = start; i <= end; i++) {\n\t\t\tconst value = Math[prop](...this.getOutline(i, cursor));\n\n\t\t\tif ((cursor === \"start\" && targetValue > value) ||\n\t\t\t\t(cursor === \"end\" && targetValue < value)) {\n\t\t\t\ttargetValue = value;\n\t\t\t\tindex = i;\n\t\t\t}\n\t\t}\n\t\treturn index;\n\t}\n\tgetEdgeValue(cursor, start, end) {\n\t\tconst outlines = this.pluck(\"outlines\", this.getEdgeIndex(cursor, start, end))\n\t\t\t.reduce((acc, v) => acc.concat(v[cursor]), []);\n\n\t\treturn outlines.length ? Math[cursor === \"start\" ? \"min\" : \"max\"](...outlines) : 0;\n\t}\n\tclearOutlines(startCursor = -1, endCursor = -1) {\n\t\tconst datas = this.get();\n\n\t\tdatas.forEach((group, cursor) => {\n\t\t\tif (startCursor <= cursor && cursor <= endCursor) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tgroup.items.forEach(item => {\n\t\t\t\titem.rect.top = DUMMY_POSITION;\n\t\t\t\titem.rect.left = DUMMY_POSITION;\n\t\t\t});\n\t\t\tgroup.outlines.start = [];\n\t\t\tgroup.outlines.end = [];\n\t\t});\n\t}\n\tgetMaxEdgeValue() {\n\t\tconst groups = this.get();\n\t\tconst length = groups.length;\n\n\t\tfor (let i = length - 1; i >= 0; --i) {\n\t\t\tconst end = groups[i].outlines.end;\n\n\t\t\tif (end.length) {\n\t\t\t\tconst pos = Math.max(...end);\n\n\t\t\t\treturn pos;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\tappend(layouted) {\n\t\tthis._data.push(layouted);\n\t\treturn layouted.items;\n\t}\n\tprepend(layouted) {\n\t\tthis._data.unshift(layouted);\n\t\treturn layouted.items;\n\t}\n\tclear() {\n\t\tthis._data = [];\n\t}\n\tremove(element, start, end) {\n\t\tlet items = [];\n\t\tconst key = element.getAttribute(GROUPKEY_ATT);\n\t\tlet data = this.get(start, end)\n\t\t\t.filter(v => String(v.groupKey) === key);\n\n\t\tif (!data.length) {\n\t\t\treturn items;\n\t\t}\n\t\tdata = data[0];\n\n\t\tconst len = data.items.length;\n\t\tlet idx = -1;\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tif (data.items[i].el === element) {\n\t\t\t\tidx = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (~idx) {\n\t\t\t// remove item information\n\t\t\tdata.items.splice(idx, 1);\n\t\t\tthis.set(data, key);\n\t\t\titems = data.items;\n\t\t}\n\t\treturn items;\n\t}\n\tindexOf(data) {\n\t\tconst groupKey = typeof data === \"object\" ? data.groupKey : data;\n\t\tconst datas = this._data;\n\t\tconst length = datas.length;\n\n\t\tfor (let i = 0; i < length; ++i) {\n\t\t\tif (groupKey === datas[i].groupKey) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\tget(start, end) {\n\t\treturn isUndefined(start) ? this._data :\n\t\t\tthis._data.slice(start, (isUndefined(end) ? start : end) + 1);\n\t}\n\tset(data, key) {\n\t\tif (!isUndefined(key) && !Array.isArray(data)) {\n\t\t\tconst len = this._data.length;\n\t\t\tlet idx = -1;\n\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tif (this._data[i].groupKey === key) {\n\t\t\t\t\tidx = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t~idx && (this._data[idx] = data);\n\t\t} else {\n\t\t\tthis._data = data.concat();\n\t\t}\n\t}\n\tgetData(index) {\n\t\treturn this._data[index];\n\t}\n}\n","import {\n\tAPPEND,\n\tPREPEND,\n\tDUMMY_POSITION,\n\tMULTI,\n\tGROUPKEY_ATT,\n\tCONTAINER_CLASSNAME,\n\tTRANSITION_NAME,\n\tTRANSITION,\n\tTRANSITION_END,\n\tTRANSFORM,\n} from \"./consts\";\nimport {window, document} from \"./browser\";\nimport {\n\t$,\n\tinnerHeight,\n\tinnerWidth,\n\tgetSize,\n\tgetStyles,\n\taddOnceEvent,\n} from \"./utils\";\n\n\nexport function resetSize(item) {\n\titem.orgSize = 0;\n\titem.size = 0;\n}\nfunction createContainer(element) {\n\tconst container = document.createElement(\"div\");\n\n\tcontainer.className = CONTAINER_CLASSNAME;\n\tcontainer.style.position = \"relative\";\n\tcontainer.style.height = \"100%\";\n\n\tconst children = element.children;\n\tconst length = children.length;\t// for IE8\n\n\tfor (let i = 0; i < length; i++) {\n\t\tcontainer.appendChild(children[0]);\n\t}\n\telement.appendChild(container);\n\treturn container;\n}\nfunction render(properties, rect, styles) {\n\tproperties.forEach(p => {\n\t\t(p in rect) && (styles[p] = `${rect[p]}px`);\n\t});\n}\nfunction setTransition(styles, transitionDuration, pos1, pos2) {\n\tstyles[`${TRANSITION}-property`] = transitionDuration ? `${TRANSFORM},width,height` : \"\";\n\tstyles[`${TRANSITION}-duration`] = transitionDuration ? `${transitionDuration}s` : \"\";\n\tstyles[`${TRANSITION}-delay`] = transitionDuration ? `0s` : \"\";\n\tstyles[TRANSFORM] = transitionDuration ? `translate(${pos1.left - pos2.left}px,${pos1.top - pos2.top}px)` : \"\";\n}\n\nexport default class DOMRenderer {\n\tstatic renderItem(item, rect, transitionDuration) {\n\t\tif (!item.el) {\n\t\t\treturn;\n\t\t}\n\t\tconst {el, prevRect} = item;\n\t\tconst styles = el.style;\n\n\t\t// for debugging\n\t\tel.setAttribute(GROUPKEY_ATT, item.groupKey);\n\t\tstyles.position = \"absolute\";\n\t\trender([\"width\", \"height\"], rect, styles);\n\t\tif (transitionDuration && TRANSITION && prevRect) {\n\t\t\tsetTransition(styles, transitionDuration, rect, prevRect);\n\t\t\tif (el[TRANSITION_NAME]) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tel[TRANSITION_NAME] = true;\n\t\t\taddOnceEvent(el, TRANSITION_END, () => {\n\t\t\t\tconst itemRect = item.rect;\n\n\t\t\t\tsetTransition(styles);\n\t\t\t\trender([\"left\", \"top\"], itemRect, styles);\n\t\t\t\titem.prevRect = itemRect;\n\t\t\t\tel[TRANSITION_NAME] = false;\n\t\t\t});\n\t\t} else {\n\t\t\trender([\"left\", \"top\"], rect, styles);\n\t\t\titem.prevRect = rect;\n\t\t}\n\t}\n\tstatic renderItems(items, transitionDuration) {\n\t\titems.forEach(item => {\n\t\t\tDOMRenderer.renderItem(item, item.rect, transitionDuration);\n\t\t});\n\t}\n\tstatic removeItems(items) {\n\t\titems.forEach(item => {\n\t\t\tif (item.el) {\n\t\t\t\tDOMRenderer.removeElement(item.el);\n\t\t\t\titem.el = null;\n\t\t\t}\n\t\t});\n\t}\n\tstatic removeElement(element) {\n\t\tconst parentNode = element && element.parentNode;\n\n\t\tif (!parentNode) {\n\t\t\treturn;\n\t\t}\n\t\tparentNode.removeChild(element);\n\t}\n\tstatic createElements(items) {\n\t\tif (!items.length) {\n\t\t\treturn;\n\t\t}\n\t\tconst noElementItems = items.filter(item => !item.el);\n\n\t\tif (!noElementItems.length) {\n\t\t\treturn;\n\t\t}\n\t\tconst elements = $(noElementItems.map(({content}) =>\n\t\t\tcontent.replace(/^[\\s\\uFEFF]+|[\\s\\uFEFF]+$/g, \"\")).join(\"\"), MULTI);\n\n\t\tnoElementItems.forEach((item, index) => {\n\t\t\titem.el = elements[index];\n\t\t});\n\t}\n\tconstructor(element, options) {\n\t\tObject.assign(this.options = {\n\t\t\tisEqualSize: false,\n\t\t\tisConstantSize: false,\n\t\t\thorizontal: false,\n\t\t\tcontainer: false,\n\t\t}, options);\n\t\tthis._size = {\n\t\t\tcontainer: -1,\n\t\t\tview: -1,\n\t\t\tviewport: -1,\n\t\t\titem: null,\n\t\t};\n\t\tthis._init(element);\n\t\tthis.resize();\n\t}\n\tgetStatus() {\n\t\treturn {\n\t\t\tcssText: this.container.style.cssText,\n\t\t\t_size: Object.assign({}, this._size),\n\t\t};\n\t}\n\tsetStatus(status) {\n\t\tthis.container.style.cssText = status.cssText;\n\t\tObject.assign(this._size, status._size);\n\t}\n\tupdateSize(items) {\n\t\tconst {isEqualSize, isConstantSize} = this.options;\n\t\tconst size = this._size;\n\n\t\treturn items.map(item => {\n\t\t\tif (!item.el) {\n\t\t\t\treturn item;\n\t\t\t}\n\t\t\tif (isEqualSize && !size.item) {\n\t\t\t\tsize.item = getSize(item.el);\n\t\t\t}\n\t\t\titem.size = (isEqualSize && Object.assign(size.item)) ||\n\t\t\t\t\t\t(isConstantSize && item.orgSize && Object.assign(item.orgSize)) ||\n\t\t\t\t\t\tgetSize(item.el);\n\t\t\tif (!item.orgSize) {\n\t\t\t\titem.orgSize = Object.assign({}, item.size);\n\t\t\t}\n\t\t\treturn item;\n\t\t});\n\t}\n\t_init(el) {\n\t\tconst element = $(el);\n\t\tconst style = getStyles(element);\n\t\tconst {container, horizontal} = this.options;\n\n\t\tthis._orgStyle = {};\n\n\t\tif (style.position === \"static\") {\n\t\t\tthis._orgStyle.position = element.style.position;\n\t\t\telement.style.position = \"relative\";\n\t\t}\n\t\tif (container) {\n\t\t\tconst target = horizontal ? [\"X\", \"Y\"] : [\"Y\", \"X\"];\n\n\t\t\tthis._orgStyle.overflowX = element.style.overflowX;\n\t\t\tthis._orgStyle.overflowY = element.style.overflowY;\n\t\t\telement.style[`overflow${target[0]}`] = \"scroll\";\n\t\t\telement.style[`overflow${target[1]}`] = \"hidden\";\n\t\t\tthis.view = element;\n\t\t\tthis.container = container === true ? createContainer(this.view) : container;\n\t\t} else {\n\t\t\tthis.view = window;\n\t\t\tthis.container = element;\n\t\t}\n\t}\n\tappend(items) {\n\t\tthis._insert(items, APPEND, {\n\t\t\ttop: DUMMY_POSITION,\n\t\t\tleft: DUMMY_POSITION,\n\t\t});\n\t}\n\tprepend(items) {\n\t\tthis._insert(items, PREPEND, {\n\t\t\ttop: DUMMY_POSITION,\n\t\t\tleft: DUMMY_POSITION,\n\t\t});\n\t}\n\tcreateAndInsert(items, isAppend) {\n\t\tDOMRenderer.createElements(items);\n\n\t\tDOMRenderer.renderItems(items);\n\t\tthis._insert(items, isAppend);\n\t}\n\t_insert(items, isAppend, styles) {\n\t\tconst container = this.container;\n\t\tconst df = document.createDocumentFragment();\n\n\t\titems.forEach(item => {\n\t\t\tstyles && DOMRenderer.renderItem(item, styles);\n\t\t\tisAppend ? df.appendChild(item.el) : df.insertBefore(item.el, df.firstChild);\n\t\t});\n\t\tisAppend ?\n\t\t\tcontainer.appendChild(df) :\n\t\t\tcontainer.insertBefore(df, container.firstChild);\n\t}\n\t_calcSize() {\n\t\treturn this.options.horizontal ?\n\t\t\tinnerHeight(this.container) : innerWidth(this.container);\n\t}\n\tgetViewSize() {\n\t\treturn this._size.view;\n\t}\n\tgetViewportSize() {\n\t\treturn this._size.viewport;\n\t}\n\tsetContainerSize(size) {\n\t\tthis.container.style[this.options.horizontal ? \"width\" : \"height\"] = `${size}px`;\n\t}\n\tresize() {\n\t\tconst horizontal = this.options.horizontal;\n\t\tconst view = this.view;\n\t\tconst isResize = this.isNeededResize();\n\n\t\tif (isResize) {\n\t\t\tthis._size = {\n\t\t\t\tviewport: this._calcSize(),\n\t\t\t\titem: null,\n\t\t\t};\n\t\t}\n\t\tthis._size.view = horizontal ? innerWidth(view) : innerHeight(view);\n\t\treturn isResize;\n\t}\n\tisNeededResize() {\n\t\treturn this._calcSize() !== this._size.viewport;\n\t}\n\tclear() {\n\t\tthis.container.innerHTML = \"\";\n\t\tthis.container.style[this.options.horizontal ? \"width\" : \"height\"] = \"\";\n\n\t\tthis._size = {\n\t\t\titem: null,\n\t\t\tviewport: -1,\n\t\t\tcontainer: -1,\n\t\t\tview: -1,\n\t\t};\n\t}\n\tdestroy() {\n\t\tthis.clear();\n\t\tconst container = this.options.container;\n\n\t\tfor (const p in this._orgStyle) {\n\t\t\tthis[container ? \"view\" : \"container\"].style[p] = this._orgStyle[p];\n\t\t}\n\t\tcontainer && this.container.parentNode.removeChild(this.container);\n\t}\n}\n\n","import {\n\tIS_IOS,\n} from \"./consts\";\nimport {\n\twindow,\n} from \"./browser\";\nimport {\n\taddEvent,\n\tremoveEvent,\n\tscroll,\n\tscrollTo,\n\tscrollBy,\n} from \"./utils\";\n\nexport default class Watcher {\n\tconstructor(view, options) {\n\t\tObject.assign(this.options = {\n\t\t\tcontainer: view,\n\t\t\tresize: () => {},\n\t\t\tcheck: () => {},\n\t\t\tisOverflowScroll: false,\n\t\t\thorizontal: false,\n\t\t}, options);\n\t\tthis._timer = {\n\t\t\tresize: null,\n\t\t\t// doubleCheck: null,\n\t\t\t// doubleCheckCount: RETRY,\n\t\t};\n\t\tthis.reset();\n\t\tthis._containerOffset = 0;\n\t\tthis._view = view;\n\t\tthis._scrollIssue = IS_IOS;\n\t\tthis._onCheck = this._onCheck.bind(this);\n\t\tthis._onResize = this._onResize.bind(this);\n\t\tthis.attachEvent();\n\t\tthis.resize();\n\t\tthis.setScrollPos();\n\t}\n\tgetStatus() {\n\t\treturn {\n\t\t\t_prevPos: this._prevPos,\n\t\t\tscrollPos: this.getOrgScrollPos(),\n\t\t};\n\t}\n\tsetStatus(status, applyScrollPos = true) {\n\t\tthis._prevPos = status._prevPos;\n\t\tapplyScrollPos && this.scrollTo(status.scrollPos);\n\t}\n\tscrollBy(pos) {\n\t\tconst arrPos = this.options.horizontal ? [pos, 0] : [0, pos];\n\n\t\tscrollBy(this._view, ...arrPos);\n\t\tthis.setScrollPos();\n\t}\n\tscrollTo(pos) {\n\t\tconst arrPos = this.options.horizontal ? [pos, 0] : [0, pos];\n\n\t\tscrollTo(this._view, ...arrPos);\n\t}\n\tgetScrollPos() {\n\t\treturn this._prevPos;\n\t}\n\tsetScrollPos(pos) {\n\t\tlet rawPos = pos;\n\n\t\tif (typeof pos === \"undefined\") {\n\t\t\trawPos = this.getOrgScrollPos();\n\t\t}\n\t\tthis._prevPos = rawPos - this.getContainerOffset();\n\t}\n\tattachEvent() {\n\t\taddEvent(this._view, \"scroll\", this._onCheck);\n\t\taddEvent(window, \"resize\", this._onResize);\n\t}\n\tgetOrgScrollPos() {\n\t\treturn scroll(this._view, this.options.horizontal);\n\t}\n\treset() {\n\t\tthis._prevPos = null;\n\t}\n\t_onCheck() {\n\t\tconst prevPos = this.getScrollPos();\n\t\tconst orgScrollPos = this.getOrgScrollPos();\n\n\t\tthis.setScrollPos(orgScrollPos);\n\t\tconst scrollPos = this.getScrollPos();\n\n\t\tif (prevPos === null || (this._scrollIssue && orgScrollPos === 0) || prevPos === scrollPos) {\n\t\t\torgScrollPos && (this._scrollIssue = false);\n\t\t\treturn;\n\t\t}\n\t\tthis._scrollIssue = false;\n\t\tthis.options.check({\n\t\t\tisForward: prevPos < scrollPos,\n\t\t\tscrollPos,\n\t\t\torgScrollPos,\n\t\t\thorizontal: this.options.horizontal,\n\t\t});\n\t}\n\tgetContainerOffset() {\n\t\treturn this._containerOffset;\n\t}\n\t_getOffset() {\n\t\tconst {container, horizontal} = this.options;\n\t\tconst rect = container.getBoundingClientRect();\n\n\t\treturn rect[horizontal ? \"left\" : \"top\"] + this.getOrgScrollPos();\n\t}\n\tresize() {\n\t\tthis._containerOffset = this.options.isOverflowScroll ? 0 : this._getOffset();\n\t}\n\t_onResize() {\n\t\tif (this._timer.resize) {\n\t\t\tclearTimeout(this._timer.resize);\n\t\t}\n\t\tthis._timer.resize = setTimeout(() => {\n\t\t\tthis.resize();\n\t\t\tthis.options.resize();\n\t\t\tthis._timer.resize = null;\n\t\t\tthis.reset();\n\t\t}, 100);\n\t}\n\tdetachEvent() {\n\t\tremoveEvent(this._view, \"scroll\", this._onCheck);\n\t\tremoveEvent(window, \"resize\", this._onResize);\n\t}\n\tdestroy() {\n\t\tthis.detachEvent();\n\t\tthis.reset();\n\t}\n}\n","\nfunction isVisible(group, threshold, scrollPos, endScrollPos) {\n\tconst {items, outlines} = group;\n\tconst start = outlines.start;\n\tconst end = outlines.end;\n\n\tif (start.legnth === 0 || end.length === 0 || !items.length || !items[0].el) {\n\t\treturn 2;\n\t}\n\tconst min = Math.min(...start);\n\tconst max = Math.max(...end);\n\n\tif ((endScrollPos + threshold < min)) {\n\t\treturn +1;\n\t} else if ((scrollPos - threshold > max)) {\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nclass Infinite {\n\tconstructor(itemManger, options) {\n\t\tthis.options = Object.assign({\n\t\t\tuseRecycle: true,\n\t\t\tthreshold: 100,\n\t\t\tappend: () => {},\n\t\t\tprepend: () => {},\n\t\t\trecycle: () => {},\n\t\t}, options);\n\t\tthis._items = itemManger;\n\t\tthis.clear();\n\t}\n\tsetSize(size) {\n\t\tthis._status.size = size;\n\t}\n\trecycle(scrollPos, isForward) {\n\t\tif (!this.options.useRecycle) {\n\t\t\treturn;\n\t\t}\n\t\tconst {startCursor, endCursor, size} = this._status;\n\n\t\tif (startCursor === -1 || endCursor === -1) {\n\t\t\treturn;\n\t\t}\n\t\tconst endScrollPos = scrollPos + size;\n\t\tconst {threshold, recycle} = this.options;\n\t\tconst visibles = this._items.get(startCursor, endCursor)\n\t\t\t.map(group => isVisible(group, threshold, scrollPos, endScrollPos));\n\t\tconst length = visibles.length;\n\t\tlet start = isForward ? 0 : visibles.lastIndexOf(0);\n\t\tlet end = isForward ? visibles.indexOf(0) - 1 : visibles.length - 1;\n\n\t\tif (!isForward && start !== -1) {\n\t\t\tstart += 1;\n\t\t}\n\t\tif (start < 0 || end < 0 || start > end || end - start + 1 >= length) {\n\t\t\treturn;\n\t\t}\n\t\tstart = startCursor + start;\n\t\tend = startCursor + end;\n\n\t\trecycle({start, end});\n\t\tif (isForward) {\n\t\t\tthis.setCursor(\"start\", end + 1);\n\t\t} else {\n\t\t\tthis.setCursor(\"end\", start - 1);\n\t\t}\n\t}\n\tscroll(scrollPos) {\n\t\tconst startCursor = this.getCursor(\"start\");\n\t\tconst endCursor = this.getCursor(\"end\");\n\t\tconst items = this._items;\n\n\t\tif (typeof scrollPos !== \"number\" || startCursor === -1 ||\n\t\t\tendCursor === -1 || !items.size()) {\n\t\t\treturn;\n\t\t}\n\t\tconst size = this._status.size;\n\t\tconst {threshold, append, prepend} = this.options;\n\t\tconst datas = items.get();\n\t\tconst endScrollPos = scrollPos + size;\n\t\tconst startEdgePos = Math.max(...datas[startCursor].outlines.start);\n\t\tconst endEdgePos = Math.min(...datas[endCursor].outlines.end);\n\t\tconst visibles = datas.map((group, i) => {\n\t\t\tconst {start, end} = group.outlines;\n\n\t\t\tif (!start.length || !end.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst startPos = Math.min(...start);\n\t\t\tconst endPos = Math.max(...end);\n\n\t\t\tif (startPos - threshold <= endScrollPos && scrollPos <= endPos + threshold) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t\tconst start = visibles.indexOf(true);\n\t\tconst end = visibles.lastIndexOf(true);\n\n\t\tif (~start && start < startCursor) {\n\t\t\tprepend({cache: datas.slice(start, Math.min(startCursor, end + 1))});\n\t\t} else if (endCursor < end) {\n\t\t\tappend({cache: datas.slice(Math.max(start, endCursor + 1), end + 1)});\n\t\t} else if (endScrollPos >= endEdgePos - threshold) {\n\t\t\tappend({cache: datas.slice(endCursor + 1, endCursor + 2)});\n\t\t} else if (scrollPos <= startEdgePos + threshold) {\n\t\t\tprepend({cache: datas.slice(startCursor - 1, startCursor)});\n\t\t}\n\t}\n\tsetCursor(cursor, index) {\n\t\tconst status = this._status;\n\t\tconst items = this._items;\n\t\tconst size = items.size();\n\n\t\tif (!this.options.useRecycle) {\n\t\t\tstatus.startCursor = 0;\n\t\t\tif (items.getOutline(size - 1, \"end\").length) {\n\t\t\t\tstatus.endCursor = size - 1;\n\t\t\t\treturn;\n\t\t\t} if (cursor !== \"end\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (cursor === \"start\") {\n\t\t\tstatus.startCursor = index;\n\t\t} else {\n\t\t\tstatus.endCursor = Math.min(size - 1, index);\n\t\t}\n\t\tstatus.startCursor = Math.max(0, status.startCursor);\n\t}\n\tsetStatus(status) {\n\t\tthis._status = Object.assign(this._status, status);\n\t}\n\tgetStatus(startKey, endKey) {\n\t\tconst {startCursor, endCursor, size} = this._status;\n\t\tconst startIndex = Math.max(this._items.indexOf(startKey), 0);\n\t\tconst endIndex = (this._items.indexOf(endKey) + 1 || this._items.size()) - 1;\n\t\tconst start = Math.max(startCursor - startIndex, ~startCursor ? 0 : -1);\n\t\tconst end = Math.max(Math.min(endCursor - startIndex, endIndex - startIndex), start);\n\n\t\treturn {\n\t\t\tstartCursor: start,\n\t\t\tendCursor: end,\n\t\t\tsize,\n\t\t};\n\t}\n\tgetEdgeOutline(cursor) {\n\t\tconst {startCursor, endCursor} = this._status;\n\n\t\tif (startCursor === -1 || endCursor === -1) {\n\t\t\treturn [];\n\t\t}\n\t\treturn this._items.getOutline(cursor === \"start\" ? startCursor : endCursor, cursor);\n\t}\n\tgetEdgeValue(cursor) {\n\t\tconst outlines = this.getEdgeOutline(cursor);\n\n\t\treturn outlines.length ? Math[cursor === \"start\" ? \"min\" : \"max\"](...outlines) : 0;\n\t}\n\tgetVisibleItems() {\n\t\treturn this._items.pluck(\"items\", this._status.startCursor, this._status.endCursor);\n\t}\n\tgetCursor(cursor) {\n\t\treturn this._status[cursor === \"start\" ? \"startCursor\" : \"endCursor\"];\n\t}\n\tgetVisibleData() {\n\t\treturn this._items.get(this._status.startCursor, this._status.endCursor);\n\t}\n\tremove(element) {\n\t\treturn this._items.remove(element, this._status.startCursor, this._status.endCursor);\n\t}\n\tclear() {\n\t\tthis._status = {\n\t\t\tstartCursor: -1,\n\t\t\tendCursor: -1,\n\t\t\tsize: -1,\n\t\t};\n\t}\n}\n\nexport default Infinite;\n","import {window} from \"./browser\";\nimport {addEvent, removeEvent, innerWidth, innerHeight} from \"./utils\";\n\nconst elements = [];\n/* eslint-disable */\nfunction onResize(e) {\n\tAutoSizer.resizeAll();\n}\n/* eslint-enable */\n\nexport default class AutoSizer {\n\tstatic add(element, prefix = \"data-\") {\n\t\tif (!element.length) {\n\t\t\taddEvent(window, \"resize\", onResize);\n\t\t}\n\t\telement.__PREFIX__ = prefix;\n\t\telements.push(element);\n\t\tAutoSizer.resize(element);\n\t}\n\tstatic remove(element, isFixed = false) {\n\t\tconst fixed = element.getAttribute(`${element.__PREFIX__}fixed`) || \"width\";\n\n\t\tif (!isFixed) {\n\t\t\telement.style[fixed === \"width\" ? \"height\" : \"width\"] = \"\";\n\t\t}\n\t\tconst index = elements.indexOf(element);\n\n\t\tif (!~index) {\n\t\t\treturn;\n\t\t}\n\t\telements.splice(index, 1);\n\t\tif (!elements.length) {\n\t\t\tremoveEvent(window, \"reisze\", onResize);\n\t\t}\n\t}\n\tstatic resize(element, prefix = \"data-\") {\n\t\tconst elementPrefix = typeof element.__PREFIX__ === \"string\" ? element.__PREFIX__ : prefix;\n\t\tconst dataWidth = element.getAttribute(`${elementPrefix}width`);\n\t\tconst dataHeight = element.getAttribute(`${elementPrefix}height`);\n\t\tconst fixed = element.getAttribute(`${elementPrefix}fixed`);\n\n\t\tif (fixed === \"height\") {\n\t\t\tconst size = innerHeight(element) || dataHeight;\n\n\t\t\telement.style.width = `${dataWidth / dataHeight * size}px`;\n\t\t} else {\n\t\t\tconst size = innerWidth(element) || dataWidth;\n\n\t\t\telement.style.height = `${dataHeight / dataWidth * size}px`;\n\t\t}\n\t}\n\tstatic resizeAll() {\n\t\telements.forEach(element => AutoSizer.resize(element));\n\t}\n}\n","import {IS_IE} from \"./consts\";\nimport {addEvent, removeEvent, toArray} from \"./utils\";\nimport AutoSizer from \"./AutoSizer\";\n\n\nexport const CHECK_ALL = 1;\nexport const CHECK_ONLY_ERROR = 2;\n\nfunction isDataAttribute(target, prefix) {\n\treturn !!target.getAttribute(`${prefix}width`);\n}\n\nclass ImageLoaded {\n\tstatic waitImageLoaded(needCheck, {prefix = \"\", length, type, complete, error, end}) {\n\t\tlet checkCount = 0;\n\t\tlet endCount = length;\n\n\t\tif (type !== CHECK_ONLY_ERROR) {\n\t\t\tcheckCount = endCount;\n\t\t}\n\t\tconst checkEnd = function() {\n\t\t\tif (--endCount !== 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tend && end();\n\t\t};\n\t\tconst checkImage = function() {\n\t\t\tcheckCount--;\n\t\t\tif (checkCount !== 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcomplete && complete();\n\t\t};\n\t\tconst onError = function(target, itemIndex = target.__ITEM_INDEX__) {\n\t\t\terror && error({\n\t\t\t\ttarget,\n\t\t\t\titemIndex,\n\t\t\t});\n\t\t};\n\t\tconst onCheck = function(e) {\n\t\t\tconst target = e.target || e.srcElement;\n\n\t\t\tremoveEvent(target, \"error\", onCheck);\n\t\t\tremoveEvent(target, \"load\", onCheck);\n\n\t\t\tif (type === CHECK_ALL && isDataAttribute(target, prefix)) {\n\t\t\t\tAutoSizer.remove(target, e.type === \"error\");\n\t\t\t} else {\n\t\t\t\tcheckImage();\n\t\t\t}\n\t\t\tif (e.type === \"error\") {\n\t\t\t\tonError(target);\n\t\t\t}\n\t\t\tdelete target.__ITEM_INDEX__;\n\t\t\tcheckEnd();\n\t\t};\n\n\t\tneedCheck.forEach((images, i) => {\n\t\t\timages.forEach(v => {\n\t\t\t\t// workaround for IE\n\t\t\t\tif (v.complete && (!IS_IE || (IS_IE && v.naturalWidth))) {\n\t\t\t\t\tif (!v.naturalWidth) {\n\t\t\t\t\t\tonError(v, i);\n\t\t\t\t\t}\n\t\t\t\t\tcheckImage();\n\t\t\t\t\tcheckEnd();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tv.__ITEM_INDEX__ = i;\n\t\t\t\tif (type === CHECK_ALL && isDataAttribute(v, prefix)) {\n\t\t\t\t\tAutoSizer.add(v, prefix);\n\t\t\t\t\tcheckImage();\n\t\t\t\t}\n\t\t\t\taddEvent(v, \"load\", onCheck);\n\t\t\t\taddEvent(v, \"error\", onCheck);\n\n\t\t\t\tIS_IE && v.setAttribute(\"src\", v.getAttribute(\"src\"));\n\t\t\t});\n\t\t});\n\t}\n\tstatic checkImageLoaded(el) {\n\t\tif (el.tagName === \"IMG\") {\n\t\t\treturn el.complete ? [] : [el];\n\t\t} else {\n\t\t\treturn toArray(el.querySelectorAll(\"img\"));\n\t\t}\n\t}\n\tstatic check(elements, {prefix, type = CHECK_ALL, complete, error, end}) {\n\t\tconst images = elements.map(element => this.checkImageLoaded(element));\n\t\tconst length = images.reduce((sum, element) => sum + element.length, 0);\n\n\t\tif (type === CHECK_ONLY_ERROR || length === 0) {\n\t\t\t// convert to async\n\t\t\tsetTimeout(() => {\n\t\t\t\tcomplete && complete();\n\t\t\t\tif (length === 0) {\n\t\t\t\t\tend && end();\n\t\t\t\t}\n\t\t\t}, 0);\n\t\t}\n\t\tif (length > 0) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.waitImageLoaded(images, {prefix, length, type, complete, error, end});\n\t\t\t}, 0);\n\t\t}\n\t}\n}\n\nexport default ImageLoaded;\n","import AutoSizer from \"./AutoSizer\";\nimport ImageLoaded, {CHECK_ALL, CHECK_ONLY_ERROR} from \"./ImageLoaded\";\nimport ItemManager from \"./ItemManager\";\nimport {matchHTML, $} from \"./utils\";\nimport {DUMMY_POSITION} from \"./consts\";\nimport DOMRenderer from \"./DOMRenderer\";\n\nfunction hasTarget(target, value) {\n\treturn ~target.indexOf(value);\n}\n\nexport default class LayoutMananger {\n\tconstructor(items, renderer, options = {}) {\n\t\tObject.assign(this.options = {\n\t\t\tattributePrefix: \"data-\",\n\t\t\tisEqualSize: false,\n\t\t\tisConstantSize: false,\n\t\t\thorizontal: false,\n\t\t}, options);\n\n\t\tthis._items = items;\n\t\tthis._renderer = renderer;\n\t\tthis._layout = null;\n\t}\n\tsetLayout(layout) {\n\t\tthis._layout = layout;\n\t}\n\tsetSize(size) {\n\t\tthis._layout.setSize(size);\n\t}\n\t_complete(groups, items, isAppend, isUpdate, callback) {\n\t\tconst itemManager = this._items;\n\t\tconst cursor = isAppend ? \"end\" : \"start\";\n\t\tconst groupIndex = itemManager.indexOf(groups[0]);\n\t\tconst prevGroup = itemManager.getData(groupIndex + (isAppend ? -1 : 1));\n\t\tlet outline = prevGroup ? prevGroup.outlines[cursor] : [0];\n\n\t\tthis._renderer.updateSize(items);\n\n\t\tconst groupInfos = groups.map(group => {\n\t\t\tconst groupOutline = group.outlines[isAppend ? \"start\" : \"end\"];\n\t\t\tconst isRelayout = isUpdate || !outline.length || (outline.length === groupOutline.length ?\n\t\t\t\t!outline.every((v, index) => v === groupOutline[index]) : true);\n\n\t\t\tif (!isRelayout) {\n\t\t\t\toutline = group.outlines[isAppend ? \"end\" : \"start\"];\n\t\t\t\tDOMRenderer.renderItems(group.items);\n\t\t\t\treturn group;\n\t\t\t}\n\t\t\tconst groupItems = group.items;\n\t\t\tconst groupInfo = this._layout[isAppend ? \"append\" : \"prepend\"](groupItems, outline, true);\n\n\t\t\tObject.assign(group, groupInfo);\n\t\t\tDOMRenderer.renderItems(groupInfo.items);\n\t\t\toutline = groupInfo.outlines[isAppend ? \"end\" : \"start\"];\n\n\t\t\treturn groupInfo;\n\t\t});\n\n\t\tcallback({\n\t\t\tgroups: groupInfos,\n\t\t\titems,\n\t\t\tisAppend,\n\t\t});\n\t}\n\t_error(removeTarget, replaceTarget, target, items, errorIndex, callback) {\n\t\tconst item = items[errorIndex];\n\t\tconst element = item.el;\n\t\tconst prefix = this.options.attributePrefix;\n\n\t\t// remove item\n\t\tconst removeItem = () => {\n\t\t\tif (hasTarget(removeTarget, element)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tremoveTarget.push(element);\n\t\t\tconst index = replaceTarget.indexOf(errorIndex);\n\n\t\t\tindex !== -1 && replaceTarget.splice(index, 1);\n\t\t};\n\t\t// remove image\n\t\tconst remove = () => {\n\t\t\tif (target === element) {\n\t\t\t\tremoveItem();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (hasTarget(removeTarget, element)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget.parentNode.removeChild(target);\n\t\t\titem.content = element.outerHTML;\n\t\t\tif (hasTarget(replaceTarget, errorIndex)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treplaceTarget.push(errorIndex);\n\t\t};\n\t\t// replace image\n\t\tconst replace = src => {\n\t\t\tif (hasTarget(removeTarget, element)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (src) {\n\t\t\t\tif (matchHTML(src) || typeof src === \"object\") {\n\t\t\t\t\tconst parentNode = target.parentNode;\n\n\t\t\t\t\tparentNode.insertBefore($(src), target);\n\t\t\t\t\tparentNode.removeChild(target);\n\t\t\t\t\titem.content = element.outerHTML;\n\t\t\t\t} else {\n\t\t\t\t\ttarget.src = src;\n\t\t\t\t\tif (target.getAttribute(`${prefix}width`)) {\n\t\t\t\t\t\tAutoSizer.remove(target);\n\t\t\t\t\t\ttarget.removeAttribute(`${prefix}width`);\n\t\t\t\t\t\ttarget.removeAttribute(`${prefix}height`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\titem.content = element.outerHTML;\n\t\t\tif (hasTarget(replaceTarget, errorIndex)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treplaceTarget.push(errorIndex);\n\t\t};\n\t\t// replace item\n\t\tconst replaceItem = content => {\n\t\t\tif (hasTarget(removeTarget, element)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telement.innerHTML = content;\n\t\t\titem.content = element.outerHTML;\n\t\t\tif (hasTarget(replaceTarget, errorIndex)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treplaceTarget.push(errorIndex);\n\t\t};\n\n\t\tcallback({\n\t\t\ttarget,\n\t\t\telement,\n\t\t\titems,\n\t\t\titem,\n\t\t\titemIndex: errorIndex,\n\t\t\treplace,\n\t\t\treplaceItem,\n\t\t\tremove,\n\t\t\tremoveItem,\n\t\t});\n\t}\n\t_end(removeTarget, replaceTarget, items, callback) {\n\t\tconst {attributePrefix} = this.options;\n\n\t\tconst removeTargetLength = removeTarget.length;\n\t\tconst replaceTargetLength = replaceTarget.length;\n\n\t\tif (!removeTargetLength && !replaceTargetLength) {\n\t\t\tcallback({remove: []});\n\t\t\treturn;\n\t\t}\n\t\tconst layoutedItems = replaceTarget.map(itemIndex => items[itemIndex]);\n\n\t\tif (!replaceTargetLength) {\n\t\t\tcallback({remove: removeTarget, layout: true});\n\t\t\treturn;\n\t\t}\n\t\t// wait layoutComplete beacause of error event.\n\t\tImageLoaded.check(layoutedItems.map(v => v.el), {\n\t\t\tprefix: attributePrefix,\n\t\t\tcomplete: () => {\n\t\t\t\tthis._renderer.updateSize(layoutedItems);\n\t\t\t\tcallback({remove: removeTarget, layout: true});\n\t\t\t},\n\t\t});\n\t}\n\t_insert({\n\t\tgroups,\n\t\titems = ItemManager.pluck(groups, \"items\"),\n\t\tisAppend,\n\t\tisUpdate,\n\t}, {\n\t\terror = () => {},\n\t\tcomplete = () => {},\n\t\tend = () => {},\n\t}) {\n\t\tif (!groups.length) {\n\t\t\treturn;\n\t\t}\n\t\tconst checkGroups = isAppend ? groups : groups.reverse();\n\t\tconst replaceTarget = [];\n\t\tconst removeTarget = [];\n\t\tconst elements = items.map(item => item.el);\n\t\tconst type = this.options.isEqualSize && this._renderer._size.item ? CHECK_ONLY_ERROR : CHECK_ALL;\n\t\tconst prefix = this.options.attributePrefix;\n\n\t\tImageLoaded.check(elements, {\n\t\t\tprefix,\n\t\t\ttype,\n\t\t\tcomplete: () => {\n\t\t\t\tif (!this._items) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._complete(checkGroups, items, isAppend, isUpdate, complete);\n\t\t\t},\n\t\t\terror: ({target, itemIndex}) => {\n\t\t\t\tif (!this._items) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._error(removeTarget, replaceTarget, target, items, itemIndex, error);\n\t\t\t},\n\t\t\tend: () => {\n\t\t\t\tif (!this._items) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._end(removeTarget, replaceTarget, items, end);\n\t\t\t},\n\t\t});\n\t}\n\tappend({groups, items, isUpdate}, callbacks = {}) {\n\t\tthis._insert({groups, items, isUpdate, isAppend: true}, callbacks);\n\t}\n\tprepend({groups, items, isUpdate}, callbacks = {}) {\n\t\tthis._insert({groups, items, isUpdate, isAppend: false}, callbacks);\n\t}\n\tlayout(isRelayout, groups, items) {\n\t\tconst renderer = this._renderer;\n\t\tconst {isEqualSize, isConstantSize} = renderer.options;\n\t\tconst layoutGroups = groups.filter(group => {\n\t\t\tconst item = group.items[0];\n\n\t\t\treturn item.orgSize && item.rect.top > DUMMY_POSITION / 10;\n\t\t});\n\n\t\tif (!layoutGroups.length) {\n\t\t\treturn [];\n\t\t}\n\t\tlet outline = layoutGroups[0].outlines.start;\n\n\t\tif (isRelayout) {\n\t\t\toutline = [outline.length ? Math.min(...outline) : 0];\n\t\t\tif (!isConstantSize && items.length) {\n\t\t\t\trenderer.updateSize(items);\n\n\t\t\t\t// update invisible items' size\n\t\t\t\tif (isEqualSize && items[0].size) {\n\t\t\t\t\tItemManager.pluck(layoutGroups, \"items\").forEach(item => {\n\t\t\t\t\t\titem.size = Object.assign({}, items[0].size);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis._layout.layout(layoutGroups, outline);\n\t\treturn layoutGroups;\n\t}\n\tdestroy() {\n\t\tthis._items = null;\n\t\tthis._renderer = null;\n\t}\n}\n","/**\n * Copyright (c) 2017 NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport ItemManager from \"./ItemManager\";\nimport DOMRenderer, {resetSize} from \"./DOMRenderer\";\nimport Watcher from \"./Watcher\";\nimport {\n\tAPPEND,\n\tPREPEND,\n\tCACHE,\n\tNO_CACHE,\n\tTRUSTED,\n\tNO_TRUSTED,\n\tIS_ANDROID2,\n\tIDLE,\n\tLOADING_APPEND,\n\tLOADING_PREPEND,\n\tPROCESSING,\n\tDEFENSE_BROWSER,\n\tIGNORE_CLASSNAME,\n\tDUMMY_POSITION,\n\tIS_IOS,\n} from \"./consts\";\nimport Infinite from \"./Infinite\";\nimport {toArray, $, outerHeight, outerWidth} from \"./utils\";\nimport LayoutMananger from \"./LayoutManager\";\n\n// IE8\n// https://stackoverflow.com/questions/43216659/babel-ie8-inherit-issue-with-object-create\n/* eslint-disable */\nif (typeof Object.create !== \"function\") {\n\tObject.create = function (o, properties) {\n\t\tif (typeof o !== \"object\" && typeof o !== \"function\") {\n\t\t\tthrow new TypeError(\"Object prototype may only be an Object: \" + o);\n\t\t} else if (o === null) {\n\t\t\tthrow new Error(\"This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.\");\n\t\t}\n\t\tfunction F() {}\n\t\tF.prototype = o;\n\t\treturn new F();\n\t};\n}\n/* eslint-enable */\n\n/**\n * A module used to arrange card elements including content infinitely according to layout type. With this module, you can implement various layouts composed of different card elements whose sizes vary. It guarantees performance by maintaining the number of DOMs the module is handling under any circumstance\n * @ko 콘텐츠가 있는 카드 엘리먼트를 레이아웃 타입에 따라 무한으로 배치하는 모듈. 다양한 크기의 카드 엘리먼트를 다양한 레이아웃으로 배치할 수 있다. 카드 엘리먼트의 개수가 계속 늘어나도 모듈이 처리하는 DOM의 개수를 일정하게 유지해 최적의 성능을 보장한다\n * @alias eg.InfiniteGrid\n * @extends eg.Component\n *\n * @example\n```\n