`, so it can be styled via any CSS solution you prefer.
* @see https://floating-ui.com/docs/FloatingOverlay
*/
const FloatingOverlay = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.forwardRef(function FloatingOverlay(props, ref) {
const {
lockScroll = false,
...rest
} = props;
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
if (!lockScroll) return;
lockCount++;
if (lockCount === 1) {
cleanup = enableScrollLock();
}
return () => {
lockCount--;
if (lockCount === 0) {
cleanup();
}
};
}, [lockScroll]);
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("div", {
ref: ref,
...rest,
style: {
position: 'fixed',
overflow: 'auto',
top: 0,
right: 0,
bottom: 0,
left: 0,
...rest.style
}
});
});
function isButtonTarget(event) {
return (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isHTMLElement)(event.target) && event.target.tagName === 'BUTTON';
}
function isAnchorTarget(event) {
return (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isHTMLElement)(event.target) && event.target.tagName === 'A';
}
function isSpaceIgnored(element) {
return (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isTypeableElement)(element);
}
/**
* Opens or closes the floating element when clicking the reference element.
* @see https://floating-ui.com/docs/useClick
*/
function useClick(context, props) {
if (props === void 0) {
props = {};
}
const {
open,
onOpenChange,
dataRef,
elements: {
domReference
}
} = context;
const {
enabled = true,
event: eventOption = 'click',
toggle = true,
ignoreMouse = false,
keyboardHandlers = true,
stickIfOpen = true
} = props;
const pointerTypeRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef();
const didKeyDownRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);
const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
onPointerDown(event) {
pointerTypeRef.current = event.pointerType;
},
onMouseDown(event) {
const pointerType = pointerTypeRef.current;
// Ignore all buttons except for the "main" button.
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
if (event.button !== 0) return;
if (eventOption === 'click') return;
if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isMouseLikePointerType)(pointerType, true) && ignoreMouse) return;
if (open && toggle && (dataRef.current.openEvent && stickIfOpen ? dataRef.current.openEvent.type === 'mousedown' : true)) {
onOpenChange(false, event.nativeEvent, 'click');
} else {
// Prevent stealing focus from the floating element
event.preventDefault();
onOpenChange(true, event.nativeEvent, 'click');
}
},
onClick(event) {
const pointerType = pointerTypeRef.current;
if (eventOption === 'mousedown' && pointerTypeRef.current) {
pointerTypeRef.current = undefined;
return;
}
if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isMouseLikePointerType)(pointerType, true) && ignoreMouse) return;
if (open && toggle && (dataRef.current.openEvent && stickIfOpen ? dataRef.current.openEvent.type === 'click' : true)) {
onOpenChange(false, event.nativeEvent, 'click');
} else {
onOpenChange(true, event.nativeEvent, 'click');
}
},
onKeyDown(event) {
pointerTypeRef.current = undefined;
if (event.defaultPrevented || !keyboardHandlers || isButtonTarget(event)) {
return;
}
if (event.key === ' ' && !isSpaceIgnored(domReference)) {
// Prevent scrolling
event.preventDefault();
didKeyDownRef.current = true;
}
if (isAnchorTarget(event)) {
return;
}
if (event.key === 'Enter') {
if (open && toggle) {
onOpenChange(false, event.nativeEvent, 'click');
} else {
onOpenChange(true, event.nativeEvent, 'click');
}
}
},
onKeyUp(event) {
if (event.defaultPrevented || !keyboardHandlers || isButtonTarget(event) || isSpaceIgnored(domReference)) {
return;
}
if (event.key === ' ' && didKeyDownRef.current) {
didKeyDownRef.current = false;
if (open && toggle) {
onOpenChange(false, event.nativeEvent, 'click');
} else {
onOpenChange(true, event.nativeEvent, 'click');
}
}
}
}), [dataRef, domReference, eventOption, ignoreMouse, keyboardHandlers, onOpenChange, open, stickIfOpen, toggle]);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {
reference
} : {}, [enabled, reference]);
}
function createVirtualElement(domElement, data) {
let offsetX = null;
let offsetY = null;
let isAutoUpdateEvent = false;
return {
contextElement: domElement || undefined,
getBoundingClientRect() {
var _data$dataRef$current;
const domRect = (domElement == null ? void 0 : domElement.getBoundingClientRect()) || {
width: 0,
height: 0,
x: 0,
y: 0
};
const isXAxis = data.axis === 'x' || data.axis === 'both';
const isYAxis = data.axis === 'y' || data.axis === 'both';
const canTrackCursorOnAutoUpdate = ['mouseenter', 'mousemove'].includes(((_data$dataRef$current = data.dataRef.current.openEvent) == null ? void 0 : _data$dataRef$current.type) || '') && data.pointerType !== 'touch';
let width = domRect.width;
let height = domRect.height;
let x = domRect.x;
let y = domRect.y;
if (offsetX == null && data.x && isXAxis) {
offsetX = domRect.x - data.x;
}
if (offsetY == null && data.y && isYAxis) {
offsetY = domRect.y - data.y;
}
x -= offsetX || 0;
y -= offsetY || 0;
width = 0;
height = 0;
if (!isAutoUpdateEvent || canTrackCursorOnAutoUpdate) {
width = data.axis === 'y' ? domRect.width : 0;
height = data.axis === 'x' ? domRect.height : 0;
x = isXAxis && data.x != null ? data.x : x;
y = isYAxis && data.y != null ? data.y : y;
} else if (isAutoUpdateEvent && !canTrackCursorOnAutoUpdate) {
height = data.axis === 'x' ? domRect.height : height;
width = data.axis === 'y' ? domRect.width : width;
}
isAutoUpdateEvent = true;
return {
width,
height,
x,
y,
top: y,
right: x + width,
bottom: y + height,
left: x
};
}
};
}
function isMouseBasedEvent(event) {
return event != null && event.clientX != null;
}
/**
* Positions the floating element relative to a client point (in the viewport),
* such as the mouse position. By default, it follows the mouse cursor.
* @see https://floating-ui.com/docs/useClientPoint
*/
function useClientPoint(context, props) {
if (props === void 0) {
props = {};
}
const {
open,
dataRef,
elements: {
floating,
domReference
},
refs
} = context;
const {
enabled = true,
axis = 'both',
x = null,
y = null
} = props;
const initialRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);
const cleanupListenerRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);
const [pointerType, setPointerType] = react__WEBPACK_IMPORTED_MODULE_0__.useState();
const [reactive, setReactive] = react__WEBPACK_IMPORTED_MODULE_0__.useState([]);
const setReference = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)((x, y) => {
if (initialRef.current) return;
// Prevent setting if the open event was not a mouse-like one
// (e.g. focus to open, then hover over the reference element).
// Only apply if the event exists.
if (dataRef.current.openEvent && !isMouseBasedEvent(dataRef.current.openEvent)) {
return;
}
refs.setPositionReference(createVirtualElement(domReference, {
x,
y,
axis,
dataRef,
pointerType
}));
});
const handleReferenceEnterOrMove = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(event => {
if (x != null || y != null) return;
if (!open) {
setReference(event.clientX, event.clientY);
} else if (!cleanupListenerRef.current) {
// If there's no cleanup, there's no listener, but we want to ensure
// we add the listener if the cursor landed on the floating element and
// then back on the reference (i.e. it's interactive).
setReactive([]);
}
});
// If the pointer is a mouse-like pointer, we want to continue following the
// mouse even if the floating element is transitioning out. On touch
// devices, this is undesirable because the floating element will move to
// the dismissal touch point.
const openCheck = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isMouseLikePointerType)(pointerType) ? floating : open;
const addListener = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(() => {
// Explicitly specified `x`/`y` coordinates shouldn't add a listener.
if (!openCheck || !enabled || x != null || y != null) return;
const win = (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getWindow)(floating);
function handleMouseMove(event) {
const target = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getTarget)(event);
if (!(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.contains)(floating, target)) {
setReference(event.clientX, event.clientY);
} else {
win.removeEventListener('mousemove', handleMouseMove);
cleanupListenerRef.current = null;
}
}
if (!dataRef.current.openEvent || isMouseBasedEvent(dataRef.current.openEvent)) {
win.addEventListener('mousemove', handleMouseMove);
const cleanup = () => {
win.removeEventListener('mousemove', handleMouseMove);
cleanupListenerRef.current = null;
};
cleanupListenerRef.current = cleanup;
return cleanup;
}
refs.setPositionReference(domReference);
}, [openCheck, enabled, x, y, floating, dataRef, refs, domReference, setReference]);
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
return addListener();
}, [addListener, reactive]);
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
if (enabled && !floating) {
initialRef.current = false;
}
}, [enabled, floating]);
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
if (!enabled && open) {
initialRef.current = true;
}
}, [enabled, open]);
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
if (enabled && (x != null || y != null)) {
initialRef.current = false;
setReference(x, y);
}
}, [enabled, x, y, setReference]);
const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
function setPointerTypeRef(_ref) {
let {
pointerType
} = _ref;
setPointerType(pointerType);
}
return {
onPointerDown: setPointerTypeRef,
onPointerEnter: setPointerTypeRef,
onMouseMove: handleReferenceEnterOrMove,
onMouseEnter: handleReferenceEnterOrMove
};
}, [handleReferenceEnterOrMove]);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {
reference
} : {}, [enabled, reference]);
}
const bubbleHandlerKeys = {
pointerdown: 'onPointerDown',
mousedown: 'onMouseDown',
click: 'onClick'
};
const captureHandlerKeys = {
pointerdown: 'onPointerDownCapture',
mousedown: 'onMouseDownCapture',
click: 'onClickCapture'
};
const normalizeProp = normalizable => {
var _normalizable$escapeK, _normalizable$outside;
return {
escapeKey: typeof normalizable === 'boolean' ? normalizable : (_normalizable$escapeK = normalizable == null ? void 0 : normalizable.escapeKey) != null ? _normalizable$escapeK : false,
outsidePress: typeof normalizable === 'boolean' ? normalizable : (_normalizable$outside = normalizable == null ? void 0 : normalizable.outsidePress) != null ? _normalizable$outside : true
};
};
/**
* Closes the floating element when a dismissal is requested — by default, when
* the user presses the `escape` key or outside of the floating element.
* @see https://floating-ui.com/docs/useDismiss
*/
function useDismiss(context, props) {
if (props === void 0) {
props = {};
}
const {
open,
onOpenChange,
elements,
dataRef
} = context;
const {
enabled = true,
escapeKey = true,
outsidePress: unstable_outsidePress = true,
outsidePressEvent = 'pointerdown',
referencePress = false,
referencePressEvent = 'pointerdown',
ancestorScroll = false,
bubbles,
capture
} = props;
const tree = useFloatingTree();
const outsidePressFn = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(typeof unstable_outsidePress === 'function' ? unstable_outsidePress : () => false);
const outsidePress = typeof unstable_outsidePress === 'function' ? outsidePressFn : unstable_outsidePress;
const endedOrStartedInsideRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);
const {
escapeKey: escapeKeyBubbles,
outsidePress: outsidePressBubbles
} = normalizeProp(bubbles);
const {
escapeKey: escapeKeyCapture,
outsidePress: outsidePressCapture
} = normalizeProp(capture);
const isComposingRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);
const closeOnEscapeKeyDown = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(event => {
var _dataRef$current$floa;
if (!open || !enabled || !escapeKey || event.key !== 'Escape') {
return;
}
// Wait until IME is settled. Pressing `Escape` while composing should
// close the compose menu, but not the floating element.
if (isComposingRef.current) {
return;
}
const nodeId = (_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.nodeId;
const children = tree ? (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getNodeChildren)(tree.nodesRef.current, nodeId) : [];
if (!escapeKeyBubbles) {
event.stopPropagation();
if (children.length > 0) {
let shouldDismiss = true;
children.forEach(child => {
var _child$context;
if ((_child$context = child.context) != null && _child$context.open && !child.context.dataRef.current.__escapeKeyBubbles) {
shouldDismiss = false;
return;
}
});
if (!shouldDismiss) {
return;
}
}
}
onOpenChange(false, (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isReactEvent)(event) ? event.nativeEvent : event, 'escape-key');
});
const closeOnEscapeKeyDownCapture = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(event => {
var _getTarget2;
const callback = () => {
var _getTarget;
closeOnEscapeKeyDown(event);
(_getTarget = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getTarget)(event)) == null || _getTarget.removeEventListener('keydown', callback);
};
(_getTarget2 = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getTarget)(event)) == null || _getTarget2.addEventListener('keydown', callback);
});
const closeOnPressOutside = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(event => {
var _dataRef$current$floa2;
// Given developers can stop the propagation of the synthetic event,
// we can only be confident with a positive value.
const insideReactTree = dataRef.current.insideReactTree;
dataRef.current.insideReactTree = false;
// When click outside is lazy (`click` event), handle dragging.
// Don't close if:
// - The click started inside the floating element.
// - The click ended inside the floating element.
const endedOrStartedInside = endedOrStartedInsideRef.current;
endedOrStartedInsideRef.current = false;
if (outsidePressEvent === 'click' && endedOrStartedInside) {
return;
}
if (insideReactTree) {
return;
}
if (typeof outsidePress === 'function' && !outsidePress(event)) {
return;
}
const target = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getTarget)(event);
const inertSelector = "[" + createAttribute('inert') + "]";
const markers = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getDocument)(elements.floating).querySelectorAll(inertSelector);
let targetRootAncestor = (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(target) ? target : null;
while (targetRootAncestor && !(0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isLastTraversableNode)(targetRootAncestor)) {
const nextParent = (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getParentNode)(targetRootAncestor);
if ((0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isLastTraversableNode)(nextParent) || !(0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(nextParent)) {
break;
}
targetRootAncestor = nextParent;
}
// Check if the click occurred on a third-party element injected after the
// floating element rendered.
if (markers.length && (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(target) && !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isRootElement)(target) &&
// Clicked on a direct ancestor (e.g. FloatingOverlay).
!(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.contains)(target, elements.floating) &&
// If the target root element contains none of the markers, then the
// element was injected after the floating element rendered.
Array.from(markers).every(marker => !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.contains)(targetRootAncestor, marker))) {
return;
}
// Check if the click occurred on the scrollbar
if ((0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isHTMLElement)(target) && floating) {
const lastTraversableNode = (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isLastTraversableNode)(target);
const style = (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getComputedStyle)(target);
const scrollRe = /auto|scroll/;
const isScrollableX = lastTraversableNode || scrollRe.test(style.overflowX);
const isScrollableY = lastTraversableNode || scrollRe.test(style.overflowY);
const canScrollX = isScrollableX && target.clientWidth > 0 && target.scrollWidth > target.clientWidth;
const canScrollY = isScrollableY && target.clientHeight > 0 && target.scrollHeight > target.clientHeight;
const isRTL = style.direction === 'rtl';
// Check click position relative to scrollbar.
// In some browsers it is possible to change the (or window)
// scrollbar to the left side, but is very rare and is difficult to
// check for. Plus, for modal dialogs with backdrops, it is more
// important that the backdrop is checked but not so much the window.
const pressedVerticalScrollbar = canScrollY && (isRTL ? event.offsetX <= target.offsetWidth - target.clientWidth : event.offsetX > target.clientWidth);
const pressedHorizontalScrollbar = canScrollX && event.offsetY > target.clientHeight;
if (pressedVerticalScrollbar || pressedHorizontalScrollbar) {
return;
}
}
const nodeId = (_dataRef$current$floa2 = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa2.nodeId;
const targetIsInsideChildren = tree && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getNodeChildren)(tree.nodesRef.current, nodeId).some(node => {
var _node$context;
return (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isEventTargetWithin)(event, (_node$context = node.context) == null ? void 0 : _node$context.elements.floating);
});
if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isEventTargetWithin)(event, elements.floating) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isEventTargetWithin)(event, elements.domReference) || targetIsInsideChildren) {
return;
}
const children = tree ? (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getNodeChildren)(tree.nodesRef.current, nodeId) : [];
if (children.length > 0) {
let shouldDismiss = true;
children.forEach(child => {
var _child$context2;
if ((_child$context2 = child.context) != null && _child$context2.open && !child.context.dataRef.current.__outsidePressBubbles) {
shouldDismiss = false;
return;
}
});
if (!shouldDismiss) {
return;
}
}
onOpenChange(false, event, 'outside-press');
});
const closeOnPressOutsideCapture = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(event => {
var _getTarget4;
const callback = () => {
var _getTarget3;
closeOnPressOutside(event);
(_getTarget3 = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getTarget)(event)) == null || _getTarget3.removeEventListener(outsidePressEvent, callback);
};
(_getTarget4 = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getTarget)(event)) == null || _getTarget4.addEventListener(outsidePressEvent, callback);
});
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
if (!open || !enabled) {
return;
}
dataRef.current.__escapeKeyBubbles = escapeKeyBubbles;
dataRef.current.__outsidePressBubbles = outsidePressBubbles;
let compositionTimeout = -1;
function onScroll(event) {
onOpenChange(false, event, 'ancestor-scroll');
}
function handleCompositionStart() {
window.clearTimeout(compositionTimeout);
isComposingRef.current = true;
}
function handleCompositionEnd() {
// Safari fires `compositionend` before `keydown`, so we need to wait
// until the next tick to set `isComposing` to `false`.
// https://bugs.webkit.org/show_bug.cgi?id=165004
compositionTimeout = window.setTimeout(() => {
isComposingRef.current = false;
},
// 0ms or 1ms don't work in Safari. 5ms appears to consistently work.
// Only apply to WebKit for the test to remain 0ms.
(0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isWebKit)() ? 5 : 0);
}
const doc = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getDocument)(elements.floating);
if (escapeKey) {
doc.addEventListener('keydown', escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);
doc.addEventListener('compositionstart', handleCompositionStart);
doc.addEventListener('compositionend', handleCompositionEnd);
}
outsidePress && doc.addEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);
let ancestors = [];
if (ancestorScroll) {
if ((0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(elements.domReference)) {
ancestors = (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getOverflowAncestors)(elements.domReference);
}
if ((0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(elements.floating)) {
ancestors = ancestors.concat((0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getOverflowAncestors)(elements.floating));
}
if (!(0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(elements.reference) && elements.reference && elements.reference.contextElement) {
ancestors = ancestors.concat((0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getOverflowAncestors)(elements.reference.contextElement));
}
}
// Ignore the visual viewport for scrolling dismissal (allow pinch-zoom)
ancestors = ancestors.filter(ancestor => {
var _doc$defaultView;
return ancestor !== ((_doc$defaultView = doc.defaultView) == null ? void 0 : _doc$defaultView.visualViewport);
});
ancestors.forEach(ancestor => {
ancestor.addEventListener('scroll', onScroll, {
passive: true
});
});
return () => {
if (escapeKey) {
doc.removeEventListener('keydown', escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);
doc.removeEventListener('compositionstart', handleCompositionStart);
doc.removeEventListener('compositionend', handleCompositionEnd);
}
outsidePress && doc.removeEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);
ancestors.forEach(ancestor => {
ancestor.removeEventListener('scroll', onScroll);
});
window.clearTimeout(compositionTimeout);
};
}, [dataRef, elements, escapeKey, outsidePress, outsidePressEvent, open, onOpenChange, ancestorScroll, enabled, escapeKeyBubbles, outsidePressBubbles, closeOnEscapeKeyDown, escapeKeyCapture, closeOnEscapeKeyDownCapture, closeOnPressOutside, outsidePressCapture, closeOnPressOutsideCapture]);
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
dataRef.current.insideReactTree = false;
}, [dataRef, outsidePress, outsidePressEvent]);
const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
onKeyDown: closeOnEscapeKeyDown,
...(referencePress && {
[bubbleHandlerKeys[referencePressEvent]]: event => {
onOpenChange(false, event.nativeEvent, 'reference-press');
},
...(referencePressEvent !== 'click' && {
onClick(event) {
onOpenChange(false, event.nativeEvent, 'reference-press');
}
})
})
}), [closeOnEscapeKeyDown, onOpenChange, referencePress, referencePressEvent]);
const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
function setMouseDownOrUpInside(event) {
if (event.button !== 0) {
return;
}
endedOrStartedInsideRef.current = true;
}
return {
onKeyDown: closeOnEscapeKeyDown,
onMouseDown: setMouseDownOrUpInside,
onMouseUp: setMouseDownOrUpInside,
[captureHandlerKeys[outsidePressEvent]]: () => {
dataRef.current.insideReactTree = true;
}
};
}, [closeOnEscapeKeyDown, outsidePressEvent, dataRef]);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {
reference,
floating
} : {}, [enabled, reference, floating]);
}
function useFloatingRootContext(options) {
const {
open = false,
onOpenChange: onOpenChangeProp,
elements: elementsProp
} = options;
const floatingId = useId();
const dataRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef({});
const [events] = react__WEBPACK_IMPORTED_MODULE_0__.useState(() => createEventEmitter());
const nested = useFloatingParentNodeId() != null;
if (true) {
const optionDomReference = elementsProp.reference;
if (optionDomReference && !(0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(optionDomReference)) {
error('Cannot pass a virtual element to the `elements.reference` option,', 'as it must be a real DOM element. Use `refs.setPositionReference()`', 'instead.');
}
}
const [positionReference, setPositionReference] = react__WEBPACK_IMPORTED_MODULE_0__.useState(elementsProp.reference);
const onOpenChange = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)((open, event, reason) => {
dataRef.current.openEvent = open ? event : undefined;
events.emit('openchange', {
open,
event,
reason,
nested
});
onOpenChangeProp == null || onOpenChangeProp(open, event, reason);
});
const refs = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
setPositionReference
}), []);
const elements = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
reference: positionReference || elementsProp.reference || null,
floating: elementsProp.floating || null,
domReference: elementsProp.reference
}), [positionReference, elementsProp.reference, elementsProp.floating]);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
dataRef,
open,
onOpenChange,
elements,
events,
floatingId,
refs
}), [open, onOpenChange, elements, events, floatingId, refs]);
}
/**
* Provides data to position a floating element and context to add interactions.
* @see https://floating-ui.com/docs/useFloating
*/
function useFloating(options) {
if (options === void 0) {
options = {};
}
const {
nodeId
} = options;
const internalRootContext = useFloatingRootContext({
...options,
elements: {
reference: null,
floating: null,
...options.elements
}
});
const rootContext = options.rootContext || internalRootContext;
const computedElements = rootContext.elements;
const [_domReference, setDomReference] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);
const [positionReference, _setPositionReference] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);
const optionDomReference = computedElements == null ? void 0 : computedElements.domReference;
const domReference = optionDomReference || _domReference;
const domReferenceRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);
const tree = useFloatingTree();
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
if (domReference) {
domReferenceRef.current = domReference;
}
}, [domReference]);
const position = (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_6__.useFloating)({
...options,
elements: {
...computedElements,
...(positionReference && {
reference: positionReference
})
}
});
const setPositionReference = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(node => {
const computedPositionReference = (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(node) ? {
getBoundingClientRect: () => node.getBoundingClientRect(),
getClientRects: () => node.getClientRects(),
contextElement: node
} : node;
// Store the positionReference in state if the DOM reference is specified externally via the
// `elements.reference` option. This ensures that it won't be overridden on future renders.
_setPositionReference(computedPositionReference);
position.refs.setReference(computedPositionReference);
}, [position.refs]);
const setReference = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(node => {
if ((0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(node) || node === null) {
domReferenceRef.current = node;
setDomReference(node);
}
// Backwards-compatibility for passing a virtual element to `reference`
// after it has set the DOM reference.
if ((0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(position.refs.reference.current) || position.refs.reference.current === null ||
// Don't allow setting virtual elements using the old technique back to
// `null` to support `positionReference` + an unstable `reference`
// callback ref.
node !== null && !(0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(node)) {
position.refs.setReference(node);
}
}, [position.refs]);
const refs = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
...position.refs,
setReference,
setPositionReference,
domReference: domReferenceRef
}), [position.refs, setReference, setPositionReference]);
const elements = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
...position.elements,
domReference: domReference
}), [position.elements, domReference]);
const context = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
...position,
...rootContext,
refs,
elements,
nodeId
}), [position, refs, elements, nodeId, rootContext]);
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
rootContext.dataRef.current.floatingContext = context;
const node = tree == null ? void 0 : tree.nodesRef.current.find(node => node.id === nodeId);
if (node) {
node.context = context;
}
});
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
...position,
context,
refs,
elements
}), [position, refs, elements, context]);
}
function isMacSafari() {
return (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isMac)() && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isSafari)();
}
/**
* Opens the floating element while the reference element has focus, like CSS
* `:focus`.
* @see https://floating-ui.com/docs/useFocus
*/
function useFocus(context, props) {
if (props === void 0) {
props = {};
}
const {
open,
onOpenChange,
events,
dataRef,
elements
} = context;
const {
enabled = true,
visibleOnly = true
} = props;
const blockFocusRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);
const timeoutRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(-1);
const keyboardModalityRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(true);
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
if (!enabled) return;
const win = (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getWindow)(elements.domReference);
// If the reference was focused and the user left the tab/window, and the
// floating element was not open, the focus should be blocked when they
// return to the tab/window.
function onBlur() {
if (!open && (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isHTMLElement)(elements.domReference) && elements.domReference === (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.activeElement)((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getDocument)(elements.domReference))) {
blockFocusRef.current = true;
}
}
function onKeyDown() {
keyboardModalityRef.current = true;
}
function onPointerDown() {
keyboardModalityRef.current = false;
}
win.addEventListener('blur', onBlur);
if (isMacSafari()) {
win.addEventListener('keydown', onKeyDown, true);
win.addEventListener('pointerdown', onPointerDown, true);
}
return () => {
win.removeEventListener('blur', onBlur);
if (isMacSafari()) {
win.removeEventListener('keydown', onKeyDown, true);
win.removeEventListener('pointerdown', onPointerDown, true);
}
};
}, [elements.domReference, open, enabled]);
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
if (!enabled) return;
function onOpenChange(_ref) {
let {
reason
} = _ref;
if (reason === 'reference-press' || reason === 'escape-key') {
blockFocusRef.current = true;
}
}
events.on('openchange', onOpenChange);
return () => {
events.off('openchange', onOpenChange);
};
}, [events, enabled]);
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
return () => {
clearTimeoutIfSet(timeoutRef);
};
}, []);
const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
onMouseLeave() {
blockFocusRef.current = false;
},
onFocus(event) {
if (blockFocusRef.current) return;
const target = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getTarget)(event.nativeEvent);
if (visibleOnly && (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(target)) {
// Safari fails to match `:focus-visible` if focus was initially
// outside the document.
if (isMacSafari() && !event.relatedTarget) {
if (!keyboardModalityRef.current && !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isTypeableElement)(target)) {
return;
}
} else if (!(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.matchesFocusVisible)(target)) {
return;
}
}
onOpenChange(true, event.nativeEvent, 'focus');
},
onBlur(event) {
blockFocusRef.current = false;
const relatedTarget = event.relatedTarget;
const nativeEvent = event.nativeEvent;
// Hit the non-modal focus management portal guard. Focus will be
// moved into the floating element immediately after.
const movedToFocusGuard = (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(relatedTarget) && relatedTarget.hasAttribute(createAttribute('focus-guard')) && relatedTarget.getAttribute('data-type') === 'outside';
// Wait for the window blur listener to fire.
timeoutRef.current = window.setTimeout(() => {
var _dataRef$current$floa;
const activeEl = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.activeElement)(elements.domReference ? elements.domReference.ownerDocument : document);
// Focus left the page, keep it open.
if (!relatedTarget && activeEl === elements.domReference) return;
// When focusing the reference element (e.g. regular click), then
// clicking into the floating element, prevent it from hiding.
// Note: it must be focusable, e.g. `tabindex="-1"`.
// We can not rely on relatedTarget to point to the correct element
// as it will only point to the shadow host of the newly focused element
// and not the element that actually has received focus if it is located
// inside a shadow root.
if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.contains)((_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.refs.floating.current, activeEl) || (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.contains)(elements.domReference, activeEl) || movedToFocusGuard) {
return;
}
onOpenChange(false, nativeEvent, 'focus');
});
}
}), [dataRef, elements.domReference, onOpenChange, visibleOnly]);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {
reference
} : {}, [enabled, reference]);
}
function mergeProps(userProps, propsList, elementKey) {
const map = new Map();
const isItem = elementKey === 'item';
let domUserProps = userProps;
if (isItem && userProps) {
const {
[ACTIVE_KEY]: _,
[SELECTED_KEY]: __,
...validProps
} = userProps;
domUserProps = validProps;
}
return {
...(elementKey === 'floating' && {
tabIndex: -1,
[FOCUSABLE_ATTRIBUTE]: ''
}),
...domUserProps,
...propsList.map(value => {
const propsOrGetProps = value ? value[elementKey] : null;
if (typeof propsOrGetProps === 'function') {
return userProps ? propsOrGetProps(userProps) : null;
}
return propsOrGetProps;
}).concat(userProps).reduce((acc, props) => {
if (!props) {
return acc;
}
Object.entries(props).forEach(_ref => {
let [key, value] = _ref;
if (isItem && [ACTIVE_KEY, SELECTED_KEY].includes(key)) {
return;
}
if (key.indexOf('on') === 0) {
if (!map.has(key)) {
map.set(key, []);
}
if (typeof value === 'function') {
var _map$get;
(_map$get = map.get(key)) == null || _map$get.push(value);
acc[key] = function () {
var _map$get2;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return (_map$get2 = map.get(key)) == null ? void 0 : _map$get2.map(fn => fn(...args)).find(val => val !== undefined);
};
}
} else {
acc[key] = value;
}
});
return acc;
}, {})
};
}
/**
* Merges an array of interaction hooks' props into prop getters, allowing
* event handler functions to be composed together without overwriting one
* another.
* @see https://floating-ui.com/docs/useInteractions
*/
function useInteractions(propsList) {
if (propsList === void 0) {
propsList = [];
}
const referenceDeps = propsList.map(key => key == null ? void 0 : key.reference);
const floatingDeps = propsList.map(key => key == null ? void 0 : key.floating);
const itemDeps = propsList.map(key => key == null ? void 0 : key.item);
const getReferenceProps = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(userProps => mergeProps(userProps, propsList, 'reference'),
// eslint-disable-next-line react-hooks/exhaustive-deps
referenceDeps);
const getFloatingProps = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(userProps => mergeProps(userProps, propsList, 'floating'),
// eslint-disable-next-line react-hooks/exhaustive-deps
floatingDeps);
const getItemProps = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(userProps => mergeProps(userProps, propsList, 'item'),
// eslint-disable-next-line react-hooks/exhaustive-deps
itemDeps);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
getReferenceProps,
getFloatingProps,
getItemProps
}), [getReferenceProps, getFloatingProps, getItemProps]);
}
const ESCAPE = 'Escape';
function doSwitch(orientation, vertical, horizontal) {
switch (orientation) {
case 'vertical':
return vertical;
case 'horizontal':
return horizontal;
default:
return vertical || horizontal;
}
}
function isMainOrientationKey(key, orientation) {
const vertical = key === ARROW_UP || key === ARROW_DOWN;
const horizontal = key === ARROW_LEFT || key === ARROW_RIGHT;
return doSwitch(orientation, vertical, horizontal);
}
function isMainOrientationToEndKey(key, orientation, rtl) {
const vertical = key === ARROW_DOWN;
const horizontal = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;
return doSwitch(orientation, vertical, horizontal) || key === 'Enter' || key === ' ' || key === '';
}
function isCrossOrientationOpenKey(key, orientation, rtl) {
const vertical = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;
const horizontal = key === ARROW_DOWN;
return doSwitch(orientation, vertical, horizontal);
}
function isCrossOrientationCloseKey(key, orientation, rtl, cols) {
const vertical = rtl ? key === ARROW_RIGHT : key === ARROW_LEFT;
const horizontal = key === ARROW_UP;
if (orientation === 'both' || orientation === 'horizontal' && cols && cols > 1) {
return key === ESCAPE;
}
return doSwitch(orientation, vertical, horizontal);
}
/**
* Adds arrow key-based navigation of a list of items, either using real DOM
* focus or virtual focus.
* @see https://floating-ui.com/docs/useListNavigation
*/
function useListNavigation(context, props) {
const {
open,
onOpenChange,
elements,
floatingId
} = context;
const {
listRef,
activeIndex,
onNavigate: unstable_onNavigate = () => {},
enabled = true,
selectedIndex = null,
allowEscape = false,
loop = false,
nested = false,
rtl = false,
virtual = false,
focusItemOnOpen = 'auto',
focusItemOnHover = true,
openOnArrowKeyDown = true,
disabledIndices = undefined,
orientation = 'vertical',
parentOrientation,
cols = 1,
scrollItemIntoView = true,
virtualItemRef,
itemSizes,
dense = false
} = props;
if (true) {
if (allowEscape) {
if (!loop) {
warn('`useListNavigation` looping must be enabled to allow escaping.');
}
if (!virtual) {
warn('`useListNavigation` must be virtual to allow escaping.');
}
}
if (orientation === 'vertical' && cols > 1) {
warn('In grid list navigation mode (`cols` > 1), the `orientation` should', 'be either "horizontal" or "both".');
}
}
const floatingFocusElement = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getFloatingFocusElement)(elements.floating);
const floatingFocusElementRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(floatingFocusElement);
const parentId = useFloatingParentNodeId();
const tree = useFloatingTree();
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
context.dataRef.current.orientation = orientation;
}, [context, orientation]);
const onNavigate = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(() => {
unstable_onNavigate(indexRef.current === -1 ? null : indexRef.current);
});
const typeableComboboxReference = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isTypeableCombobox)(elements.domReference);
const focusItemOnOpenRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(focusItemOnOpen);
const indexRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(selectedIndex != null ? selectedIndex : -1);
const keyRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);
const isPointerModalityRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(true);
const previousOnNavigateRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(onNavigate);
const previousMountedRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(!!elements.floating);
const previousOpenRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(open);
const forceSyncFocusRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);
const forceScrollIntoViewRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);
const disabledIndicesRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(disabledIndices);
const latestOpenRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(open);
const scrollItemIntoViewRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(scrollItemIntoView);
const selectedIndexRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(selectedIndex);
const [activeId, setActiveId] = react__WEBPACK_IMPORTED_MODULE_0__.useState();
const [virtualId, setVirtualId] = react__WEBPACK_IMPORTED_MODULE_0__.useState();
const focusItem = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(() => {
function runFocus(item) {
if (virtual) {
var _item$id;
if ((_item$id = item.id) != null && _item$id.endsWith('-fui-option')) {
item.id = floatingId + "-" + Math.random().toString(16).slice(2, 10);
}
setActiveId(item.id);
tree == null || tree.events.emit('virtualfocus', item);
if (virtualItemRef) {
virtualItemRef.current = item;
}
} else {
enqueueFocus(item, {
sync: forceSyncFocusRef.current,
preventScroll: true
});
}
}
const initialItem = listRef.current[indexRef.current];
const forceScrollIntoView = forceScrollIntoViewRef.current;
if (initialItem) {
runFocus(initialItem);
}
const scheduler = forceSyncFocusRef.current ? v => v() : requestAnimationFrame;
scheduler(() => {
const waitedItem = listRef.current[indexRef.current] || initialItem;
if (!waitedItem) return;
if (!initialItem) {
runFocus(waitedItem);
}
const scrollIntoViewOptions = scrollItemIntoViewRef.current;
const shouldScrollIntoView = scrollIntoViewOptions && item && (forceScrollIntoView || !isPointerModalityRef.current);
if (shouldScrollIntoView) {
// JSDOM doesn't support `.scrollIntoView()` but it's widely supported
// by all browsers.
waitedItem.scrollIntoView == null || waitedItem.scrollIntoView(typeof scrollIntoViewOptions === 'boolean' ? {
block: 'nearest',
inline: 'nearest'
} : scrollIntoViewOptions);
}
});
});
// Sync `selectedIndex` to be the `activeIndex` upon opening the floating
// element. Also, reset `activeIndex` upon closing the floating element.
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
if (!enabled) return;
if (open && elements.floating) {
if (focusItemOnOpenRef.current && selectedIndex != null) {
// Regardless of the pointer modality, we want to ensure the selected
// item comes into view when the floating element is opened.
forceScrollIntoViewRef.current = true;
indexRef.current = selectedIndex;
onNavigate();
}
} else if (previousMountedRef.current) {
// Since the user can specify `onNavigate` conditionally
// (onNavigate: open ? setActiveIndex : setSelectedIndex),
// we store and call the previous function.
indexRef.current = -1;
previousOnNavigateRef.current();
}
}, [enabled, open, elements.floating, selectedIndex, onNavigate]);
// Sync `activeIndex` to be the focused item while the floating element is
// open.
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
if (!enabled) return;
if (!open) return;
if (!elements.floating) return;
if (activeIndex == null) {
forceSyncFocusRef.current = false;
if (selectedIndexRef.current != null) {
return;
}
// Reset while the floating element was open (e.g. the list changed).
if (previousMountedRef.current) {
indexRef.current = -1;
focusItem();
}
// Initial sync.
if ((!previousOpenRef.current || !previousMountedRef.current) && focusItemOnOpenRef.current && (keyRef.current != null || focusItemOnOpenRef.current === true && keyRef.current == null)) {
let runs = 0;
const waitForListPopulated = () => {
if (listRef.current[0] == null) {
// Avoid letting the browser paint if possible on the first try,
// otherwise use rAF. Don't try more than twice, since something
// is wrong otherwise.
if (runs < 2) {
const scheduler = runs ? requestAnimationFrame : queueMicrotask;
scheduler(waitForListPopulated);
}
runs++;
} else {
indexRef.current = keyRef.current == null || isMainOrientationToEndKey(keyRef.current, orientation, rtl) || nested ? (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getMinListIndex)(listRef, disabledIndicesRef.current) : (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getMaxListIndex)(listRef, disabledIndicesRef.current);
keyRef.current = null;
onNavigate();
}
};
waitForListPopulated();
}
} else if (!(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isIndexOutOfListBounds)(listRef, activeIndex)) {
indexRef.current = activeIndex;
focusItem();
forceScrollIntoViewRef.current = false;
}
}, [enabled, open, elements.floating, activeIndex, selectedIndexRef, nested, listRef, orientation, rtl, onNavigate, focusItem, disabledIndicesRef]);
// Ensure the parent floating element has focus when a nested child closes
// to allow arrow key navigation to work after the pointer leaves the child.
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
var _nodes$find;
if (!enabled || elements.floating || !tree || virtual || !previousMountedRef.current) {
return;
}
const nodes = tree.nodesRef.current;
const parent = (_nodes$find = nodes.find(node => node.id === parentId)) == null || (_nodes$find = _nodes$find.context) == null ? void 0 : _nodes$find.elements.floating;
const activeEl = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.activeElement)((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getDocument)(elements.floating));
const treeContainsActiveEl = nodes.some(node => node.context && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.contains)(node.context.elements.floating, activeEl));
if (parent && !treeContainsActiveEl && isPointerModalityRef.current) {
parent.focus({
preventScroll: true
});
}
}, [enabled, elements.floating, tree, parentId, virtual]);
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
if (!enabled) return;
if (!tree) return;
if (!virtual) return;
if (parentId) return;
function handleVirtualFocus(item) {
setVirtualId(item.id);
if (virtualItemRef) {
virtualItemRef.current = item;
}
}
tree.events.on('virtualfocus', handleVirtualFocus);
return () => {
tree.events.off('virtualfocus', handleVirtualFocus);
};
}, [enabled, tree, virtual, parentId, virtualItemRef]);
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
previousOnNavigateRef.current = onNavigate;
previousOpenRef.current = open;
previousMountedRef.current = !!elements.floating;
});
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
if (!open) {
keyRef.current = null;
focusItemOnOpenRef.current = focusItemOnOpen;
}
}, [open, focusItemOnOpen]);
const hasActiveIndex = activeIndex != null;
const item = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
function syncCurrentTarget(currentTarget) {
if (!latestOpenRef.current) return;
const index = listRef.current.indexOf(currentTarget);
if (index !== -1 && indexRef.current !== index) {
indexRef.current = index;
onNavigate();
}
}
const props = {
onFocus(_ref) {
let {
currentTarget
} = _ref;
forceSyncFocusRef.current = true;
syncCurrentTarget(currentTarget);
},
onClick: _ref2 => {
let {
currentTarget
} = _ref2;
return currentTarget.focus({
preventScroll: true
});
},
// Safari
onMouseMove(_ref3) {
let {
currentTarget
} = _ref3;
forceSyncFocusRef.current = true;
forceScrollIntoViewRef.current = false;
if (focusItemOnHover) {
syncCurrentTarget(currentTarget);
}
},
onPointerLeave(_ref4) {
let {
pointerType
} = _ref4;
if (!isPointerModalityRef.current || pointerType === 'touch') {
return;
}
forceSyncFocusRef.current = true;
if (!focusItemOnHover) {
return;
}
indexRef.current = -1;
onNavigate();
if (!virtual) {
var _floatingFocusElement;
(_floatingFocusElement = floatingFocusElementRef.current) == null || _floatingFocusElement.focus({
preventScroll: true
});
}
}
};
return props;
}, [latestOpenRef, floatingFocusElementRef, focusItemOnHover, listRef, onNavigate, virtual]);
const getParentOrientation = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(() => {
var _tree$nodesRef$curren;
return parentOrientation != null ? parentOrientation : tree == null || (_tree$nodesRef$curren = tree.nodesRef.current.find(node => node.id === parentId)) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.context) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.dataRef) == null ? void 0 : _tree$nodesRef$curren.current.orientation;
}, [parentId, tree, parentOrientation]);
const commonOnKeyDown = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(event => {
isPointerModalityRef.current = false;
forceSyncFocusRef.current = true;
// When composing a character, Chrome fires ArrowDown twice. Firefox/Safari
// don't appear to suffer from this. `event.isComposing` is avoided due to
// Safari not supporting it properly (although it's not needed in the first
// place for Safari, just avoiding any possible issues).
if (event.which === 229) {
return;
}
// If the floating element is animating out, ignore navigation. Otherwise,
// the `activeIndex` gets set to 0 despite not being open so the next time
// the user ArrowDowns, the first item won't be focused.
if (!latestOpenRef.current && event.currentTarget === floatingFocusElementRef.current) {
return;
}
if (nested && isCrossOrientationCloseKey(event.key, orientation, rtl, cols)) {
// If the nested list's close key is also the parent navigation key,
// let the parent navigate. Otherwise, stop propagating the event.
if (!isMainOrientationKey(event.key, getParentOrientation())) {
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
}
onOpenChange(false, event.nativeEvent, 'list-navigation');
if ((0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isHTMLElement)(elements.domReference)) {
if (virtual) {
tree == null || tree.events.emit('virtualfocus', elements.domReference);
} else {
elements.domReference.focus();
}
}
return;
}
const currentIndex = indexRef.current;
const minIndex = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getMinListIndex)(listRef, disabledIndices);
const maxIndex = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getMaxListIndex)(listRef, disabledIndices);
if (!typeableComboboxReference) {
if (event.key === 'Home') {
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
indexRef.current = minIndex;
onNavigate();
}
if (event.key === 'End') {
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
indexRef.current = maxIndex;
onNavigate();
}
}
// Grid navigation.
if (cols > 1) {
const sizes = itemSizes || Array.from({
length: listRef.current.length
}, () => ({
width: 1,
height: 1
}));
// To calculate movements on the grid, we use hypothetical cell indices
// as if every item was 1x1, then convert back to real indices.
const cellMap = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.createGridCellMap)(sizes, cols, dense);
const minGridIndex = cellMap.findIndex(index => index != null && !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isListIndexDisabled)(listRef, index, disabledIndices));
// last enabled index
const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isListIndexDisabled)(listRef, index, disabledIndices) ? cellIndex : foundIndex, -1);
const index = cellMap[(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getGridNavigatedIndex)({
current: cellMap.map(itemIndex => itemIndex != null ? listRef.current[itemIndex] : null)
}, {
event,
orientation,
loop,
rtl,
cols,
// treat undefined (empty grid spaces) as disabled indices so we
// don't end up in them
disabledIndices: (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getGridCellIndices)([...((typeof disabledIndices !== 'function' ? disabledIndices : null) || listRef.current.map((_, index) => (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isListIndexDisabled)(listRef, index, disabledIndices) ? index : undefined)), undefined], cellMap),
minIndex: minGridIndex,
maxIndex: maxGridIndex,
prevIndex: (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getGridCellIndexOfCorner)(indexRef.current > maxIndex ? minIndex : indexRef.current, sizes, cellMap, cols,
// use a corner matching the edge closest to the direction
// we're moving in so we don't end up in the same item. Prefer
// top/left over bottom/right.
event.key === ARROW_DOWN ? 'bl' : event.key === (rtl ? ARROW_LEFT : ARROW_RIGHT) ? 'tr' : 'tl'),
stopEvent: true
})];
if (index != null) {
indexRef.current = index;
onNavigate();
}
if (orientation === 'both') {
return;
}
}
if (isMainOrientationKey(event.key, orientation)) {
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
// Reset the index if no item is focused.
if (open && !virtual && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.activeElement)(event.currentTarget.ownerDocument) === event.currentTarget) {
indexRef.current = isMainOrientationToEndKey(event.key, orientation, rtl) ? minIndex : maxIndex;
onNavigate();
return;
}
if (isMainOrientationToEndKey(event.key, orientation, rtl)) {
if (loop) {
indexRef.current = currentIndex >= maxIndex ? allowEscape && currentIndex !== listRef.current.length ? -1 : minIndex : (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.findNonDisabledListIndex)(listRef, {
startingIndex: currentIndex,
disabledIndices
});
} else {
indexRef.current = Math.min(maxIndex, (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.findNonDisabledListIndex)(listRef, {
startingIndex: currentIndex,
disabledIndices
}));
}
} else {
if (loop) {
indexRef.current = currentIndex <= minIndex ? allowEscape && currentIndex !== -1 ? listRef.current.length : maxIndex : (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.findNonDisabledListIndex)(listRef, {
startingIndex: currentIndex,
decrement: true,
disabledIndices
});
} else {
indexRef.current = Math.max(minIndex, (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.findNonDisabledListIndex)(listRef, {
startingIndex: currentIndex,
decrement: true,
disabledIndices
}));
}
}
if ((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isIndexOutOfListBounds)(listRef, indexRef.current)) {
indexRef.current = -1;
}
onNavigate();
}
});
const ariaActiveDescendantProp = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
return virtual && open && hasActiveIndex && {
'aria-activedescendant': virtualId || activeId
};
}, [virtual, open, hasActiveIndex, virtualId, activeId]);
const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
return {
'aria-orientation': orientation === 'both' ? undefined : orientation,
...(!typeableComboboxReference ? ariaActiveDescendantProp : {}),
onKeyDown: commonOnKeyDown,
onPointerMove() {
isPointerModalityRef.current = true;
}
};
}, [ariaActiveDescendantProp, commonOnKeyDown, orientation, typeableComboboxReference]);
const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
function checkVirtualMouse(event) {
if (focusItemOnOpen === 'auto' && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isVirtualClick)(event.nativeEvent)) {
focusItemOnOpenRef.current = true;
}
}
function checkVirtualPointer(event) {
// `pointerdown` fires first, reset the state then perform the checks.
focusItemOnOpenRef.current = focusItemOnOpen;
if (focusItemOnOpen === 'auto' && (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.isVirtualPointerEvent)(event.nativeEvent)) {
focusItemOnOpenRef.current = true;
}
}
return {
...ariaActiveDescendantProp,
onKeyDown(event) {
isPointerModalityRef.current = false;
const isArrowKey = event.key.startsWith('Arrow');
const isHomeOrEndKey = ['Home', 'End'].includes(event.key);
const isMoveKey = isArrowKey || isHomeOrEndKey;
const isCrossOpenKey = isCrossOrientationOpenKey(event.key, orientation, rtl);
const isCrossCloseKey = isCrossOrientationCloseKey(event.key, orientation, rtl, cols);
const isParentCrossOpenKey = isCrossOrientationOpenKey(event.key, getParentOrientation(), rtl);
const isMainKey = isMainOrientationKey(event.key, orientation);
const isNavigationKey = (nested ? isParentCrossOpenKey : isMainKey) || event.key === 'Enter' || event.key.trim() === '';
if (virtual && open) {
const rootNode = tree == null ? void 0 : tree.nodesRef.current.find(node => node.parentId == null);
const deepestNode = tree && rootNode ? (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getDeepestNode)(tree.nodesRef.current, rootNode.id) : null;
if (isMoveKey && deepestNode && virtualItemRef) {
const eventObject = new KeyboardEvent('keydown', {
key: event.key,
bubbles: true
});
if (isCrossOpenKey || isCrossCloseKey) {
var _deepestNode$context, _deepestNode$context2;
const isCurrentTarget = ((_deepestNode$context = deepestNode.context) == null ? void 0 : _deepestNode$context.elements.domReference) === event.currentTarget;
const dispatchItem = isCrossCloseKey && !isCurrentTarget ? (_deepestNode$context2 = deepestNode.context) == null ? void 0 : _deepestNode$context2.elements.domReference : isCrossOpenKey ? listRef.current.find(item => (item == null ? void 0 : item.id) === activeId) : null;
if (dispatchItem) {
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
dispatchItem.dispatchEvent(eventObject);
setVirtualId(undefined);
}
}
if ((isMainKey || isHomeOrEndKey) && deepestNode.context) {
if (deepestNode.context.open && deepestNode.parentId && event.currentTarget !== deepestNode.context.elements.domReference) {
var _deepestNode$context$;
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
(_deepestNode$context$ = deepestNode.context.elements.domReference) == null || _deepestNode$context$.dispatchEvent(eventObject);
return;
}
}
}
return commonOnKeyDown(event);
}
// If a floating element should not open on arrow key down, avoid
// setting `activeIndex` while it's closed.
if (!open && !openOnArrowKeyDown && isArrowKey) {
return;
}
if (isNavigationKey) {
const isParentMainKey = isMainOrientationKey(event.key, getParentOrientation());
keyRef.current = nested && isParentMainKey ? null : event.key;
}
if (nested) {
if (isParentCrossOpenKey) {
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
if (open) {
indexRef.current = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getMinListIndex)(listRef, disabledIndicesRef.current);
onNavigate();
} else {
onOpenChange(true, event.nativeEvent, 'list-navigation');
}
}
return;
}
if (isMainKey) {
if (selectedIndex != null) {
indexRef.current = selectedIndex;
}
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
if (!open && openOnArrowKeyDown) {
onOpenChange(true, event.nativeEvent, 'list-navigation');
} else {
commonOnKeyDown(event);
}
if (open) {
onNavigate();
}
}
},
onFocus() {
if (open && !virtual) {
indexRef.current = -1;
onNavigate();
}
},
onPointerDown: checkVirtualPointer,
onPointerEnter: checkVirtualPointer,
onMouseDown: checkVirtualMouse,
onClick: checkVirtualMouse
};
}, [activeId, ariaActiveDescendantProp, cols, commonOnKeyDown, disabledIndicesRef, focusItemOnOpen, listRef, nested, onNavigate, onOpenChange, open, openOnArrowKeyDown, orientation, getParentOrientation, rtl, selectedIndex, tree, virtual, virtualItemRef]);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {
reference,
floating,
item
} : {}, [enabled, reference, floating, item]);
}
const componentRoleToAriaRoleMap = /*#__PURE__*/new Map([['select', 'listbox'], ['combobox', 'listbox'], ['label', false]]);
/**
* Adds base screen reader props to the reference and floating elements for a
* given floating element `role`.
* @see https://floating-ui.com/docs/useRole
*/
function useRole(context, props) {
var _elements$domReferenc, _componentRoleToAriaR;
if (props === void 0) {
props = {};
}
const {
open,
elements,
floatingId: defaultFloatingId
} = context;
const {
enabled = true,
role = 'dialog'
} = props;
const defaultReferenceId = useId();
const referenceId = ((_elements$domReferenc = elements.domReference) == null ? void 0 : _elements$domReferenc.id) || defaultReferenceId;
const floatingId = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
var _getFloatingFocusElem;
return ((_getFloatingFocusElem = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getFloatingFocusElement)(elements.floating)) == null ? void 0 : _getFloatingFocusElem.id) || defaultFloatingId;
}, [elements.floating, defaultFloatingId]);
const ariaRole = (_componentRoleToAriaR = componentRoleToAriaRoleMap.get(role)) != null ? _componentRoleToAriaR : role;
const parentId = useFloatingParentNodeId();
const isNested = parentId != null;
const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
if (ariaRole === 'tooltip' || role === 'label') {
return {
["aria-" + (role === 'label' ? 'labelledby' : 'describedby')]: open ? floatingId : undefined
};
}
return {
'aria-expanded': open ? 'true' : 'false',
'aria-haspopup': ariaRole === 'alertdialog' ? 'dialog' : ariaRole,
'aria-controls': open ? floatingId : undefined,
...(ariaRole === 'listbox' && {
role: 'combobox'
}),
...(ariaRole === 'menu' && {
id: referenceId
}),
...(ariaRole === 'menu' && isNested && {
role: 'menuitem'
}),
...(role === 'select' && {
'aria-autocomplete': 'none'
}),
...(role === 'combobox' && {
'aria-autocomplete': 'list'
})
};
}, [ariaRole, floatingId, isNested, open, referenceId, role]);
const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
const floatingProps = {
id: floatingId,
...(ariaRole && {
role: ariaRole
})
};
if (ariaRole === 'tooltip' || role === 'label') {
return floatingProps;
}
return {
...floatingProps,
...(ariaRole === 'menu' && {
'aria-labelledby': referenceId
})
};
}, [ariaRole, floatingId, referenceId, role]);
const item = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(_ref => {
let {
active,
selected
} = _ref;
const commonProps = {
role: 'option',
...(active && {
id: floatingId + "-fui-option"
})
};
// For `menu`, we are unable to tell if the item is a `menuitemradio`
// or `menuitemcheckbox`. For backwards-compatibility reasons, also
// avoid defaulting to `menuitem` as it may overwrite custom role props.
switch (role) {
case 'select':
case 'combobox':
return {
...commonProps,
'aria-selected': selected
};
}
return {};
}, [floatingId, role]);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {
reference,
floating,
item
} : {}, [enabled, reference, floating, item]);
}
// Converts a JS style key like `backgroundColor` to a CSS transition-property
// like `background-color`.
const camelCaseToKebabCase = str => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase());
function execWithArgsOrReturn(valueOrFn, args) {
return typeof valueOrFn === 'function' ? valueOrFn(args) : valueOrFn;
}
function useDelayUnmount(open, durationMs) {
const [isMounted, setIsMounted] = react__WEBPACK_IMPORTED_MODULE_0__.useState(open);
if (open && !isMounted) {
setIsMounted(true);
}
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
if (!open && isMounted) {
const timeout = setTimeout(() => setIsMounted(false), durationMs);
return () => clearTimeout(timeout);
}
}, [open, isMounted, durationMs]);
return isMounted;
}
/**
* Provides a status string to apply CSS transitions to a floating element,
* correctly handling placement-aware transitions.
* @see https://floating-ui.com/docs/useTransition#usetransitionstatus
*/
function useTransitionStatus(context, props) {
if (props === void 0) {
props = {};
}
const {
open,
elements: {
floating
}
} = context;
const {
duration = 250
} = props;
const isNumberDuration = typeof duration === 'number';
const closeDuration = (isNumberDuration ? duration : duration.close) || 0;
const [status, setStatus] = react__WEBPACK_IMPORTED_MODULE_0__.useState('unmounted');
const isMounted = useDelayUnmount(open, closeDuration);
if (!isMounted && status === 'close') {
setStatus('unmounted');
}
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
if (!floating) return;
if (open) {
setStatus('initial');
const frame = requestAnimationFrame(() => {
// Ensure it opens before paint. With `FloatingDelayGroup`,
// this avoids a flicker when moving between floating elements
// to ensure one is always open with no missing frames.
react_dom__WEBPACK_IMPORTED_MODULE_5__.flushSync(() => {
setStatus('open');
});
});
return () => {
cancelAnimationFrame(frame);
};
}
setStatus('close');
}, [open, floating]);
return {
isMounted,
status
};
}
/**
* Provides styles to apply CSS transitions to a floating element, correctly
* handling placement-aware transitions. Wrapper around `useTransitionStatus`.
* @see https://floating-ui.com/docs/useTransition#usetransitionstyles
*/
function useTransitionStyles(context, props) {
if (props === void 0) {
props = {};
}
const {
initial: unstable_initial = {
opacity: 0
},
open: unstable_open,
close: unstable_close,
common: unstable_common,
duration = 250
} = props;
const placement = context.placement;
const side = placement.split('-')[0];
const fnArgs = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
side,
placement
}), [side, placement]);
const isNumberDuration = typeof duration === 'number';
const openDuration = (isNumberDuration ? duration : duration.open) || 0;
const closeDuration = (isNumberDuration ? duration : duration.close) || 0;
const [styles, setStyles] = react__WEBPACK_IMPORTED_MODULE_0__.useState(() => ({
...execWithArgsOrReturn(unstable_common, fnArgs),
...execWithArgsOrReturn(unstable_initial, fnArgs)
}));
const {
isMounted,
status
} = useTransitionStatus(context, {
duration
});
const initialRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(unstable_initial);
const openRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(unstable_open);
const closeRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(unstable_close);
const commonRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(unstable_common);
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
const initialStyles = execWithArgsOrReturn(initialRef.current, fnArgs);
const closeStyles = execWithArgsOrReturn(closeRef.current, fnArgs);
const commonStyles = execWithArgsOrReturn(commonRef.current, fnArgs);
const openStyles = execWithArgsOrReturn(openRef.current, fnArgs) || Object.keys(initialStyles).reduce((acc, key) => {
acc[key] = '';
return acc;
}, {});
if (status === 'initial') {
setStyles(styles => ({
transitionProperty: styles.transitionProperty,
...commonStyles,
...initialStyles
}));
}
if (status === 'open') {
setStyles({
transitionProperty: Object.keys(openStyles).map(camelCaseToKebabCase).join(','),
transitionDuration: openDuration + "ms",
...commonStyles,
...openStyles
});
}
if (status === 'close') {
const styles = closeStyles || initialStyles;
setStyles({
transitionProperty: Object.keys(styles).map(camelCaseToKebabCase).join(','),
transitionDuration: closeDuration + "ms",
...commonStyles,
...styles
});
}
}, [closeDuration, closeRef, initialRef, openRef, commonRef, openDuration, status, fnArgs]);
return {
isMounted,
styles
};
}
/**
* Provides a matching callback that can be used to focus an item as the user
* types, often used in tandem with `useListNavigation()`.
* @see https://floating-ui.com/docs/useTypeahead
*/
function useTypeahead(context, props) {
var _ref;
const {
open,
dataRef
} = context;
const {
listRef,
activeIndex,
onMatch: unstable_onMatch,
onTypingChange: unstable_onTypingChange,
enabled = true,
findMatch = null,
resetMs = 750,
ignoreKeys = [],
selectedIndex = null
} = props;
const timeoutIdRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(-1);
const stringRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef('');
const prevIndexRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef((_ref = selectedIndex != null ? selectedIndex : activeIndex) != null ? _ref : -1);
const matchIndexRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);
const onMatch = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(unstable_onMatch);
const onTypingChange = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(unstable_onTypingChange);
const findMatchRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(findMatch);
const ignoreKeysRef = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useLatestRef)(ignoreKeys);
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
if (open) {
clearTimeoutIfSet(timeoutIdRef);
matchIndexRef.current = null;
stringRef.current = '';
}
}, [open]);
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useModernLayoutEffect)(() => {
// Sync arrow key navigation but not typeahead navigation.
if (open && stringRef.current === '') {
var _ref2;
prevIndexRef.current = (_ref2 = selectedIndex != null ? selectedIndex : activeIndex) != null ? _ref2 : -1;
}
}, [open, selectedIndex, activeIndex]);
const setTypingChange = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(value => {
if (value) {
if (!dataRef.current.typing) {
dataRef.current.typing = value;
onTypingChange(value);
}
} else {
if (dataRef.current.typing) {
dataRef.current.typing = value;
onTypingChange(value);
}
}
});
const onKeyDown = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(event => {
function getMatchingIndex(list, orderedList, string) {
const str = findMatchRef.current ? findMatchRef.current(orderedList, string) : orderedList.find(text => (text == null ? void 0 : text.toLocaleLowerCase().indexOf(string.toLocaleLowerCase())) === 0);
return str ? list.indexOf(str) : -1;
}
const listContent = listRef.current;
if (stringRef.current.length > 0 && stringRef.current[0] !== ' ') {
if (getMatchingIndex(listContent, listContent, stringRef.current) === -1) {
setTypingChange(false);
} else if (event.key === ' ') {
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
}
}
if (listContent == null || ignoreKeysRef.current.includes(event.key) ||
// Character key.
event.key.length !== 1 ||
// Modifier key.
event.ctrlKey || event.metaKey || event.altKey) {
return;
}
if (open && event.key !== ' ') {
(0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.stopEvent)(event);
setTypingChange(true);
}
// Bail out if the list contains a word like "llama" or "aaron". TODO:
// allow it in this case, too.
const allowRapidSuccessionOfFirstLetter = listContent.every(text => {
var _text$, _text$2;
return text ? ((_text$ = text[0]) == null ? void 0 : _text$.toLocaleLowerCase()) !== ((_text$2 = text[1]) == null ? void 0 : _text$2.toLocaleLowerCase()) : true;
});
// Allows the user to cycle through items that start with the same letter
// in rapid succession.
if (allowRapidSuccessionOfFirstLetter && stringRef.current === event.key) {
stringRef.current = '';
prevIndexRef.current = matchIndexRef.current;
}
stringRef.current += event.key;
clearTimeoutIfSet(timeoutIdRef);
timeoutIdRef.current = window.setTimeout(() => {
stringRef.current = '';
prevIndexRef.current = matchIndexRef.current;
setTypingChange(false);
}, resetMs);
const prevIndex = prevIndexRef.current;
const index = getMatchingIndex(listContent, [...listContent.slice((prevIndex || 0) + 1), ...listContent.slice(0, (prevIndex || 0) + 1)], stringRef.current);
if (index !== -1) {
onMatch(index);
matchIndexRef.current = index;
} else if (event.key !== ' ') {
stringRef.current = '';
setTypingChange(false);
}
});
const reference = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
onKeyDown
}), [onKeyDown]);
const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => {
return {
onKeyDown,
onKeyUp(event) {
if (event.key === ' ') {
setTypingChange(false);
}
}
};
}, [onKeyDown, setTypingChange]);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {
reference,
floating
} : {}, [enabled, reference, floating]);
}
function getArgsWithCustomFloatingHeight(state, height) {
return {
...state,
rects: {
...state.rects,
floating: {
...state.rects.floating,
height
}
}
};
}
/**
* Positions the floating element such that an inner element inside of it is
* anchored to the reference element.
* @see https://floating-ui.com/docs/inner
* @deprecated
*/
const inner = props => ({
name: 'inner',
options: props,
async fn(state) {
const {
listRef,
overflowRef,
onFallbackChange,
offset: innerOffset = 0,
index = 0,
minItemsVisible = 4,
referenceOverflowThreshold = 0,
scrollRef,
...detectOverflowOptions
} = (0,_floating_ui_utils__WEBPACK_IMPORTED_MODULE_8__.evaluate)(props, state);
const {
rects,
platform,
elements: {
floating
}
} = state;
const item = listRef.current[index];
const scrollEl = (scrollRef == null ? void 0 : scrollRef.current) || floating;
// Valid combinations:
// 1. Floating element is the scrollRef and has a border (default)
// 2. Floating element is not the scrollRef, floating element has a border
// 3. Floating element is not the scrollRef, scrollRef has a border
// Floating > {...getFloatingProps()} wrapper > scrollRef > items is not
// allowed as VoiceOver doesn't work.
const clientTop = floating.clientTop || scrollEl.clientTop;
const floatingIsBordered = floating.clientTop !== 0;
const scrollElIsBordered = scrollEl.clientTop !== 0;
const floatingIsScrollEl = floating === scrollEl;
if (true) {
if (!state.placement.startsWith('bottom')) {
warn('`placement` side must be "bottom" when using the `inner`', 'middleware.');
}
}
if (!item) {
return {};
}
const nextArgs = {
...state,
...(await (0,_floating_ui_react_dom__WEBPACK_IMPORTED_MODULE_6__.offset)(-item.offsetTop - floating.clientTop - rects.reference.height / 2 - item.offsetHeight / 2 - innerOffset).fn(state))
};
const overflow = await platform.detectOverflow(getArgsWithCustomFloatingHeight(nextArgs, scrollEl.scrollHeight + clientTop + floating.clientTop), detectOverflowOptions);
const refOverflow = await platform.detectOverflow(nextArgs, {
...detectOverflowOptions,
elementContext: 'reference'
});
const diffY = (0,_floating_ui_utils__WEBPACK_IMPORTED_MODULE_8__.max)(0, overflow.top);
const nextY = nextArgs.y + diffY;
const isScrollable = scrollEl.scrollHeight > scrollEl.clientHeight;
const rounder = isScrollable ? v => v : _floating_ui_utils__WEBPACK_IMPORTED_MODULE_8__.round;
const maxHeight = rounder((0,_floating_ui_utils__WEBPACK_IMPORTED_MODULE_8__.max)(0, scrollEl.scrollHeight + (floatingIsBordered && floatingIsScrollEl || scrollElIsBordered ? clientTop * 2 : 0) - diffY - (0,_floating_ui_utils__WEBPACK_IMPORTED_MODULE_8__.max)(0, overflow.bottom)));
scrollEl.style.maxHeight = maxHeight + "px";
scrollEl.scrollTop = diffY;
// There is not enough space, fallback to standard anchored positioning
if (onFallbackChange) {
const shouldFallback = scrollEl.offsetHeight < item.offsetHeight * (0,_floating_ui_utils__WEBPACK_IMPORTED_MODULE_8__.min)(minItemsVisible, listRef.current.length) - 1 || refOverflow.top >= -referenceOverflowThreshold || refOverflow.bottom >= -referenceOverflowThreshold;
react_dom__WEBPACK_IMPORTED_MODULE_5__.flushSync(() => onFallbackChange(shouldFallback));
}
if (overflowRef) {
overflowRef.current = await platform.detectOverflow(getArgsWithCustomFloatingHeight({
...nextArgs,
y: nextY
}, scrollEl.offsetHeight + clientTop + floating.clientTop), detectOverflowOptions);
}
return {
y: nextY
};
}
});
/**
* Changes the `inner` middleware's `offset` upon a `wheel` event to
* expand the floating element's height, revealing more list items.
* @see https://floating-ui.com/docs/inner
* @deprecated
*/
function useInnerOffset(context, props) {
const {
open,
elements
} = context;
const {
enabled = true,
overflowRef,
scrollRef,
onChange: unstable_onChange
} = props;
const onChange = (0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(unstable_onChange);
const controlledScrollingRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false);
const prevScrollTopRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);
const initialOverflowRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);
react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {
if (!enabled) return;
function onWheel(e) {
if (e.ctrlKey || !el || overflowRef.current == null) {
return;
}
const dY = e.deltaY;
const isAtTop = overflowRef.current.top >= -0.5;
const isAtBottom = overflowRef.current.bottom >= -0.5;
const remainingScroll = el.scrollHeight - el.clientHeight;
const sign = dY < 0 ? -1 : 1;
const method = dY < 0 ? 'max' : 'min';
if (el.scrollHeight <= el.clientHeight) {
return;
}
if (!isAtTop && dY > 0 || !isAtBottom && dY < 0) {
e.preventDefault();
react_dom__WEBPACK_IMPORTED_MODULE_5__.flushSync(() => {
onChange(d => d + Math[method](dY, remainingScroll * sign));
});
} else if (/firefox/i.test((0,_floating_ui_react_utils__WEBPACK_IMPORTED_MODULE_1__.getUserAgent)())) {
// Needed to propagate scrolling during momentum scrolling phase once
// it gets limited by the boundary. UX improvement, not critical.
el.scrollTop += dY;
}
}
const el = (scrollRef == null ? void 0 : scrollRef.current) || elements.floating;
if (open && el) {
el.addEventListener('wheel', onWheel);
// Wait for the position to be ready.
requestAnimationFrame(() => {
prevScrollTopRef.current = el.scrollTop;
if (overflowRef.current != null) {
initialOverflowRef.current = {
...overflowRef.current
};
}
});
return () => {
prevScrollTopRef.current = null;
initialOverflowRef.current = null;
el.removeEventListener('wheel', onWheel);
};
}
}, [enabled, open, elements.floating, overflowRef, scrollRef, onChange]);
const floating = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => ({
onKeyDown() {
controlledScrollingRef.current = true;
},
onWheel() {
controlledScrollingRef.current = false;
},
onPointerMove() {
controlledScrollingRef.current = false;
},
onScroll() {
const el = (scrollRef == null ? void 0 : scrollRef.current) || elements.floating;
if (!overflowRef.current || !el || !controlledScrollingRef.current) {
return;
}
if (prevScrollTopRef.current !== null) {
const scrollDiff = el.scrollTop - prevScrollTopRef.current;
if (overflowRef.current.bottom < -0.5 && scrollDiff < -1 || overflowRef.current.top < -0.5 && scrollDiff > 1) {
react_dom__WEBPACK_IMPORTED_MODULE_5__.flushSync(() => onChange(d => d + scrollDiff));
}
}
// [Firefox] Wait for the height change to have been applied.
requestAnimationFrame(() => {
prevScrollTopRef.current = el.scrollTop;
});
}
}), [elements.floating, onChange, overflowRef, scrollRef]);
return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(() => enabled ? {
floating
} : {}, [enabled, floating]);
}
function getNodeChildren(nodes, id, onlyOpenChildren) {
if (onlyOpenChildren === void 0) {
onlyOpenChildren = true;
}
const directChildren = nodes.filter(node => {
var _node$context;
return node.parentId === id && (!onlyOpenChildren || ((_node$context = node.context) == null ? void 0 : _node$context.open));
});
return directChildren.flatMap(child => [child, ...getNodeChildren(nodes, child.id, onlyOpenChildren)]);
}
function isPointInPolygon(point, polygon) {
const [x, y] = point;
let isInside = false;
const length = polygon.length;
for (let i = 0, j = length - 1; i < length; j = i++) {
const [xi, yi] = polygon[i] || [0, 0];
const [xj, yj] = polygon[j] || [0, 0];
const intersect = yi >= y !== yj >= y && x <= (xj - xi) * (y - yi) / (yj - yi) + xi;
if (intersect) {
isInside = !isInside;
}
}
return isInside;
}
function isInside(point, rect) {
return point[0] >= rect.x && point[0] <= rect.x + rect.width && point[1] >= rect.y && point[1] <= rect.y + rect.height;
}
/**
* Generates a safe polygon area that the user can traverse without closing the
* floating element once leaving the reference element.
* @see https://floating-ui.com/docs/useHover#safepolygon
*/
function safePolygon(options) {
if (options === void 0) {
options = {};
}
const {
buffer = 0.5,
blockPointerEvents = false,
requireIntent = true
} = options;
const timeoutRef = {
current: -1
};
let hasLanded = false;
let lastX = null;
let lastY = null;
let lastCursorTime = typeof performance !== 'undefined' ? performance.now() : 0;
function getCursorSpeed(x, y) {
const currentTime = performance.now();
const elapsedTime = currentTime - lastCursorTime;
if (lastX === null || lastY === null || elapsedTime === 0) {
lastX = x;
lastY = y;
lastCursorTime = currentTime;
return null;
}
const deltaX = x - lastX;
const deltaY = y - lastY;
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
const speed = distance / elapsedTime; // px / ms
lastX = x;
lastY = y;
lastCursorTime = currentTime;
return speed;
}
const fn = _ref => {
let {
x,
y,
placement,
elements,
onClose,
nodeId,
tree
} = _ref;
return function onMouseMove(event) {
function close() {
clearTimeoutIfSet(timeoutRef);
onClose();
}
clearTimeoutIfSet(timeoutRef);
if (!elements.domReference || !elements.floating || placement == null || x == null || y == null) {
return;
}
const {
clientX,
clientY
} = event;
const clientPoint = [clientX, clientY];
const target = getTarget(event);
const isLeave = event.type === 'mouseleave';
const isOverFloatingEl = contains(elements.floating, target);
const isOverReferenceEl = contains(elements.domReference, target);
const refRect = elements.domReference.getBoundingClientRect();
const rect = elements.floating.getBoundingClientRect();
const side = placement.split('-')[0];
const cursorLeaveFromRight = x > rect.right - rect.width / 2;
const cursorLeaveFromBottom = y > rect.bottom - rect.height / 2;
const isOverReferenceRect = isInside(clientPoint, refRect);
const isFloatingWider = rect.width > refRect.width;
const isFloatingTaller = rect.height > refRect.height;
const left = (isFloatingWider ? refRect : rect).left;
const right = (isFloatingWider ? refRect : rect).right;
const top = (isFloatingTaller ? refRect : rect).top;
const bottom = (isFloatingTaller ? refRect : rect).bottom;
if (isOverFloatingEl) {
hasLanded = true;
if (!isLeave) {
return;
}
}
if (isOverReferenceEl) {
hasLanded = false;
}
if (isOverReferenceEl && !isLeave) {
hasLanded = true;
return;
}
// Prevent overlapping floating element from being stuck in an open-close
// loop: https://github.com/floating-ui/floating-ui/issues/1910
if (isLeave && (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_3__.isElement)(event.relatedTarget) && contains(elements.floating, event.relatedTarget)) {
return;
}
// If any nested child is open, abort.
if (tree && getNodeChildren(tree.nodesRef.current, nodeId).length) {
return;
}
// If the pointer is leaving from the opposite side, the "buffer" logic
// creates a point where the floating element remains open, but should be
// ignored.
// A constant of 1 handles floating point rounding errors.
if (side === 'top' && y >= refRect.bottom - 1 || side === 'bottom' && y <= refRect.top + 1 || side === 'left' && x >= refRect.right - 1 || side === 'right' && x <= refRect.left + 1) {
return close();
}
// Ignore when the cursor is within the rectangular trough between the
// two elements. Since the triangle is created from the cursor point,
// which can start beyond the ref element's edge, traversing back and
// forth from the ref to the floating element can cause it to close. This
// ensures it always remains open in that case.
let rectPoly = [];
switch (side) {
case 'top':
rectPoly = [[left, refRect.top + 1], [left, rect.bottom - 1], [right, rect.bottom - 1], [right, refRect.top + 1]];
break;
case 'bottom':
rectPoly = [[left, rect.top + 1], [left, refRect.bottom - 1], [right, refRect.bottom - 1], [right, rect.top + 1]];
break;
case 'left':
rectPoly = [[rect.right - 1, bottom], [rect.right - 1, top], [refRect.left + 1, top], [refRect.left + 1, bottom]];
break;
case 'right':
rectPoly = [[refRect.right - 1, bottom], [refRect.right - 1, top], [rect.left + 1, top], [rect.left + 1, bottom]];
break;
}
function getPolygon(_ref2) {
let [x, y] = _ref2;
switch (side) {
case 'top':
{
const cursorPointOne = [isFloatingWider ? x + buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y + buffer + 1];
const cursorPointTwo = [isFloatingWider ? x - buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y + buffer + 1];
const commonPoints = [[rect.left, cursorLeaveFromRight ? rect.bottom - buffer : isFloatingWider ? rect.bottom - buffer : rect.top], [rect.right, cursorLeaveFromRight ? isFloatingWider ? rect.bottom - buffer : rect.top : rect.bottom - buffer]];
return [cursorPointOne, cursorPointTwo, ...commonPoints];
}
case 'bottom':
{
const cursorPointOne = [isFloatingWider ? x + buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y - buffer];
const cursorPointTwo = [isFloatingWider ? x - buffer / 2 : cursorLeaveFromRight ? x + buffer * 4 : x - buffer * 4, y - buffer];
const commonPoints = [[rect.left, cursorLeaveFromRight ? rect.top + buffer : isFloatingWider ? rect.top + buffer : rect.bottom], [rect.right, cursorLeaveFromRight ? isFloatingWider ? rect.top + buffer : rect.bottom : rect.top + buffer]];
return [cursorPointOne, cursorPointTwo, ...commonPoints];
}
case 'left':
{
const cursorPointOne = [x + buffer + 1, isFloatingTaller ? y + buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];
const cursorPointTwo = [x + buffer + 1, isFloatingTaller ? y - buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];
const commonPoints = [[cursorLeaveFromBottom ? rect.right - buffer : isFloatingTaller ? rect.right - buffer : rect.left, rect.top], [cursorLeaveFromBottom ? isFloatingTaller ? rect.right - buffer : rect.left : rect.right - buffer, rect.bottom]];
return [...commonPoints, cursorPointOne, cursorPointTwo];
}
case 'right':
{
const cursorPointOne = [x - buffer, isFloatingTaller ? y + buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];
const cursorPointTwo = [x - buffer, isFloatingTaller ? y - buffer / 2 : cursorLeaveFromBottom ? y + buffer * 4 : y - buffer * 4];
const commonPoints = [[cursorLeaveFromBottom ? rect.left + buffer : isFloatingTaller ? rect.left + buffer : rect.right, rect.top], [cursorLeaveFromBottom ? isFloatingTaller ? rect.left + buffer : rect.right : rect.left + buffer, rect.bottom]];
return [cursorPointOne, cursorPointTwo, ...commonPoints];
}
}
}
if (isPointInPolygon([clientX, clientY], rectPoly)) {
return;
}
if (hasLanded && !isOverReferenceRect) {
return close();
}
if (!isLeave && requireIntent) {
const cursorSpeed = getCursorSpeed(event.clientX, event.clientY);
const cursorSpeedThreshold = 0.1;
if (cursorSpeed !== null && cursorSpeed < cursorSpeedThreshold) {
return close();
}
}
if (!isPointInPolygon([clientX, clientY], getPolygon([x, y]))) {
close();
} else if (!hasLanded && requireIntent) {
timeoutRef.current = window.setTimeout(close, 40);
}
};
};
fn.__options = {
blockPointerEvents
};
return fn;
}
/***/ }),
/***/ "./node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs":
/*!**************************************************************************!*\
!*** ./node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs ***!
\**************************************************************************/
/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
var react__WEBPACK_IMPORTED_MODULE_1___namespace_cache;
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ activeElement: function() { return /* binding */ activeElement; },
/* harmony export */ contains: function() { return /* binding */ contains; },
/* harmony export */ createGridCellMap: function() { return /* binding */ createGridCellMap; },
/* harmony export */ disableFocusInside: function() { return /* binding */ disableFocusInside; },
/* harmony export */ enableFocusInside: function() { return /* binding */ enableFocusInside; },
/* harmony export */ findNonDisabledListIndex: function() { return /* binding */ findNonDisabledListIndex; },
/* harmony export */ getDeepestNode: function() { return /* binding */ getDeepestNode; },
/* harmony export */ getDocument: function() { return /* binding */ getDocument; },
/* harmony export */ getFloatingFocusElement: function() { return /* binding */ getFloatingFocusElement; },
/* harmony export */ getGridCellIndexOfCorner: function() { return /* binding */ getGridCellIndexOfCorner; },
/* harmony export */ getGridCellIndices: function() { return /* binding */ getGridCellIndices; },
/* harmony export */ getGridNavigatedIndex: function() { return /* binding */ getGridNavigatedIndex; },
/* harmony export */ getMaxListIndex: function() { return /* binding */ getMaxListIndex; },
/* harmony export */ getMinListIndex: function() { return /* binding */ getMinListIndex; },
/* harmony export */ getNextTabbable: function() { return /* binding */ getNextTabbable; },
/* harmony export */ getNodeAncestors: function() { return /* binding */ getNodeAncestors; },
/* harmony export */ getNodeChildren: function() { return /* binding */ getNodeChildren; },
/* harmony export */ getPlatform: function() { return /* binding */ getPlatform; },
/* harmony export */ getPreviousTabbable: function() { return /* binding */ getPreviousTabbable; },
/* harmony export */ getTabbableOptions: function() { return /* binding */ getTabbableOptions; },
/* harmony export */ getTarget: function() { return /* binding */ getTarget; },
/* harmony export */ getUserAgent: function() { return /* binding */ getUserAgent; },
/* harmony export */ isAndroid: function() { return /* binding */ isAndroid; },
/* harmony export */ isDifferentGridRow: function() { return /* binding */ isDifferentGridRow; },
/* harmony export */ isEventTargetWithin: function() { return /* binding */ isEventTargetWithin; },
/* harmony export */ isIndexOutOfListBounds: function() { return /* binding */ isIndexOutOfListBounds; },
/* harmony export */ isJSDOM: function() { return /* binding */ isJSDOM; },
/* harmony export */ isListIndexDisabled: function() { return /* binding */ isListIndexDisabled; },
/* harmony export */ isMac: function() { return /* binding */ isMac; },
/* harmony export */ isMouseLikePointerType: function() { return /* binding */ isMouseLikePointerType; },
/* harmony export */ isOutsideEvent: function() { return /* binding */ isOutsideEvent; },
/* harmony export */ isReactEvent: function() { return /* binding */ isReactEvent; },
/* harmony export */ isRootElement: function() { return /* binding */ isRootElement; },
/* harmony export */ isSafari: function() { return /* binding */ isSafari; },
/* harmony export */ isTypeableCombobox: function() { return /* binding */ isTypeableCombobox; },
/* harmony export */ isTypeableElement: function() { return /* binding */ isTypeableElement; },
/* harmony export */ isVirtualClick: function() { return /* binding */ isVirtualClick; },
/* harmony export */ isVirtualPointerEvent: function() { return /* binding */ isVirtualPointerEvent; },
/* harmony export */ matchesFocusVisible: function() { return /* binding */ matchesFocusVisible; },
/* harmony export */ stopEvent: function() { return /* binding */ stopEvent; },
/* harmony export */ useEffectEvent: function() { return /* binding */ useEffectEvent; },
/* harmony export */ useLatestRef: function() { return /* binding */ useLatestRef; },
/* harmony export */ useModernLayoutEffect: function() { return /* binding */ index; }
/* harmony export */ });
/* harmony import */ var _floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @floating-ui/utils/dom */ "./node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "react");
/* harmony import */ var _floating_ui_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @floating-ui/utils */ "./node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs");
/* harmony import */ var tabbable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tabbable */ "./node_modules/tabbable/dist/index.esm.js");
// Avoid Chrome DevTools blue warning.
function getPlatform() {
const uaData = navigator.userAgentData;
if (uaData != null && uaData.platform) {
return uaData.platform;
}
return navigator.platform;
}
function getUserAgent() {
const uaData = navigator.userAgentData;
if (uaData && Array.isArray(uaData.brands)) {
return uaData.brands.map(_ref => {
let {
brand,
version
} = _ref;
return brand + "/" + version;
}).join(' ');
}
return navigator.userAgent;
}
function isSafari() {
// Chrome DevTools does not complain about navigator.vendor
return /apple/i.test(navigator.vendor);
}
function isAndroid() {
const re = /android/i;
return re.test(getPlatform()) || re.test(getUserAgent());
}
function isMac() {
return getPlatform().toLowerCase().startsWith('mac') && !navigator.maxTouchPoints;
}
function isJSDOM() {
return getUserAgent().includes('jsdom/');
}
const FOCUSABLE_ATTRIBUTE = 'data-floating-ui-focusable';
const TYPEABLE_SELECTOR = "input:not([type='hidden']):not([disabled])," + "[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";
const ARROW_LEFT = 'ArrowLeft';
const ARROW_RIGHT = 'ArrowRight';
const ARROW_UP = 'ArrowUp';
const ARROW_DOWN = 'ArrowDown';
function activeElement(doc) {
let activeElement = doc.activeElement;
while (((_activeElement = activeElement) == null || (_activeElement = _activeElement.shadowRoot) == null ? void 0 : _activeElement.activeElement) != null) {
var _activeElement;
activeElement = activeElement.shadowRoot.activeElement;
}
return activeElement;
}
function contains(parent, child) {
if (!parent || !child) {
return false;
}
const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();
// First, attempt with faster native method
if (parent.contains(child)) {
return true;
}
// then fallback to custom implementation with Shadow DOM support
if (rootNode && (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_0__.isShadowRoot)(rootNode)) {
let next = child;
while (next) {
if (parent === next) {
return true;
}
// @ts-ignore
next = next.parentNode || next.host;
}
}
// Give up, the result is false
return false;
}
function getTarget(event) {
if ('composedPath' in event) {
return event.composedPath()[0];
}
// TS thinks `event` is of type never as it assumes all browsers support
// `composedPath()`, but browsers without shadow DOM don't.
return event.target;
}
function isEventTargetWithin(event, node) {
if (node == null) {
return false;
}
if ('composedPath' in event) {
return event.composedPath().includes(node);
}
// TS thinks `event` is of type never as it assumes all browsers support composedPath, but browsers without shadow dom don't
const e = event;
return e.target != null && node.contains(e.target);
}
function isRootElement(element) {
return element.matches('html,body');
}
function getDocument(node) {
return (node == null ? void 0 : node.ownerDocument) || document;
}
function isTypeableElement(element) {
return (0,_floating_ui_utils_dom__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element) && element.matches(TYPEABLE_SELECTOR);
}
function isTypeableCombobox(element) {
if (!element) return false;
return element.getAttribute('role') === 'combobox' && isTypeableElement(element);
}
function matchesFocusVisible(element) {
// We don't want to block focus from working with `visibleOnly`
// (JSDOM doesn't match `:focus-visible` when the element has `:focus`)
if (!element || isJSDOM()) return true;
try {
return element.matches(':focus-visible');
} catch (_e) {
return true;
}
}
function getFloatingFocusElement(floatingElement) {
if (!floatingElement) {
return null;
}
// Try to find the element that has `{...getFloatingProps()}` spread on it.
// This indicates the floating element is acting as a positioning wrapper, and
// so focus should be managed on the child element with the event handlers and
// aria props.
return floatingElement.hasAttribute(FOCUSABLE_ATTRIBUTE) ? floatingElement : floatingElement.querySelector("[" + FOCUSABLE_ATTRIBUTE + "]") || floatingElement;
}
function getNodeChildren(nodes, id, onlyOpenChildren) {
if (onlyOpenChildren === void 0) {
onlyOpenChildren = true;
}
const directChildren = nodes.filter(node => {
var _node$context;
return node.parentId === id && (!onlyOpenChildren || ((_node$context = node.context) == null ? void 0 : _node$context.open));
});
return directChildren.flatMap(child => [child, ...getNodeChildren(nodes, child.id, onlyOpenChildren)]);
}
function getDeepestNode(nodes, id) {
let deepestNodeId;
let maxDepth = -1;
function findDeepest(nodeId, depth) {
if (depth > maxDepth) {
deepestNodeId = nodeId;
maxDepth = depth;
}
const children = getNodeChildren(nodes, nodeId);
children.forEach(child => {
findDeepest(child.id, depth + 1);
});
}
findDeepest(id, 0);
return nodes.find(node => node.id === deepestNodeId);
}
function getNodeAncestors(nodes, id) {
var _nodes$find;
let allAncestors = [];
let currentParentId = (_nodes$find = nodes.find(node => node.id === id)) == null ? void 0 : _nodes$find.parentId;
while (currentParentId) {
const currentNode = nodes.find(node => node.id === currentParentId);
currentParentId = currentNode == null ? void 0 : currentNode.parentId;
if (currentNode) {
allAncestors = allAncestors.concat(currentNode);
}
}
return allAncestors;
}
function stopEvent(event) {
event.preventDefault();
event.stopPropagation();
}
function isReactEvent(event) {
return 'nativeEvent' in event;
}
// License: https://github.com/adobe/react-spectrum/blob/b35d5c02fe900badccd0cf1a8f23bb593419f238/packages/@react-aria/utils/src/isVirtualEvent.ts
function isVirtualClick(event) {
// FIXME: Firefox is now emitting a deprecation warning for `mozInputSource`.
// Try to find a workaround for this. `react-aria` source still has the check.
if (event.mozInputSource === 0 && event.isTrusted) {
return true;
}
if (isAndroid() && event.pointerType) {
return event.type === 'click' && event.buttons === 1;
}
return event.detail === 0 && !event.pointerType;
}
function isVirtualPointerEvent(event) {
if (isJSDOM()) return false;
return !isAndroid() && event.width === 0 && event.height === 0 || isAndroid() && event.width === 1 && event.height === 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === 'mouse' ||
// iOS VoiceOver returns 0.333• for width/height.
event.width < 1 && event.height < 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === 'touch';
}
function isMouseLikePointerType(pointerType, strict) {
// On some Linux machines with Chromium, mouse inputs return a `pointerType`
// of "pen": https://github.com/floating-ui/floating-ui/issues/2015
const values = ['mouse', 'pen'];
if (!strict) {
values.push('', undefined);
}
return values.includes(pointerType);
}
var isClient = typeof document !== 'undefined';
var noop = function noop() {};
var index = isClient ? react__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect : noop;
// https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379
const SafeReact = {
.../*#__PURE__*/ (react__WEBPACK_IMPORTED_MODULE_1___namespace_cache || (react__WEBPACK_IMPORTED_MODULE_1___namespace_cache = __webpack_require__.t(react__WEBPACK_IMPORTED_MODULE_1__, 2)))
};
function useLatestRef(value) {
const ref = react__WEBPACK_IMPORTED_MODULE_1__.useRef(value);
index(() => {
ref.current = value;
});
return ref;
}
const useInsertionEffect = SafeReact.useInsertionEffect;
const useSafeInsertionEffect = useInsertionEffect || (fn => fn());
function useEffectEvent(callback) {
const ref = react__WEBPACK_IMPORTED_MODULE_1__.useRef(() => {
if (true) {
throw new Error('Cannot call an event handler while rendering.');
}
});
useSafeInsertionEffect(() => {
ref.current = callback;
});
return react__WEBPACK_IMPORTED_MODULE_1__.useCallback(function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return ref.current == null ? void 0 : ref.current(...args);
}, []);
}
function isDifferentGridRow(index, cols, prevRow) {
return Math.floor(index / cols) !== prevRow;
}
function isIndexOutOfListBounds(listRef, index) {
return index < 0 || index >= listRef.current.length;
}
function getMinListIndex(listRef, disabledIndices) {
return findNonDisabledListIndex(listRef, {
disabledIndices
});
}
function getMaxListIndex(listRef, disabledIndices) {
return findNonDisabledListIndex(listRef, {
decrement: true,
startingIndex: listRef.current.length,
disabledIndices
});
}
function findNonDisabledListIndex(listRef, _temp) {
let {
startingIndex = -1,
decrement = false,
disabledIndices,
amount = 1
} = _temp === void 0 ? {} : _temp;
let index = startingIndex;
do {
index += decrement ? -amount : amount;
} while (index >= 0 && index <= listRef.current.length - 1 && isListIndexDisabled(listRef, index, disabledIndices));
return index;
}
function getGridNavigatedIndex(listRef, _ref) {
let {
event,
orientation,
loop,
rtl,
cols,
disabledIndices,
minIndex,
maxIndex,
prevIndex,
stopEvent: stop = false
} = _ref;
let nextIndex = prevIndex;
if (event.key === ARROW_UP) {
stop && stopEvent(event);
if (prevIndex === -1) {
nextIndex = maxIndex;
} else {
nextIndex = findNonDisabledListIndex(listRef, {
startingIndex: nextIndex,
amount: cols,
decrement: true,
disabledIndices
});
if (loop && (prevIndex - cols < minIndex || nextIndex < 0)) {
const col = prevIndex % cols;
const maxCol = maxIndex % cols;
const offset = maxIndex - (maxCol - col);
if (maxCol === col) {
nextIndex = maxIndex;
} else {
nextIndex = maxCol > col ? offset : offset - cols;
}
}
}
if (isIndexOutOfListBounds(listRef, nextIndex)) {
nextIndex = prevIndex;
}
}
if (event.key === ARROW_DOWN) {
stop && stopEvent(event);
if (prevIndex === -1) {
nextIndex = minIndex;
} else {
nextIndex = findNonDisabledListIndex(listRef, {
startingIndex: prevIndex,
amount: cols,
disabledIndices
});
if (loop && prevIndex + cols > maxIndex) {
nextIndex = findNonDisabledListIndex(listRef, {
startingIndex: prevIndex % cols - cols,
amount: cols,
disabledIndices
});
}
}
if (isIndexOutOfListBounds(listRef, nextIndex)) {
nextIndex = prevIndex;
}
}
// Remains on the same row/column.
if (orientation === 'both') {
const prevRow = (0,_floating_ui_utils__WEBPACK_IMPORTED_MODULE_2__.floor)(prevIndex / cols);
if (event.key === (rtl ? ARROW_LEFT : ARROW_RIGHT)) {
stop && stopEvent(event);
if (prevIndex % cols !== cols - 1) {
nextIndex = findNonDisabledListIndex(listRef, {
startingIndex: prevIndex,
disabledIndices
});
if (loop && isDifferentGridRow(nextIndex, cols, prevRow)) {
nextIndex = findNonDisabledListIndex(listRef, {
startingIndex: prevIndex - prevIndex % cols - 1,
disabledIndices
});
}
} else if (loop) {
nextIndex = findNonDisabledListIndex(listRef, {
startingIndex: prevIndex - prevIndex % cols - 1,
disabledIndices
});
}
if (isDifferentGridRow(nextIndex, cols, prevRow)) {
nextIndex = prevIndex;
}
}
if (event.key === (rtl ? ARROW_RIGHT : ARROW_LEFT)) {
stop && stopEvent(event);
if (prevIndex % cols !== 0) {
nextIndex = findNonDisabledListIndex(listRef, {
startingIndex: prevIndex,
decrement: true,
disabledIndices
});
if (loop && isDifferentGridRow(nextIndex, cols, prevRow)) {
nextIndex = findNonDisabledListIndex(listRef, {
startingIndex: prevIndex + (cols - prevIndex % cols),
decrement: true,
disabledIndices
});
}
} else if (loop) {
nextIndex = findNonDisabledListIndex(listRef, {
startingIndex: prevIndex + (cols - prevIndex % cols),
decrement: true,
disabledIndices
});
}
if (isDifferentGridRow(nextIndex, cols, prevRow)) {
nextIndex = prevIndex;
}
}
const lastRow = (0,_floating_ui_utils__WEBPACK_IMPORTED_MODULE_2__.floor)(maxIndex / cols) === prevRow;
if (isIndexOutOfListBounds(listRef, nextIndex)) {
if (loop && lastRow) {
nextIndex = event.key === (rtl ? ARROW_RIGHT : ARROW_LEFT) ? maxIndex : findNonDisabledListIndex(listRef, {
startingIndex: prevIndex - prevIndex % cols - 1,
disabledIndices
});
} else {
nextIndex = prevIndex;
}
}
}
return nextIndex;
}
/** For each cell index, gets the item index that occupies that cell */
function createGridCellMap(sizes, cols, dense) {
const cellMap = [];
let startIndex = 0;
sizes.forEach((_ref2, index) => {
let {
width,
height
} = _ref2;
if (width > cols) {
if (true) {
throw new Error("[Floating UI]: Invalid grid - item width at index " + index + " is greater than grid columns");
}
}
let itemPlaced = false;
if (dense) {
startIndex = 0;
}
while (!itemPlaced) {
const targetCells = [];
for (let i = 0; i < width; i++) {
for (let j = 0; j < height; j++) {
targetCells.push(startIndex + i + j * cols);
}
}
if (startIndex % cols + width <= cols && targetCells.every(cell => cellMap[cell] == null)) {
targetCells.forEach(cell => {
cellMap[cell] = index;
});
itemPlaced = true;
} else {
startIndex++;
}
}
});
// convert into a non-sparse array
return [...cellMap];
}
/** Gets cell index of an item's corner or -1 when index is -1. */
function getGridCellIndexOfCorner(index, sizes, cellMap, cols, corner) {
if (index === -1) return -1;
const firstCellIndex = cellMap.indexOf(index);
const sizeItem = sizes[index];
switch (corner) {
case 'tl':
return firstCellIndex;
case 'tr':
if (!sizeItem) {
return firstCellIndex;
}
return firstCellIndex + sizeItem.width - 1;
case 'bl':
if (!sizeItem) {
return firstCellIndex;
}
return firstCellIndex + (sizeItem.height - 1) * cols;
case 'br':
return cellMap.lastIndexOf(index);
}
}
/** Gets all cell indices that correspond to the specified indices */
function getGridCellIndices(indices, cellMap) {
return cellMap.flatMap((index, cellIndex) => indices.includes(index) ? [cellIndex] : []);
}
function isListIndexDisabled(listRef, index, disabledIndices) {
if (typeof disabledIndices === 'function') {
return disabledIndices(index);
} else if (disabledIndices) {
return disabledIndices.includes(index);
}
const element = listRef.current[index];
return element == null || element.hasAttribute('disabled') || element.getAttribute('aria-disabled') === 'true';
}
const getTabbableOptions = () => ({
getShadowRoot: true,
displayCheck:
// JSDOM does not support the `tabbable` library. To solve this we can
// check if `ResizeObserver` is a real function (not polyfilled), which
// determines if the current environment is JSDOM-like.
typeof ResizeObserver === 'function' && ResizeObserver.toString().includes('[native code]') ? 'full' : 'none'
});
function getTabbableIn(container, dir) {
const list = (0,tabbable__WEBPACK_IMPORTED_MODULE_3__.tabbable)(container, getTabbableOptions());
const len = list.length;
if (len === 0) return;
const active = activeElement(getDocument(container));
const index = list.indexOf(active);
const nextIndex = index === -1 ? dir === 1 ? 0 : len - 1 : index + dir;
return list[nextIndex];
}
function getNextTabbable(referenceElement) {
return getTabbableIn(getDocument(referenceElement).body, 1) || referenceElement;
}
function getPreviousTabbable(referenceElement) {
return getTabbableIn(getDocument(referenceElement).body, -1) || referenceElement;
}
function isOutsideEvent(event, container) {
const containerElement = container || event.currentTarget;
const relatedTarget = event.relatedTarget;
return !relatedTarget || !contains(containerElement, relatedTarget);
}
function disableFocusInside(container) {
const tabbableElements = (0,tabbable__WEBPACK_IMPORTED_MODULE_3__.tabbable)(container, getTabbableOptions());
tabbableElements.forEach(element => {
element.dataset.tabindex = element.getAttribute('tabindex') || '';
element.setAttribute('tabindex', '-1');
});
}
function enableFocusInside(container) {
const elements = container.querySelectorAll('[data-tabindex]');
elements.forEach(element => {
const tabindex = element.dataset.tabindex;
delete element.dataset.tabindex;
if (tabindex) {
element.setAttribute('tabindex', tabindex);
} else {
element.removeAttribute('tabindex');
}
});
}
/***/ }),
/***/ "./node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs":
/*!************************************************************************!*\
!*** ./node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs ***!
\************************************************************************/
/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ getComputedStyle: function() { return /* binding */ getComputedStyle; },
/* harmony export */ getContainingBlock: function() { return /* binding */ getContainingBlock; },
/* harmony export */ getDocumentElement: function() { return /* binding */ getDocumentElement; },
/* harmony export */ getFrameElement: function() { return /* binding */ getFrameElement; },
/* harmony export */ getNearestOverflowAncestor: function() { return /* binding */ getNearestOverflowAncestor; },
/* harmony export */ getNodeName: function() { return /* binding */ getNodeName; },
/* harmony export */ getNodeScroll: function() { return /* binding */ getNodeScroll; },
/* harmony export */ getOverflowAncestors: function() { return /* binding */ getOverflowAncestors; },
/* harmony export */ getParentNode: function() { return /* binding */ getParentNode; },
/* harmony export */ getWindow: function() { return /* binding */ getWindow; },
/* harmony export */ isContainingBlock: function() { return /* binding */ isContainingBlock; },
/* harmony export */ isElement: function() { return /* binding */ isElement; },
/* harmony export */ isHTMLElement: function() { return /* binding */ isHTMLElement; },
/* harmony export */ isLastTraversableNode: function() { return /* binding */ isLastTraversableNode; },
/* harmony export */ isNode: function() { return /* binding */ isNode; },
/* harmony export */ isOverflowElement: function() { return /* binding */ isOverflowElement; },
/* harmony export */ isShadowRoot: function() { return /* binding */ isShadowRoot; },
/* harmony export */ isTableElement: function() { return /* binding */ isTableElement; },
/* harmony export */ isTopLayer: function() { return /* binding */ isTopLayer; },
/* harmony export */ isWebKit: function() { return /* binding */ isWebKit; }
/* harmony export */ });
function hasWindow() {
return typeof window !== 'undefined';
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || '').toLowerCase();
}
// Mocked nodes in testing environments may not be instances of Node. By
// returning `#document` an infinite loop won't occur.
// https://github.com/floating-ui/floating-ui/issues/2317
return '#document';
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';
}
function isTableElement(element) {
return /^(table|td|th)$/.test(getNodeName(element));
}
function isTopLayer(element) {
try {
if (element.matches(':popover-open')) {
return true;
}
} catch (_e) {
// no-op
}
try {
return element.matches(':modal');
} catch (_e) {
return false;
}
}
const willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
const containRe = /paint|layout|strict|content/;
const isNotNone = value => !!value && value !== 'none';
let isWebKitValue;
function isContainingBlock(elementOrCss) {
const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (isWebKitValue == null) {
isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');
}
return isWebKitValue;
}
function isLastTraversableNode(node) {
return /^(html|body|#document)$/.test(getNodeName(node));
}
function getComputedStyle(element) {
return getWindow(element).getComputedStyle(element);
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.scrollX,
scrollTop: element.scrollY
};
}
function getParentNode(node) {
if (getNodeName(node) === 'html') {
return node;
}
const result =
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot ||
// DOM Element detected.
node.parentNode ||
// ShadowRoot detected.
isShadowRoot(node) && node.host ||
// Fallback.
getDocumentElement(node);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list, traverseIframes) {
var _node$ownerDocument2;
if (list === void 0) {
list = [];
}
if (traverseIframes === void 0) {
traverseIframes = true;
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
const frameElement = getFrameElement(win);
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
} else {
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
}
}
function getFrameElement(win) {
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
}
/***/ }),
/***/ "./node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs":
/*!********************************************************************!*\
!*** ./node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs ***!
\********************************************************************/
/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ alignments: function() { return /* binding */ alignments; },
/* harmony export */ clamp: function() { return /* binding */ clamp; },
/* harmony export */ createCoords: function() { return /* binding */ createCoords; },
/* harmony export */ evaluate: function() { return /* binding */ evaluate; },
/* harmony export */ expandPaddingObject: function() { return /* binding */ expandPaddingObject; },
/* harmony export */ floor: function() { return /* binding */ floor; },
/* harmony export */ getAlignment: function() { return /* binding */ getAlignment; },
/* harmony export */ getAlignmentAxis: function() { return /* binding */ getAlignmentAxis; },
/* harmony export */ getAlignmentSides: function() { return /* binding */ getAlignmentSides; },
/* harmony export */ getAxisLength: function() { return /* binding */ getAxisLength; },
/* harmony export */ getExpandedPlacements: function() { return /* binding */ getExpandedPlacements; },
/* harmony export */ getOppositeAlignmentPlacement: function() { return /* binding */ getOppositeAlignmentPlacement; },
/* harmony export */ getOppositeAxis: function() { return /* binding */ getOppositeAxis; },
/* harmony export */ getOppositeAxisPlacements: function() { return /* binding */ getOppositeAxisPlacements; },
/* harmony export */ getOppositePlacement: function() { return /* binding */ getOppositePlacement; },
/* harmony export */ getPaddingObject: function() { return /* binding */ getPaddingObject; },
/* harmony export */ getSide: function() { return /* binding */ getSide; },
/* harmony export */ getSideAxis: function() { return /* binding */ getSideAxis; },
/* harmony export */ max: function() { return /* binding */ max; },
/* harmony export */ min: function() { return /* binding */ min; },
/* harmony export */ placements: function() { return /* binding */ placements; },
/* harmony export */ rectToClientRect: function() { return /* binding */ rectToClientRect; },
/* harmony export */ round: function() { return /* binding */ round; },
/* harmony export */ sides: function() { return /* binding */ sides; }
/* harmony export */ });
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
const sides = ['top', 'right', 'bottom', 'left'];
const alignments = ['start', 'end'];
const placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-" + alignments[0], side + "-" + alignments[1]), []);
const min = Math.min;
const max = Math.max;
const round = Math.round;
const floor = Math.floor;
const createCoords = v => ({
x: v,
y: v
});
const oppositeSideMap = {
left: 'right',
right: 'left',
bottom: 'top',
top: 'bottom'
};
function clamp(start, value, end) {
return max(start, min(value, end));
}
function evaluate(value, param) {
return typeof value === 'function' ? value(param) : value;
}
function getSide(placement) {
return placement.split('-')[0];
}
function getAlignment(placement) {
return placement.split('-')[1];
}
function getOppositeAxis(axis) {
return axis === 'x' ? 'y' : 'x';
}
function getAxisLength(axis) {
return axis === 'y' ? 'height' : 'width';
}
function getSideAxis(placement) {
const firstChar = placement[0];
return firstChar === 't' || firstChar === 'b' ? 'y' : 'x';
}
function getAlignmentAxis(placement) {
return getOppositeAxis(getSideAxis(placement));
}
function getAlignmentSides(placement, rects, rtl) {
if (rtl === void 0) {
rtl = false;
}
const alignment = getAlignment(placement);
const alignmentAxis = getAlignmentAxis(placement);
const length = getAxisLength(alignmentAxis);
let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
if (rects.reference[length] > rects.floating[length]) {
mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
}
return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
}
function getExpandedPlacements(placement) {
const oppositePlacement = getOppositePlacement(placement);
return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
}
function getOppositeAlignmentPlacement(placement) {
return placement.includes('start') ? placement.replace('start', 'end') : placement.replace('end', 'start');
}
const lrPlacement = ['left', 'right'];
const rlPlacement = ['right', 'left'];
const tbPlacement = ['top', 'bottom'];
const btPlacement = ['bottom', 'top'];
function getSideList(side, isStart, rtl) {
switch (side) {
case 'top':
case 'bottom':
if (rtl) return isStart ? rlPlacement : lrPlacement;
return isStart ? lrPlacement : rlPlacement;
case 'left':
case 'right':
return isStart ? tbPlacement : btPlacement;
default:
return [];
}
}
function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
const alignment = getAlignment(placement);
let list = getSideList(getSide(placement), direction === 'start', rtl);
if (alignment) {
list = list.map(side => side + "-" + alignment);
if (flipAlignment) {
list = list.concat(list.map(getOppositeAlignmentPlacement));
}
}
return list;
}
function getOppositePlacement(placement) {
const side = getSide(placement);
return oppositeSideMap[side] + placement.slice(side.length);
}
function expandPaddingObject(padding) {
return {
top: 0,
right: 0,
bottom: 0,
left: 0,
...padding
};
}
function getPaddingObject(padding) {
return typeof padding !== 'number' ? expandPaddingObject(padding) : {
top: padding,
right: padding,
bottom: padding,
left: padding
};
}
function rectToClientRect(rect) {
const {
x,
y,
width,
height
} = rect;
return {
width,
height,
top: y,
left: x,
right: x + width,
bottom: y + height,
x,
y
};
}
/***/ }),
/***/ "./node_modules/dompurify/dist/purify.es.mjs":
/*!***************************************************!*\
!*** ./node_modules/dompurify/dist/purify.es.mjs ***!
\***************************************************/
/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": function() { return /* binding */ purify; }
/* harmony export */ });
/*! @license DOMPurify 3.3.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.0/LICENSE */
const {
entries,
setPrototypeOf,
isFrozen,
getPrototypeOf,
getOwnPropertyDescriptor
} = Object;
let {
freeze,
seal,
create
} = Object; // eslint-disable-line import/no-mutable-exports
let {
apply,
construct
} = typeof Reflect !== 'undefined' && Reflect;
if (!freeze) {
freeze = function freeze(x) {
return x;
};
}
if (!seal) {
seal = function seal(x) {
return x;
};
}
if (!apply) {
apply = function apply(func, thisArg) {
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}
return func.apply(thisArg, args);
};
}
if (!construct) {
construct = function construct(Func) {
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
return new Func(...args);
};
}
const arrayForEach = unapply(Array.prototype.forEach);
const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
const arrayPop = unapply(Array.prototype.pop);
const arrayPush = unapply(Array.prototype.push);
const arraySplice = unapply(Array.prototype.splice);
const stringToLowerCase = unapply(String.prototype.toLowerCase);
const stringToString = unapply(String.prototype.toString);
const stringMatch = unapply(String.prototype.match);
const stringReplace = unapply(String.prototype.replace);
const stringIndexOf = unapply(String.prototype.indexOf);
const stringTrim = unapply(String.prototype.trim);
const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
const regExpTest = unapply(RegExp.prototype.test);
const typeErrorCreate = unconstruct(TypeError);
/**
* Creates a new function that calls the given function with a specified thisArg and arguments.
*
* @param func - The function to be wrapped and called.
* @returns A new function that calls the given function with a specified thisArg and arguments.
*/
function unapply(func) {
return function (thisArg) {
if (thisArg instanceof RegExp) {
thisArg.lastIndex = 0;
}
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
args[_key3 - 1] = arguments[_key3];
}
return apply(func, thisArg, args);
};
}
/**
* Creates a new function that constructs an instance of the given constructor function with the provided arguments.
*
* @param func - The constructor function to be wrapped and called.
* @returns A new function that constructs an instance of the given constructor function with the provided arguments.
*/
function unconstruct(Func) {
return function () {
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
return construct(Func, args);
};
}
/**
* Add properties to a lookup table
*
* @param set - The set to which elements will be added.
* @param array - The array containing elements to be added to the set.
* @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.
* @returns The modified set with added elements.
*/
function addToSet(set, array) {
let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
if (setPrototypeOf) {
// Make 'in' and truthy checks like Boolean(set.constructor)
// independent of any properties defined on Object.prototype.
// Prevent prototype setters from intercepting set as a this value.
setPrototypeOf(set, null);
}
let l = array.length;
while (l--) {
let element = array[l];
if (typeof element === 'string') {
const lcElement = transformCaseFunc(element);
if (lcElement !== element) {
// Config presets (e.g. tags.js, attrs.js) are immutable.
if (!isFrozen(array)) {
array[l] = lcElement;
}
element = lcElement;
}
}
set[element] = true;
}
return set;
}
/**
* Clean up an array to harden against CSPP
*
* @param array - The array to be cleaned.
* @returns The cleaned version of the array
*/
function cleanArray(array) {
for (let index = 0; index < array.length; index++) {
const isPropertyExist = objectHasOwnProperty(array, index);
if (!isPropertyExist) {
array[index] = null;
}
}
return array;
}
/**
* Shallow clone an object
*
* @param object - The object to be cloned.
* @returns A new object that copies the original.
*/
function clone(object) {
const newObject = create(null);
for (const [property, value] of entries(object)) {
const isPropertyExist = objectHasOwnProperty(object, property);
if (isPropertyExist) {
if (Array.isArray(value)) {
newObject[property] = cleanArray(value);
} else if (value && typeof value === 'object' && value.constructor === Object) {
newObject[property] = clone(value);
} else {
newObject[property] = value;
}
}
}
return newObject;
}
/**
* This method automatically checks if the prop is function or getter and behaves accordingly.
*
* @param object - The object to look up the getter function in its prototype chain.
* @param prop - The property name for which to find the getter function.
* @returns The getter function found in the prototype chain or a fallback function.
*/
function lookupGetter(object, prop) {
while (object !== null) {
const desc = getOwnPropertyDescriptor(object, prop);
if (desc) {
if (desc.get) {
return unapply(desc.get);
}
if (typeof desc.value === 'function') {
return unapply(desc.value);
}
}
object = getPrototypeOf(object);
}
function fallbackValue() {
return null;
}
return fallbackValue;
}
const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
// List of SVG elements that are disallowed by default.
// We still need to know them so that we can do namespace
// checks properly in case one wants to add them to
// allow-list.
const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);
const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);
// Similarly to SVG, we want to know all MathML elements,
// even those that we disallow by default.
const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
const text = freeze(['#text']);
const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'mask-type', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
// eslint-disable-next-line unicorn/better-regex
const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex
const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
);
const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
);
const DOCTYPE_NAME = seal(/^html$/i);
const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
var EXPRESSIONS = /*#__PURE__*/Object.freeze({
__proto__: null,
ARIA_ATTR: ARIA_ATTR,
ATTR_WHITESPACE: ATTR_WHITESPACE,
CUSTOM_ELEMENT: CUSTOM_ELEMENT,
DATA_ATTR: DATA_ATTR,
DOCTYPE_NAME: DOCTYPE_NAME,
ERB_EXPR: ERB_EXPR,
IS_ALLOWED_URI: IS_ALLOWED_URI,
IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
MUSTACHE_EXPR: MUSTACHE_EXPR,
TMPLIT_EXPR: TMPLIT_EXPR
});
/* eslint-disable @typescript-eslint/indent */
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
const NODE_TYPE = {
element: 1,
attribute: 2,
text: 3,
cdataSection: 4,
entityReference: 5,
// Deprecated
entityNode: 6,
// Deprecated
progressingInstruction: 7,
comment: 8,
document: 9,
documentType: 10,
documentFragment: 11,
notation: 12 // Deprecated
};
const getGlobal = function getGlobal() {
return typeof window === 'undefined' ? null : window;
};
/**
* Creates a no-op policy for internal use only.
* Don't export this function outside this module!
* @param trustedTypes The policy factory.
* @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
* @return The policy created (or null, if Trusted Types
* are not supported or creating the policy failed).
*/
const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
return null;
}
// Allow the callers to control the unique policy name
// by adding a data-tt-policy-suffix to the script element with the DOMPurify.
// Policy creation with duplicate names throws in Trusted Types.
let suffix = null;
const ATTR_NAME = 'data-tt-policy-suffix';
if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
suffix = purifyHostElement.getAttribute(ATTR_NAME);
}
const policyName = 'dompurify' + (suffix ? '#' + suffix : '');
try {
return trustedTypes.createPolicy(policyName, {
createHTML(html) {
return html;
},
createScriptURL(scriptUrl) {
return scriptUrl;
}
});
} catch (_) {
// Policy creation failed (most likely another DOMPurify script has
// already run). Skip creating the policy, as this will only cause errors
// if TT are enforced.
console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
return null;
}
};
const _createHooksMap = function _createHooksMap() {
return {
afterSanitizeAttributes: [],
afterSanitizeElements: [],
afterSanitizeShadowDOM: [],
beforeSanitizeAttributes: [],
beforeSanitizeElements: [],
beforeSanitizeShadowDOM: [],
uponSanitizeAttribute: [],
uponSanitizeElement: [],
uponSanitizeShadowNode: []
};
};
function createDOMPurify() {
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
const DOMPurify = root => createDOMPurify(root);
DOMPurify.version = '3.3.0';
DOMPurify.removed = [];
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
// Not running in a browser, provide a factory function
// so that you can pass your own Window
DOMPurify.isSupported = false;
return DOMPurify;
}
let {
document
} = window;
const originalDocument = document;
const currentScript = originalDocument.currentScript;
const {
DocumentFragment,
HTMLTemplateElement,
Node,
Element,
NodeFilter,
NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,
HTMLFormElement,
DOMParser,
trustedTypes
} = window;
const ElementPrototype = Element.prototype;
const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
const remove = lookupGetter(ElementPrototype, 'remove');
const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
// As per issue #47, the web-components registry is inherited by a
// new document created via createHTMLDocument. As per the spec
// (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
// a new empty registry is used when creating a template contents owner
// document, so we use that as our parent document to ensure nothing
// is inherited.
if (typeof HTMLTemplateElement === 'function') {
const template = document.createElement('template');
if (template.content && template.content.ownerDocument) {
document = template.content.ownerDocument;
}
}
let trustedTypesPolicy;
let emptyHTML = '';
const {
implementation,
createNodeIterator,
createDocumentFragment,
getElementsByTagName
} = document;
const {
importNode
} = originalDocument;
let hooks = _createHooksMap();
/**
* Expose whether this browser supports running the full DOMPurify.
*/
DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
const {
MUSTACHE_EXPR,
ERB_EXPR,
TMPLIT_EXPR,
DATA_ATTR,
ARIA_ATTR,
IS_SCRIPT_OR_DATA,
ATTR_WHITESPACE,
CUSTOM_ELEMENT
} = EXPRESSIONS;
let {
IS_ALLOWED_URI: IS_ALLOWED_URI$1
} = EXPRESSIONS;
/**
* We consider the elements and attributes below to be safe. Ideally
* don't add any new ones but feel free to remove unwanted ones.
*/
/* allowed element names */
let ALLOWED_TAGS = null;
const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
/* Allowed attribute names */
let ALLOWED_ATTR = null;
const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
/*
* Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.
* @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
* @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
* @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
*/
let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
tagNameCheck: {
writable: true,
configurable: false,
enumerable: true,
value: null
},
attributeNameCheck: {
writable: true,
configurable: false,
enumerable: true,
value: null
},
allowCustomizedBuiltInElements: {
writable: true,
configurable: false,
enumerable: true,
value: false
}
}));
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
let FORBID_TAGS = null;
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
let FORBID_ATTR = null;
/* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */
const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
tagCheck: {
writable: true,
configurable: false,
enumerable: true,
value: null
},
attributeCheck: {
writable: true,
configurable: false,
enumerable: true,
value: null
}
}));
/* Decide if ARIA attributes are okay */
let ALLOW_ARIA_ATTR = true;
/* Decide if custom data attributes are okay */
let ALLOW_DATA_ATTR = true;
/* Decide if unknown protocols are okay */
let ALLOW_UNKNOWN_PROTOCOLS = false;
/* Decide if self-closing tags in attributes are allowed.
* Usually removed due to a mXSS issue in jQuery 3.0 */
let ALLOW_SELF_CLOSE_IN_ATTR = true;
/* Output should be safe for common template engines.
* This means, DOMPurify removes data attributes, mustaches and ERB
*/
let SAFE_FOR_TEMPLATES = false;
/* Output should be safe even for XML used within HTML and alike.
* This means, DOMPurify removes comments when containing risky content.
*/
let SAFE_FOR_XML = true;
/* Decide if document with ... should be returned */
let WHOLE_DOCUMENT = false;
/* Track whether config is already set on this instance of DOMPurify. */
let SET_CONFIG = false;
/* Decide if all elements (e.g. style, script) must be children of
* document.body. By default, browsers might move them to document.head */
let FORCE_BODY = false;
/* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
* string (or a TrustedHTML object if Trusted Types are supported).
* If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
*/
let RETURN_DOM = false;
/* Decide if a DOM `DocumentFragment` should be returned, instead of a html
* string (or a TrustedHTML object if Trusted Types are supported) */
let RETURN_DOM_FRAGMENT = false;
/* Try to return a Trusted Type object instead of a string, return a string in
* case Trusted Types are not supported */
let RETURN_TRUSTED_TYPE = false;
/* Output should be free from DOM clobbering attacks?
* This sanitizes markups named with colliding, clobberable built-in DOM APIs.
*/
let SANITIZE_DOM = true;
/* Achieve full DOM Clobbering protection by isolating the namespace of named
* properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
*
* HTML/DOM spec rules that enable DOM Clobbering:
* - Named Access on Window (§7.3.3)
* - DOM Tree Accessors (§3.1.5)
* - Form Element Parent-Child Relations (§4.10.3)
* - Iframe srcdoc / Nested WindowProxies (§4.8.5)
* - HTMLCollection (§4.2.10.2)
*
* Namespace isolation is implemented by prefixing `id` and `name` attributes
* with a constant string, i.e., `user-content-`
*/
let SANITIZE_NAMED_PROPS = false;
const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
/* Keep element content when removing element? */
let KEEP_CONTENT = true;
/* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
* of importing it into a new Document and returning a sanitized copy */
let IN_PLACE = false;
/* Allow usage of profiles like html, svg and mathMl */
let USE_PROFILES = {};
/* Tags to ignore content of when KEEP_CONTENT is true */
let FORBID_CONTENTS = null;
const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);
/* Tags that are safe for data: URIs */
let DATA_URI_TAGS = null;
const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
/* Attributes safe for values like "javascript:" */
let URI_SAFE_ATTRIBUTES = null;
const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
/* Document namespace */
let NAMESPACE = HTML_NAMESPACE;
let IS_EMPTY_INPUT = false;
/* Allowed XHTML+XML namespaces */
let ALLOWED_NAMESPACES = null;
const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);
// Certain elements are allowed in both SVG and HTML
// namespace. We need to specify them explicitly
// so that they don't get erroneously deleted from
// HTML namespace.
const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
/* Parsing of strict XHTML documents */
let PARSER_MEDIA_TYPE = null;
const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
let transformCaseFunc = null;
/* Keep a reference to config to pass to hooks */
let CONFIG = null;
/* Ideally, do not touch anything below this line */
/* ______________________________________________ */
const formElement = document.createElement('form');
const isRegexOrFunction = function isRegexOrFunction(testValue) {
return testValue instanceof RegExp || testValue instanceof Function;
};
/**
* _parseConfig
*
* @param cfg optional config literal
*/
// eslint-disable-next-line complexity
const _parseConfig = function _parseConfig() {
let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (CONFIG && CONFIG === cfg) {
return;
}
/* Shield configuration object from tampering */
if (!cfg || typeof cfg !== 'object') {
cfg = {};
}
/* Shield configuration object from prototype pollution */
cfg = clone(cfg);
PARSER_MEDIA_TYPE =
// eslint-disable-next-line unicorn/prefer-includes
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
// HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
/* Set configuration parameters */
ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
FORCE_BODY = cfg.FORCE_BODY || false; // Default false
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
IN_PLACE = cfg.IN_PLACE || false; // Default false
IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;
HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
}
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
}
if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {
CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
}
if (SAFE_FOR_TEMPLATES) {
ALLOW_DATA_ATTR = false;
}
if (RETURN_DOM_FRAGMENT) {
RETURN_DOM = true;
}
/* Parse profile info */
if (USE_PROFILES) {
ALLOWED_TAGS = addToSet({}, text);
ALLOWED_ATTR = [];
if (USE_PROFILES.html === true) {
addToSet(ALLOWED_TAGS, html$1);
addToSet(ALLOWED_ATTR, html);
}
if (USE_PROFILES.svg === true) {
addToSet(ALLOWED_TAGS, svg$1);
addToSet(ALLOWED_ATTR, svg);
addToSet(ALLOWED_ATTR, xml);
}
if (USE_PROFILES.svgFilters === true) {
addToSet(ALLOWED_TAGS, svgFilters);
addToSet(ALLOWED_ATTR, svg);
addToSet(ALLOWED_ATTR, xml);
}
if (USE_PROFILES.mathMl === true) {
addToSet(ALLOWED_TAGS, mathMl$1);
addToSet(ALLOWED_ATTR, mathMl);
addToSet(ALLOWED_ATTR, xml);
}
}
/* Merge configuration parameters */
if (cfg.ADD_TAGS) {
if (typeof cfg.ADD_TAGS === 'function') {
EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
} else {
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
ALLOWED_TAGS = clone(ALLOWED_TAGS);
}
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
}
}
if (cfg.ADD_ATTR) {
if (typeof cfg.ADD_ATTR === 'function') {
EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
} else {
if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
ALLOWED_ATTR = clone(ALLOWED_ATTR);
}
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
}
}
if (cfg.ADD_URI_SAFE_ATTR) {
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
}
if (cfg.FORBID_CONTENTS) {
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
FORBID_CONTENTS = clone(FORBID_CONTENTS);
}
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
}
/* Add #text in case KEEP_CONTENT is set to true */
if (KEEP_CONTENT) {
ALLOWED_TAGS['#text'] = true;
}
/* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
if (WHOLE_DOCUMENT) {
addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
}
/* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
if (ALLOWED_TAGS.table) {
addToSet(ALLOWED_TAGS, ['tbody']);
delete FORBID_TAGS.tbody;
}
if (cfg.TRUSTED_TYPES_POLICY) {
if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
}
if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
}
// Overwrite existing TrustedTypes policy.
trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
// Sign local variables required by `sanitize`.
emptyHTML = trustedTypesPolicy.createHTML('');
} else {
// Uninitialized policy, attempt to initialize the internal dompurify policy.
if (trustedTypesPolicy === undefined) {
trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
}
// If creating the internal policy succeeded sign internal variables.
if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {
emptyHTML = trustedTypesPolicy.createHTML('');
}
}
// Prevent further manipulation of configuration.
// Not available in IE8, Safari 5, etc.
if (freeze) {
freeze(cfg);
}
CONFIG = cfg;
};
/* Keep track of all possible SVG and MathML tags
* so that we can perform the namespace checks
* correctly. */
const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
/**
* @param element a DOM element whose namespace is being checked
* @returns Return false if the element has a
* namespace that a spec-compliant parser would never
* return. Return true otherwise.
*/
const _checkValidNamespace = function _checkValidNamespace(element) {
let parent = getParentNode(element);
// In JSDOM, if we're inside shadow DOM, then parentNode
// can be null. We just simulate parent in this case.
if (!parent || !parent.tagName) {
parent = {
namespaceURI: NAMESPACE,
tagName: 'template'
};
}
const tagName = stringToLowerCase(element.tagName);
const parentTagName = stringToLowerCase(parent.tagName);
if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
return false;
}
if (element.namespaceURI === SVG_NAMESPACE) {
// The only way to switch from HTML namespace to SVG
// is via