export declare const fsp = "\n(function () {\n const isDebug = isDebugFsp();\n const nope = function () {};\n const print = isDebug ? console.log.bind(console.log, 'jt_sfsp: ') : nope;\n const ignoreAttrName = 'data-jstracker-nofsp';\n const stopEvents = ['mousedown', 'touchstart'];\n\n if (typeof window === 'undefined' || typeof performance === 'undefined' || typeof MutationObserver === 'undefined' || typeof screen == 'undefined') {\n if (typeof module !== 'undefined') {\n module.exports = {\n on: nope,\n un: nope,\n forceStop: nope,\n install: nope,\n };\n }\n return;\n }\n\n const NOT_DEEP_IN = {\n SCRIPT: 1,\n LINK: 1,\n HEAD: 1,\n MATE: 1,\n TITLE: 1,\n STYLE: 1,\n BR: 1,\n SVG: 2,\n IMG: 2,\n CANVAS: 2,\n VIDEO: 2,\n };\n\n const { width: screenWidth, height: screenHeight } = screen;\n const { clientWidth: pageWidth, clientHeight: pageHeight } = document.documentElement;\n\n const miniBorderSize = Math.round(Math.max(Math.min(screenWidth, screenHeight) * 0.02, 12));\n const bottomBarHeight = Math.round(screenHeight * 0.05);\n\n // \u9996\u5C4F\u5185\u5BB9\u5C3A\u5BF8.\n const contentHeight = Math.min(pageHeight, screenHeight);\n const contentWidth = Math.min(pageWidth, screenWidth);\n const contentArea = contentHeight * contentWidth;\n\n // \u6700\u5927\u76D1\u63A7\u65F6\u957F\uFF0C\u5F53\u9875\u9762\u6CA1\u6709\u8F6E\u64AD\u5185\u5BB9\uFF0C\u5E94\u4F9D\u8D56 maxRenderIdle\uFF0C\u6709\u8F6E\u64AD\u5185\u5BB9\u65F6\u4F1A\u5BFC\u81F3\u9875\u9762\u6301\u7EED\u7684dom\u53D8\u66F4\u548C\u6E32\u67D3\uFF0C\u6700\u7EC8\u4F9D\u8D56\u8BE5\u6761\u4EF6\u505C\u6B62;\n const MAX_RUNNING_LIMIT = 30 * 1000;\n const maxRenderIdle = 3 * 1000;\n\n const frames = [];\n let maxHandleTimer = null;\n let isStop = false;\n let ignoreBucket = null;\n let idleTimer = null;\n let timeBoard = null;\n let haveIgnoreAttr = false;\n let execCost = 0;\n\n // print({ screenWidth, screenHeight, pageWidth, pageHeight, miniBorderSize, bottomBarHeight });\n\n const output = {\n version: '20221212',\n listeners: [],\n lazy: function () {\n if (!maxHandleTimer) {\n init();\n }\n },\n on: function (fn) {\n if (this.listeners.indexOf(fn) === -1) {\n this.listeners.push(fn);\n }\n },\n un: function (fn) {\n if (fn) {\n let i = this.listeners.indexOf(fn);\n this.listeners.splice(i, 1);\n }\n },\n forceStop: function () {\n // \u5F3A\u5236\u505C\u6B62; \u76F4\u63A5\u4EE5\u5F53\u524D\u6E32\u67D3\u60C5\u51B5\u5F00\u59CB\u5224\u5B9A\u9996\u5C4F\u65F6\u95F4;\n stopHandle({ type: 'force' });\n },\n _fn: function (result) {\n let fn;\n for (let index in this.listeners) {\n fn = this.listeners[index];\n fn && fn(result);\n }\n this.listeners = [];\n },\n getFrames: function () {\n return frames;\n },\n getIgnoreNodes: function () {\n return ignoreBucket;\n },\n install: function () {\n init();\n },\n getXPATH,\n };\n\n let isMyTime = false; // \u9632\u6B62\u5728\u9875\u9762\u88AB\u5F15\u7528\u591A\u6B21\n if (window._JT_FSP) {\n output.listeners = window._JT_FSP.listeners;\n output.forceStop = window._JT_FSP.forceStop;\n isStop = true;\n } else {\n window._JT_FSP = output;\n isMyTime = true;\n }\n\n let mutationObserver = new MutationObserver(handleDOMChange);\n\n // if (document) {\n // isLazy() || init();\n // }\n\n function init() {\n if (!isMyTime || !!maxHandleTimer || isStop) {\n return;\n }\n\n // \u521B\u5EFA\u5DF2\u6709\u5FFD\u7565\u96C6\n ignoreBucket = [];\n timeBoard = TimePointer();\n\n // \u4FDD\u8BC1\u6267\u884C,\u76F4\u63A5\u4EE5html\u4E3A\u6839\n const rootElement = document.firstElementChild;\n\n // \u5982\u679C\u6709body\uFF0C\u5219\u662Ftracker\u88AB\u63D2\u5230\u9875\u9762\u4E0B\u65B9, \u6B64\u65F6\u9875\u540C\u4E2D\u53EF\u80FD\u6709\u5185\u5BB9\u4F46readyState\u4E0D\u4E3Acomplete\uFF0C\u5C3D\u65E9\u542F\u52A8;\n if (document.body) {\n const bodyChild = document.querySelectorAll('BODY > *');\n\n if (bodyChild.length > 0) {\n // \u5982\u679Cbody\u5DF2\u6709\u5185\u5BB9\uFF0C\u5219\u627E\u4E00\u6B21\u5FFD\u7565\u5143\u7D20\n forEach(document.querySelectorAll(\"[\" + ignoreAttrName + \"]\"), (one) => {\n ignoreBucket.push(one);\n haveIgnoreAttr = true;\n });\n\n // body\u7684\u76F4\u63A5\u540E\u4EE3. \u540C\u6B65\u5185\u5BB9\u4E0D\u7528\u7BA1\uFF0C\u5F02\u6B65\u5185\u5BB9\u53EA\u7BA1\u56FE\u7247\uFF0C \u6700\u5C0F\u503C\u4F1A\u53D6fp\u6216fcp\u4E0D\u518D\u4EE5\u9996\u6B21\u6267\u884C\u65F6\u95F4\u4E3A\u51C6\n makeFrames(document.querySelectorAll('BODY IMG'), true);\n }\n }\n\n timeBoard();\n\n mutationObserver.observe(rootElement, {\n childList: true,\n subtree: true,\n });\n\n const handleUserEvent = () => {\n // \u7528\u6237\u4EA4\u4E92\u4E8B\u4EF6\u505C\u6B62\n stopEvents.forEach(ename => rootElement.addEventListener(ename, stopHandle, true));\n };\n\n if (document.readyState !== 'loading') {\n handleUserEvent();\n } else {\n document.addEventListener('DOMContentLoaded', handleUserEvent);\n }\n\n // \u6700\u5927\u76D1\u63A7\u65F6\u95F4\n maxHandleTimer = setTimeout(() => {\n stopHandle({ type: 'timeout' });\n }, MAX_RUNNING_LIMIT);\n }\n\n window.fspTracker=output;\n window.fspTracker.install();\n window.fspTracker.listeners=[function(fsp){console.log('[fsp-report-in-html]',fsp);window.__FSP=fsp}];\n \n let delayTimer = null;\n let addDoms = [];\n function handleDOMChange(records) {\n if (isStop) {\n return;\n }\n\n forEach(records, (record) => {\n const { target, addedNodes } = record;\n const { nodeName } = target;\n\n if (NOT_DEEP_IN[nodeName] === 1) {\n return;\n }\n\n if (someList(ignoreBucket, (one) => one && one.contains && one.contains(target))) {\n return;\n }\n\n if (frames.length > 0 && nodeName !== 'HTML' && nodeName !== 'BODY') {\n const { top, left, bottom, right } = target.getBoundingClientRect();\n // \u4F4D\u7F6E\u68C0\u6D4B,\u4E0D\u4FEE\u6B63\u5373\u8D85\u51FA\u9996\u5C4F\u7684\u76F4\u63A5\u8FD4\u56DE, \u540C\u65F6\u63A7\u5236\u4E0D\u5411\u4E0B\u8FED\u4EE3\n if (bottom < bottomBarHeight || top > contentHeight - bottomBarHeight || right < bottomBarHeight || left > contentWidth - bottomBarHeight) {\n return;\n }\n }\n\n forEach(addedNodes, (node) => {\n try {\n // \u65E0\u4E0A\u5C42\u5143\u7D20\uFF0C\u8868\u793A\u5DF2\u5220\u9664, \u4E00\u822C\u4E3A\u9AA8\u67B6\u5C4F\u5360\u4F4D\u7C7B\u5185\u5BB9\n if (!node.parentElement) {\n return;\n }\n let c = node;\n if (isValidTextNode(node) && node.parentElement.childNodes.length === 1) {\n c = node.parentElement;\n }\n // \u4EC5\u6392\u9664\u975E\u5143\u7D20\u8282\u70B9\uFF0C\u4E0D\u53EF\u89C1\u5143\u7D20\u9762\u79EF\u4E3A0 \u8BA1\u7B97\u65F6\u4F1A\u76F4\u63A5\u88AB\u5FFD\u7565\uFF0C\u65E0\u9700\u7279\u522B\u8FC7\u6EE4;\n if (c.nodeType !== 1 && c.nodeType !== 9) {\n return;\n }\n\n if (NOT_DEEP_IN[c.nodeName] === 1) {\n return;\n }\n\n const isSub = someList(addDoms, (one) => one.contains(c));\n !isSub && addDoms.push(c);\n } catch (err) { }\n });\n });\n\n if (addDoms.length > 0) {\n // \u6BCF\u79D260\u5E27\u63A7\u901F..\n if (delayTimer === null) {\n // let t = now();\n delayTimer = setTimeout(() => {\n // print('wait delay timer...', now() - t);\n makeFrames(addDoms);\n addDoms = [];\n delayTimer = null;\n }, 1000 / 60);\n }\n }\n }\n\n function updateLastTime(frameObj, time) {\n if (isStop) {\n return;\n }\n timeBoard();\n time = time || now();\n const { top, left, bottom, right } = frameObj;\n\n const frameHeight = Math.abs(bottom - top);\n const frameWidth = Math.abs(right - left);\n\n // \u6700\u540E\u66F4\u65B0\u7684\u5185\u5BB9\u65F6\u95F4\n frameObj.lastTime = Math.max(time, frameObj.lastTime);\n\n // \u5F71\u54CD\u8303\u56F4\n frameObj.v = Math.floor(frameHeight * frameWidth / contentArea * 10000) / 10000;\n\n idleTimer && clearTimeout(idleTimer);\n idleTimer = setTimeout(() => {\n stopHandle({ type: 'idle' });\n }, maxRenderIdle);\n\n const size = frames.length;\n\n // \u5C0F\u4E8E\u5C3E\u90E8\u5224\u65AD\u6761\u4EF6\u65E0\u6267\u884C\u610F\u4E49\n if (size < 4) {\n return;\n }\n\n let sumArea = 0;\n let maxAreaFrame = 0;\n let s = 0;\n\n let pGroup = {};\n for (let aIndex = 0; aIndex < size; aIndex++) {\n const ac = frames[aIndex];\n ac.g = (ac.g || aIndex + 1);\n\n // \u56FE\u7247\u53EF\u80FD\u672A\u8FD4\u56DE\uFF0C\u5B58\u5728\u8F83\u5C0F\u9762\u79EF.. \u6392\u9664\u5373\u53EF.\n if (ac.bottom - ac.top < miniBorderSize || ac.right - ac.left < miniBorderSize) {\n continue;\n }\n\n sumArea += Math.min(ac.v, 1);\n\n if (ac.v >= s) {\n s = ac.v;\n maxAreaFrame = aIndex;\n }\n\n if (sumArea > 4) {\n // \u7EDF\u8BA1\u6E32\u67D3\u9762\u79EF\u8FC7\u5927.\n stopHandle({ type: 'sum_area', p: maxAreaFrame });\n break;\n }\n\n for (let bIndex = 0; bIndex < aIndex; bIndex++) {\n const bc = frames[bIndex];\n\n // \u56FE\u7247\u53EF\u80FD\u672A\u8FD4\u56DE\uFF0C\u5B58\u5728\u8F83\u5C0F\u9762\u79EF.. \u6392\u9664\u5373\u53EF.\n if (bc.bottom - bc.top < miniBorderSize || bc.right - bc.left < miniBorderSize) {\n continue;\n }\n\n let d = isNear(ac, bc, miniBorderSize);\n if (d) {\n const g = ac.g = bc.g;\n pGroup[g] = (pGroup[g] || 0) + 1;\n if (pGroup[g] >= 3) {\n // \u76F8\u8FD1\u4F4D\u7F6E\uFF0C\u8FDE\u7EED\u66F4\u65B0, \u5EFA\u7EC4\u65F6\u9ED8\u8BA4+1\u9632\u6B620\u4E0D\u597D\u5224\u65AD\u3002\n stopHandle({ type: 'tail', p: g - 1 });\n }\n break;\n }\n }\n }\n\n // do {\n // current = frames[n];\n // nextOne = frames[n - 1];\n\n // // \u56FE\u7247\u53EF\u80FD\u672A\u8FD4\u56DE\uFF0C\u5B58\u5728\u8F83\u5C0F\u9762\u79EF.. \u6392\u9664\u5373\u53EF.\n // if (current.bottom - current.top < miniBorderSize || current.right - current.left < miniBorderSize) {\n // continue;\n // }\n\n // if (isNear(current, nextOne, miniBorderSize)) {\n // tail++;\n // } else {\n // sumArea += current.v;\n // if (current.v >= s) {\n // s = current.v;\n // maxAreaFrame = n;\n // }\n\n // if (sumArea > 4) {\n // // \u7EDF\u8BA1\u6E32\u67D3\u9762\u79EF\u8FC7\u5927.\n // stopHandle({ type: 'sum_area', p: maxAreaFrame + 1 });\n // break;\n // } else if (tail > 3) {\n // // \u76F8\u8FD1\u4F4D\u7F6E\uFF0C\u8FDE\u7EED\u66F4\u65B0\n // stopHandle({ type: 'tail', p: n });\n // break;\n // }\n // tail = 0;\n // }\n // } while (--n > 0);\n }\n /**\n *\n * @param {*} args\n */\n function makeFrames(addDoms) {\n try {\n const { meaningfulList, box: frameObj, cost } = findViewRectInFirstScreen(addDoms);\n\n if (!frameObj || !frameObj.count) {\n return;\n }\n\n frames.push(frameObj);\n execCost += cost;\n print(\"makeFrames cost:\" + cost + \"ms; frames count: \" + frames.length, frameObj);\n\n frameObj.wait = 0;\n frameObj.imgSeq = [];\n\n forEach(meaningfulList, (node) => {\n const { nodeName } = node;\n if (nodeName === 'IMG') {\n frameObj.wait += 1;\n let loadCount = node.complete ? 1 : 0;\n let firstSrc = node.src;\n\n const handleLoadEvent = function () {\n let p = null;\n\n if (isStop) {\n // \u53BB\u6389\u4E86 img.complete\u5224\u65AD\uFF0C\u7528\u4E8E\u5904\u7406\u66FF\u6362src\u7684\u4E8C\u6B21\u8F7D\u5165, \u8FD9\u91CC\u5728\u505C\u6B62\u540E\uFF0C\u5378\u6389onload\u7B49\u4E8B\u4EF6;\n node.removeEventListener('load', handleLoadEvent, true);\n return;\n }\n\n if (loadCount > 0) {\n if (node.src === firstSrc) {\n // print('loaded same src', firstSrc, now());\n return;\n } else {\n print('img change src', firstSrc, node.src, now());\n }\n }\n\n // \u4EC5\u5141\u8BB8\u8F83\u65E9\u63D2\u5165\u7684\u56FE\u7247\u4E8C\u6B21\u8F7D\u5165. \u4E14\u5927\u4E8E2\u6B21\u5FFD\u7565\n if (++loadCount > 2 && frameObj.startTime > 1000) {\n return;\n }\n\n // try {\n // p = node.decode && node.decode();\n // } catch (e) {}\n\n waitRenderTime(() => {\n const { top, left, bottom, right, width, height } = node.getBoundingClientRect();\n\n // \u4E8C\u6B21\u68C0\u6D4B\u9762\u79EF\uFF0C\u8FC7\u5C0F\u5FFD\u7565\n if (width < miniBorderSize || height < miniBorderSize) {\n return;\n }\n\n // \u4F4D\u7F6E\u68C0\u6D4B,\u4E0D\u4FEE\u6B63\u5373\u8D85\u51FA\u9996\u5C4F\u7684\u76F4\u63A5\u8FD4\u56DE, \u540C\u65F6\u63A7\u5236\u4E0D\u5411\u4E0B\u8FED\u4EE3\n if (bottom < bottomBarHeight || top > contentHeight - bottomBarHeight || right < bottomBarHeight || left > contentWidth - bottomBarHeight) {\n return;\n }\n\n // isDebug && print('image loaded', /^data:/i.test(node.src) ? 'Base64_Image' : node.src, now(), loadCount);\n\n frameObj.left = Math.min(left, frameObj.left);\n frameObj.top = Math.min(top, frameObj.top);\n frameObj.bottom = Math.max(frameObj.bottom, top + height);\n frameObj.right = Math.max(frameObj.right, left + width);\n\n frameObj.imgSeq.push({ node, time: now() });\n updateLastTime(frameObj);\n }, p);\n };\n node.addEventListener('load', handleLoadEvent, true);\n } else if (nodeName === 'VIDEO' && node.poster) {\n frameObj.bgImg.push(node.poster);\n }\n });\n\n updateLastTime(frameObj);\n } catch (err) {}\n }\n\n function profileResourceTiming(checkList, callback, notWaitingLoadEvent) {\n let navigationTiming = fakeTiming();\n const { loadEventStart } = navigationTiming;\n\n // \u5224\u65ADload\u72B6\u6001\uFF0C\u5B8C\u6210\u5219\u76F4\u63A5\u5224\u65ADSSR\u5185\u5BB9\u65F6\u95F4, \u5426\u5219\u7B49\u5F85load\u4E8B\u4EF6\n if ((notWaitingLoadEvent !== true) && loadEventStart <= 0) {\n // print('Waiting loaded event...');\n waitPageLoadOrMaxTime(() => profileResourceTiming(checkList, callback, true));\n return;\n }\n\n const timingMap = {};\n let fcp = -1, fp = -1;\n let ssrVal = 0;\n let lastImg = null;\n\n const list = performance.getEntries();\n forEach(list, (one) => {\n const { entryType, name, startTime, duration } = one;\n if (entryType == 'paint') {\n switch (name) {\n case 'first-contentful-paint':\n fcp = startTime;\n break;\n case 'first-paint':\n fp = startTime;\n break;\n }\n } else {\n timingMap[pureUrl(name)] = startTime + duration;\n }\n });\n\n let checkResult = {};\n let checkResultMaxValue = 0;\n if (checkList && checkList.length > 0) {\n forEach(checkList, (img) => {\n img = pureUrl(img);\n if (timingMap[img]) {\n print('check img from resourceTiming: ', img, timingMap[img]);\n checkResult[img] = timingMap[img];\n checkResultMaxValue = Math.max(checkResult[img], checkResultMaxValue);\n }\n });\n }\n\n // check ssr time\n if (loadEventStart > 0) {\n let cacheList = [];\n let domList = document.body && document.body.querySelectorAll('*[style]');\n\n const checkImgElement = (dom, imgSrc, cacheList) => {\n imgSrc = pureUrl(imgSrc);\n // \u6CA1\u56FE\u7247\u6216base64\n if (!imgSrc || /^data:/i.test(imgSrc)) {\n return;\n }\n\n const time = timingMap[imgSrc];\n if (time > loadEventStart) {\n return;\n }\n\n const box = createScreenBox(dom, cacheList);\n\n if (!box) {\n return; // \u4E0D\u5728\u9996\u5C4F\n }\n\n const { width, height } = box;\n // \u5F71\u54CD\u8303\u56F4\n // const v = Math.floor(height * width / contentArea * 10000) / 10000;\n\n // \u5355\u4E2Adom\u5143\u7D20\u4E0D\u5408\u5E76\uFF0C\u4E0D\u4F7F\u7528\u603B\u9762\u79EF2%\u6761\u4EF6. \u5426\u5219\u629B\u5F03\u5185\u5BB9\u8FC7\u591A;\n if (box.isCutoff == false && width > miniBorderSize && height > miniBorderSize) {\n if (ssrVal < time) {\n ssrVal = time;\n lastImg = dom;\n }\n } else {\n print('small size img', dom);\n }\n };\n\n if (domList && domList.length > 0) {\n // \u5C3D\u91CF\u68C0\u6D4B\u5230\u6709\u80CC\u666F\u5185\u5BB9\u7684\u5143\u7D20\n forEach(domList, (one) => {\n const regTestUrl = /url\\(['\"]?(.*?)['\"]?\\)/i;\n let bgImgUrl = regTestUrl.exec((one.style && one.style.backgroundImage) || '');\n bgImgUrl = bgImgUrl && bgImgUrl[1];\n checkImgElement(one, bgImgUrl, cacheList);\n });\n }\n\n forEach(document.images, (one) => checkImgElement(one, one.src, cacheList));\n }\n\n callback({ ssrTime: Math.max(ssrVal, fcp, fp), fcp, fp, ssrLastImg: lastImg, checkResult, checkResultMaxValue });\n }\n\n // \u505C\u6B62\n function stopHandle(args) {\n if (isStop) {\n return;\n }\n const { type, p } = args;\n\n let fcp = 0;\n let t = now();\n try {\n let entry = performance.getEntriesByName('first-contentful-paint')[0];\n if (entry && entry.startTime) {\n fcp = entry.startTime;\n }\n if (stopEvents.indexOf(type) != -1 && (fcp === 0 || (now() - fcp < 200))) {\n print('no fcp, ignore mousedown', t);\n return;\n }\n } catch (e) {}\n\n maxHandleTimer && clearTimeout(maxHandleTimer);\n idleTimer && clearTimeout(idleTimer);\n\n isStop = true;\n\n if (mutationObserver) {\n // \u505C\u6B62\u76D1\u542C\n mutationObserver.disconnect();\n // \u6E05\u9664\u672A\u5904\u7406\u7684\u53D8\u52A8\n mutationObserver.takeRecords();\n mutationObserver = null;\n }\n\n let validFrames = null;\n let waitingCheckFromResourceTiming = [];\n\n function noMini(frames) {\n let list = [];\n if (frames.length <= 1) {\n list = frames.slice(0);\n const { bgImg } = list[0] || {};\n if (bgImg) {\n forEach(bgImg, i => waitingCheckFromResourceTiming.push(i));\n }\n } else {\n forEach(frames, (one) => {\n const { v, bgImg } = one;\n if (v < 0.02) {\n return;\n }\n\n if (bgImg) {\n forEach(bgImg, i => waitingCheckFromResourceTiming.push(i));\n }\n\n list.push(one);\n });\n }\n return list;\n }\n\n // \u51B3\u5B9A\u9996\u5C4F\u65F6\u95F4\n switch (type) {\n case 'tail':\n case 'sum_area':\n // TODO: \u6B64\u5904\u6781\u5C0F\u6982\u7387\u78B0\u5230\u5939\u7F1D\u95EE\u9898\u5373\u9884\u5230\u5806\u6808\u8BB0\u5F55\u4E3A XXXABAAAA \u65F6\u4F1A\u5C06\u591A\u4F59\u7684B\u4E00\u5E76\u51CF\u6389. \u540E\u7EED\u53EF\u8003\u8651\u4F18\u5316.\n validFrames = noMini(frames.slice(0, p));\n break;\n default:\n // \u6B63\u5E38\u505C\u6B62\uFF0C\u4EE5\u8D85\u7A33\u5B9A\u65F6\u9650\uFF0C\u961F\u5217\u4E2D\u53BB\u9664\u5C0F\u9762\u79EF\u53CA\u540C\u4F4D\u7F6E\u66F4\u65B0.\n let list = noMini(frames);\n // \u5C0F\u4E8E 2 \u4E0D\u5B58\u5728\u53EF\u6D88\u9664\u957F\u5C3E\n let n = list.length;\n if (n >= 2) {\n n--;\n let t = 0;\n do {\n const current = list[n];\n const nextOne = list[n - 1];\n if (isNear(current, nextOne, miniBorderSize)) {\n t++;\n // console.log('find tail,', current, nextOne);\n } else {\n break;\n }\n } while (--n > 0);\n\n if (t > 0) {\n // \u5982\u679C n \u4E3A0\uFF0C\u5219\u5168\u90E8\u4E3A\u540C\u4F4D\u7F6E\u66F4\u65B0\uFF0C\u8868\u793A\u4E00\u76F4\u5728\u6574\u9875\u66F4\u65B0\u57FA\u672C\u4E3A\u6574\u9875\u4E8C\u5237\uFF0C\u4FDD\u7559\u6700\u524D\u4E00\u5E27\uFF0C\u514D\u5F97\u6328\u9A82.\n (n === 0) && print('Full Screen Reflash x 2.');\n list = list.slice(0, n || 1);\n }\n }\n validFrames = list;\n }\n let timeCost = 0, lastFrame = null;\n if (validFrames.length) {\n forEach(validFrames, (one) => {\n if (one.lastTime > timeCost) {\n timeCost = one.lastTime;\n lastFrame = one;\n }\n });\n } else {\n timeCost = fcp;\n }\n\n profileResourceTiming(waitingCheckFromResourceTiming, (data) => {\n try {\n const { ssrTime, fcp, fp, ssrLastImg, checkResult, checkResultMaxValue } = data;\n\n if (checkResultMaxValue > timeCost) {\n timeCost = checkResultMaxValue;\n }\n\n const timestamp = (performance.timeOrigin || performance.timing.navigationStart) + timeCost;\n print(\"stopHandleBy \" + type + \", sfsp: \" + \"timeCost\" + \", checkImg: \" + checkResultMaxValue + \", ssrTime: \" + ssrTime + \", fcp: \" + fcp + \", fp: \" + fp + \", ssrLastImg: \", ssrLastImg, validFrames, checkResult);\n\n const { domSize, imgSeq } = lastFrame || {};\n\n let xPathLastImg = '';\n try {\n if (imgSeq && imgSeq.length > 0) {\n xPathLastImg = getXPATH(imgSeq[imgSeq.length - 1].node);\n }\n } catch (err) {}\n\n const result = {\n endType: (stopEvents.indexOf(type) != -1 ? stopEvents[0] : type),\n timestamp,\n cost: timeCost,\n domSize: domSize,\n validFrames: validFrames,\n ssrTime,\n ssrLastImg,\n bgImgRecord: checkResult,\n bgImgMaxTime: checkResultMaxValue,\n fcp,\n fp,\n haveIgnoreAttr,\n lastImg: xPathLastImg,\n execCost,\n version: output.version,\n };\n\n // \u81EA\u5B9A\u4E49__SSR_TRACE_ID\n window.__SSR_TRACE_ID = 'fcp:' + fcp + ',fp:' + fp;\n\n if (window.dispatchEvent && window.CustomEvent) { // ie9 \u4EE5\u4E0B\u4E0D\u5B58\u5728\n let evt = new CustomEvent('jstracker.fsp', { detail: result });\n window.dispatchEvent(evt);\n }\n\n try {\n output._fn(result);\n } catch (err) {}\n\n timeBoard(timeCost);\n\n if (!isDebug) {\n frames.length = 0;\n ignoreBucket && (ignoreBucket.length = 0, ignoreBucket = null);\n }\n } catch (err) {}\n }, type === 'force');\n }\n\n /**\n * dom\u5B50\u6811\u53EF\u89C6\u8303\u56F4\u83B7\u53D6.\n * @param {*} node\n */\n function findViewRectInFirstScreen(list, cacheObj = []) {\n const t0 = now();\n const box = {\n startTime: t0,\n lastTime: t0,\n left: Number.MAX_SAFE_INTEGER,\n top: Number.MAX_SAFE_INTEGER,\n right: 0,\n bottom: 0,\n count: 0,\n searchNodes: 0,\n bgImg: [],\n domSize: currentDomSize(),\n };\n\n const meaningfulList = box.meaningfulList = [];\n\n const mergeBox = (b, deepOne) => {\n if (b) {\n const { top, left, width, height, backgroundImage } = b;\n box.left = Math.min(left, box.left);\n box.top = Math.min(top, box.top);\n box.bottom = Math.max(box.bottom, top + height);\n box.right = Math.max(box.right, left + width);\n meaningfulList.push(deepOne);\n box.count++;\n backgroundImage && box.bgImg.push(backgroundImage);\n }\n };\n\n const checkFn = (deepOne) => {\n box.searchNodes++;\n const r = createScreenBox(deepOne, cacheObj);\n if (r) {\n mergeBox(r, deepOne);\n return true;\n }\n return r;\n };\n\n forEach(list, (one) => {\n const flag = NOT_DEEP_IN[one.nodeName] || 3;\n if (flag < 2) {\n return;\n }\n (checkFn(one) !== 0) && forEach(findMeaningfulDom(one, []), checkFn);\n });\n\n return { meaningfulList, cacheObj, box, cost: now() - t0 };\n }\n\n if (isDebug) {\n output.findViewRectInFirstScreen = findViewRectInFirstScreen;\n output.createScreenBox = createScreenBox;\n output.findMeaningfulDom = findMeaningfulDom;\n }\n\n function createScreenBox(node, cacheObj) {\n let cacheItem = null;\n\n if (!cacheObj) {\n cacheObj = [];\n }\n\n if (cacheItem = findCache(cacheObj, node)) {\n if (cacheItem.result) {\n return cacheItem.result;\n }\n } else {\n cacheItem = createCacheItem(node);\n cacheObj.push(cacheItem);\n\n // \u81EA\u8EAB\u6807\u8BB0\u5FFD\u7565\n if (cacheItem.ignore) {\n ignoreBucket.push(node);\n return cacheItem.result = 0;\n }\n\n // \u5DF2\u77E5\u7236\u8282\u70B9\u4E2D\u6807\u8BB0\u5FFD\u7565\n if (someList(ignoreBucket, (one) => one && one.contains && one.contains(node))) {\n return cacheItem.result = 0;\n }\n }\n const { backgroundImage = null, pBox: nodeBox } = cacheItem;\n let { top, left, bottom, right, width, height } = nodeBox;\n let isCutoff = false;\n let b = 4; // \u8BA9\u8FB9\uFF0C\u9632\u6B62\u8FB9\u6846\u548C\u4EC5\u663E\u793A\u4E00\u6761\u7EBF\u7684\u5F71\u54CD.\n let pCheck = true;\n // \u56FE\u7247\u53EF\u80FD\u6CA1\u8BBE\u5BBD\u9AD8. \u7B49\u8F7D\u5165\u5B8C\u518D\u770B\u9762\u79EF;\n if (node.nodeName === 'IMG' && node.complete !== true && (width === 0 || height === 0)) {\n pCheck = false;\n } else {\n // \u9762\u79EF\u68C0\u6D4B\n if (width < miniBorderSize || height < miniBorderSize) {\n // console.log('ignore image:', node.src);\n return cacheItem.result = false;\n }\n\n // \u4F4D\u7F6E\u68C0\u6D4B,\u4E0D\u4FEE\u6B63\u5373\u8D85\u51FA\u9996\u5C4F\u7684\u76F4\u63A5\u8FD4\u56DE, \u540C\u65F6\u63A7\u5236\u4E0D\u5411\u4E0B\u8FED\u4EE3\n if (bottom < bottomBarHeight || top > screenHeight - bottomBarHeight || right < bottomBarHeight || left > screenWidth - bottomBarHeight) {\n return cacheItem.result = 0;\n }\n }\n\n let p = node.parentElement;\n let parentCacheItem = null;\n const pageScrollElement = (document.scrollingElement || document.documentElement);\n\n while (p) {\n parentCacheItem = findCache(cacheObj, p);\n if (!parentCacheItem) {\n parentCacheItem = createCacheItem(p);\n\n if (parentCacheItem.ignore) {\n ignoreBucket.push(p);\n }\n\n cacheObj.push(parentCacheItem);\n }\n\n if (parentCacheItem.ignore) {\n return cacheItem.result = 0;\n }\n\n const { scrollTop, scrollLeft, scrollHeight, scrollWidth, clientHeight, clientWidth, overflowX, overflowY } = parentCacheItem;\n\n // \u68C0\u6D4B\u7236\u5143\u7D20\u662F\u5426\u6709\u6EDA\u52A8\n if ((scrollHeight > clientHeight && (p === pageScrollElement || overflowY !== 'visible')) || (scrollWidth > clientWidth && (p === pageScrollElement || overflowX !== 'visible'))) {\n // \u6709\u6EDA\u52A8\u8FD8\u539F\u6EDA\u52A8\u504F\u79FB\n top += scrollTop;\n bottom += scrollTop;\n\n left += scrollLeft;\n right += scrollLeft;\n\n // \u68C0\u67E5\u8FD8\u539F\u4F4D\u7F6E\u540E\u7684\u5185\u5BB9\u662F\u5426\u5728\u7236\u5143\u7D20\u7684\u6EDA\u52A8\u533A\u5185\u663E\u793A\n const pBox = parentCacheItem.box ? parentCacheItem.box : p.getBoundingClientRect();\n\n parentCacheItem.box = parentCacheItem.box || pBox;\n\n if ((top - pBox.bottom) > b || (left - pBox.right) > b || (pBox.top - bottom) > b || (pBox.left - right) > b) {\n // isCutoff = isCutoff || true;\n return cacheItem.result = false;\n }\n }\n p = p.parentElement;\n parentCacheItem = null;\n }\n\n isCutoff = isCutoff || top >= contentHeight || left >= contentWidth;\n\n // \u4F4D\u7F6E\u68C0\u6D4B\n if (pCheck && (bottom < bottomBarHeight || top > contentHeight - bottomBarHeight || right < bottomBarHeight || left > contentWidth - bottomBarHeight)) {\n return cacheItem.result = false;\n }\n\n return cacheItem.result = { top, left, width, height, isCutoff, backgroundImage };\n }\n\n // ==== utils ====\n\n // \u5904\u7406\u56FE\u7247\u6E32\u67D3, \u6709\u652F\u6301decode\u65F6\u5F85decode\u5B8C\u6210\uFF0C\u4E0D\u652F\u6301decode\u65F6\uFF0C\u4EC5\u5EF6\u8FDF\u4E00\u6B21\u6E32\u67D3;\n function waitRenderTime(cb, p) {\n if (p && p.then && p.catch) {\n p.then(() => {\n waitRenderTime(cb);\n }).catch(() => {\n waitRenderTime(cb);\n });\n } else if (window.requestAnimationFrame) {\n requestAnimationFrame(cb);\n } else {\n setTimeout(cb, 0);\n }\n }\n\n function waitPageLoadOrMaxTime(callback) {\n let timer = null;\n let once = 0;\n const fn = () => {\n timer && clearTimeout(timer);\n window.removeEventListener('load', fn);\n if (once++ === 0) {\n callback();\n }\n };\n\n timer = setTimeout(fn, MAX_RUNNING_LIMIT - now());\n window.addEventListener('load', fn);\n }\n\n // \u6B27\u6C0F\u8DDD\u79BB\uFF0C\u8BA1\u7B97\u89D2\u70B9\u662F\u5426\u76F8\u8FD1\n function isNear(b1, b2, d = 8) {\n const l1 = Math.sqrt(Math.pow(b1.top - b2.top, 2) + Math.pow(b1.left - b2.left, 2));\n const l2 = Math.sqrt(Math.pow(b1.bottom - b2.bottom, 2) + Math.pow(b1.right - b2.right, 2));\n // \u5DE6\u4E0A\u53CA\u53F3\u4E0B\u89D2\u70B9\u7684\u8DDD\u79BB\uFF0Cd\u505A\u4E3A\u534A\u5F84. \u5B9E\u9645\u8DDD\u79BB\u505A\u4E582\u5904\u7406.\n return l1 < d * 2 && l2 < d * 2;\n }\n\n function currentDomSize() {\n return document.all ? document.all.length : document.getElementsByTagName('*').length;\n }\n\n function fakeTiming() {\n let navigationTiming = (performance.getEntriesByType && performance.getEntriesByType('navigation')[0]) || null;\n if (navigationTiming) {\n return navigationTiming;\n }\n const obj = performance.timing;\n return {\n loadEventStart: obj.loadEventStart - obj.navigationStart,\n domContentLoadedEventStart: obj.domContentLoadedEventStart - obj.navigationStart,\n };\n }\n\n function findMeaningfulDom(node, out) {\n out = out || [];\n let obj = node.firstChild;\n if (obj) {\n let deepFlage;\n do {\n switch (obj.nodeType) {\n case 1:\n deepFlage = NOT_DEEP_IN[obj.nodeName] || 0;\n if (deepFlage === 1) {\n break;\n }\n\n if (obj.nodeName === 'IMG' || obj.nodeName === 'VIDEO') {\n out.push(obj);\n break;\n } else if (obj.childElementCount === 0) {\n out.push(obj);\n break;\n }\n\n findMeaningfulDom(obj, out);\n break;\n case 3:\n if (!/^[\\r\\n\\s]*$/.test(obj.wholeText)) {\n out.push(node);\n }\n }\n } while (obj = obj.nextSibling);\n }\n return out;\n }\n\n function findCache(list, keyObj) {\n let n = list.length - 1;\n for (let index = n; index >= 0; index--) {\n const one = list[index];\n if (one.key === keyObj) {\n return one;\n }\n }\n return null;\n }\n\n function createCacheItem(keyObj) {\n let result = {\n key: keyObj,\n pBox: keyObj.getBoundingClientRect(),\n scrollTop: keyObj.scrollTop,\n scrollLeft: keyObj.scrollLeft,\n scrollHeight: keyObj.scrollHeight,\n scrollWidth: keyObj.scrollWidth,\n clientHeight: keyObj.clientHeight,\n clientWidth: keyObj.clientWidth,\n isNew: true,\n };\n\n if (keyObj.tagName !== 'BODY') {\n if (window.getComputedStyle) {\n const domNodeCssStyle = window.getComputedStyle(keyObj, null);\n result.display = domNodeCssStyle.display;\n result.position = domNodeCssStyle.position;\n result.overflow = domNodeCssStyle.overflow;\n result.overflowX = domNodeCssStyle.overflowX;\n result.overflowY = domNodeCssStyle.overflowY;\n result.transform = domNodeCssStyle.transform;\n\n const regTestUrl = /url\\(['\"]?(.*?)['\"]?\\)/i;\n let bgImgUrl = domNodeCssStyle.backgroundImage;\n\n if (regTestUrl.test(bgImgUrl)) {\n bgImgUrl = bgImgUrl.replace(regTestUrl, '$1');\n if (!/^data:/i.test(bgImgUrl)) {\n result.backgroundImage = bgImgUrl;\n }\n }\n\n // fixed\u7EDD\u5BF9\u6392\u9664\uFF0C\u5176\u5B83\u4E0D\u53EF\u89C1\u5185\u5BB9\u4EC5\u5728\u8FDE\u7EED\u66F4\u65B0\u7684\u60C5\u51B5\u4E0B\u624D\u5224\u65AD\n if (domNodeCssStyle.position === 'fixed' || (frames.length > 0 && (domNodeCssStyle.display === 'none' || domNodeCssStyle.opacity === '0' || domNodeCssStyle.visibility === 'hidden'))) {\n result.ignore = true;\n }\n }\n\n if (keyObj.hasAttribute(ignoreAttrName)) {\n result.ignore = true;\n haveIgnoreAttr = true;\n }\n }\n\n return result;\n }\n\n function isValidTextNode(node) {\n return node.nodeType === 3 && !/^[\\r\\n\\s]*$/.test(node.wholeText);\n }\n\n function isLazy() {\n const mm = document.querySelector('meta[name=jstracker-lazy-sfsp]');\n return mm && mm.getAttribute('content') === 'true';\n }\n\n function now() {\n return performance.now();\n }\n\n function forEach(list, cb) {\n if (!cb || !list) return;\n let len = list.length || 0;\n for (let i = 0; i < len; i++) {\n cb(list[i], i);\n }\n }\n\n function someList(list, cb) {\n if (!cb || !list) return;\n let len = list.length || 0;\n for (let i = 0; i < len; i++) {\n if (cb(list[i], i)) {\n return true;\n }\n }\n return false;\n }\n\n function pureUrl(str) {\n return str ? str.replace(/^https?:///i, '//') : str;\n }\n\n function isDebugFsp() {\n return location.href.indexOf('jt_debug=fsp') != -1;\n }\n\n function TimePointer() {\n let wraper = null;\n let timer = null;\n\n if (!isDebug) {\n return nope;\n }\n\n let rv = (val) => {\n if (wraper) {\n let t = Date.now();\n if (val) {\n cancelAnimationFrame(timer);\n const timestamp = (performance.timeOrigin || performance.timing.navigationStart) + val;\n t = Math.round(timestamp);\n wraper.style.color = '#0ff';\n }\n wraper.innerHTML = t + \" | \" + Math.round(val || performance.now());\n }\n };\n\n let timestampUpdate = () => {\n if (isStop) {\n return;\n }\n timer = requestAnimationFrame(timestampUpdate);\n if (wraper) {\n wraper.innerHTML = (Date.now()).toString();\n }\n };\n\n let fn = () => {\n if (timer) {\n return;\n }\n wraper = document.createElement('div');\n let styleObj = {\n position: 'fixed',\n bottom: '6px',\n right: '6px',\n color: '#fff',\n padding: '0 4px',\n backgroundColor: 'rgba(0, 0, 0, 0.6)',\n zIndex: 99999990,\n textAlign: 'center',\n fontSize: '12px',\n };\n\n for (let key in styleObj) {\n wraper.style[key] = styleObj[key];\n }\n\n document.body.appendChild(wraper);\n requestAnimationFrame(timestampUpdate);\n };\n\n if (document.body) {\n fn();\n } else {\n window.addEventListener('DOMContentLoaded', fn);\n }\n\n return rv;\n }\n\n\n function getXPATH(target) {\n let result = [];\n let getNodeName = (node) => {\n return node.className ? node.tagName + '[@class=\"' + node.className + '\"]' : node.tagName;\n };\n\n let getPathOne = (node) => {\n let resultName = getNodeName(node);\n let seq = 1;\n let c = node;\n while (c = c.previousElementSibling) {\n if (getNodeName(c) === resultName) {\n seq++;\n }\n }\n result.push(resultName + \"[\" + seq + \"]\");\n };\n\n let p = target;\n do {\n getPathOne(p);\n } while ((p.tagName !== 'BODY' && (p = p.parentElement)));\n result.push('/');\n return result.reverse().join('/');\n }\n\n if (typeof module !== 'undefined') {\n module.exports = output;\n }\n})();\n"; export declare const fspStr = "(function(){var isDebug=isDebugFsp();var nope=function nope(){};var print=isDebug?console.log.bind(console.log,'jt_sfsp: '):nope;var ignoreAttrName='data-jstracker-nofsp';var stopEvents=['mousedown','touchstart'];if(typeof window==='undefined'||typeof performance==='undefined'||typeof MutationObserver==='undefined'||typeof screen=='undefined'){if(typeof module!=='undefined'){module.exports={on:nope,un:nope,forceStop:nope,install:nope}}return}var NOT_DEEP_IN={SCRIPT:1,LINK:1,HEAD:1,MATE:1,TITLE:1,STYLE:1,BR:1,SVG:2,IMG:2,CANVAS:2,VIDEO:2};var _screen=screen,screenWidth=_screen.width,screenHeight=_screen.height;var _document$documentEle=document.documentElement,pageWidth=_document$documentEle.clientWidth,pageHeight=_document$documentEle.clientHeight;var miniBorderSize=Math.round(Math.max(Math.min(screenWidth,screenHeight)*0.02,12));var bottomBarHeight=Math.round(screenHeight*0.05);var contentHeight=Math.min(pageHeight,screenHeight);var contentWidth=Math.min(pageWidth,screenWidth);var contentArea=contentHeight*contentWidth;var MAX_RUNNING_LIMIT=30*1000;var maxRenderIdle=3*1000;var frames=[];var maxHandleTimer=null;var isStop=false;var ignoreBucket=null;var idleTimer=null;var timeBoard=null;var haveIgnoreAttr=false;var execCost=0;var output={version:'20221212',listeners:[],lazy:function lazy(){if(!maxHandleTimer){init()}},on:function on(fn){if(this.listeners.indexOf(fn)===-1){this.listeners.push(fn)}},un:function un(fn){if(fn){var i=this.listeners.indexOf(fn);this.listeners.splice(i,1)}},forceStop:function forceStop(){stopHandle({type:'force'})},_fn:function _fn(result){var fn;for(var index in this.listeners){fn=this.listeners[index];fn&&fn(result)}this.listeners=[]},getFrames:function getFrames(){return frames},getIgnoreNodes:function getIgnoreNodes(){return ignoreBucket},install:function install(){init()},getXPATH:getXPATH};var isMyTime=false;if(window._JT_FSP){output.listeners=window._JT_FSP.listeners;output.forceStop=window._JT_FSP.forceStop;isStop=true}else{window._JT_FSP=output;isMyTime=true}var mutationObserver=new MutationObserver(handleDOMChange);function init(){if(!isMyTime||!!maxHandleTimer||isStop){return}ignoreBucket=[];timeBoard=TimePointer();var rootElement=document.firstElementChild;if(document.body){var bodyChild=document.querySelectorAll('BODY > *');if(bodyChild.length>0){forEach(document.querySelectorAll(\"[\"+ignoreAttrName+\"]\"),function(one){ignoreBucket.push(one);haveIgnoreAttr=true});makeFrames(document.querySelectorAll('BODY IMG'),true)}}timeBoard();mutationObserver.observe(rootElement,{childList:true,subtree:true});var handleUserEvent=function handleUserEvent(){stopEvents.forEach(function(ename){return rootElement.addEventListener(ename,stopHandle,true)})};if(document.readyState!=='loading'){handleUserEvent()}else{document.addEventListener('DOMContentLoaded',handleUserEvent)}maxHandleTimer=setTimeout(function(){stopHandle({type:'timeout'})},MAX_RUNNING_LIMIT)}window.fspTracker=output;window.fspTracker.install();window.fspTracker.listeners=[function(fsp){console.log('[fsp-report-in-html]',fsp);window.__FSP=fsp}];var delayTimer=null;var addDoms=[];function handleDOMChange(records){if(isStop){return}forEach(records,function(record){var target=record.target,addedNodes=record.addedNodes;var nodeName=target.nodeName;if(NOT_DEEP_IN[nodeName]===1){return}if(someList(ignoreBucket,function(one){return one&&one.contains&&one.contains(target)})){return}if(frames.length>0&&nodeName!=='HTML'&&nodeName!=='BODY'){var _target$getBoundingCl=target.getBoundingClientRect(),top=_target$getBoundingCl.top,left=_target$getBoundingCl.left,bottom=_target$getBoundingCl.bottom,right=_target$getBoundingCl.right;if(bottomcontentHeight-bottomBarHeight||rightcontentWidth-bottomBarHeight){return}}forEach(addedNodes,function(node){try{if(!node.parentElement){return}var c=node;if(isValidTextNode(node)&&node.parentElement.childNodes.length===1){c=node.parentElement}if(c.nodeType!==1&&c.nodeType!==9){return}if(NOT_DEEP_IN[c.nodeName]===1){return}var isSub=someList(addDoms,function(one){return one.contains(c)});!isSub&&addDoms.push(c)}catch(err){}})});if(addDoms.length>0){if(delayTimer===null){delayTimer=setTimeout(function(){makeFrames(addDoms);addDoms=[];delayTimer=null},1000/60)}}}function updateLastTime(frameObj,time){if(isStop){return}timeBoard();time=time||now();var top=frameObj.top,left=frameObj.left,bottom=frameObj.bottom,right=frameObj.right;var frameHeight=Math.abs(bottom-top);var frameWidth=Math.abs(right-left);frameObj.lastTime=Math.max(time,frameObj.lastTime);frameObj.v=Math.floor(frameHeight*frameWidth/contentArea*10000)/10000;idleTimer&&clearTimeout(idleTimer);idleTimer=setTimeout(function(){stopHandle({type:'idle'})},maxRenderIdle);var size=frames.length;if(size<4){return}var sumArea=0;var maxAreaFrame=0;var s=0;var pGroup={};for(var aIndex=0;aIndex=s){s=ac.v;maxAreaFrame=aIndex}if(sumArea>4){stopHandle({type:'sum_area',p:maxAreaFrame});break}for(var bIndex=0;bIndex=3){stopHandle({type:'tail',p:g-1})}break}}}}function makeFrames(addDoms){try{var _findViewRectInFirstS=findViewRectInFirstScreen(addDoms),meaningfulList=_findViewRectInFirstS.meaningfulList,frameObj=_findViewRectInFirstS.box,cost=_findViewRectInFirstS.cost;if(!frameObj||!frameObj.count){return}frames.push(frameObj);execCost+=cost;print(\"makeFrames cost:\"+cost+\"ms; frames count: \"+frames.length,frameObj);frameObj.wait=0;frameObj.imgSeq=[];forEach(meaningfulList,function(node){var nodeName=node.nodeName;if(nodeName==='IMG'){frameObj.wait+=1;var loadCount=node.complete?1:0;var firstSrc=node.src;var handleLoadEvent=function handleLoadEvent(){var p=null;if(isStop){node.removeEventListener('load',handleLoadEvent,true);return}if(loadCount>0){if(node.src===firstSrc){return}else{print('img change src',firstSrc,node.src,now())}}if(++loadCount>2&&frameObj.startTime>1000){return}waitRenderTime(function(){var _node$getBoundingClie=node.getBoundingClientRect(),top=_node$getBoundingClie.top,left=_node$getBoundingClie.left,bottom=_node$getBoundingClie.bottom,right=_node$getBoundingClie.right,width=_node$getBoundingClie.width,height=_node$getBoundingClie.height;if(widthcontentHeight-bottomBarHeight||rightcontentWidth-bottomBarHeight){return}frameObj.left=Math.min(left,frameObj.left);frameObj.top=Math.min(top,frameObj.top);frameObj.bottom=Math.max(frameObj.bottom,top+height);frameObj.right=Math.max(frameObj.right,left+width);frameObj.imgSeq.push({node:node,time:now()});updateLastTime(frameObj)},p)};node.addEventListener('load',handleLoadEvent,true)}else if(nodeName==='VIDEO'&&node.poster){frameObj.bgImg.push(node.poster)}});updateLastTime(frameObj)}catch(err){}}function profileResourceTiming(checkList,callback,notWaitingLoadEvent){var navigationTiming=fakeTiming();var loadEventStart=navigationTiming.loadEventStart;if(notWaitingLoadEvent!==true&&loadEventStart<=0){waitPageLoadOrMaxTime(function(){return profileResourceTiming(checkList,callback,true)});return}var timingMap={};var fcp=-1,fp=-1;var ssrVal=0;var lastImg=null;var list=performance.getEntries();forEach(list,function(one){var entryType=one.entryType,name=one.name,startTime=one.startTime,duration=one.duration;if(entryType=='paint'){switch(name){case'first-contentful-paint':fcp=startTime;break;case'first-paint':fp=startTime;break}}else{timingMap[pureUrl(name)]=startTime+duration}});var checkResult={};var checkResultMaxValue=0;if(checkList&&checkList.length>0){forEach(checkList,function(img){img=pureUrl(img);if(timingMap[img]){print('check img from resourceTiming: ',img,timingMap[img]);checkResult[img]=timingMap[img];checkResultMaxValue=Math.max(checkResult[img],checkResultMaxValue)}})}if(loadEventStart>0){var cacheList=[];var domList=document.body&&document.body.querySelectorAll('*[style]');var checkImgElement=function checkImgElement(dom,imgSrc,cacheList){imgSrc=pureUrl(imgSrc);if(!imgSrc||/^data:/i.test(imgSrc)){return}var time=timingMap[imgSrc];if(time>loadEventStart){return}var box=createScreenBox(dom,cacheList);if(!box){return}var width=box.width,height=box.height;if(box.isCutoff==false&&width>miniBorderSize&&height>miniBorderSize){if(ssrVal0){forEach(domList,function(one){var regTestUrl=/url\\(['\"]?(.*?)['\"]?\\)/i;var bgImgUrl=regTestUrl.exec(one.style&&one.style.backgroundImage||'');bgImgUrl=bgImgUrl&&bgImgUrl[1];checkImgElement(one,bgImgUrl,cacheList)})}forEach(document.images,function(one){return checkImgElement(one,one.src,cacheList)})}callback({ssrTime:Math.max(ssrVal,fcp,fp),fcp:fcp,fp:fp,ssrLastImg:lastImg,checkResult:checkResult,checkResultMaxValue:checkResultMaxValue})}function stopHandle(args){if(isStop){return}var type=args.type,p=args.p;var fcp=0;var t=now();try{var entry=performance.getEntriesByName('first-contentful-paint')[0];if(entry&&entry.startTime){fcp=entry.startTime}if(stopEvents.indexOf(type)!=-1&&(fcp===0||now()-fcp<200)){print('no fcp, ignore mousedown',t);return}}catch(e){}maxHandleTimer&&clearTimeout(maxHandleTimer);idleTimer&&clearTimeout(idleTimer);isStop=true;if(mutationObserver){mutationObserver.disconnect();mutationObserver.takeRecords();mutationObserver=null}var validFrames=null;var waitingCheckFromResourceTiming=[];function noMini(frames){var list=[];if(frames.length<=1){list=frames.slice(0);var _ref=list[0]||{},bgImg=_ref.bgImg;if(bgImg){forEach(bgImg,function(i){return waitingCheckFromResourceTiming.push(i)})}}else{forEach(frames,function(one){var v=one.v,bgImg=one.bgImg;if(v<0.02){return}if(bgImg){forEach(bgImg,function(i){return waitingCheckFromResourceTiming.push(i)})}list.push(one)})}return list}switch(type){case'tail':case'sum_area':validFrames=noMini(frames.slice(0,p));break;default:var list=noMini(frames);var n=list.length;if(n>=2){n--;var _t=0;do{var current=list[n];var nextOne=list[n-1];if(isNear(current,nextOne,miniBorderSize)){_t++}else{break}}while(--n>0);if(_t>0){n===0&&print('Full Screen Reflash x 2.');list=list.slice(0,n||1)}}validFrames=list}var timeCost=0,lastFrame=null;if(validFrames.length){forEach(validFrames,function(one){if(one.lastTime>timeCost){timeCost=one.lastTime;lastFrame=one}})}else{timeCost=fcp}profileResourceTiming(waitingCheckFromResourceTiming,function(data){try{var ssrTime=data.ssrTime,_fcp=data.fcp,fp=data.fp,ssrLastImg=data.ssrLastImg,checkResult=data.checkResult,checkResultMaxValue=data.checkResultMaxValue;if(checkResultMaxValue>timeCost){timeCost=checkResultMaxValue}var timestamp=(performance.timeOrigin||performance.timing.navigationStart)+timeCost;print(\"stopHandleBy \"+type+\", sfsp: timeCost, checkImg: \"+checkResultMaxValue+\", ssrTime: \"+ssrTime+\", fcp: \"+_fcp+\", fp: \"+fp+\", ssrLastImg: \",ssrLastImg,validFrames,checkResult);var _ref2=lastFrame||{},domSize=_ref2.domSize,imgSeq=_ref2.imgSeq;var xPathLastImg='';try{if(imgSeq&&imgSeq.length>0){xPathLastImg=getXPATH(imgSeq[imgSeq.length-1].node)}}catch(err){}var result={endType:stopEvents.indexOf(type)!=-1?stopEvents[0]:type,timestamp:timestamp,cost:timeCost,domSize:domSize,validFrames:validFrames,ssrTime:ssrTime,ssrLastImg:ssrLastImg,bgImgRecord:checkResult,bgImgMaxTime:checkResultMaxValue,fcp:_fcp,fp:fp,haveIgnoreAttr:haveIgnoreAttr,lastImg:xPathLastImg,execCost:execCost,version:output.version};window.__SSR_TRACE_ID='fcp:'+_fcp+',fp:'+fp;if(window.dispatchEvent&&window.CustomEvent){var evt=new CustomEvent('jstracker.fsp',{detail:result});window.dispatchEvent(evt)}try{output._fn(result)}catch(err){}timeBoard(timeCost);if(!isDebug){frames.length=0;ignoreBucket&&(ignoreBucket.length=0,ignoreBucket=null)}}catch(err){}},type==='force')}function findViewRectInFirstScreen(list){var cacheObj=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[];var t0=now();var box={startTime:t0,lastTime:t0,left:Number.MAX_SAFE_INTEGER,top:Number.MAX_SAFE_INTEGER,right:0,bottom:0,count:0,searchNodes:0,bgImg:[],domSize:currentDomSize()};var meaningfulList=box.meaningfulList=[];var mergeBox=function mergeBox(b,deepOne){if(b){var top=b.top,left=b.left,width=b.width,height=b.height,backgroundImage=b.backgroundImage;box.left=Math.min(left,box.left);box.top=Math.min(top,box.top);box.bottom=Math.max(box.bottom,top+height);box.right=Math.max(box.right,left+width);meaningfulList.push(deepOne);box.count++;backgroundImage&&box.bgImg.push(backgroundImage)}};var checkFn=function checkFn(deepOne){box.searchNodes++;var r=createScreenBox(deepOne,cacheObj);if(r){mergeBox(r,deepOne);return true}return r};forEach(list,function(one){var flag=NOT_DEEP_IN[one.nodeName]||3;if(flag<2){return}checkFn(one)!==0&&forEach(findMeaningfulDom(one,[]),checkFn)});return{meaningfulList:meaningfulList,cacheObj:cacheObj,box:box,cost:now()-t0}}if(isDebug){output.findViewRectInFirstScreen=findViewRectInFirstScreen;output.createScreenBox=createScreenBox;output.findMeaningfulDom=findMeaningfulDom}function createScreenBox(node,cacheObj){var cacheItem=null;if(!cacheObj){cacheObj=[]}if(cacheItem=findCache(cacheObj,node)){if(cacheItem.result){return cacheItem.result}}else{cacheItem=createCacheItem(node);cacheObj.push(cacheItem);if(cacheItem.ignore){ignoreBucket.push(node);return cacheItem.result=0}if(someList(ignoreBucket,function(one){return one&&one.contains&&one.contains(node)})){return cacheItem.result=0}}var _cacheItem=cacheItem,_cacheItem$background=_cacheItem.backgroundImage,backgroundImage=_cacheItem$background===void 0?null:_cacheItem$background,nodeBox=_cacheItem.pBox;var top=nodeBox.top,left=nodeBox.left,bottom=nodeBox.bottom,right=nodeBox.right,width=nodeBox.width,height=nodeBox.height;var isCutoff=false;var b=4;var pCheck=true;if(node.nodeName==='IMG'&&node.complete!==true&&(width===0||height===0)){pCheck=false}else{if(widthscreenHeight-bottomBarHeight||rightscreenWidth-bottomBarHeight){return cacheItem.result=0}}var p=node.parentElement;var parentCacheItem=null;var pageScrollElement=document.scrollingElement||document.documentElement;while(p){parentCacheItem=findCache(cacheObj,p);if(!parentCacheItem){parentCacheItem=createCacheItem(p);if(parentCacheItem.ignore){ignoreBucket.push(p)}cacheObj.push(parentCacheItem)}if(parentCacheItem.ignore){return cacheItem.result=0}var _parentCacheItem=parentCacheItem,scrollTop=_parentCacheItem.scrollTop,scrollLeft=_parentCacheItem.scrollLeft,scrollHeight=_parentCacheItem.scrollHeight,scrollWidth=_parentCacheItem.scrollWidth,clientHeight=_parentCacheItem.clientHeight,clientWidth=_parentCacheItem.clientWidth,overflowX=_parentCacheItem.overflowX,overflowY=_parentCacheItem.overflowY;if(scrollHeight>clientHeight&&(p===pageScrollElement||overflowY!=='visible')||scrollWidth>clientWidth&&(p===pageScrollElement||overflowX!=='visible')){top+=scrollTop;bottom+=scrollTop;left+=scrollLeft;right+=scrollLeft;var pBox=parentCacheItem.box?parentCacheItem.box:p.getBoundingClientRect();parentCacheItem.box=parentCacheItem.box||pBox;if(top-pBox.bottom>b||left-pBox.right>b||pBox.top-bottom>b||pBox.left-right>b){return cacheItem.result=false}}p=p.parentElement;parentCacheItem=null}isCutoff=isCutoff||top>=contentHeight||left>=contentWidth;if(pCheck&&(bottomcontentHeight-bottomBarHeight||rightcontentWidth-bottomBarHeight)){return cacheItem.result=false}return cacheItem.result={top:top,left:left,width:width,height:height,isCutoff:isCutoff,backgroundImage:backgroundImage}}function waitRenderTime(cb,p){if(p&&p.then&&p[\"catch\"]){p.then(function(){waitRenderTime(cb)})[\"catch\"](function(){waitRenderTime(cb)})}else if(window.requestAnimationFrame){requestAnimationFrame(cb)}else{setTimeout(cb,0)}}function waitPageLoadOrMaxTime(callback){var timer=null;var once=0;var fn=function fn(){timer&&clearTimeout(timer);window.removeEventListener('load',fn);if(once++===0){callback()}};timer=setTimeout(fn,MAX_RUNNING_LIMIT-now());window.addEventListener('load',fn)}function isNear(b1,b2){var d=arguments.length>2&&arguments[2]!==undefined?arguments[2]:8;var l1=Math.sqrt(Math.pow(b1.top-b2.top,2)+Math.pow(b1.left-b2.left,2));var l2=Math.sqrt(Math.pow(b1.bottom-b2.bottom,2)+Math.pow(b1.right-b2.right,2));return l1=0;index--){var one=list[index];if(one.key===keyObj){return one}}return null}function createCacheItem(keyObj){var result={key:keyObj,pBox:keyObj.getBoundingClientRect(),scrollTop:keyObj.scrollTop,scrollLeft:keyObj.scrollLeft,scrollHeight:keyObj.scrollHeight,scrollWidth:keyObj.scrollWidth,clientHeight:keyObj.clientHeight,clientWidth:keyObj.clientWidth,isNew:true};if(keyObj.tagName!=='BODY'){if(window.getComputedStyle){var domNodeCssStyle=window.getComputedStyle(keyObj,null);result.display=domNodeCssStyle.display;result.position=domNodeCssStyle.position;result.overflow=domNodeCssStyle.overflow;result.overflowX=domNodeCssStyle.overflowX;result.overflowY=domNodeCssStyle.overflowY;result.transform=domNodeCssStyle.transform;var regTestUrl=/url\\(['\"]?(.*?)['\"]?\\)/i;var bgImgUrl=domNodeCssStyle.backgroundImage;if(regTestUrl.test(bgImgUrl)){bgImgUrl=bgImgUrl.replace(regTestUrl,'$1');if(!/^data:/i.test(bgImgUrl)){result.backgroundImage=bgImgUrl}}if(domNodeCssStyle.position==='fixed'||frames.length>0&&(domNodeCssStyle.display==='none'||domNodeCssStyle.opacity==='0'||domNodeCssStyle.visibility==='hidden')){result.ignore=true}}if(keyObj.hasAttribute(ignoreAttrName)){result.ignore=true;haveIgnoreAttr=true}}return result}function isValidTextNode(node){return node.nodeType===3&&!/^[\\r\\n\\s]*$/.test(node.wholeText)}function isLazy(){var mm=document.querySelector('meta[name=jstracker-lazy-sfsp]');return mm&&mm.getAttribute('content')==='true'}function now(){return performance.now()}function forEach(list,cb){if(!cb||!list)return;var len=list.length||0;for(var i=0;i