Spaces:
Sleeping
Sleeping
rag-context-optimizer / frontend /node_modules /next /dist /esm /client /components /layout-router.js
| 'use client'; | |
| import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; | |
| import { ACTION_SERVER_PATCH } from './router-reducer/router-reducer-types'; | |
| import React, { useContext, use, startTransition, Suspense, useDeferredValue } from 'react'; | |
| import ReactDOM from 'react-dom'; | |
| import { LayoutRouterContext, GlobalLayoutRouterContext, TemplateContext } from '../../shared/lib/app-router-context.shared-runtime'; | |
| import { fetchServerResponse } from './router-reducer/fetch-server-response'; | |
| import { unresolvedThenable } from './unresolved-thenable'; | |
| import { ErrorBoundary } from './error-boundary'; | |
| import { matchSegment } from './match-segments'; | |
| import { disableSmoothScrollDuringRouteTransition } from '../../shared/lib/router/utils/disable-smooth-scroll'; | |
| import { RedirectBoundary } from './redirect-boundary'; | |
| import { HTTPAccessFallbackBoundary } from './http-access-fallback/error-boundary'; | |
| import { createRouterCacheKey } from './router-reducer/create-router-cache-key'; | |
| import { hasInterceptionRouteInCurrentTree } from './router-reducer/reducers/has-interception-route-in-current-tree'; | |
| import { dispatchAppRouterAction } from './use-action-queue'; | |
| import { useRouterBFCache } from './bfcache'; | |
| import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths'; | |
| const Activity = process.env.__NEXT_ROUTER_BF_CACHE ? require('react').unstable_Activity : null; | |
| /** | |
| * Add refetch marker to router state at the point of the current layout segment. | |
| * This ensures the response returned is not further down than the current layout segment. | |
| */ function walkAddRefetch(segmentPathToWalk, treeToRecreate) { | |
| if (segmentPathToWalk) { | |
| const [segment, parallelRouteKey] = segmentPathToWalk; | |
| const isLast = segmentPathToWalk.length === 2; | |
| if (matchSegment(treeToRecreate[0], segment)) { | |
| if (treeToRecreate[1].hasOwnProperty(parallelRouteKey)) { | |
| if (isLast) { | |
| const subTree = walkAddRefetch(undefined, treeToRecreate[1][parallelRouteKey]); | |
| return [ | |
| treeToRecreate[0], | |
| { | |
| ...treeToRecreate[1], | |
| [parallelRouteKey]: [ | |
| subTree[0], | |
| subTree[1], | |
| subTree[2], | |
| 'refetch' | |
| ] | |
| } | |
| ]; | |
| } | |
| return [ | |
| treeToRecreate[0], | |
| { | |
| ...treeToRecreate[1], | |
| [parallelRouteKey]: walkAddRefetch(segmentPathToWalk.slice(2), treeToRecreate[1][parallelRouteKey]) | |
| } | |
| ]; | |
| } | |
| } | |
| } | |
| return treeToRecreate; | |
| } | |
| const __DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; | |
| // TODO-APP: Replace with new React API for finding dom nodes without a `ref` when available | |
| /** | |
| * Wraps ReactDOM.findDOMNode with additional logic to hide React Strict Mode warning | |
| */ function findDOMNode(instance) { | |
| // Tree-shake for server bundle | |
| if (typeof window === 'undefined') return null; | |
| // __DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.findDOMNode is null during module init. | |
| // We need to lazily reference it. | |
| const internal_reactDOMfindDOMNode = __DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.findDOMNode; | |
| return internal_reactDOMfindDOMNode(instance); | |
| } | |
| const rectProperties = [ | |
| 'bottom', | |
| 'height', | |
| 'left', | |
| 'right', | |
| 'top', | |
| 'width', | |
| 'x', | |
| 'y' | |
| ]; | |
| /** | |
| * Check if a HTMLElement is hidden or fixed/sticky position | |
| */ function shouldSkipElement(element) { | |
| // we ignore fixed or sticky positioned elements since they'll likely pass the "in-viewport" check | |
| // and will result in a situation we bail on scroll because of something like a fixed nav, | |
| // even though the actual page content is offscreen | |
| if ([ | |
| 'sticky', | |
| 'fixed' | |
| ].includes(getComputedStyle(element).position)) { | |
| if (process.env.NODE_ENV === 'development') { | |
| console.warn('Skipping auto-scroll behavior due to `position: sticky` or `position: fixed` on element:', element); | |
| } | |
| return true; | |
| } | |
| // Uses `getBoundingClientRect` to check if the element is hidden instead of `offsetParent` | |
| // because `offsetParent` doesn't consider document/body | |
| const rect = element.getBoundingClientRect(); | |
| return rectProperties.every((item)=>rect[item] === 0); | |
| } | |
| /** | |
| * Check if the top corner of the HTMLElement is in the viewport. | |
| */ function topOfElementInViewport(element, viewportHeight) { | |
| const rect = element.getBoundingClientRect(); | |
| return rect.top >= 0 && rect.top <= viewportHeight; | |
| } | |
| /** | |
| * Find the DOM node for a hash fragment. | |
| * If `top` the page has to scroll to the top of the page. This mirrors the browser's behavior. | |
| * If the hash fragment is an id, the page has to scroll to the element with that id. | |
| * If the hash fragment is a name, the page has to scroll to the first element with that name. | |
| */ function getHashFragmentDomNode(hashFragment) { | |
| // If the hash fragment is `top` the page has to scroll to the top of the page. | |
| if (hashFragment === 'top') { | |
| return document.body; | |
| } | |
| var _document_getElementById; | |
| // If the hash fragment is an id, the page has to scroll to the element with that id. | |
| return (_document_getElementById = document.getElementById(hashFragment)) != null ? _document_getElementById : // If the hash fragment is a name, the page has to scroll to the first element with that name. | |
| document.getElementsByName(hashFragment)[0]; | |
| } | |
| class InnerScrollAndFocusHandler extends React.Component { | |
| componentDidMount() { | |
| this.handlePotentialScroll(); | |
| } | |
| componentDidUpdate() { | |
| // Because this property is overwritten in handlePotentialScroll it's fine to always run it when true as it'll be set to false for subsequent renders. | |
| if (this.props.focusAndScrollRef.apply) { | |
| this.handlePotentialScroll(); | |
| } | |
| } | |
| render() { | |
| return this.props.children; | |
| } | |
| constructor(...args){ | |
| super(...args), this.handlePotentialScroll = ()=>{ | |
| // Handle scroll and focus, it's only applied once in the first useEffect that triggers that changed. | |
| const { focusAndScrollRef, segmentPath } = this.props; | |
| if (focusAndScrollRef.apply) { | |
| // segmentPaths is an array of segment paths that should be scrolled to | |
| // if the current segment path is not in the array, the scroll is not applied | |
| // unless the array is empty, in which case the scroll is always applied | |
| if (focusAndScrollRef.segmentPaths.length !== 0 && !focusAndScrollRef.segmentPaths.some((scrollRefSegmentPath)=>segmentPath.every((segment, index)=>matchSegment(segment, scrollRefSegmentPath[index])))) { | |
| return; | |
| } | |
| let domNode = null; | |
| const hashFragment = focusAndScrollRef.hashFragment; | |
| if (hashFragment) { | |
| domNode = getHashFragmentDomNode(hashFragment); | |
| } | |
| // `findDOMNode` is tricky because it returns just the first child if the component is a fragment. | |
| // This already caused a bug where the first child was a <link/> in head. | |
| if (!domNode) { | |
| domNode = findDOMNode(this); | |
| } | |
| // If there is no DOM node this layout-router level is skipped. It'll be handled higher-up in the tree. | |
| if (!(domNode instanceof Element)) { | |
| return; | |
| } | |
| // Verify if the element is a HTMLElement and if we want to consider it for scroll behavior. | |
| // If the element is skipped, try to select the next sibling and try again. | |
| while(!(domNode instanceof HTMLElement) || shouldSkipElement(domNode)){ | |
| if (process.env.NODE_ENV !== 'production') { | |
| var _domNode_parentElement; | |
| if (((_domNode_parentElement = domNode.parentElement) == null ? void 0 : _domNode_parentElement.localName) === 'head') { | |
| // TODO: We enter this state when metadata was rendered as part of the page or via Next.js. | |
| // This is always a bug in Next.js and caused by React hoisting metadata. | |
| // We need to replace `findDOMNode` in favor of Fragment Refs (when available) so that we can skip over metadata. | |
| } | |
| } | |
| // No siblings found that match the criteria are found, so handle scroll higher up in the tree instead. | |
| if (domNode.nextElementSibling === null) { | |
| return; | |
| } | |
| domNode = domNode.nextElementSibling; | |
| } | |
| // State is mutated to ensure that the focus and scroll is applied only once. | |
| focusAndScrollRef.apply = false; | |
| focusAndScrollRef.hashFragment = null; | |
| focusAndScrollRef.segmentPaths = []; | |
| disableSmoothScrollDuringRouteTransition(()=>{ | |
| // In case of hash scroll, we only need to scroll the element into view | |
| if (hashFragment) { | |
| ; | |
| domNode.scrollIntoView(); | |
| return; | |
| } | |
| // Store the current viewport height because reading `clientHeight` causes a reflow, | |
| // and it won't change during this function. | |
| const htmlElement = document.documentElement; | |
| const viewportHeight = htmlElement.clientHeight; | |
| // If the element's top edge is already in the viewport, exit early. | |
| if (topOfElementInViewport(domNode, viewportHeight)) { | |
| return; | |
| } | |
| // Otherwise, try scrolling go the top of the document to be backward compatible with pages | |
| // scrollIntoView() called on `<html/>` element scrolls horizontally on chrome and firefox (that shouldn't happen) | |
| // We could use it to scroll horizontally following RTL but that also seems to be broken - it will always scroll left | |
| // scrollLeft = 0 also seems to ignore RTL and manually checking for RTL is too much hassle so we will scroll just vertically | |
| htmlElement.scrollTop = 0; | |
| // Scroll to domNode if domNode is not in viewport when scrolled to top of document | |
| if (!topOfElementInViewport(domNode, viewportHeight)) { | |
| // Scroll into view doesn't scroll horizontally by default when not needed | |
| ; | |
| domNode.scrollIntoView(); | |
| } | |
| }, { | |
| // We will force layout by querying domNode position | |
| dontForceLayout: true, | |
| onlyHashChange: focusAndScrollRef.onlyHashChange | |
| }); | |
| // Mutate after scrolling so that it can be read by `disableSmoothScrollDuringRouteTransition` | |
| focusAndScrollRef.onlyHashChange = false; | |
| // Set focus on the element | |
| domNode.focus(); | |
| } | |
| }; | |
| } | |
| } | |
| function ScrollAndFocusHandler(param) { | |
| let { segmentPath, children } = param; | |
| const context = useContext(GlobalLayoutRouterContext); | |
| if (!context) { | |
| throw Object.defineProperty(new Error('invariant global layout router not mounted'), "__NEXT_ERROR_CODE", { | |
| value: "E473", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| return /*#__PURE__*/ _jsx(InnerScrollAndFocusHandler, { | |
| segmentPath: segmentPath, | |
| focusAndScrollRef: context.focusAndScrollRef, | |
| children: children | |
| }); | |
| } | |
| /** | |
| * InnerLayoutRouter handles rendering the provided segment based on the cache. | |
| */ function InnerLayoutRouter(param) { | |
| let { tree, segmentPath, cacheNode, url } = param; | |
| const context = useContext(GlobalLayoutRouterContext); | |
| if (!context) { | |
| throw Object.defineProperty(new Error('invariant global layout router not mounted'), "__NEXT_ERROR_CODE", { | |
| value: "E473", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| const { tree: fullTree } = context; | |
| // `rsc` represents the renderable node for this segment. | |
| // If this segment has a `prefetchRsc`, it's the statically prefetched data. | |
| // We should use that on initial render instead of `rsc`. Then we'll switch | |
| // to `rsc` when the dynamic response streams in. | |
| // | |
| // If no prefetch data is available, then we go straight to rendering `rsc`. | |
| const resolvedPrefetchRsc = cacheNode.prefetchRsc !== null ? cacheNode.prefetchRsc : cacheNode.rsc; | |
| // We use `useDeferredValue` to handle switching between the prefetched and | |
| // final values. The second argument is returned on initial render, then it | |
| // re-renders with the first argument. | |
| const rsc = useDeferredValue(cacheNode.rsc, resolvedPrefetchRsc); | |
| // `rsc` is either a React node or a promise for a React node, except we | |
| // special case `null` to represent that this segment's data is missing. If | |
| // it's a promise, we need to unwrap it so we can determine whether or not the | |
| // data is missing. | |
| const resolvedRsc = typeof rsc === 'object' && rsc !== null && typeof rsc.then === 'function' ? use(rsc) : rsc; | |
| if (!resolvedRsc) { | |
| // The data for this segment is not available, and there's no pending | |
| // navigation that will be able to fulfill it. We need to fetch more from | |
| // the server and patch the cache. | |
| // Check if there's already a pending request. | |
| let lazyData = cacheNode.lazyData; | |
| if (lazyData === null) { | |
| /** | |
| * Router state with refetch marker added | |
| */ // TODO-APP: remove '' | |
| const refetchTree = walkAddRefetch([ | |
| '', | |
| ...segmentPath | |
| ], fullTree); | |
| const includeNextUrl = hasInterceptionRouteInCurrentTree(fullTree); | |
| const navigatedAt = Date.now(); | |
| cacheNode.lazyData = lazyData = fetchServerResponse(new URL(url, location.origin), { | |
| flightRouterState: refetchTree, | |
| nextUrl: includeNextUrl ? context.nextUrl : null | |
| }).then((serverResponse)=>{ | |
| startTransition(()=>{ | |
| dispatchAppRouterAction({ | |
| type: ACTION_SERVER_PATCH, | |
| previousTree: fullTree, | |
| serverResponse, | |
| navigatedAt | |
| }); | |
| }); | |
| return serverResponse; | |
| }); | |
| // Suspend while waiting for lazyData to resolve | |
| use(lazyData); | |
| } | |
| // Suspend infinitely as `changeByServerResponse` will cause a different part of the tree to be rendered. | |
| // A falsey `resolvedRsc` indicates missing data -- we should not commit that branch, and we need to wait for the data to arrive. | |
| use(unresolvedThenable); | |
| } | |
| // If we get to this point, then we know we have something we can render. | |
| const subtree = // The layout router context narrows down tree and childNodes at each level. | |
| /*#__PURE__*/ _jsx(LayoutRouterContext.Provider, { | |
| value: { | |
| parentTree: tree, | |
| parentCacheNode: cacheNode, | |
| parentSegmentPath: segmentPath, | |
| // TODO-APP: overriding of url for parallel routes | |
| url: url | |
| }, | |
| children: resolvedRsc | |
| }); | |
| // Ensure root layout is not wrapped in a div as the root layout renders `<html>` | |
| return subtree; | |
| } | |
| /** | |
| * Renders suspense boundary with the provided "loading" property as the fallback. | |
| * If no loading property is provided it renders the children without a suspense boundary. | |
| */ function LoadingBoundary(param) { | |
| let { loading, children } = param; | |
| // If loading is a promise, unwrap it. This happens in cases where we haven't | |
| // yet received the loading data from the server — which includes whether or | |
| // not this layout has a loading component at all. | |
| // | |
| // It's OK to suspend here instead of inside the fallback because this | |
| // promise will resolve simultaneously with the data for the segment itself. | |
| // So it will never suspend for longer than it would have if we didn't use | |
| // a Suspense fallback at all. | |
| let loadingModuleData; | |
| if (typeof loading === 'object' && loading !== null && typeof loading.then === 'function') { | |
| const promiseForLoading = loading; | |
| loadingModuleData = use(promiseForLoading); | |
| } else { | |
| loadingModuleData = loading; | |
| } | |
| if (loadingModuleData) { | |
| const loadingRsc = loadingModuleData[0]; | |
| const loadingStyles = loadingModuleData[1]; | |
| const loadingScripts = loadingModuleData[2]; | |
| return /*#__PURE__*/ _jsx(Suspense, { | |
| fallback: /*#__PURE__*/ _jsxs(_Fragment, { | |
| children: [ | |
| loadingStyles, | |
| loadingScripts, | |
| loadingRsc | |
| ] | |
| }), | |
| children: children | |
| }); | |
| } | |
| return /*#__PURE__*/ _jsx(_Fragment, { | |
| children: children | |
| }); | |
| } | |
| /** | |
| * OuterLayoutRouter handles the current segment as well as <Offscreen> rendering of other segments. | |
| * It can be rendered next to each other with a different `parallelRouterKey`, allowing for Parallel routes. | |
| */ export default function OuterLayoutRouter(param) { | |
| let { parallelRouterKey, error, errorStyles, errorScripts, templateStyles, templateScripts, template, notFound, forbidden, unauthorized, segmentViewBoundaries } = param; | |
| const context = useContext(LayoutRouterContext); | |
| if (!context) { | |
| throw Object.defineProperty(new Error('invariant expected layout router to be mounted'), "__NEXT_ERROR_CODE", { | |
| value: "E56", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| const { parentTree, parentCacheNode, parentSegmentPath, url } = context; | |
| // Get the CacheNode for this segment by reading it from the parent segment's | |
| // child map. | |
| const parentParallelRoutes = parentCacheNode.parallelRoutes; | |
| let segmentMap = parentParallelRoutes.get(parallelRouterKey); | |
| // If the parallel router cache node does not exist yet, create it. | |
| // This writes to the cache when there is no item in the cache yet. It never *overwrites* existing cache items which is why it's safe in concurrent mode. | |
| if (!segmentMap) { | |
| segmentMap = new Map(); | |
| parentParallelRoutes.set(parallelRouterKey, segmentMap); | |
| } | |
| const parentTreeSegment = parentTree[0]; | |
| const segmentPath = parentSegmentPath === null ? // path. This has led to a bunch of special cases scattered throughout | |
| // the code. We should clean this up. | |
| [ | |
| parallelRouterKey | |
| ] : parentSegmentPath.concat([ | |
| parentTreeSegment, | |
| parallelRouterKey | |
| ]); | |
| // The "state" key of a segment is the one passed to React — it represents the | |
| // identity of the UI tree. Whenever the state key changes, the tree is | |
| // recreated and the state is reset. In the App Router model, search params do | |
| // not cause state to be lost, so two segments with the same segment path but | |
| // different search params should have the same state key. | |
| // | |
| // The "cache" key of a segment, however, *does* include the search params, if | |
| // it's possible that the segment accessed the search params on the server. | |
| // (This only applies to page segments; layout segments cannot access search | |
| // params on the server.) | |
| const activeTree = parentTree[1][parallelRouterKey]; | |
| const activeSegment = activeTree[0]; | |
| const activeStateKey = createRouterCacheKey(activeSegment, true) // no search params | |
| ; | |
| // At each level of the route tree, not only do we render the currently | |
| // active segment — we also render the last N segments that were active at | |
| // this level inside a hidden <Activity> boundary, to preserve their state | |
| // if or when the user navigates to them again. | |
| // | |
| // bfcacheEntry is a linked list of FlightRouterStates. | |
| let bfcacheEntry = useRouterBFCache(activeTree, activeStateKey); | |
| let children = []; | |
| do { | |
| const tree = bfcacheEntry.tree; | |
| const stateKey = bfcacheEntry.stateKey; | |
| const segment = tree[0]; | |
| const cacheKey = createRouterCacheKey(segment); | |
| // Read segment path from the parallel router cache node. | |
| let cacheNode = segmentMap.get(cacheKey); | |
| if (cacheNode === undefined) { | |
| // When data is not available during rendering client-side we need to fetch | |
| // it from the server. | |
| const newLazyCacheNode = { | |
| lazyData: null, | |
| rsc: null, | |
| prefetchRsc: null, | |
| head: null, | |
| prefetchHead: null, | |
| parallelRoutes: new Map(), | |
| loading: null, | |
| navigatedAt: -1 | |
| }; | |
| // Flight data fetch kicked off during render and put into the cache. | |
| cacheNode = newLazyCacheNode; | |
| segmentMap.set(cacheKey, newLazyCacheNode); | |
| } | |
| /* | |
| - Error boundary | |
| - Only renders error boundary if error component is provided. | |
| - Rendered for each segment to ensure they have their own error state. | |
| - When gracefully degrade for bots, skip rendering error boundary. | |
| - Loading boundary | |
| - Only renders suspense boundary if loading components is provided. | |
| - Rendered for each segment to ensure they have their own loading state. | |
| - Passed to the router during rendering to ensure it can be immediately rendered when suspending on a Flight fetch. | |
| */ let segmentBoundaryTriggerNode = null; | |
| let segmentViewStateNode = null; | |
| if (process.env.NODE_ENV !== 'production' && process.env.__NEXT_DEVTOOL_SEGMENT_EXPLORER) { | |
| const { SegmentBoundaryTriggerNode, SegmentViewStateNode } = require('../../next-devtools/userspace/app/segment-explorer-node'); | |
| const pagePrefix = normalizeAppPath(url); | |
| segmentViewStateNode = /*#__PURE__*/ _jsx(SegmentViewStateNode, { | |
| page: pagePrefix | |
| }, pagePrefix); | |
| segmentBoundaryTriggerNode = /*#__PURE__*/ _jsx(_Fragment, { | |
| children: /*#__PURE__*/ _jsx(SegmentBoundaryTriggerNode, {}) | |
| }); | |
| } | |
| // TODO: The loading module data for a segment is stored on the parent, then | |
| // applied to each of that parent segment's parallel route slots. In the | |
| // simple case where there's only one parallel route (the `children` slot), | |
| // this is no different from if the loading module data where stored on the | |
| // child directly. But I'm not sure this actually makes sense when there are | |
| // multiple parallel routes. It's not a huge issue because you always have | |
| // the option to define a narrower loading boundary for a particular slot. But | |
| // this sort of smells like an implementation accident to me. | |
| const loadingModuleData = parentCacheNode.loading; | |
| let child = /*#__PURE__*/ _jsxs(TemplateContext.Provider, { | |
| value: /*#__PURE__*/ _jsxs(ScrollAndFocusHandler, { | |
| segmentPath: segmentPath, | |
| children: [ | |
| /*#__PURE__*/ _jsx(ErrorBoundary, { | |
| errorComponent: error, | |
| errorStyles: errorStyles, | |
| errorScripts: errorScripts, | |
| children: /*#__PURE__*/ _jsx(LoadingBoundary, { | |
| loading: loadingModuleData, | |
| children: /*#__PURE__*/ _jsx(HTTPAccessFallbackBoundary, { | |
| notFound: notFound, | |
| forbidden: forbidden, | |
| unauthorized: unauthorized, | |
| children: /*#__PURE__*/ _jsxs(RedirectBoundary, { | |
| children: [ | |
| /*#__PURE__*/ _jsx(InnerLayoutRouter, { | |
| url: url, | |
| tree: tree, | |
| cacheNode: cacheNode, | |
| segmentPath: segmentPath | |
| }), | |
| segmentBoundaryTriggerNode | |
| ] | |
| }) | |
| }) | |
| }) | |
| }), | |
| segmentViewStateNode | |
| ] | |
| }), | |
| children: [ | |
| templateStyles, | |
| templateScripts, | |
| template | |
| ] | |
| }, stateKey); | |
| if (process.env.NODE_ENV !== 'production') { | |
| const { SegmentStateProvider } = require('../../next-devtools/userspace/app/segment-explorer-node'); | |
| child = /*#__PURE__*/ _jsxs(SegmentStateProvider, { | |
| children: [ | |
| child, | |
| segmentViewBoundaries | |
| ] | |
| }, stateKey); | |
| } | |
| if (process.env.__NEXT_ROUTER_BF_CACHE) { | |
| child = /*#__PURE__*/ _jsx(Activity, { | |
| mode: stateKey === activeStateKey ? 'visible' : 'hidden', | |
| children: child | |
| }, stateKey); | |
| } | |
| children.push(child); | |
| bfcacheEntry = bfcacheEntry.next; | |
| }while (bfcacheEntry !== null); | |
| return children; | |
| } | |
| //# sourceMappingURL=layout-router.js.map |