@deck.gl/widgets 9.3.4 → 9.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/zoom-widget.tsx", "../src/lib/components/button-group.tsx", "../src/lib/components/icon-button.tsx", "../src/lib/data-url.ts", "../src/reset-view-widget.tsx", "../src/gimbal-widget.tsx", "../src/compass-widget.tsx", "../src/scale-widget.tsx", "../src/geocoder-widget.tsx", "../src/lib/components/dropdown-menu.tsx", "../src/lib/geocode/geocoder-history.ts", "../src/lib/geocode/geocoders.ts", "../src/fullscreen-widget.tsx", "../src/splitter-widget.tsx", "../src/info-widget.tsx", "../src/lib/components/popover.tsx", "../src/lib/components/user-content.tsx", "../src/popup-widget.tsx", "../src/context-menu-widget.tsx", "../src/scrollbar-widget.tsx", "../src/lib/components/range-input.tsx", "../src/icon-widget.tsx", "../src/toggle-widget.tsx", "../src/selector-widget.tsx", "../src/timeline-widget.tsx", "../src/screenshot-widget.tsx", "../src/theme-widget.tsx", "../src/themes.ts", "../src/loading-widget.tsx", "../src/stats-widget.tsx"],
4
- "sourcesContent": ["// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Navigation widgets\nexport {ZoomWidget} from './zoom-widget';\nexport {ResetViewWidget} from './reset-view-widget';\nexport {GimbalWidget} from './gimbal-widget';\n\n// Geospatial widgets\nexport {CompassWidget} from './compass-widget';\nexport {ScaleWidget as _ScaleWidget} from './scale-widget';\nexport {GeocoderWidget as _GeocoderWidget} from './geocoder-widget';\n\n// View widgets\nexport {FullscreenWidget} from './fullscreen-widget';\nexport {SplitterWidget as _SplitterWidget} from './splitter-widget';\n\n// Information widgets\nexport {InfoWidget} from './info-widget';\nexport {PopupWidget} from './popup-widget';\nexport {ContextMenuWidget} from './context-menu-widget';\nexport {ScrollbarWidget} from './scrollbar-widget';\n\n// Control widgets\nexport {IconWidget} from './icon-widget';\nexport {ToggleWidget} from './toggle-widget';\nexport {SelectorWidget} from './selector-widget';\nexport {TimelineWidget as _TimelineWidget} from './timeline-widget';\n\n// Utility widgets\nexport {ScreenshotWidget} from './screenshot-widget';\nexport {ThemeWidget} from './theme-widget';\nexport {LoadingWidget} from './loading-widget';\nexport {StatsWidget as _StatsWidget} from './stats-widget';\n\nexport type {FullscreenWidgetProps} from './fullscreen-widget';\nexport type {CompassWidgetProps} from './compass-widget';\nexport type {ZoomWidgetProps} from './zoom-widget';\nexport type {ScreenshotWidgetProps} from './screenshot-widget';\nexport type {ResetViewWidgetProps} from './reset-view-widget';\nexport type {GeocoderWidgetProps} from './geocoder-widget';\nexport type {LoadingWidgetProps} from './loading-widget';\nexport type {IconWidgetProps} from './icon-widget';\nexport type {ToggleWidgetProps} from './toggle-widget';\nexport type {ScaleWidgetProps} from './scale-widget';\nexport type {ThemeWidgetProps} from './theme-widget';\nexport type {InfoWidgetProps} from './info-widget';\nexport type {PopupWidgetProps} from './popup-widget';\nexport type {StatsWidgetProps} from './stats-widget';\nexport type {ContextMenuWidgetProps} from './context-menu-widget';\nexport type {SplitterWidgetProps} from './splitter-widget';\nexport type {TimelineWidgetProps} from './timeline-widget';\nexport type {SelectorWidgetProps} from './selector-widget';\nexport type {GimbalWidgetProps} from './gimbal-widget';\nexport type {ContentBounds, ScrollbarWidgetProps, ScrollbarDecoration} from './scrollbar-widget';\n\nexport {LightTheme, DarkTheme, LightGlassTheme, DarkGlassTheme} from './themes';\nexport type {DeckWidgetTheme} from './themes';\n\n// Experimental preact components\nexport {ButtonGroup as _ButtonGroup, type ButtonGroupProps} from './lib/components/button-group';\nexport {IconButton as _IconButton, type IconButtonProps} from './lib/components/icon-button';\nexport {\n DropdownMenu as _DropdownMenu,\n type DropdownMenuProps,\n SimpleMenu as _SimpleMenu,\n type SimpleMenuProps\n} from './lib/components/dropdown-menu';\nexport {\n RangeInput as _RangeInput,\n type RangeInputProps,\n type RangeInputDecoration\n} from './lib/components/range-input';\n\n// Experimental geocoders. May be removed, use at your own risk!\nexport {type Geocoder} from './lib/geocode/geocoder';\nexport {\n GoogleGeocoder as _GoogleGeocoder,\n MapboxGeocoder as _MapboxGeocoder,\n OpenCageGeocoder as _OpenCageGeocoder,\n CoordinatesGeocoder as _CoordinatesGeocoder,\n CurrentLocationGeocoder as _CurrentLocationGeocoder\n} from './lib/geocode/geocoders';\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, FlyToInterpolator, LinearInterpolator, OrthographicView} from '@deck.gl/core';\nimport type {WidgetProps, WidgetPlacement, OrthographicViewState} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {ButtonGroup} from './lib/components/button-group';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type ZoomWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Button orientation. */\n orientation?: 'vertical' | 'horizontal';\n /** Tooltip message on zoom in button. */\n zoomInLabel?: string;\n /** Tooltip message on zoom out button. */\n zoomOutLabel?: string;\n /** Zoom transition duration in ms. 0 disables the transition */\n transitionDuration?: number;\n /** Which axes to apply zoom to. One of 'X', 'Y' or 'all'.\n * Only effective if the current view is OrthographicView.\n */\n zoomAxis?: 'X' | 'Y' | 'all';\n /**\n * Callback when zoom buttons are clicked.\n * Called for each viewport that will be zoomed.\n */\n onZoom?: (params: {\n /** The view being zoomed */\n viewId: string;\n /** Zoom direction: +1 for zoom in, -1 for zoom out */\n delta: number;\n /** The new zoom level */\n zoom: number;\n /** The new zoom level of the X axis, if using OrthographicView */\n zoomX?: number;\n /** The new zoom level of the Y axis, if using OrthographicView */\n zoomY?: number;\n }) => void;\n};\n\nexport class ZoomWidget extends Widget<ZoomWidgetProps> {\n static defaultProps: Required<ZoomWidgetProps> = {\n ...Widget.defaultProps,\n id: 'zoom',\n placement: 'top-left',\n orientation: 'vertical',\n transitionDuration: 200,\n zoomInLabel: 'Zoom In',\n zoomOutLabel: 'Zoom Out',\n zoomAxis: 'all',\n viewId: null,\n onZoom: () => {}\n };\n\n className = 'deck-widget-zoom';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ZoomWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ZoomWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const ui = (\n <ButtonGroup orientation={this.props.orientation}>\n <IconButton\n onClick={() => this.handleZoomIn()}\n label={this.props.zoomInLabel}\n className=\"deck-widget-zoom-in\"\n />\n <IconButton\n onClick={() => this.handleZoomOut()}\n label={this.props.zoomOutLabel}\n className=\"deck-widget-zoom-out\"\n />\n </ButtonGroup>\n );\n render(ui, rootElement);\n }\n\n isOrthographicView(viewId: string): boolean {\n const deck = this.deck;\n const view = deck?.isInitialized && deck.getView(viewId);\n return view instanceof OrthographicView;\n }\n\n handleZoom(viewId: string, delta: number) {\n // Respect minZoom/maxZoom constraints from the view state\n const viewState = this.getViewState(viewId);\n const newViewState: Record<string, unknown> = {};\n\n if (this.isOrthographicView(viewId)) {\n const {zoomAxis} = this.props;\n const {zoomX, minZoomX, maxZoomX, zoomY, minZoomY, maxZoomY} = normalizeOrthographicViewState(\n viewState as any\n );\n let nextZoom: number;\n let nextZoomY: number;\n if (zoomAxis === 'X') {\n nextZoom = clamp(zoomX + delta, minZoomX, maxZoomX);\n nextZoomY = zoomY;\n } else if (zoomAxis === 'Y') {\n nextZoom = zoomX;\n nextZoomY = clamp(zoomY + delta, minZoomY, maxZoomY);\n } else {\n const clampedDelta = clamp(\n delta,\n Math.max(minZoomX - zoomX, minZoomY - zoomY),\n Math.min(maxZoomX - zoomX, maxZoomY - zoomY)\n );\n nextZoom = zoomX + clampedDelta;\n nextZoomY = zoomY + clampedDelta;\n }\n newViewState.zoom = [nextZoom, nextZoomY];\n newViewState.zoomX = nextZoom;\n newViewState.zoomY = nextZoomY;\n // Call callback\n this.props.onZoom?.({\n viewId,\n delta,\n // `zoom` will not match the new state if using 2D zoom. Deprecated behavior for backward compatibility.\n zoom: zoomAxis === 'Y' ? nextZoomY : nextZoom,\n zoomX: nextZoom,\n zoomY: nextZoomY\n });\n } else {\n const {zoom = 0, minZoom, maxZoom} = viewState as any;\n const nextZoom = clamp(zoom + delta, minZoom, maxZoom);\n newViewState.zoom = nextZoom;\n // Call callback\n this.props.onZoom?.({\n viewId,\n delta,\n zoom: nextZoom\n });\n }\n\n const nextViewState: Record<string, unknown> = {\n ...viewState,\n ...newViewState\n };\n if (this.props.transitionDuration > 0) {\n nextViewState.transitionDuration = this.props.transitionDuration;\n nextViewState.transitionInterpolator =\n 'latitude' in nextViewState\n ? new FlyToInterpolator()\n : new LinearInterpolator({\n transitionProps: 'zoomX' in newViewState ? ['zoomX', 'zoomY'] : ['zoom']\n });\n }\n this.setViewState(viewId, nextViewState);\n }\n\n handleZoomIn() {\n for (const viewId of this.viewIds) {\n this.handleZoom(viewId, 1);\n }\n }\n\n handleZoomOut() {\n for (const viewId of this.viewIds) {\n this.handleZoom(viewId, -1);\n }\n }\n}\n\nfunction clamp(zoom: number, minZoom: number, maxZoom: number): number {\n return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;\n}\n\nfunction normalizeOrthographicViewState({\n zoom = 0,\n zoomX,\n zoomY,\n minZoom = -Infinity,\n maxZoom = Infinity,\n minZoomX = minZoom,\n maxZoomX = maxZoom,\n minZoomY = minZoom,\n maxZoomY = maxZoom\n}: OrthographicViewState): {\n zoomX: number;\n zoomY: number;\n minZoomX: number;\n maxZoomX: number;\n minZoomY: number;\n maxZoomY: number;\n} {\n zoomX = zoomX ?? (Array.isArray(zoom) ? zoom[0] : zoom);\n zoomY = zoomY ?? (Array.isArray(zoom) ? zoom[1] : zoom);\n return {zoomX, zoomY, minZoomX, minZoomY, maxZoomX, maxZoomY};\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren} from 'preact';\n\nexport type ButtonGroupProps = {\n children: ComponentChildren;\n orientation: 'vertical' | 'horizontal';\n};\n\n/** Renders a group of buttons with Widget CSS */\nexport const ButtonGroup = (props: ButtonGroupProps) => {\n const {children, orientation = 'horizontal'} = props;\n return <div className={`deck-widget-button-group ${orientation}`}>{children}</div>;\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren, JSX} from 'preact';\nimport {useMemo} from 'preact/hooks';\nimport {getCSSMask} from '../data-url';\n\nexport type IconButtonProps = {\n className?: string;\n icon?: string;\n label?: string;\n color?: string;\n style?: JSX.CSSProperties;\n onClick?: JSX.MouseEventHandler<HTMLButtonElement>;\n children?: ComponentChildren;\n};\n\n/** Renders a button component with widget CSS */\nexport const IconButton = (props: IconButtonProps) => {\n const {className = '', style, color, icon, label, onClick, children} = props;\n\n const iconStyle = useMemo(() => {\n const css: JSX.CSSProperties | undefined = getCSSMask(icon);\n if (!color) return css;\n return {...css, backgroundColor: color};\n }, [color, icon]);\n\n return (\n <div className=\"deck-widget-button\" style={style}>\n <button\n className={`deck-widget-icon-button ${className}`}\n type=\"button\"\n onClick={onClick}\n title={label}\n >\n {children ? children : <div className=\"deck-widget-icon\" style={iconStyle} />}\n </button>\n </div>\n );\n};\n", "export function getCSSMask(imageUrl: string | null | undefined) {\n if (!imageUrl) return undefined;\n const cssUrl = `url(\"${imageUrl.replace(/\"/g, `'`)}\")`;\n return {maskImage: cssUrl, WebkitMaskImage: cssUrl};\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport type {ViewStateMap, View} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** @note Mirrors an internal calss in deck.gl/core. We can easily redefine it here */\ntype ViewOrViews = View | View[] | null;\n\n/** Properties for the ResetViewWidget */\nexport type ResetViewWidgetProps<ViewsT extends ViewOrViews = null> = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** Tooltip message */\n label?: string;\n /** The initial view state to reset the view to. Defaults to deck.props.initialViewState */\n initialViewState?: ViewStateMap<ViewsT>;\n /** View to interact with. Required when using multiple views. */\n viewId?: string | null;\n /**\n * Callback when the reset view button is clicked.\n */\n onReset?: (params: {\n /** The view being reset */\n viewId: string;\n /** The view state being reset to */\n viewState: Record<string, unknown>;\n }) => void;\n};\n\n/**\n * A button widget that resets the view state of deck to an initial state.\n */\nexport class ResetViewWidget<ViewsT extends ViewOrViews = null> extends Widget<\n ResetViewWidgetProps<ViewsT>,\n ViewsT\n> {\n static defaultProps: Required<ResetViewWidgetProps> = {\n ...Widget.defaultProps,\n id: 'reset-view',\n placement: 'top-left',\n label: 'Reset View',\n initialViewState: undefined!,\n viewId: null,\n onReset: () => {}\n };\n\n className = 'deck-widget-reset-view';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ResetViewWidgetProps<ViewsT> = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ResetViewWidgetProps<ViewsT>>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n className=\"deck-widget-reset-focus\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />,\n rootElement\n );\n }\n\n handleClick() {\n const initialViewState = this.props.initialViewState || this.deck?.props.initialViewState;\n this.resetViewState(initialViewState);\n }\n\n resetViewState(viewState?: ViewStateMap<ViewsT>) {\n for (const viewId of this.viewIds) {\n const nextViewState = {\n ...(viewState?.[viewId] ?? viewState)\n // only works for geospatial?\n // transitionDuration: this.props.transitionDuration,\n // transitionInterpolator: new FlyToInterpolator()\n };\n\n // Call callback\n this.props.onReset?.({viewId, viewState: nextViewState as Record<string, unknown>});\n\n this.setViewState(viewId, nextViewState);\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, LinearInterpolator} from '@deck.gl/core';\nimport type {Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\n\nexport type GimbalWidgetProps = WidgetProps & {\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message. */\n label?: string;\n /** Width of gimbal lines. */\n strokeWidth?: number;\n /** Transition duration in ms when resetting rotation. */\n transitionDuration?: number;\n /**\n * Callback when the gimbal reset button is clicked.\n * Called for each viewport that will be reset.\n */\n onReset?: (params: {\n /** The view being reset */\n viewId: string;\n /** The new rotationOrbit value (0) */\n rotationOrbit: number;\n /** The new rotationX value (0) */\n rotationX: number;\n }) => void;\n};\n\nexport class GimbalWidget extends Widget<GimbalWidgetProps> {\n static defaultProps: Required<GimbalWidgetProps> = {\n ...Widget.defaultProps,\n id: 'gimbal',\n placement: 'top-left',\n viewId: null,\n label: 'Gimbal',\n strokeWidth: 1.5,\n transitionDuration: 200,\n onReset: () => {}\n };\n\n className = 'deck-widget-gimbal';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: GimbalWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<GimbalWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const viewId = this.viewId || Object.values(this.viewports)[0]?.id || 'default-view';\n const widgetViewport = this.viewports[viewId];\n const {rotationOrbit, rotationX} = this.getNormalizedRotation(widgetViewport);\n // Note - we use CSS 3D transforms instead of SVG 2D transforms\n const ui = (\n <div className=\"deck-widget-button\" style={{perspective: 100, pointerEvents: 'auto'}}>\n <button\n type=\"button\"\n onClick={() => {\n for (const viewport of Object.values(this.viewports)) {\n this.resetOrbitView(viewport);\n }\n }}\n title={this.props.label}\n style={{position: 'relative', width: 26, height: 26}}\n >\n {/* Outer ring */}\n <svg\n className=\"gimbal-outer-ring\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 26 26\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `rotateY(${rotationOrbit}deg)`\n }}\n >\n <circle\n cx=\"13\"\n cy=\"13\"\n r=\"10\"\n stroke=\"var(--icon-gimbal-outer-color, rgb(68, 92, 204))\"\n strokeWidth={this.props.strokeWidth}\n fill=\"none\"\n />\n </svg>\n\n {/* Inner ring */}\n <svg\n className=\"gimbal-inner-ring\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 26 26\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `rotateX(${rotationX}deg)`\n }}\n >\n <circle\n cx=\"13\"\n cy=\"13\"\n r=\"7\"\n stroke=\"var(--icon-gimbal-inner-color, rgb(240, 92, 68))\"\n strokeWidth={this.props.strokeWidth}\n fill=\"none\"\n />\n </svg>\n </button>\n </div>\n );\n\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n this.viewports[viewport.id] = viewport;\n this.updateHTML();\n }\n\n resetOrbitView(viewport?: Viewport) {\n const viewId = this.viewId || viewport?.id || 'OrbitView';\n const viewState = this.getViewState(viewId);\n if ('rotationOrbit' in viewState || 'rotationX' in viewState) {\n // Call callback\n this.props.onReset?.({viewId, rotationOrbit: 0, rotationX: 0});\n\n const nextViewState = {\n ...viewState,\n rotationOrbit: 0,\n rotationX: 0,\n transitionDuration: this.props.transitionDuration,\n transitionInterpolator: new LinearInterpolator({\n transitionProps: ['rotationOrbit', 'rotationX']\n })\n };\n this.setViewState(viewId, nextViewState);\n }\n }\n\n getNormalizedRotation(viewport?: Viewport): {rotationOrbit: number; rotationX: number} {\n const viewId = this.viewId || viewport?.id || 'OrbitView';\n const viewState = this.getViewState(viewId);\n const [rz, rx] = this.getRotation(viewState);\n const rotationOrbit = normalizeAndClampAngle(rz);\n const rotationX = normalizeAndClampAngle(rx);\n return {rotationOrbit, rotationX};\n }\n\n getRotation(viewState?: any): [number, number] {\n if (viewState && ('rotationOrbit' in viewState || 'rotationX' in viewState)) {\n return [-(viewState.rotationOrbit || 0), viewState.rotationX || 0];\n }\n return [0, 0];\n }\n}\n\nfunction normalizeAndClampAngle(angle: number): number {\n // Bring angle into [-180, 180]\n let normalized = ((((angle + 180) % 360) + 360) % 360) - 180;\n\n // Avoid rotating the gimbal rings to close to 90 degrees as they will visually disappear\n const AVOID_ANGLE_DELTA = 10;\n const distanceFrom90 = normalized - 90;\n if (Math.abs(distanceFrom90) < AVOID_ANGLE_DELTA) {\n if (distanceFrom90 < AVOID_ANGLE_DELTA) {\n normalized = 90 + AVOID_ANGLE_DELTA;\n } else if (distanceFrom90 > -AVOID_ANGLE_DELTA) {\n normalized = 90 - AVOID_ANGLE_DELTA;\n }\n }\n // Clamp to [-80, 80]\n return normalized; // Math.max(-80, Math.min(80, normalized));\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, FlyToInterpolator, WebMercatorViewport, _GlobeViewport} from '@deck.gl/core';\nimport type {Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\n\nexport type CompassWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message. */\n label?: string;\n /** Bearing and pitch reset transition duration in ms. */\n transitionDuration?: number;\n /**\n * Callback when the compass reset button is clicked.\n * Called for each viewport that will be reset.\n */\n onReset?: (params: {\n /** The view being reset */\n viewId: string;\n /** The new bearing value (0) */\n bearing: number;\n /** The new pitch value (0 if bearing was already 0) */\n pitch: number;\n }) => void;\n};\n\nexport class CompassWidget extends Widget<CompassWidgetProps> {\n static defaultProps: Required<CompassWidgetProps> = {\n ...Widget.defaultProps,\n id: 'compass',\n placement: 'top-left',\n viewId: null,\n label: 'Reset Compass',\n transitionDuration: 200,\n onReset: () => {}\n };\n\n className = 'deck-widget-compass';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: CompassWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<CompassWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const viewId = this.viewId || Object.values(this.viewports)[0]?.id;\n const widgetViewport = this.viewports[viewId];\n const [rz, rx] = this.getRotation(widgetViewport);\n\n const ui = (\n <div className=\"deck-widget-button\" style={{perspective: 100}}>\n <button\n type=\"button\"\n onClick={() => {\n for (const viewport of Object.values(this.viewports)) {\n this.handleCompassReset(viewport);\n }\n }}\n title={this.props.label}\n style={{transform: `rotateX(${rx}deg)`}}\n >\n <svg fill=\"none\" width=\"100%\" height=\"100%\" viewBox=\"0 0 26 26\">\n <g transform={`rotate(${rz},13,13)`}>\n <path\n d=\"M10 13.0001L12.9999 5L15.9997 13.0001H10Z\"\n fill=\"var(--icon-compass-north-color, rgb(240, 92, 68))\"\n />\n <path\n d=\"M16.0002 12.9999L13.0004 21L10.0005 12.9999H16.0002Z\"\n fill=\"var(--icon-compass-south-color, rgb(204, 204, 204))\"\n />\n </g>\n </svg>\n </button>\n </div>\n );\n\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n // no need to update if viewport is the same\n if (!viewport.equals(this.viewports[viewport.id])) {\n this.viewports[viewport.id] = viewport;\n this.updateHTML();\n }\n }\n\n getRotation(viewport?: Viewport) {\n if (viewport instanceof WebMercatorViewport) {\n return [-viewport.bearing, viewport.pitch];\n } else if (viewport instanceof _GlobeViewport) {\n return [0, Math.max(-80, Math.min(80, viewport.latitude))];\n }\n return [0, 0];\n }\n\n handleCompassReset(viewport: Viewport) {\n const viewId = this.viewId || viewport.id;\n if (viewport instanceof WebMercatorViewport) {\n const viewState = this.getViewState(viewId);\n const resetPitch = this.getRotation(viewport)[0] === 0;\n const nextBearing = 0;\n const nextPitch = resetPitch ? 0 : viewport.pitch;\n\n // Call callback\n this.props.onReset?.({viewId, bearing: nextBearing, pitch: nextPitch});\n\n const nextViewState = {\n ...viewState,\n bearing: nextBearing,\n ...(resetPitch ? {pitch: nextPitch} : {}),\n transitionDuration: this.props.transitionDuration,\n transitionInterpolator: new FlyToInterpolator()\n };\n this.setViewState(viewId, nextViewState);\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\n\nexport type ScaleWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** Label for the scale widget */\n label?: string;\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n};\n\n/**\n * A scale widget that displays a Google Maps\u2013like scale indicator.\n * Instead of text inside a div, this widget renders an SVG that contains a horizontal line\n * with two vertical tick marks (extending upward from the line only) and a pretty distance label\n * positioned to the left of the line. The horizontal line\u2019s length is computed from a \u201Cnice\u201D\n * candidate distance (e.g. 200, 500, 1000 m, etc.) so that its pixel width is between 100 and 200.\n */\nexport class ScaleWidget extends Widget<ScaleWidgetProps> {\n static defaultProps: Required<ScaleWidgetProps> = {\n ...Widget.defaultProps,\n id: 'scale',\n placement: 'bottom-left',\n label: 'Scale',\n viewId: null\n };\n\n className = 'deck-widget-scale';\n placement: WidgetPlacement = 'bottom-left';\n\n // The pixel width of the scale line (computed from a candidate distance)\n scaleWidth: number = 10;\n // The candidate distance (in meters) corresponding to the scale line length.\n scaleValue: number = 0;\n // The formatted distance label (e.g. \"200 m\" or \"1.0 km\")\n scaleText: string = '';\n\n constructor(props: ScaleWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ScaleWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n // Reserve space for the text label (to the left of the horizontal line)\n const lineOffsetX = 50;\n // Overall SVG width includes the left offset plus the computed scale line width.\n const svgWidth = lineOffsetX + this.scaleWidth;\n const tickHeight = 10; // vertical tick extends upward by 10 pixels from the horizontal line\n render(\n <svg\n className=\"deck-widget-scale\"\n width={svgWidth}\n height={30}\n style={{overflow: 'visible', background: 'transparent'}}\n onClick={this.handleClick.bind(this)}\n >\n {/* Pretty distance label positioned to the left of the horizontal line */}\n <text\n x={lineOffsetX + 5}\n y=\"10\"\n textAnchor=\"end\"\n alignmentBaseline=\"middle\"\n style={{fontSize: '16px', fill: 'black', fontWeight: 'bold', fontFamily: 'sans-serif'}}\n >\n {this.scaleText}\n </text>\n {/* Horizontal line */}\n <line\n x1={lineOffsetX}\n y1=\"15\"\n x2={lineOffsetX + this.scaleWidth}\n y2=\"15\"\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n {/* Left vertical tick (extending upward from the horizontal line) */}\n <line\n x1={lineOffsetX}\n y1=\"15\"\n x2={lineOffsetX}\n y2={15 - tickHeight}\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n {/* Right vertical tick (extending upward from the horizontal line) */}\n <line\n x1={lineOffsetX + this.scaleWidth}\n y1=\"15\"\n x2={lineOffsetX + this.scaleWidth}\n y2={15 - tickHeight}\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n </svg>,\n rootElement\n );\n }\n\n onViewportChange(viewport: Viewport): void {\n // Only handle geospatial viewports (which contain latitude)\n if (!('latitude' in viewport)) return;\n\n const {latitude, zoom} = viewport as {latitude: number; zoom: number};\n const metersPerPixel = getMetersPerPixel(latitude, zoom);\n const {candidate, candidatePixels} = computeScaleCandidate(metersPerPixel);\n\n this.scaleValue = candidate;\n this.scaleWidth = candidatePixels;\n // Format the candidate distance for display (using km if >= 1000 m)\n if (candidate >= 1000) {\n this.scaleText = `${(candidate / 1000).toFixed(1)} km`;\n } else {\n this.scaleText = `${candidate} m`;\n }\n this.updateHTML();\n }\n\n handleClick(): void {}\n}\n\n/**\n * Compute the meters per pixel at a given latitude and zoom level.\n *\n * @param latitude - The current latitude.\n * @param zoom - The current zoom level.\n * @returns The number of meters per pixel.\n */\nfunction getMetersPerPixel(latitude: number, zoom: number): number {\n const earthCircumference = 40075016.686;\n return (earthCircumference * Math.cos((latitude * Math.PI) / 180)) / Math.pow(2, zoom + 8);\n}\n\n/**\n * Compute a \"nice\" scale candidate such that the scale bar width in pixels is between 100 and 200.\n * The candidate distance (in meters) will be one of a set of round numbers (100, 200, 500, 1000, 2000, 5000, etc.).\n *\n * @param metersPerPixel - The number of meters per pixel at the current zoom/latitude.\n * @returns An object containing the candidate distance and its width in pixels.\n */\nfunction computeScaleCandidate(metersPerPixel: number): {\n candidate: number;\n candidatePixels: number;\n} {\n const minPixels = 100;\n const maxPixels = 200;\n const targetPixels = (minPixels + maxPixels) / 2;\n const targetDistance = targetPixels * metersPerPixel;\n\n const exponent = Math.floor(Math.log10(targetDistance));\n const base = Math.pow(10, exponent);\n const multipliers = [1, 2, 5];\n\n let candidate = multipliers[0] * base;\n let candidatePixels = candidate / metersPerPixel;\n\n for (let i = 0; i < multipliers.length; i++) {\n const currentCandidate = multipliers[i] * base;\n const currentPixels = currentCandidate / metersPerPixel;\n if (currentPixels >= minPixels && currentPixels <= maxPixels) {\n candidate = currentCandidate;\n candidatePixels = currentPixels;\n break;\n }\n if (currentPixels > maxPixels) {\n candidate = i > 0 ? multipliers[i - 1] * base : currentCandidate;\n candidatePixels = candidate / metersPerPixel;\n break;\n }\n if (i === multipliers.length - 1 && currentPixels < minPixels) {\n candidate = multipliers[0] * base * 10;\n candidatePixels = candidate / metersPerPixel;\n }\n }\n return {candidate, candidatePixels};\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {FlyToInterpolator, LinearInterpolator} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {DropdownMenu, type MenuItem} from './lib/components/dropdown-menu';\nimport {type Geocoder} from './lib/geocode/geocoder';\nimport {GeocoderHistory} from './lib/geocode/geocoder-history';\nimport {\n GoogleGeocoder,\n MapboxGeocoder,\n OpenCageGeocoder,\n CoordinatesGeocoder,\n CurrentLocationGeocoder\n} from './lib/geocode/geocoders';\n\n/** @todo - is the the best we can do? */\ntype ViewState = Record<string, unknown>;\n\nconst CURRENT_LOCATION = 'current';\n\n// Location pin icon (from Google Material Symbols)\nconst LOCATION_ICON = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M480-480q33 0 56.5-23.5T560-560q0-33-23.5-56.5T480-640q-33 0-56.5 23.5T400-560q0 33 23.5 56.5T480-480Zm0 294q122-112 181-203.5T720-552q0-109-69.5-178.5T480-800q-101 0-170.5 69.5T240-552q0 71 59 162.5T480-186Zm0 106Q319-217 239.5-334.5T160-552q0-150 96.5-239T480-880q127 0 223.5 89T800-552q0 100-79.5 217.5T480-80Z'/%3E%3C/svg%3E`;\n\nconst CURRENT_LOCATION_ITEM: MenuItem = {\n label: 'Current location',\n value: CURRENT_LOCATION,\n icon: LOCATION_ICON\n};\n\n/** Properties for the GeocoderWidget */\nexport type GeocoderWidgetProps = WidgetProps & {\n viewId?: string | null;\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** Tooltip message */\n label?: string;\n /** View state reset transition duration in ms. 0 disables the transition */\n transitionDuration?: number;\n /** Geocoding service selector, for declarative usage */\n geocoder?: 'google' | 'mapbox' | 'opencage' | 'coordinates' | 'custom';\n /** Custom geocoding service (Used when geocoder = 'custom') */\n customGeocoder?: Geocoder;\n /** API key used for geocoding services */\n apiKey?: string;\n /** Whether to use geolocation @note Experimental*/\n _geolocation?: boolean;\n /**\n * Callback when a location is geocoded and the view will navigate to it.\n */\n onGeocode?: (params: {\n /** The view being updated */\n viewId: string;\n /** The geocoded coordinates */\n coordinates: {longitude: number; latitude: number; zoom?: number};\n }) => void;\n};\n\n/**\n * A widget that display a text box that lets user type in a location\n * and a button that moves the view to that location.\n * @todo For now only supports coordinates, Could be extended with location service integrations.\n */\nexport class GeocoderWidget extends Widget<GeocoderWidgetProps> {\n static defaultProps: Required<GeocoderWidgetProps> = {\n ...Widget.defaultProps,\n id: 'geocoder',\n viewId: null,\n placement: 'top-left',\n label: 'Geocoder',\n transitionDuration: 200,\n geocoder: 'coordinates',\n customGeocoder: CoordinatesGeocoder,\n apiKey: '',\n _geolocation: false,\n onGeocode: () => {}\n };\n\n className = 'deck-widget-geocoder';\n placement: WidgetPlacement = 'top-left';\n\n geocodeHistory = new GeocoderHistory({});\n addressText: string = '';\n geocoder: Geocoder = CoordinatesGeocoder;\n isGettingLocation: boolean = false;\n\n constructor(props: GeocoderWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<GeocoderWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n this.geocoder = getGeocoder(this.props);\n if (this.geocoder.requiresApiKey && !this.props.apiKey) {\n throw new Error(`API key is required for the ${this.geocoder.name} geocoder`);\n }\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const menuItems: MenuItem[] = this.props._geolocation\n ? [CURRENT_LOCATION_ITEM, ...this.geocodeHistory.addressHistory]\n : [...this.geocodeHistory.addressHistory];\n render(\n <div className=\"deck-widget-geocoder\">\n <input\n className=\"deck-widget-geocoder-input\"\n type=\"text\"\n placeholder={\n this.isGettingLocation\n ? 'Finding your location...'\n : (this.geocoder.placeholderLocation ?? 'Enter address or location')\n }\n value={this.geocodeHistory.addressText}\n // @ts-expect-error event type\n onInput={e => this.setInput(e.target?.value || '')}\n onKeyPress={this.handleKeyPress}\n />\n <DropdownMenu menuItems={menuItems} onSelect={this.handleSelect} />\n {this.geocodeHistory.errorText && (\n <div className=\"deck-widget-geocoder-error\">{this.geocodeHistory.errorText}</div>\n )}\n </div>,\n rootElement\n );\n }\n\n setInput = (text: string) => {\n this.addressText = text;\n };\n\n handleKeyPress = e => {\n if (e.key === 'Enter') {\n this.handleSubmit();\n }\n };\n\n handleSelect = (value: string) => {\n if (value === CURRENT_LOCATION) {\n // Don't put \"current\" in the text field, just trigger geolocation\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.getCurrentLocation();\n } else {\n this.setInput(value);\n this.handleSubmit();\n }\n };\n\n /** Sync wrapper for async geocode() */\n handleSubmit = () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.geocode(this.addressText);\n };\n\n /** Get current location via browser geolocation API */\n getCurrentLocation = async () => {\n this.isGettingLocation = true;\n if (this.rootElement) {\n this.updateHTML();\n }\n\n try {\n const coordinates = await CurrentLocationGeocoder.geocode();\n if (coordinates) {\n this.flyTo(coordinates);\n }\n } catch (error) {\n this.geocodeHistory.errorText = error instanceof Error ? error.message : 'Location error';\n } finally {\n this.isGettingLocation = false;\n if (this.rootElement) {\n this.updateHTML();\n }\n }\n };\n\n /** Perform geocoding */\n geocode: (address: string) => Promise<void> = async address => {\n const coordinates = await this.geocodeHistory.geocode(\n this.geocoder,\n this.addressText,\n this.props.apiKey\n );\n // Re-render to show updated history or error (guard against torn-down widget)\n if (this.rootElement) {\n this.updateHTML();\n }\n if (coordinates) {\n this.flyTo(coordinates);\n }\n };\n\n flyTo(viewState: ViewState) {\n for (const viewId of this.viewIds) {\n // Call callback with geocoded coordinates\n if ('longitude' in viewState && 'latitude' in viewState) {\n this.props.onGeocode?.({\n viewId,\n coordinates: {\n longitude: viewState.longitude as number,\n latitude: viewState.latitude as number,\n zoom: viewState.zoom as number | undefined\n }\n });\n }\n\n const currentViewState = this.getViewState(viewId);\n const nextViewState: ViewState = {\n ...currentViewState,\n ...viewState\n };\n if (this.props.transitionDuration > 0) {\n nextViewState.transitionDuration = this.props.transitionDuration;\n nextViewState.transitionInterpolator =\n 'latitude' in nextViewState ? new FlyToInterpolator() : new LinearInterpolator();\n }\n this.setViewState(viewId, nextViewState);\n }\n }\n}\n\nfunction getGeocoder(props: {geocoder?: string; customGeocoder?: Geocoder}): Geocoder {\n switch (props.geocoder) {\n case 'google':\n return GoogleGeocoder;\n case 'mapbox':\n return MapboxGeocoder;\n case 'opencage':\n return OpenCageGeocoder;\n case 'coordinates':\n return CoordinatesGeocoder;\n case 'custom':\n if (!props.customGeocoder) {\n throw new Error('Custom geocoder is not defined');\n }\n return props.customGeocoder;\n default:\n throw new Error(`Unknown geocoder: ${props.geocoder}`);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type JSX, type ComponentChild} from 'preact';\nimport {useState, useRef, useEffect} from 'preact/hooks';\nimport {getCSSMask} from '../data-url';\n\nexport type MenuItem =\n | string\n | {\n value?: string;\n label: string;\n icon?: string;\n onSelect?: () => void;\n };\n\nexport type DropdownMenuProps = {\n menuItems: MenuItem[];\n onSelect?: (value: string) => void;\n style?: Partial<CSSStyleDeclaration>;\n};\n\nfunction getMenuItemValue(item: MenuItem): string | undefined {\n return typeof item === 'string' ? item : item.value;\n}\n\nfunction getMenuItemLabel(item: MenuItem): string {\n return typeof item === 'string' ? item : item.label;\n}\n\nfunction getMenuItemIcon(item: MenuItem): string | undefined {\n return typeof item === 'string' ? undefined : item.icon;\n}\n\nexport const DropdownMenu = (props: DropdownMenuProps) => {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <SimpleMenu\n {...props}\n style={{...props.style, position: 'absolute'}}\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n trigger={\n <button className=\"deck-widget-dropdown-button\" onClick={() => setIsOpen(!isOpen)}>\n <span className={`deck-widget-dropdown-icon ${isOpen ? 'open' : ''}`} />\n </button>\n }\n />\n );\n};\n\nexport type SimpleMenuProps = DropdownMenuProps & {\n trigger?: ComponentChild;\n isOpen: boolean;\n onClose: () => void;\n};\n\nexport const SimpleMenu = (props: SimpleMenuProps) => {\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n props.onClose();\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, []);\n\n const handleSelect = (value: string | undefined, item: MenuItem) => {\n if (value) {\n if (typeof item === 'object') {\n item.onSelect?.();\n }\n props.onSelect?.(value);\n props.onClose();\n }\n };\n\n // Don't render anything if there are no menu items\n if (props.menuItems.length === 0) {\n return null;\n }\n\n return (\n <div className=\"deck-widget-dropdown-container\" ref={dropdownRef}>\n {props.trigger}\n {props.isOpen && (\n <ul className=\"deck-widget-dropdown-menu\" style={props.style as JSX.CSSProperties}>\n {props.menuItems.map((item, i) => {\n const value = getMenuItemValue(item);\n const icon = getMenuItemIcon(item);\n return (\n <li\n className={`deck-widget-dropdown-item ${value ? '' : 'disabled'}`}\n key={i}\n onClick={() => handleSelect(value, item)}\n >\n {icon && (\n <span className=\"deck-widget-dropdown-item-icon\" style={getCSSMask(icon)} />\n )}\n {getMenuItemLabel(item)}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type Geocoder} from './geocoder';\n\nconst CURRENT_LOCATION = 'current';\nconst LOCAL_STORAGE_KEY = 'deck-geocoder-history';\n\nexport type GeocoderHistoryProps = {\n maxEntries?: number;\n};\n\n/**\n * An internal, experimental helper class for storing a list of locations in local storage.\n * @todo Remove the UI related state.\n */\nexport class GeocoderHistory {\n props: Required<GeocoderHistoryProps>;\n addressText = '';\n errorText = '';\n addressHistory: string[] = [];\n\n constructor(props: GeocoderHistoryProps) {\n this.props = {maxEntries: 5, ...props};\n this.addressHistory = this.loadPreviousAddresses();\n }\n\n /** PErform geocoding */\n async geocode(geocoder: Geocoder, address: string, apiKey: string) {\n this.errorText = '';\n this.addressText = address;\n try {\n const coordinates = await geocoder.geocode(address, apiKey);\n if (coordinates) {\n this.storeAddress(this.addressText);\n return coordinates;\n }\n this.errorText = 'Invalid address';\n } catch (error) {\n this.errorText = `${(error as Error).message}`;\n }\n return null;\n }\n\n loadPreviousAddresses(): string[] {\n try {\n const stored = window.localStorage.getItem(LOCAL_STORAGE_KEY);\n const list = stored && JSON.parse(stored);\n const addresses = Array.isArray(list)\n ? list.filter((v): v is string => typeof v === 'string')\n : [];\n return addresses;\n } catch {\n // ignore\n }\n return [];\n }\n\n storeAddress(address: string) {\n const cleaned = address.trim();\n if (!cleaned || cleaned === CURRENT_LOCATION) {\n return;\n }\n const deduped = [cleaned, ...this.addressHistory.filter(a => a !== cleaned)];\n this.addressHistory = deduped.slice(0, this.props.maxEntries);\n try {\n window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.addressHistory));\n } catch {\n // ignore\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type Geocoder} from './geocoder';\n\nconst GOOGLE_URL = 'https://maps.googleapis.com/maps/api/geocode/json';\nconst MAPBOX_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places';\nconst OPENCAGE_API_URL = 'https://api.opencagedata.com/geocode/v1/json';\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from Google\n * @see https://developers.google.com/maps/documentation/geocoding/get-api-key\n */\nexport const GoogleGeocoder = {\n name: 'google',\n requiresApiKey: true,\n async geocode(\n address: string,\n apiKey: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const json = await fetchJson(`${GOOGLE_URL}?address=${encodedAddress}&key=${apiKey}`);\n\n switch (json.status) {\n case 'OK':\n const loc = json.results.length > 0 && json.results[0].geometry.location;\n return loc ? {longitude: loc.lng, latitude: loc.lat} : null;\n default:\n throw new Error(`Google Geocoder failed: ${json.status}`);\n }\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from Mapbox\n * @see https://docs.mapbox.com/api/search/geocoding/\n */\nexport const MapboxGeocoder = {\n name: 'google',\n requiresApiKey: true,\n async geocode(\n address: string,\n apiKey: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const json = await fetchJson(`${MAPBOX_URL}/${encodedAddress}.json?access_token=${apiKey}`);\n\n if (Array.isArray(json.features) && json.features.length > 0) {\n const center = json.features[0].center;\n if (Array.isArray(center) && center.length >= 2) {\n return {longitude: center[0], latitude: center[1]};\n }\n }\n return null;\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from OpenCageData\n * @see https://opencagedata.com/api\n */\nexport const OpenCageGeocoder = {\n name: 'opencage',\n requiresApiKey: true,\n async geocode(\n address: string,\n key: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const data = await fetchJson(`${OPENCAGE_API_URL}?q=${encodedAddress}&key=${key}`);\n if (Array.isArray(data.results) && data.results.length > 0) {\n const geometry = data.results[0].geometry;\n return {longitude: geometry.lng, latitude: geometry.lat};\n }\n return null;\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder adapter that wraps the browser's geolocation API. Always returns the user's current location.\n * @note Not technically a geocoder, but a geolocation service that provides a source of locations.\n * @note The user must allow location access for this to work.\n */\nexport const CurrentLocationGeocoder = {\n name: 'current',\n requiresApiKey: false,\n /** Attempt to call browsers geolocation API */\n async geocode(): Promise<{longitude: number; latitude: number} | null> {\n if (!navigator.geolocation) {\n throw new Error('Geolocation not supported');\n }\n return new Promise((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(\n /** @see https://developer.mozilla.org/docs/Web/API/GeolocationPosition */\n (position: GeolocationPosition) => {\n const {longitude, latitude} = position.coords;\n resolve({longitude, latitude});\n },\n /** @see https://developer.mozilla.org/docs/Web/API/GeolocationPositionError */\n (error: GeolocationPositionError) => reject(new Error(error.message))\n );\n });\n }\n} as const satisfies Geocoder;\n\n/** Fetch JSON, catching HTTP errors */\nasync function fetchJson(url: string): Promise<any> {\n let response: Response;\n try {\n response = await fetch(url);\n } catch (error) {\n // Annoyingly, fetch reports some errors (e.g. CORS) using excpetions, not response.ok\n throw new Error(`CORS error? ${error}. ${url}: `);\n }\n if (!response.ok) {\n throw new Error(`${response.statusText}. ${url}: `);\n }\n const data = await response.json();\n if (!data) {\n throw new Error(`No data returned. ${url}`);\n }\n return data;\n}\n\n/**\n * Parse a coordinate string.\n * Supports comma- or semicolon-separated values.\n * Heuristically determines which value is longitude and which is latitude.\n */\nexport const CoordinatesGeocoder = {\n name: 'coordinates',\n requiresApiKey: false,\n placeholderLocation: `-122.45, 37.8 or 37\u00B048'N, 122\u00B027'W`,\n async geocode(address: string): Promise<{longitude: number; latitude: number} | null> {\n return parseCoordinates(address) || null;\n }\n} as const satisfies Geocoder;\n\n/**\n * Parse an input string for coordinates.\n * Supports comma- or semicolon-separated values.\n * Heuristically determines which value is longitude and which is latitude.\n */\nfunction parseCoordinates(input) {\n input = input.trim();\n const parts = input.split(/[,;]/).map(p => p.trim());\n if (parts.length < 2) return null;\n const first = parseCoordinatePart(parts[0]);\n const second = parseCoordinatePart(parts[1]);\n if (first === null || second === null) return null;\n if (Math.abs(first) > 90 && Math.abs(second) > 90) {\n return null;\n }\n // Use a heuristic:\n // If one number exceeds 90 in absolute value, it's likely a longitude.\n if (Math.abs(first) > 90) {\n return {longitude: first, latitude: second};\n }\n if (Math.abs(second) > 90) {\n return {longitude: second, latitude: first};\n }\n // If both are <= 90, assume order: latitude, longitude.\n return {latitude: first, longitude: second};\n}\n\n/**\n * Parse a single coordinate part (which may be in decimal or DMS format).\n */\nfunction parseCoordinatePart(s: string): number | null {\n s = s.trim();\n // If the string contains a degree symbol or similar markers, use DMS parsing.\n if (s.includes('\u00B0') || s.includes(\"'\") || s.includes('\"')) {\n const value = dmsToDecimal(s);\n return isNaN(value) ? null : value;\n }\n // Otherwise, check for a cardinal letter and remove it.\n let sign = 1;\n if (/[SW]/i.test(s)) sign = -1;\n s = s.replace(/[NSEW]/gi, '');\n const value = parseFloat(s);\n return isNaN(value) ? null : sign * value;\n}\n\n/** Convert a DMS string (e.g. \"37\u00B048'00\\\"N\") to decimal degrees. */\nfunction dmsToDecimal(s: string): number {\n // A simple regex to extract degrees, minutes, seconds and direction.\n const regex = /(-?\\d+)[\u00B0d]\\s*(\\d+)?['\u2032m]?\\s*(\\d+(?:\\.\\d+)?)?[\\\"\u2033s]?\\s*([NSEW])?/i;\n const match = s.match(regex);\n if (!match) return NaN;\n const degrees = parseFloat(match[1]) || 0;\n const minutes = parseFloat(match[2]) || 0;\n const seconds = parseFloat(match[3]) || 0;\n const direction = match[4] || '';\n let dec = degrees + minutes / 60 + seconds / 3600;\n if (/[SW]/i.test(direction)) {\n dec = -dec;\n }\n return dec;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport {log, Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {IconButton} from './lib/components/icon-button';\n\n/* eslint-enable max-len */\n\nexport type FullscreenWidgetProps = WidgetProps & {\n id?: string;\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message when out of fullscreen. */\n enterLabel?: string;\n /** Tooltip message when fullscreen. */\n exitLabel?: string;\n /**\n * A compatible DOM element which should be made full screen. By default, the map container element will be made full screen.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#Compatible_elements\n */\n container?: HTMLElement;\n /**\n * Callback when fullscreen state changes (via user click or browser fullscreen events).\n */\n onFullscreenChange?: (fullscreen: boolean) => void;\n};\n\nexport class FullscreenWidget extends Widget<FullscreenWidgetProps> {\n static defaultProps: Required<FullscreenWidgetProps> = {\n ...Widget.defaultProps,\n id: 'fullscreen',\n placement: 'top-left',\n viewId: null,\n enterLabel: 'Enter Fullscreen',\n exitLabel: 'Exit Fullscreen',\n container: undefined!,\n onFullscreenChange: () => {}\n };\n\n className = 'deck-widget-fullscreen';\n placement: WidgetPlacement = 'top-left';\n fullscreen: boolean = false;\n\n constructor(props: FullscreenWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n onAdd(): void {\n document.addEventListener('fullscreenchange', this.onFullscreenChange.bind(this));\n }\n\n onRemove() {\n document.removeEventListener('fullscreenchange', this.onFullscreenChange.bind(this));\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const isFullscreen = this.getFullscreen();\n render(\n <IconButton\n onClick={() => {\n this.handleClick().catch(err => log.error(err)());\n }}\n label={isFullscreen ? this.props.exitLabel : this.props.enterLabel}\n className={isFullscreen ? 'deck-widget-fullscreen-exit' : 'deck-widget-fullscreen-enter'}\n />,\n rootElement\n );\n }\n\n setProps(props: Partial<FullscreenWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n getContainer() {\n return this.props.container || this.deck?.props.parent || this.deck?.getCanvas()?.parentElement;\n }\n\n getFullscreen(): boolean {\n return this.fullscreen;\n }\n\n onFullscreenChange() {\n const fullscreen = document.fullscreenElement === this.getContainer();\n if (fullscreen !== this.fullscreen) {\n this.fullscreen = fullscreen;\n this.props.onFullscreenChange?.(fullscreen);\n this.updateHTML();\n }\n }\n\n async handleClick() {\n const isFullscreen = this.getFullscreen();\n if (isFullscreen) {\n await this.exitFullscreen();\n } else {\n await this.requestFullscreen();\n }\n // Note: updateHTML is called by onFullscreenChange event handler\n }\n\n async requestFullscreen() {\n const container = this.getContainer();\n if (container?.requestFullscreen) {\n await container.requestFullscreen({navigationUI: 'hide'});\n } else {\n this.togglePseudoFullscreen();\n }\n }\n\n async exitFullscreen() {\n if (document.exitFullscreen) {\n await document.exitFullscreen();\n } else {\n this.togglePseudoFullscreen();\n }\n }\n\n togglePseudoFullscreen() {\n this.getContainer()?.classList.toggle('deck-pseudo-fullscreen');\n // No fullscreenchange event fires for pseudo-fullscreen, so manually update state\n this.fullscreen = !this.fullscreen;\n this.props.onFullscreenChange?.(this.fullscreen);\n this.updateHTML();\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {JSX, render} from 'preact';\nimport {useState, useRef, useEffect} from 'preact/hooks';\nimport {\n Widget,\n _deepEqual as deepEqual,\n type Deck,\n type WidgetProps,\n type View\n} from '@deck.gl/core';\n\nexport type ViewLayout = {\n /** Stacking orientation of the sub views */\n orientation: 'vertical' | 'horizontal';\n /** Initial instances that describe the sub views.\n * x, y, width and height of the views' props will be overwritten by the SplitterWidget as split changes. */\n views: [view1: View | ViewLayout, view2: View | ViewLayout];\n /** The ratio of view1's share over the whole available height (vertical) or width (horizontal). Between 0-1.\n * @default 0.5\n */\n initialSplit?: number;\n /** Whether the split can be changed by dragging the border between the two views.\n * @default true\n */\n editable?: boolean;\n /** Min value of the split\n * @default 0.05\n */\n minSplit?: number;\n /** Max value of the split\n * @default 0.95\n */\n maxSplit?: number;\n};\n\ntype ManagedViewLayout = {\n id: number;\n orientation: 'vertical' | 'horizontal';\n views: [view1: View | ManagedViewLayout, view2: View | ManagedViewLayout];\n split: number;\n editable: boolean;\n minSplit: number;\n maxSplit: number;\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\nfunction parseViewLayout(root: ViewLayout): ManagedViewLayout[] {\n const layoutsById: ManagedViewLayout[] = [];\n const isViewLayout = (v: View | ViewLayout): v is ViewLayout => 'views' in v;\n function createManagedViewLayout(l: ViewLayout): ManagedViewLayout {\n const id = layoutsById.length;\n const minSplit = l.minSplit ?? 0.05;\n const maxSplit = l.maxSplit ?? 0.95;\n const split = Math.min(Math.max(l.initialSplit ?? 0.5, minSplit), maxSplit);\n const managed: ManagedViewLayout = {\n id,\n orientation: l.orientation,\n views: l.views as [view1: View | ManagedViewLayout, view2: View | ManagedViewLayout],\n split,\n editable: l.editable ?? true,\n minSplit,\n maxSplit,\n x: 0,\n y: 0,\n width: 0,\n height: 0\n };\n layoutsById.push(managed);\n managed.views = [\n isViewLayout(l.views[0]) ? createManagedViewLayout(l.views[0]) : l.views[0],\n isViewLayout(l.views[1]) ? createManagedViewLayout(l.views[1]) : l.views[1]\n ];\n return managed;\n }\n createManagedViewLayout(root);\n return layoutsById;\n}\n\nfunction evaluateViews(root: ManagedViewLayout): View[] {\n const views: View[] = [];\n function evaluateViewLayout(\n l: ManagedViewLayout,\n x: number,\n y: number,\n width: number,\n height: number\n ) {\n l.x = x;\n l.y = y;\n l.width = width;\n l.height = height;\n\n const child1X = x;\n const child1Y = y;\n let child1Width = width;\n let child1Height = height;\n let child2X = x;\n let child2Y = y;\n let child2Width = width;\n let child2Height = height;\n\n if (l.orientation === 'horizontal') {\n child1Width = width * l.split;\n child2X = x + child1Width;\n child2Width = width - child1Width;\n } else {\n child1Height = height * l.split;\n child2Y = y + child1Height;\n child2Height = height - child1Height;\n }\n\n const [view1, view2] = l.views;\n if ('views' in view1) {\n evaluateViewLayout(view1, child1X, child1Y, child1Width, child1Height);\n } else {\n views.push(\n view1.clone({\n x: `${child1X}%`,\n y: `${child1Y}%`,\n width: `${child1Width}%`,\n height: `${child1Height}%`\n })\n );\n }\n\n if ('views' in view2) {\n evaluateViewLayout(view2, child2X, child2Y, child2Width, child2Height);\n } else {\n views.push(\n view2.clone({\n x: `${child2X}%`,\n y: `${child2Y}%`,\n width: `${child2Width}%`,\n height: `${child2Height}%`\n })\n );\n }\n }\n\n evaluateViewLayout(root, 0, 0, 100, 100);\n return views;\n}\n\n/** Properties for the SplitterWidget */\nexport type SplitterWidgetProps<ViewsT extends View[] = View[]> = WidgetProps & {\n /** Stacking views descriptor */\n viewLayout: ViewLayout;\n /** Callback invoked when the splitter is dragged with the new split value */\n onChange?: (views: ViewsT) => void;\n /** Callback invoked when dragging starts */\n onDragStart?: () => void;\n /** Callback invoked when dragging ends */\n onDragEnd?: () => void;\n};\n\n/**\n * A draggable splitter widget that appears as a vertical or horizontal line\n * across the deck.gl canvas. It positions itself based on the split percentage\n * of the first view and provides callbacks when dragged.\n */\nexport class SplitterWidget<ViewsT extends View[] = View[]> extends Widget<\n SplitterWidgetProps<ViewsT>,\n ViewsT\n> {\n static defaultProps: Required<SplitterWidgetProps> = {\n ...Widget.defaultProps,\n id: 'splitter-widget',\n viewLayout: undefined!,\n onChange: () => {},\n onDragStart: () => {},\n onDragEnd: () => {}\n };\n\n className = 'deck-widget-splitter';\n placement = 'fill' as const;\n viewLayouts!: ManagedViewLayout[];\n /** evaluated from the current viewLayouts */\n views!: ViewsT;\n /** views set in the last update */\n lastViews?: ViewsT;\n needsUpdate = true;\n\n constructor(props: SplitterWidgetProps<ViewsT>) {\n super(props);\n this.viewLayouts = parseViewLayout(this.props.viewLayout);\n }\n\n setProps(props: Partial<SplitterWidgetProps<ViewsT>>) {\n if (props.viewLayout && !deepEqual(props.viewLayout, this.props.viewLayout, -1)) {\n this.viewLayouts = parseViewLayout(props.viewLayout);\n this.views = undefined!;\n }\n super.setProps(props);\n }\n\n onRedraw() {\n // Actually update DOM\n super.updateHTML();\n }\n\n // Usually widgets rerender their DOM elements here\n // In this case we need the widget UI to synchronize with deck view states\n // so we update deck props here and rerender DOM in the next onRedraw\n updateHTML() {\n if (!this.views) {\n // viewLayouts has changed, re-evaluate\n this.views = evaluateViews(this.viewLayouts[0]) as ViewsT;\n // we send a copy to the callback so that externally set views can be differentiated from internal\n this.props.onChange(this.views.slice() as ViewsT);\n }\n // This method is called inside deck.setProps > widgetManager.setProps > widget.setProps\n // Calling deck.setProps immediately would cause infinite loop\n requestAnimationFrame(() => {\n this.doUpdate();\n });\n }\n\n private doUpdate() {\n if (this.deck) {\n const deckViews = this.deck.props.views;\n const isManagedExternally =\n // is not empty\n deckViews &&\n // is not set by us\n deckViews !== this.lastViews;\n\n if (!isManagedExternally && this.lastViews !== this.views) {\n this.lastViews = this.views;\n this.deck.setProps({views: this.views});\n }\n }\n }\n\n private onChange(newSplit: number, layout: ManagedViewLayout) {\n layout.split = newSplit;\n // layout has updated, re-evaluate\n this.views = evaluateViews(this.viewLayouts[0]) as ViewsT;\n // we send a copy to the callback so that externally set views can be differentiated from internal\n this.props.onChange(this.views.slice() as ViewsT);\n this.doUpdate();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <>\n {this.viewLayouts.map(\n layout =>\n layout.editable && (\n <Splitter\n {...layout}\n onChange={newSplit => this.onChange(newSplit, layout)}\n onDragStart={() => this.props.onDragStart()}\n onDragEnd={() => this.props.onDragStart()}\n />\n )\n )}\n </>,\n rootElement\n );\n }\n}\n\n/**\n * A functional component that renders a draggable splitter line.\n * It computes its position based on the provided split percentage and\n * updates it during mouse drag events.\n */\nfunction Splitter({\n orientation,\n x,\n y,\n width,\n height,\n split,\n minSplit,\n maxSplit,\n onChange,\n onDragStart,\n onDragEnd\n}: {\n orientation: 'vertical' | 'horizontal';\n x: number;\n y: number;\n width: number;\n height: number;\n split: number;\n minSplit: number;\n maxSplit: number;\n onChange?: (newSplit: number) => void;\n onDragStart?: () => void;\n onDragEnd?: () => void;\n}) {\n const [dragging, setDragging] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!dragging) {\n return undefined;\n }\n\n const handleDragging = (event: PointerEvent) => {\n if (!containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n let newSplit: number;\n if (orientation === 'horizontal') {\n newSplit = (event.clientX - rect.left) / rect.width;\n } else {\n newSplit = (event.clientY - rect.top) / rect.height;\n }\n // Clamp newSplit between 5% and 95%\n newSplit = Math.min(Math.max(newSplit, minSplit), maxSplit);\n onChange?.(newSplit);\n };\n\n const handleDragEnd = () => {\n onDragEnd?.();\n setDragging(false);\n };\n\n document.addEventListener('pointermove', handleDragging);\n document.addEventListener('pointerup', handleDragEnd);\n document.addEventListener('pointerleave', handleDragEnd);\n\n return () => {\n document.removeEventListener('pointermove', handleDragging);\n document.removeEventListener('pointerup', handleDragEnd);\n document.removeEventListener('pointerleave', handleDragEnd);\n };\n }, [dragging]);\n\n const handleDragStart = (event: PointerEvent) => {\n setDragging(true);\n onDragStart?.();\n event.preventDefault();\n };\n\n // The splitter line style based on orientation and the current split percentage.\n const splitterStyle: JSX.CSSProperties =\n orientation === 'horizontal' ? {left: `${split * 100}%`} : {top: `${split * 100}%`};\n\n // Container style to fill the entire deck.gl canvas.\n const containerStyle: JSX.CSSProperties = {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: `${width}%`,\n height: `${height}%`\n };\n\n return (\n <div ref={containerRef} style={containerStyle}>\n <div\n className={`deck-widget-splitter-handle deck-widget-splitter-handle--${orientation} ${dragging ? 'active' : ''}`}\n style={splitterStyle}\n onPointerDown={handleDragStart} // Use the appropriate Preact event type.\n />\n </div>\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, PickingInfo, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render, JSX} from 'preact';\nimport {Popover, type PopoverProps} from './lib/components/popover';\nimport {UserContent} from './lib/components/user-content';\n\nexport type TooltipContent = {\n /** Anchor of the popup in world coordinates, e.g. [longitude, latitude].\n * If not supplied, default to the mouse position where the popup was triggered.\n */\n position?: number[];\n /** Text content to display in the popup */\n text?: string;\n /** HTML content to display in the popup. If supplied, `text` is ignored. */\n html?: string;\n /** HTML element to attach inside the popup. */\n element?: HTMLElement | null;\n /** Custom class name to add to the popup */\n className?: string;\n /** CSS style overrides of the popup */\n style?: Partial<CSSStyleDeclaration>;\n};\n\nexport type InfoWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Determines the interaction mode of the widget */\n mode: 'click' | 'hover';\n /** Function to generate the popup contents from the selected element */\n getTooltip?: (\n info: PickingInfo,\n widget: InfoWidget\n ) => TooltipContent | string | null | undefined;\n /** Position popup relative to the anchor.\n * @default 'right'\n */\n placement?: PopoverProps['placement'];\n /** Pixel offset\n * @default 10\n */\n offset?: PopoverProps['offset'];\n /**\n * Show an arrow pointing at the anchor. Optionally accepts a pixel size.\n * @default 10\n */\n arrow?: PopoverProps['arrow'];\n};\n\nexport class InfoWidget extends Widget<InfoWidgetProps> {\n static defaultProps: Required<InfoWidgetProps> = {\n ...Widget.defaultProps,\n id: 'info',\n viewId: null,\n mode: 'hover',\n getTooltip: undefined!,\n placement: 'right',\n offset: 10,\n arrow: 10\n };\n\n className = 'deck-widget-info';\n placement = 'fill' as const;\n viewport?: Viewport;\n tooltip: Required<TooltipContent> | null = null;\n\n constructor(props: InfoWidgetProps) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<InfoWidgetProps>) {\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onAdd({deck}: {deck: Deck<any>; viewId: string | null}) {\n this.deck = deck;\n }\n\n onRemove() {\n // Invoke clean up of preact hooks\n if (this.rootElement) {\n render(null, this.rootElement);\n }\n }\n\n onViewportChange(viewport) {\n this.viewport = viewport;\n this.updateHTML();\n }\n\n onHover(info: PickingInfo): void {\n if (this.props.mode === 'hover') {\n this.tooltip = this._getTooltip(info);\n }\n }\n\n onClick(info: PickingInfo): void {\n if (this.props.mode === 'click') {\n this.tooltip = this._getTooltip(info);\n }\n }\n\n protected _getTooltip(info: PickingInfo): Required<TooltipContent> | null {\n if (!this.props.getTooltip) return null;\n\n const content = this.props.getTooltip(info, this) ?? null;\n if (content === null) return null;\n const normalizedTooltip: TooltipContent =\n typeof content === 'string' ? {text: content} : content;\n\n const position = normalizedTooltip.position || info.coordinate;\n if (!position) return null;\n\n return {\n position,\n text: '',\n html: '',\n element: null,\n className: '',\n style: {},\n ...normalizedTooltip\n };\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n if (!this.viewport || this.tooltip === null) {\n render(null, rootElement);\n return;\n }\n const style: Partial<CSSStyleDeclaration> = {\n ...this.props.style,\n ...this.tooltip.style\n };\n // Project the clicked geographic coordinate to canvas (x, y)\n const [x, y] = this.viewport.project(this.tooltip.position);\n\n // Render the popup container with a content box and a placeholder for the arrow.\n // The container is positioned absolutely (initially at 0,0) and will be repositioned after measuring.\n const ui = (\n <Popover\n x={x}\n y={y}\n placement={this.props.placement}\n arrow={this.props.arrow}\n arrowColor=\"var(--menu-background, #fff)\"\n offset={this.props.offset}\n >\n <UserContent\n className={`deck-widget-popup-content ${this.tooltip.className} ${this.props.className}`}\n style={style as JSX.CSSProperties}\n html={this.tooltip.html}\n text={this.tooltip.text}\n element={this.tooltip.element}\n />\n </Popover>\n );\n render(ui, rootElement);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport type {JSX, ComponentChildren} from 'preact';\nimport {useRef, useEffect, useMemo} from 'preact/hooks';\nimport {\n computePosition,\n flip,\n shift,\n offset,\n arrow,\n autoUpdate,\n type Placement,\n type ComputePositionConfig\n} from '@floating-ui/dom';\n\nexport type PopoverProps = {\n /** Anchor x */\n x: number;\n /** Anchor y */\n y: number;\n /** Position content relative to the anchor.\n * @default 'right'\n */\n placement?: Placement;\n /** Pixel offset\n * @default 0\n */\n offset?: number;\n /**\n * Show an arrow pointing at the anchor. Optionally accepts a pixel size.\n * @default false\n */\n arrow?: false | number | [width: number, height: number];\n /**\n * CSS color of the arrow\n * @default 'white'\n */\n arrowColor?: string;\n /** Content of the popover */\n children: ComponentChildren;\n};\n\nexport const Popover = ({\n x,\n y,\n placement = 'right',\n offset: pixelOffset = 0,\n arrow: arrowSize = false,\n arrowColor = 'white',\n children\n}: PopoverProps) => {\n const anchorRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const arrowRef = useRef<HTMLDivElement>(null);\n const updaterRef = useRef<() => void>();\n\n updaterRef.current = () => {\n if (!anchorRef.current || !contentRef.current) return;\n\n const arrowWidth = Array.isArray(arrowSize) ? arrowSize[0] : arrowSize || 0;\n const arrowHeight = Array.isArray(arrowSize) ? arrowSize[1] : arrowSize || 0;\n const padding = pixelOffset + Math.max(arrowHeight, arrowWidth);\n\n const middleware: ComputePositionConfig['middleware'] = placement.includes('-')\n ? [offset(padding), flip(), shift()]\n : [offset(padding), shift(), flip()];\n if (arrowRef.current) middleware.push(arrow({element: arrowRef.current}));\n computePosition(anchorRef.current, contentRef.current, {\n placement,\n strategy: 'fixed',\n middleware\n }).then(popoverPos => {\n if (contentRef.current) {\n Object.assign(contentRef.current.style, {\n left: `${popoverPos.x}px`,\n top: `${popoverPos.y}px`\n });\n }\n\n const arrowData = popoverPos.middlewareData.arrow;\n if (arrowData && arrowRef.current) {\n const arrowStyle = createArrow(arrowWidth, arrowHeight, arrowColor, popoverPos.placement);\n arrowStyle.transform = `translate(${arrowData.x || 0}px, ${arrowData.y || 0}px)`;\n Object.assign(arrowRef.current.style, arrowStyle);\n }\n });\n };\n\n useMemo(() => {\n updaterRef.current?.();\n }, [x, y, placement, arrowSize, pixelOffset]);\n\n useEffect(() => {\n // initial mount\n const anchor = anchorRef.current;\n const content = contentRef.current;\n if (!anchor || !content) {\n return undefined;\n }\n content.style.visibility = 'visible';\n const cleanup = autoUpdate(anchor, content, () => updaterRef.current?.());\n return () => {\n cleanup();\n };\n }, []);\n\n return (\n <div style={{position: 'absolute', left: x, top: y}} ref={anchorRef}>\n <div\n className=\"deck-widget deck-widget-popover\"\n style={{position: 'fixed', visibility: 'hidden', pointerEvents: 'none'}}\n ref={contentRef}\n >\n {Boolean(arrowSize) && (\n <div\n className=\"deck-widget-popover-arrow\"\n style={{position: 'absolute'}}\n ref={arrowRef}\n />\n )}\n {children}\n </div>\n </div>\n );\n};\n\nfunction createArrow(\n width: number,\n height: number,\n color: string,\n placement: Placement\n): JSX.CSSProperties {\n const result: JSX.CSSProperties = {\n width: 0,\n height: 0,\n top: '',\n bottom: '',\n left: '',\n right: ''\n };\n if (placement.startsWith('bottom')) {\n result.borderLeft = `${width / 2}px solid transparent`;\n result.borderRight = `${width / 2}px solid transparent`;\n result.borderBottom = `${height}px solid ${color}`;\n result.borderTop = '';\n result.top = `${-height}px`;\n } else if (placement.startsWith('top')) {\n result.borderLeft = `${width / 2}px solid transparent`;\n result.borderRight = `${width / 2}px solid transparent`;\n result.borderTop = `${height}px solid ${color}`;\n result.borderBottom = '';\n result.bottom = `${-height}px`;\n } else if (placement.startsWith('right')) {\n result.borderTop = `${width / 2}px solid transparent`;\n result.borderBottom = `${width / 2}px solid transparent`;\n result.borderRight = `${height}px solid ${color}`;\n result.borderLeft = '';\n result.left = `${-height}px`;\n } else if (placement.startsWith('left')) {\n result.borderTop = `${width / 2}px solid transparent`;\n result.borderBottom = `${width / 2}px solid transparent`;\n result.borderLeft = `${height}px solid ${color}`;\n result.borderRight = '';\n result.right = `${-height}px`;\n }\n return result;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport type {JSX, ComponentChildren} from 'preact';\nimport {useEffect, useRef} from 'preact/hooks';\n\nexport type UserContentProps = JSX.HTMLAttributes<HTMLDivElement> & {\n text?: string;\n html?: string;\n element?: HTMLElement | null;\n};\n\nexport const UserContent = ({text, html, element, ...props}: UserContentProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (containerRef.current && element) {\n containerRef.current.append(element);\n }\n return () => {\n element?.remove();\n };\n }, [element]);\n\n return (\n <div ref={containerRef} {...props} dangerouslySetInnerHTML={html ? {__html: html} : undefined}>\n {text}\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render, JSX} from 'preact';\nimport {Popover, type PopoverProps} from './lib/components/popover';\nimport {UserContent} from './lib/components/user-content';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type PopupContent = {\n text?: string;\n html?: string;\n element?: HTMLElement | null;\n};\n\nexport type PopupWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Content to display at the anchor. Opens the popup if clicked. */\n marker?: PopupContent | null;\n /** Content to display in the popup */\n content: string | PopupContent;\n /** Whether the pop up is open by default\n * @default true\n */\n defaultIsOpen?: boolean;\n /** Anchor of the popup in world coordinates, e.g. [longitude, latitude]. */\n position: number[];\n /** Position popup relative to the anchor.\n * @default 'right'\n */\n placement?: PopoverProps['placement'];\n /** Pixel offset\n * @default 10\n */\n offset?: PopoverProps['offset'];\n /**\n * Show an arrow pointing at the anchor. Optionally accepts a pixel size.\n * @default 10\n */\n arrow?: PopoverProps['arrow'];\n /** Whether to show a close button in the popup\n * @default true\n */\n closeButton?: boolean;\n /** Close the popup if clicked outside\n * @default false\n */\n closeOnClickOutside?: boolean;\n /** Callback when popup is opened/closed */\n onOpenChange?: (isOpen: boolean) => void;\n};\n\nexport class PopupWidget extends Widget<PopupWidgetProps> {\n static defaultProps: Required<PopupWidgetProps> = {\n ...Widget.defaultProps,\n id: 'info',\n viewId: null,\n position: [0, 0],\n marker: null,\n defaultIsOpen: true,\n content: '',\n placement: 'right',\n offset: 10,\n arrow: 10,\n closeButton: true,\n closeOnClickOutside: false,\n onOpenChange: () => {}\n };\n\n className = 'deck-widget-popup';\n placement = 'fill' as const;\n viewport?: Viewport;\n isOpen: boolean;\n\n constructor(props: PopupWidgetProps) {\n super(props);\n this.setProps(this.props);\n this.isOpen = this.props.defaultIsOpen;\n }\n\n setProps(props: Partial<PopupWidgetProps>) {\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onAdd({deck}: {deck: Deck<any>; viewId: string | null}) {\n this.deck = deck;\n }\n\n onRemove() {\n // Invoke clean up of preact hooks\n if (this.rootElement) {\n render(null, this.rootElement);\n }\n }\n\n onViewportChange(viewport) {\n this.viewport = viewport;\n this.updateHTML();\n }\n\n onClick() {\n if (this.props.closeOnClickOutside) {\n this._setIsOpen(false);\n }\n }\n\n protected _setIsOpen(isOpen: boolean) {\n if (this.isOpen === isOpen) return;\n this.isOpen = isOpen;\n this.props.onOpenChange?.(isOpen);\n this.updateHTML();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n if (!this.viewport) {\n render(null, rootElement);\n return;\n }\n const {marker, content, style} = this.props;\n // Project the clicked geographic coordinate to canvas (x, y)\n const [x, y] = this.viewport.project(this.props.position);\n\n // Render the popup container with a content box and a placeholder for the arrow.\n // The container is positioned absolutely (initially at 0,0) and will be repositioned after measuring.\n const ui = (\n <div>\n {marker && (\n <div className=\"deck-widget-popup-marker\" style={{left: x, top: y}}>\n <UserContent {...marker} onClick={() => this._setIsOpen(true)} />\n </div>\n )}\n {this.isOpen && (\n <Popover\n x={x}\n y={y}\n placement={this.props.placement}\n arrow={this.props.arrow}\n arrowColor=\"var(--menu-background, #fff)\"\n offset={this.props.offset}\n >\n <div\n className={`deck-widget-popup-content ${this.props.className}`}\n style={style as JSX.CSSProperties}\n >\n {this.props.closeButton && (\n <div\n className=\"deck-widget-popup-controls\"\n style={{width: '100%', display: 'flex', justifyContent: 'end'}}\n >\n <IconButton\n className=\"deck-widget-popup-close-button\"\n onClick={() => this._setIsOpen(false)}\n />\n </div>\n )}\n <UserContent {...(typeof content === 'string' ? {text: content} : content)} />\n </div>\n </Popover>\n )}\n </div>\n );\n render(ui, rootElement);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, PickingInfo, WidgetProps} from '@deck.gl/core';\nimport {render, type JSX} from 'preact';\nimport {SimpleMenu, type MenuItem} from './lib/components/dropdown-menu';\nimport {Popover, type PopoverProps} from './lib/components/popover';\n\nexport type ContextMenuWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Menu items for the menu. */\n menuItems?: MenuItem[];\n /** Callback to provide menu items for the menu given the picked object. Overrides `menuItems` */\n getMenuItems?: (info: PickingInfo, widget: ContextMenuWidget) => MenuItem[] | null;\n /** Callback when a menu item is selected */\n onMenuItemSelected?: (value: string, pickInfo: PickingInfo | null) => void;\n /** Position menu relative to the anchor.\n * @default 'bottom-start'\n */\n placement?: PopoverProps['placement'];\n /** Pixel offset\n * @default 10\n */\n offset?: PopoverProps['offset'];\n /**\n * Show an arrow pointing at the anchor. Optionally accepts a pixel size.\n * @default false\n */\n arrow?: PopoverProps['arrow'];\n};\n\nexport class ContextMenuWidget extends Widget<ContextMenuWidgetProps> {\n static defaultProps: Required<ContextMenuWidgetProps> = {\n ...Widget.defaultProps,\n id: 'context',\n viewId: null,\n menuItems: [],\n getMenuItems: undefined!,\n onMenuItemSelected: () => {},\n placement: 'bottom-start',\n offset: 10,\n arrow: false\n };\n\n className = 'deck-widget-context-menu';\n placement = 'fill' as const;\n\n menu: {\n items: MenuItem[];\n pickInfo: PickingInfo;\n } | null = null;\n\n constructor(props: ContextMenuWidgetProps) {\n super(props);\n this.setProps(this.props);\n }\n\n onAdd({deck}: {deck: Deck<any>}) {\n deck.getCanvas()?.addEventListener('contextmenu', event => this.handleContextMenu(event));\n }\n\n handleContextMenu(srcEvent: MouseEvent) {\n const targetRect = (srcEvent.target as HTMLElement).getBoundingClientRect();\n const x = srcEvent.clientX - targetRect.x;\n const y = srcEvent.clientY - targetRect.y;\n\n const pickInfo = this.deck?.pickObject({x, y}) || {\n x,\n y,\n picked: false,\n layer: null,\n color: null,\n index: -1,\n pixelRatio: 1\n };\n const menuItems = this.props.getMenuItems?.(pickInfo, this) || this.props.menuItems;\n this.menu =\n menuItems.length > 0\n ? {\n items: menuItems,\n pickInfo\n }\n : null;\n srcEvent.preventDefault();\n this.updateHTML();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n if (!this.menu) {\n render(null, rootElement);\n return;\n }\n const {items, pickInfo} = this.menu;\n\n const style = {\n pointerEvents: 'auto',\n position: 'static',\n ...this.props.style\n };\n\n const ui = (\n <Popover\n x={pickInfo.x}\n y={pickInfo.y}\n placement={this.props.placement}\n arrow={this.props.arrow}\n arrowColor=\"var(--menu-background, #fff)\"\n offset={this.props.offset}\n >\n <SimpleMenu\n menuItems={items}\n onSelect={value => this.props.onMenuItemSelected(value, pickInfo)}\n style={style}\n isOpen\n onClose={() => this.hide()}\n />\n </Popover>\n );\n render(ui, rootElement);\n }\n\n hide() {\n this.menu = null;\n this.updateHTML();\n }\n}\n", "import {Widget} from '@deck.gl/core';\nimport type {Position, Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {RangeInput, type RangeInputDecoration} from './lib/components/range-input';\n\nexport type ScrollbarOrientation = 'vertical' | 'horizontal';\n\nexport type ContentBounds = [min: Position, max: Position];\n\nexport type ScrollbarDecoration = {\n contentBounds: ContentBounds;\n color: string;\n title?: string;\n /** Callback when the decoration is clicked. Return `true` to mark the event as handled, and prevent the default behavior. */\n onClick?: (evt: MouseEvent) => boolean;\n};\n\nconst clamp = (value: number, min: number, max: number) => {\n if (value < min) {\n return min;\n }\n if (value > max) {\n return max;\n }\n return value;\n};\n\nexport type ScrollbarWidgetProps = WidgetProps & {\n /** The full extent of the scrollable content, in world coordinates.\n * The widget relies on this value to calculate the position and size of the slider button and track.\n * If not supplied, the scrollbar will always be hidden.\n */\n contentBounds?: ContentBounds | null;\n placement?: WidgetPlacement;\n viewId?: string | null;\n /** Direction of the scrollbar. `'horizontal'` scrolls the camera along the X axis, and `'vertical'` scrolls the camera along the Y axis.\n * @default 'vertical'\n */\n orientation?: ScrollbarOrientation;\n /* Pixels scrolled when clicked on the step buttons.\n * @default 1/10 of the viewport size\n */\n stepSize?: number | null;\n /* Pixels scrolled when clicked on the track.\n * @default 100% of the viewport size\n */\n pageSize?: number | null;\n /** Label of the step button at the start.\n * @default 'Scroll left' | 'Scroll up'\n */\n startButtonAriaLabel?: string;\n /** Label of the end button at the start.\n * @default 'Scroll right' | 'Scroll down'\n */\n endButtonAriaLabel?: string;\n /** If `true`, mouse wheel events over the canvas will be intercepted by this scrollbar.\n * Useful when simulating the native scrollbar's behavior.\n * @default false\n */\n captureWheel?: boolean;\n /** Custom markers to overlay on the track. */\n decorations?: ScrollbarDecoration[];\n};\n\ntype ScrollbarWidgetRequiredProps = Required<ScrollbarWidgetProps>;\n\n/** A scrollbar widget to be used with OrthographicView */\nexport class ScrollbarWidget extends Widget<ScrollbarWidgetProps> {\n static override defaultProps: ScrollbarWidgetRequiredProps = {\n ...Widget.defaultProps,\n contentBounds: null,\n placement: 'top-right',\n viewId: null,\n orientation: 'vertical',\n stepSize: null,\n pageSize: null,\n startButtonAriaLabel: '',\n endButtonAriaLabel: '',\n captureWheel: false,\n decorations: []\n };\n\n override className = 'deck-widget-scrollbar';\n\n placement: WidgetPlacement = 'fill';\n\n private viewport?: Viewport;\n private contentSize = 0;\n private viewportSize = 0;\n private scrollOffset = 0;\n\n constructor(props: ScrollbarWidgetProps) {\n const resolved = {\n ...ScrollbarWidget.defaultProps,\n ...props\n } as ScrollbarWidgetRequiredProps;\n super(resolved);\n this.viewId = resolved.viewId ?? null;\n }\n\n override onViewportChange(viewport: Viewport) {\n this.viewport = viewport;\n this.onRenderHTML();\n }\n\n override onRenderHTML(): void {\n const element = this.rootElement;\n if (!element) {\n return;\n }\n\n element.dataset.placement = this.props.placement;\n const viewport = this.viewport;\n this.updateViewport(viewport);\n\n const clampedOffset = this.getClampedOffset();\n const wheelTarget = this.getWheelEventTarget(this.props.captureWheel ? 'global' : 'local');\n const decorations = this.getDecorations(viewport);\n const isVertical = this.isVertical();\n const startLabel =\n this.props.startButtonAriaLabel ?? (isVertical ? 'Scroll up' : 'Scroll left');\n const endLabel = this.props.endButtonAriaLabel ?? (isVertical ? 'Scroll down' : 'Scroll right');\n\n const ui = (\n <RangeInput\n min={0}\n max={Math.max(0, this.contentSize)}\n step={this.getEffectiveStep()}\n pageSize={this.getEffectivePage()}\n value={[clampedOffset, clampedOffset + this.viewportSize]}\n orientation={this.props.orientation}\n stepButtons\n startButtonAriaLabel={startLabel}\n endButtonAriaLabel={endLabel}\n eventTarget={wheelTarget}\n decorations={decorations}\n onChange={this.handleRangeChange}\n />\n );\n\n render(ui, element);\n }\n\n override onRemove(): void {\n if (this.rootElement) {\n render(null, this.rootElement);\n }\n super.onRemove();\n }\n\n private getContentBounds(viewId: string): ContentBounds | null {\n return this.props.contentBounds ?? this.deck?.getView(viewId)?.controller?.maxBounds ?? null;\n }\n\n private updateViewport(viewport?: Viewport): void {\n if (!viewport) {\n this.contentSize = 0;\n this.scrollOffset = 0;\n this.viewportSize = 0;\n return;\n }\n\n const contentBounds = this.getContentBounds(viewport.id);\n const isVertical = this.isVertical();\n const projectedBounds = contentBounds\n ? projectBounds(contentBounds, viewport, isVertical)\n : ([0, 0] as [number, number]);\n\n this.contentSize = projectedBounds[1] - projectedBounds[0];\n this.scrollOffset = -projectedBounds[0];\n this.viewportSize = isVertical ? viewport.height : viewport.width;\n }\n\n private getDecorations(viewport?: Viewport): RangeInputDecoration[] {\n const {decorations = []} = this.props;\n if (!viewport || decorations.length === 0) {\n return [];\n }\n const contentBounds = this.getContentBounds(viewport.id);\n if (!contentBounds) {\n return [];\n }\n\n const isVertical = this.isVertical();\n const [contentStart] = projectBounds(contentBounds, viewport, isVertical);\n\n return decorations.map(decoration => {\n const [start, end] = projectBounds(decoration.contentBounds, viewport, isVertical);\n const onClick = decoration.onClick\n ? (e: MouseEvent) => {\n const handled = decoration.onClick?.(e);\n if (handled) {\n e.stopPropagation();\n e.preventDefault();\n }\n }\n : undefined;\n return {\n position: [start - contentStart, end - contentStart],\n element: (\n <div\n style={{\n pointerEvents: onClick ? 'all' : 'none',\n width: '100%',\n height: '100%',\n backgroundColor: decoration.color\n }}\n title={decoration.title}\n onClick={onClick}\n />\n )\n };\n });\n }\n\n private getWheelEventTarget(mode: 'global' | 'local' | null) {\n if (mode === null) return null;\n if (mode === 'local') return this.rootElement;\n\n return this.deck?.props.parent || this.deck?.getCanvas()?.parentElement || this.rootElement;\n }\n\n private getMaxScroll(): number {\n return Math.max(0, this.contentSize - this.viewportSize);\n }\n\n private getClampedOffset(): number {\n const maxScroll = this.getMaxScroll();\n return clamp(this.scrollOffset, 0, maxScroll);\n }\n\n private isVertical(): boolean {\n return this.props.orientation !== 'horizontal';\n }\n\n private getEffectiveStep(): number {\n if (typeof this.props.stepSize === 'number' && !Number.isNaN(this.props.stepSize)) {\n return this.props.stepSize;\n }\n return Math.max(1, this.viewportSize / 10 || 1);\n }\n\n private getEffectivePage(): number {\n if (typeof this.props.pageSize === 'number' && !Number.isNaN(this.props.pageSize)) {\n return this.props.pageSize;\n }\n return this.viewportSize;\n }\n\n private emitScroll(next: number): void {\n const maxScroll = this.getMaxScroll();\n const target = clamp(Math.round(next), 0, maxScroll);\n const viewport = this.viewport;\n if (viewport && target !== this.getClampedOffset()) {\n const pixel = viewport.project(viewport.position) as [number, number];\n if (this.isVertical()) {\n pixel[1] -= target - this.scrollOffset;\n } else {\n pixel[0] -= target - this.scrollOffset;\n }\n const {target: newTarget} = viewport.panByPosition(viewport.position, pixel);\n\n // @ts-expect-error Using private method temporary until there's a public one\n this.deck._onViewStateChange({\n viewId: viewport.id,\n viewState: {\n ...this.getViewState(viewport.id),\n target: newTarget\n },\n interactionState: {}\n });\n }\n }\n\n private handleRangeChange = (nextValue: [number, number]) => {\n this.emitScroll(nextValue[0]);\n };\n}\n\nfunction projectBounds(\n bounds: ContentBounds,\n viewport: Viewport,\n isVertical: boolean\n): [min: number, max: number] {\n return bounds\n .map(([x, y]) => viewport.project([x, y, 0]))\n .reduce(\n (range: [number, number], [x, y]) => {\n const value = isVertical ? y : x;\n range[0] = Math.min(range[0], value);\n range[1] = Math.max(range[1], value);\n return range;\n },\n [Infinity, -Infinity]\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport type {JSX} from 'preact';\nimport {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'preact/hooks';\n\nexport type RangeInputDecoration = {\n position: [start: number, end: number];\n element: JSX.Element;\n};\n\nexport type RangeInputProps = {\n className?: string;\n min: number;\n max: number;\n step: number;\n value: [start: number, end: number];\n orientation: 'horizontal' | 'vertical';\n pageSize?: number;\n /** Show step buttons at ends */\n stepButtons?: boolean;\n startButtonAriaLabel?: string;\n endButtonAriaLabel?: string;\n /** Target element for wheel and keyboard events.\n * If not supplied, falls back to the root element of the input.\n */\n eventTarget?: HTMLElement | null;\n decorations?: RangeInputDecoration[];\n onChange?: (nextValue: [start: number, end: number]) => void;\n};\n\ntype DragState = {\n pointerId: number;\n startCoord: number;\n startRatio: number;\n min: number;\n max: number;\n maxStart: number;\n};\n\nconst wheelListenerOptions: AddEventListenerOptions = {passive: false};\n\nconst clamp = (value: number, min: number, max: number) => {\n if (value < min) {\n return min;\n }\n if (value > max) {\n return max;\n }\n return value;\n};\n\nconst getTrackDimension = (track: HTMLDivElement | null, vertical: boolean) => {\n if (!track || !track.firstElementChild) {\n return [0, 0];\n }\n const rect = track.firstElementChild.getBoundingClientRect();\n if (vertical) {\n return [rect.top, rect.height];\n }\n return vertical ? [rect.top, rect.height] : [rect.left, rect.width];\n};\n\nconst getEffectiveStep = (step: number, range: number) => {\n if (typeof step === 'number' && !Number.isNaN(step) && step > 0) {\n return step;\n }\n return Math.max(1, range / 10 || 1);\n};\n\nconst getEffectivePage = (pageSize: number | undefined, rangeSize: number) => {\n if (typeof pageSize === 'number' && !Number.isNaN(pageSize) && pageSize > 0) {\n return pageSize;\n }\n return Math.max(1, rangeSize || 1);\n};\n\nexport function RangeInput(props: RangeInputProps) {\n const {\n className = '',\n min,\n max,\n step,\n value,\n orientation,\n pageSize,\n stepButtons = false,\n startButtonAriaLabel,\n endButtonAriaLabel,\n eventTarget,\n decorations = [],\n onChange\n } = props;\n\n const vertical = orientation !== 'horizontal';\n const rootRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const thumbRef = useRef<HTMLDivElement>(null);\n const dragStateRef = useRef<DragState | null>(null);\n const [trackLength, setTrackLength] = useState(0);\n\n const range = max - min;\n const rangeSize = Math.max(0, value[1] - value[0]);\n const maxStart = Math.max(0, range - rangeSize);\n const clampedStart = clamp(value[0], min, min + maxStart);\n\n const {thumbLength, thumbOffset} = useMemo(() => {\n if (trackLength <= 0 || range <= 0) {\n return {thumbLength: 0, thumbOffset: 0};\n }\n\n if (range <= rangeSize) {\n return {thumbLength: 1, thumbOffset: 0};\n }\n\n const nextThumbLength = rangeSize / range;\n const travel = Math.max(0, 1 - nextThumbLength);\n const ratio = maxStart <= 0 ? 0 : clamp((clampedStart - min) / maxStart, 0, 1);\n\n return {\n thumbLength: Math.max(0, Math.min(nextThumbLength, 1)),\n thumbOffset: travel * ratio\n };\n }, [trackLength, range, rangeSize, maxStart, clampedStart, min]);\n\n const emitRange = useCallback(\n (nextStart: number) => {\n if (!onChange) {\n return;\n }\n const clamped = clamp(nextStart, min, min + maxStart);\n onChange([clamped, clamped + rangeSize]);\n },\n [onChange, min, maxStart, rangeSize]\n );\n\n const handleStepNegative = useCallback(\n (event: MouseEvent) => {\n event.stopPropagation();\n emitRange(clampedStart - getEffectiveStep(step, range));\n },\n [emitRange, clampedStart, step, range]\n );\n\n const handleStepPositive = useCallback(\n (event: MouseEvent) => {\n event.stopPropagation();\n emitRange(clampedStart + getEffectiveStep(step, range));\n },\n [emitRange, clampedStart, step, range]\n );\n\n const handleTrackClick = useCallback(\n (event: MouseEvent) => {\n if (event.button !== 0) {\n return;\n }\n const target = event.target as HTMLElement | null;\n if (target?.dataset.scrollbarThumb === 'true') {\n return;\n }\n\n const track = trackRef.current;\n if (!track) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n const [trackStart] = getTrackDimension(track, vertical);\n const coordinate = vertical ? event.clientY - trackStart : event.clientX - trackStart;\n const span = Math.max(1, 1 - thumbLength) * trackLength;\n const thumbCenter = (thumbLength / 2) * trackLength;\n const ratio = span <= 0 ? 0 : clamp((coordinate - thumbCenter) / span, 0, 1);\n emitRange(min + ratio * maxStart);\n },\n [vertical, trackLength, thumbLength, emitRange, min, maxStart]\n );\n\n const handleThumbPointerDown = (event: PointerEvent) => {\n if (event.button !== 0) {\n return;\n }\n const track = trackRef.current;\n if (!track) {\n return;\n }\n\n dragStateRef.current = {\n pointerId: event.pointerId,\n startCoord: vertical ? event.clientY : event.clientX,\n startRatio: thumbOffset,\n min,\n max,\n maxStart\n };\n\n (event.currentTarget as HTMLDivElement).setPointerCapture(event.pointerId);\n event.preventDefault();\n event.stopPropagation();\n };\n\n const handleThumbPointerMove = useCallback(\n (event: PointerEvent) => {\n const state = dragStateRef.current;\n if (!state || state.pointerId !== event.pointerId) {\n return;\n }\n\n const [trackStart, trackLength] = getTrackDimension(trackRef.current, vertical);\n const coordinate = vertical ? event.clientY : event.clientX;\n const delta = coordinate - state.startCoord;\n\n const ratio = state.startRatio + delta / trackLength;\n\n const nextStart = clamp(ratio * (state.max - state.min), 0, state.maxStart) + state.min;\n emitRange(nextStart);\n event.preventDefault();\n },\n [emitRange, vertical]\n );\n\n const handleThumbPointerUp = useCallback((event: PointerEvent) => {\n const state = dragStateRef.current;\n if (state && state.pointerId === event.pointerId) {\n dragStateRef.current = null;\n thumbRef.current?.releasePointerCapture(event.pointerId);\n event.preventDefault();\n }\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowUp':\n case 'ArrowLeft':\n if ((vertical && event.key === 'ArrowUp') || (!vertical && event.key === 'ArrowLeft')) {\n emitRange(clampedStart - getEffectiveStep(step, range));\n event.preventDefault();\n }\n break;\n case 'ArrowDown':\n case 'ArrowRight':\n if (\n (vertical && event.key === 'ArrowDown') ||\n (!vertical && event.key === 'ArrowRight')\n ) {\n emitRange(clampedStart + getEffectiveStep(step, range));\n event.preventDefault();\n }\n break;\n case 'PageUp':\n emitRange(clampedStart - getEffectivePage(pageSize, rangeSize));\n event.preventDefault();\n break;\n case 'PageDown':\n emitRange(clampedStart + getEffectivePage(pageSize, rangeSize));\n event.preventDefault();\n break;\n case 'Home':\n emitRange(min);\n event.preventDefault();\n break;\n case 'End':\n emitRange(min + maxStart);\n event.preventDefault();\n break;\n default:\n break;\n }\n },\n [vertical, emitRange, clampedStart, step, range, pageSize, rangeSize, min, maxStart]\n );\n\n const handleWheel = useCallback(\n (event: WheelEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n if (maxStart === 0) {\n return;\n }\n\n let delta = vertical ? event.deltaY : event.deltaX;\n if (!vertical && delta === 0) {\n delta = event.deltaY;\n }\n\n if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n delta *= getEffectiveStep(step, range);\n } else if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n delta *= getEffectivePage(pageSize, rangeSize);\n }\n\n if (delta === 0) {\n return;\n }\n\n emitRange(clampedStart + delta);\n },\n [emitRange, clampedStart, maxStart, vertical, step, range, pageSize, rangeSize]\n );\n\n useLayoutEffect(() => {\n setTrackLength(getTrackDimension(trackRef.current, vertical)[1]);\n }, [vertical]);\n\n useLayoutEffect(() => {\n const track = trackRef.current;\n if (!track) {\n return undefined;\n }\n\n const update = () => {\n setTrackLength(getTrackDimension(track, vertical)[1]);\n };\n\n update();\n\n if (typeof ResizeObserver !== 'undefined') {\n const observer = new ResizeObserver(update);\n observer.observe(track);\n return () => observer.disconnect();\n }\n\n if (typeof window !== 'undefined') {\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }\n\n return undefined;\n }, [vertical]);\n\n useEffect(() => {\n const eventRoot = eventTarget ?? rootRef.current;\n if (!eventRoot) return undefined;\n\n eventRoot.addEventListener('keydown', handleKeyDown);\n eventRoot.addEventListener('wheel', handleWheel, wheelListenerOptions);\n return () => {\n eventRoot.removeEventListener('keydown', handleKeyDown);\n eventRoot.removeEventListener('wheel', handleWheel, wheelListenerOptions);\n };\n }, [eventTarget, handleKeyDown, handleWheel]);\n\n const decorationElements = useMemo(() => {\n if (!decorations.length || range <= 0) {\n return [];\n }\n\n return decorations.map((decoration, index) => {\n const [start, end] = decoration.position;\n const startRatio = (start - min) / range;\n const endRatio = (end - min) / range;\n const offsetPct = Math.round(startRatio * 1000) / 10;\n const sizePct = Math.max(0, Math.round((endRatio - startRatio) * 1000) / 10);\n const style = vertical\n ? {\n left: '0',\n width: '100%',\n top: `${offsetPct}%`,\n height: `${sizePct}%`\n }\n : {\n top: '0',\n height: '100%',\n left: `${offsetPct}%`,\n width: `${sizePct}%`\n };\n\n return (\n <div key={`decoration-${index}`} className=\"deck-widget-range__decoration\" style={style}>\n {decoration.element}\n </div>\n );\n });\n }, [decorations, range, min, vertical]);\n\n return (\n <div\n ref={rootRef}\n tabIndex={0}\n role=\"scrollbar\"\n aria-valuemin={min}\n aria-valuemax={min + maxStart}\n aria-valuenow={clampedStart}\n aria-orientation={orientation}\n className={`${className} deck-widget-range deck-widget-range--${orientation} ${maxStart === 0 ? 'deck-widget-range--disabled' : ''}`}\n >\n {stepButtons && (\n <button\n type=\"button\"\n className=\"deck-widget-range__button deck-widget-range__button--start\"\n aria-label={startButtonAriaLabel}\n disabled={clampedStart <= min}\n onClick={handleStepNegative}\n >\n <span className=\"deck-widget-icon\" />\n </button>\n )}\n <div className=\"deck-widget-range__track\" ref={trackRef} onClick={handleTrackClick}>\n <div className=\"deck-widget-range__decorations\">{decorationElements}</div>\n <div\n className=\"deck-widget-range__thumb\"\n data-scrollbar-thumb=\"true\"\n ref={thumbRef}\n style={\n vertical\n ? {height: `${thumbLength * 100}%`, top: `${thumbOffset * 100}%`}\n : {width: `${thumbLength * 100}%`, left: `${thumbOffset * 100}%`}\n }\n onPointerDown={handleThumbPointerDown}\n onPointerMove={handleThumbPointerMove}\n onPointerUp={handleThumbPointerUp}\n onPointerCancel={handleThumbPointerUp}\n />\n </div>\n {stepButtons && (\n <button\n type=\"button\"\n className=\"deck-widget-range__button deck-widget-range__button--end\"\n aria-label={endButtonAriaLabel}\n disabled={clampedStart >= min + maxStart}\n onClick={handleStepPositive}\n >\n <span className=\"deck-widget-icon\" />\n </button>\n )}\n </div>\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render, type JSX} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type IconWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Data url to display as icon */\n icon: string;\n /** Tooltip label */\n label?: string;\n /** Icon color, a CSS Color string */\n color?: string;\n /** Callback when the widget is clicked */\n onClick?: () => void;\n};\n\n/**\n * A generic widget that displays a button with icon or text content.\n */\nexport class IconWidget extends Widget<IconWidgetProps> {\n static defaultProps: Required<IconWidgetProps> = {\n ...Widget.defaultProps,\n id: 'icon',\n placement: 'top-left',\n viewId: null,\n icon: '',\n label: '',\n color: '',\n onClick: undefined!\n };\n\n className = '';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: IconWidgetProps) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<IconWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {className, style, icon, color, label, onClick} = this.props;\n\n render(\n <IconButton\n className={className}\n style={style as JSX.CSSProperties}\n color={color}\n icon={icon}\n label={label}\n onClick={onClick}\n />,\n rootElement\n );\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render, type JSX} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type ToggleWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** If the toggle is checked when first added */\n initialChecked?: boolean;\n /** Data url to display as icon */\n icon: string;\n /** Data url to display as icon when it is checked */\n onIcon?: string;\n /** Tooltip label */\n label?: string;\n /** Tooltip label when it is checked */\n onLabel?: string;\n /** Icon color, a CSS Color string */\n color?: string;\n /** Icon color when it is checked, a CSS Color string */\n onColor?: string;\n /** Callback when the widget is clicked */\n onChange?: (checked: boolean) => void;\n};\n\n/**\n * A generic widget that displays a button with icon or text content.\n */\nexport class ToggleWidget extends Widget<ToggleWidgetProps> {\n static defaultProps: Required<ToggleWidgetProps> = {\n ...Widget.defaultProps,\n id: 'icon',\n placement: 'top-left',\n viewId: null,\n initialChecked: false,\n icon: '',\n onIcon: undefined!,\n label: '',\n onLabel: undefined!,\n color: '',\n onColor: undefined!,\n onChange: undefined!\n };\n\n className = 'deck-widget-toggle';\n placement: WidgetPlacement = 'top-left';\n checked: boolean;\n\n constructor(props: ToggleWidgetProps) {\n super(props);\n this.checked = this.props.initialChecked;\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ToggleWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {\n className,\n style,\n icon,\n label,\n color,\n onIcon = icon,\n onLabel = label,\n onColor = color\n } = this.props;\n const on = this.checked;\n\n rootElement.dataset.checked = String(on);\n\n render(\n <IconButton\n className={className}\n style={style as JSX.CSSProperties}\n icon={on ? onIcon : icon}\n label={on ? onLabel : label}\n color={on ? onColor : color}\n onClick={this._toggle}\n />,\n rootElement\n );\n }\n\n private _toggle = () => {\n this.checked = !this.checked;\n this.props.onChange?.(this.checked);\n this.updateHTML();\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {render} from 'preact';\nimport {Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {SimpleMenu, type MenuItem} from './lib/components/dropdown-menu';\nimport {Popover, type PopoverProps} from './lib/components/popover';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type SelectorWidgetOption<ValueT = string> = {\n value: ValueT;\n icon: string;\n label?: string;\n};\n\n/** Properties for the ViewSelectorWidget */\nexport type SelectorWidgetProps<ValueT = string> = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n options: SelectorWidgetOption<ValueT>[];\n /** The initial value. Default to the first option. */\n initialValue?: ValueT;\n /** Callback invoked when the value changes */\n onChange?: (value: ValueT) => void;\n};\n\n/**\n * A widget that renders a popup menu for selecting a view mode.\n * It displays a button with the current view mode icon. Clicking the button\n * toggles a popup that shows three icons for:\n * - Single view\n * - Two views, split horizontally\n * - Two views, split vertically\n */\nexport class SelectorWidget<ValueT = string> extends Widget<SelectorWidgetProps<ValueT>> {\n static defaultProps: Required<SelectorWidgetProps> = {\n ...Widget.defaultProps,\n id: 'view-selector',\n placement: 'top-left',\n viewId: null,\n initialValue: '',\n options: [],\n onChange: () => {}\n };\n\n className = 'deck-widget-selector';\n placement: WidgetPlacement = 'top-left';\n value: ValueT;\n isOpen: {x: number; y: number; placement: PopoverProps['placement']} | false = false;\n\n constructor(props: SelectorWidgetProps<ValueT>) {\n super(props);\n this.value = this.props.initialValue;\n this.setProps(this.props);\n }\n\n setProps(props: Partial<SelectorWidgetProps<ValueT>>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement) {\n const selectedOption =\n this.props.options.find(opt => opt.value === this.value) ?? this.props.options[0];\n\n render(\n <div>\n <IconButton\n icon={selectedOption.icon}\n label={selectedOption.label}\n onClick={this._toggleMenu}\n />\n {this.isOpen && (\n <Popover {...this.isOpen}>\n <SimpleMenu\n isOpen\n style={{pointerEvents: 'auto', position: 'static'}}\n menuItems={this.props.options as MenuItem[]}\n onSelect={this._handleSelectMode}\n onClose={this._toggleMenu}\n />\n </Popover>\n )}\n </div>,\n rootElement\n );\n }\n\n private _toggleMenu = () => {\n if (this.isOpen) {\n this.isOpen = false;\n } else if (this.rootElement) {\n this.isOpen = {\n x: this.rootElement.offsetLeft,\n y: this.rootElement.offsetTop,\n placement: this.props.placement.includes('right') ? 'left-start' : 'right-start'\n };\n }\n this.updateHTML();\n };\n\n private _handleSelectMode = (value: string) => {\n this.value = value as ValueT;\n this.props.onChange(value as ValueT);\n this.updateHTML();\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, type WidgetPlacement, type WidgetProps} from '@deck.gl/core';\nimport type {Timeline} from '@luma.gl/engine';\nimport {render} from 'preact';\nimport {IconButton} from './lib/components/icon-button';\nimport {RangeInput} from './lib/components/range-input';\n\nexport type TimelineWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Timeline instance to manipulate. */\n timeline?: Timeline | null;\n /** Slider timeRange [min, max]. */\n timeRange?: [number, number];\n /** Slider step.\n * @default 1\n */\n step?: number;\n /** Initial slider value for uncontrolled usage.\n * @default `timeRange[0]`\n */\n initialTime?: number;\n /**\n * Controlled time value. When provided, the widget is in controlled mode\n * for the time slider.\n */\n time?: number;\n /** Callback when time value changes (via slider or playback). */\n onTimeChange?: (value: number) => void;\n /** Start playing automatically\n * @default false\n */\n autoPlay?: boolean;\n /** Start from the beginning whentime reaches the end\n * @default false\n */\n loop?: boolean;\n /** Play interval in milliseconds.\n * @default 1000\n */\n playInterval?: number;\n /**\n * Controlled playing state. When provided, the widget is in controlled mode\n * for play/pause.\n */\n playing?: boolean;\n /**\n * Callback when play/pause button is clicked.\n * In controlled mode, use this to update the playing prop.\n */\n onPlayingChange?: (playing: boolean) => void;\n /** Callback to get label from time value */\n formatLabel?: (value: number) => string;\n};\n\nexport class TimelineWidget extends Widget<TimelineWidgetProps> {\n id = 'timeline';\n className = 'deck-widget-timeline';\n placement: WidgetPlacement = 'fill';\n\n private _playing = false;\n private timerId: number | null = null;\n currentTime: number;\n\n /**\n * Returns the current time value.\n * In controlled mode, returns the time prop.\n * In uncontrolled mode, returns the internal state.\n */\n getTime(): number {\n return this.props.time ?? this.currentTime;\n }\n\n /**\n * Returns the current playing state.\n * In controlled mode, returns the playing prop.\n * In uncontrolled mode, returns the internal state.\n */\n getPlaying(): boolean {\n return this.props.playing ?? this._playing;\n }\n\n static defaultProps: Required<TimelineWidgetProps> = {\n ...Widget.defaultProps,\n id: 'timeline',\n placement: 'bottom-left',\n viewId: null,\n timeline: null,\n timeRange: [0, 100],\n step: 1,\n initialTime: undefined!,\n time: undefined!,\n onTimeChange: () => {},\n autoPlay: false,\n loop: false,\n playInterval: 1000,\n playing: undefined!,\n onPlayingChange: () => {},\n formatLabel: String\n };\n\n constructor(props: TimelineWidgetProps = {}) {\n super(props);\n this.currentTime = this.props.initialTime ?? this.props.timeRange[0];\n // In controlled mode, sync Timeline to the controlled time prop\n const syncTime = this.props.time ?? this.currentTime;\n this.props.timeline?.setTime(syncTime);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<TimelineWidgetProps>): void {\n const {playing: prevPlaying, time: prevTime} = this.props;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n\n // Sync Timeline object when controlled time prop changes\n if (props.time !== undefined && props.time !== prevTime) {\n this.props.timeline?.setTime(props.time);\n }\n\n // Handle controlled playing state changes\n if (props.playing !== undefined && props.playing !== prevPlaying) {\n if (props.playing && !this._playing) {\n this._startTimer();\n } else if (!props.playing && this._playing) {\n this._stopTimer();\n }\n }\n }\n\n onAdd(): void {\n this._playing = false;\n this.timerId = null;\n if (this.props.autoPlay) {\n if (this.props.playing !== undefined) {\n // In controlled mode, notify parent instead of starting directly\n this.props.onPlayingChange?.(true);\n } else {\n this.play();\n }\n }\n }\n\n onRemove(): void {\n this.stop();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {timeRange, step, formatLabel} = this.props;\n const isPlaying = this.getPlaying();\n const currentTime = this.getTime();\n\n rootElement.dataset.placement = this.props.placement;\n\n render(\n <div className=\"deck-widget-button-group\">\n {isPlaying ? (\n <IconButton\n label=\"Pause\"\n className=\"deck-widget-timeline-pause\"\n onClick={this.handlePlayPause}\n />\n ) : (\n <IconButton\n label=\"Play\"\n className=\"deck-widget-timeline-play\"\n onClick={this.handlePlayPause}\n />\n )}\n <RangeInput\n min={timeRange[0]}\n max={timeRange[1]}\n orientation=\"horizontal\"\n step={step}\n value={[currentTime, currentTime]}\n onChange={this.handleTimeChange}\n decorations={[\n {\n position: [currentTime, currentTime + step],\n element: (\n <div className=\"deck-widget-timeline-label deck-widget-timeline-label--current\">\n {formatLabel(currentTime)}\n </div>\n )\n }\n ]}\n />\n </div>,\n rootElement\n );\n }\n\n private handlePlayPause = (): void => {\n const isPlaying = this.getPlaying();\n const nextPlaying = !isPlaying;\n\n // Always call callback if provided\n this.props.onPlayingChange?.(nextPlaying);\n\n // Only update internal state if uncontrolled\n if (this.props.playing === undefined) {\n if (nextPlaying) {\n this.play();\n } else {\n this.stop();\n }\n }\n // In controlled mode, parent will update playing prop which triggers start/stop via setProps\n };\n\n private handleTimeChange = ([value]: [number, number]): void => {\n // Always call callback\n this.props.onTimeChange(value);\n\n // Only update internal state if uncontrolled\n if (this.props.time === undefined) {\n this.currentTime = value;\n this.props.timeline?.setTime(value);\n this.updateHTML();\n }\n // In controlled mode, parent will update time prop which triggers updateHTML via setProps\n };\n\n public play(): void {\n this._playing = true;\n const {\n timeRange: [min, max]\n } = this.props;\n // In uncontrolled mode, reset to start if at end\n if (this.props.time === undefined && this.getTime() >= max) {\n this.currentTime = min;\n this.props.onTimeChange(min);\n this.props.timeline?.setTime(min);\n }\n this.updateHTML();\n this.tick();\n }\n\n public stop(): void {\n this._stopTimer();\n this.updateHTML();\n }\n\n /** Start the playback timer (used internally) */\n private _startTimer(): void {\n this._playing = true;\n this.tick();\n }\n\n /** Stop the playback timer (used internally) */\n private _stopTimer(): void {\n this._playing = false;\n if (this.timerId !== null) {\n window.clearTimeout(this.timerId);\n this.timerId = null;\n }\n }\n\n private tick = (): void => {\n const {\n timeRange: [min, max],\n step,\n loop\n } = this.props;\n if (step > 0) {\n const currentTime = this.getTime();\n let next = Math.round(currentTime / step) * step + step;\n if (next > max) {\n if (currentTime < max) {\n next = max;\n } else if (loop) {\n next = min;\n } else {\n next = max;\n this._playing = false;\n this.props.onPlayingChange?.(false);\n }\n }\n\n // Always call callback\n this.props.onTimeChange(next);\n\n // Only update internal state if uncontrolled\n if (this.props.time === undefined) {\n this.currentTime = next;\n this.props.timeline?.setTime(next);\n }\n this.updateHTML();\n }\n if (this._playing) {\n this.timerId = window.setTimeout(this.tick, this.props.playInterval);\n } else {\n this.timerId = null;\n }\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the ScreenshotWidget */\nexport type ScreenshotWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message */\n label?: string;\n /** Filename to save to */\n filename?: string;\n /** Image format */\n imageFormat?: 'image/png' | 'image/jpeg';\n /** Callback, if defined user overrides the capture logic */\n onCapture?: (widget: ScreenshotWidget) => void;\n};\n\n/**\n * A button widget that captures a screenshot of the current canvas and downloads it as a (png) file.\n * @note only captures canvas contents, not HTML DOM or CSS styles\n */\nexport class ScreenshotWidget extends Widget<ScreenshotWidgetProps> {\n static defaultProps: Required<ScreenshotWidgetProps> = {\n ...Widget.defaultProps,\n id: 'screenshot',\n placement: 'top-left',\n viewId: null,\n label: 'Screenshot',\n filename: 'screenshot.png',\n imageFormat: 'image/png',\n onCapture: undefined!\n };\n\n className = 'deck-widget-screenshot';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ScreenshotWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ScreenshotWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n className=\"deck-widget-camera\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />,\n rootElement\n );\n }\n\n handleClick() {\n // Allow user to override the capture logic\n if (this.props.onCapture) {\n this.props.onCapture(this);\n return;\n }\n const dataURL = this.captureScreenToDataURL(this.props.imageFormat);\n if (dataURL) {\n this.downloadDataURL(dataURL, this.props.filename);\n }\n }\n\n /** @note only captures canvas contents, not HTML DOM or CSS styles */\n captureScreenToDataURL(imageFormat: string): string | undefined {\n const canvas = this.deck?.getCanvas();\n return canvas?.toDataURL(imageFormat);\n }\n\n /** Download a data URL */\n downloadDataURL(dataURL: string, filename: string): void {\n const link = document.createElement('a');\n link.href = dataURL;\n link.download = filename;\n link.click();\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log, _deepEqual as deepEqual, _applyStyles as applyStyles} from '@deck.gl/core';\nimport {Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\n// import {useCallback} from 'preact/hooks';\nimport {IconButton} from './lib/components/icon-button';\nimport type {DeckWidgetTheme} from './themes';\nimport {LightGlassTheme, DarkGlassTheme} from './themes';\n\nexport type ThemeWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message when dark mode is selected. */\n lightModeLabel?: string;\n /** Styles for light mode theme */\n lightModeTheme?: DeckWidgetTheme;\n /** Tooltip message when light mode is selected. */\n darkModeLabel?: string;\n /** Styles for dark mode theme */\n darkModeTheme?: DeckWidgetTheme;\n /** Initial theme mode for uncontrolled usage. 'auto' reads the browser default setting */\n initialThemeMode?: 'auto' | 'light' | 'dark';\n /**\n * Controlled theme mode. When provided, the widget is in controlled mode\n * and this prop determines the current theme.\n */\n themeMode?: 'light' | 'dark';\n /**\n * Callback when the user clicks the theme toggle button.\n * In controlled mode, use this to update the themeMode prop.\n * In uncontrolled mode, this is called after the internal state updates.\n */\n onThemeModeChange?: (newMode: 'light' | 'dark') => void;\n};\n\nexport class ThemeWidget extends Widget<ThemeWidgetProps> {\n static defaultProps: Required<ThemeWidgetProps> = {\n ...Widget.defaultProps,\n id: 'theme',\n placement: 'top-left',\n viewId: null,\n lightModeLabel: 'Light Mode',\n lightModeTheme: LightGlassTheme,\n darkModeLabel: 'Dark Mode',\n darkModeTheme: DarkGlassTheme,\n initialThemeMode: 'auto',\n themeMode: undefined!,\n onThemeModeChange: () => {}\n };\n\n className = 'deck-widget-theme';\n placement: WidgetPlacement = 'top-left';\n themeMode: 'light' | 'dark' = 'dark';\n appliedTheme: DeckWidgetTheme = {};\n\n constructor(props: ThemeWidgetProps = {}) {\n super(props);\n this.themeMode = this._getInitialThemeMode();\n this.setProps(this.props);\n }\n\n // eslint-disable-next-line complexity\n setProps(props: Partial<ThemeWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {lightModeLabel, darkModeLabel} = this.props;\n const currentMode = this.getThemeMode();\n this._applyTheme(currentMode, rootElement);\n\n render(\n <IconButton\n onClick={this._handleClick.bind(this)}\n label={currentMode === 'dark' ? darkModeLabel : lightModeLabel}\n className={currentMode === 'dark' ? 'deck-widget-moon' : 'deck-widget-sun'}\n />,\n rootElement\n );\n }\n\n /**\n * Returns the current theme mode.\n * In controlled mode, returns the themeMode prop.\n * In uncontrolled mode, returns the internal state.\n */\n getThemeMode(): 'light' | 'dark' {\n return this.props.themeMode ?? this.themeMode;\n }\n\n _handleClick() {\n const currentMode = this.getThemeMode();\n const nextMode = currentMode === 'dark' ? 'light' : 'dark';\n\n // Always call callback if provided\n this.props.onThemeModeChange?.(nextMode);\n\n // Only update internal state if uncontrolled\n if (this.props.themeMode === undefined) {\n this.themeMode = nextMode;\n this.updateHTML();\n }\n // In controlled mode, parent will update themeMode prop which triggers _applyTheme via setProps\n }\n\n /** Apply theme styling without changing internal state */\n _applyTheme(themeMode: 'light' | 'dark', rootElement: HTMLElement) {\n const themeStyle = themeMode === 'dark' ? this.props.darkModeTheme : this.props.lightModeTheme;\n if (deepEqual(themeStyle, this.appliedTheme, 1)) {\n return;\n }\n const container = rootElement.closest<HTMLDivElement>('.deck-widget-container');\n if (!container) return;\n\n applyStyles(container, themeStyle);\n this.appliedTheme = themeStyle;\n\n const label = themeMode === 'dark' ? this.props.darkModeLabel : this.props.lightModeLabel;\n log.log(1, `Switched theme to ${label}`, themeStyle)();\n }\n\n /** Read browser preference */\n _getInitialThemeMode(): 'light' | 'dark' {\n const {initialThemeMode} = this.props;\n if (initialThemeMode !== 'auto') {\n return initialThemeMode;\n }\n if (typeof window === 'undefined') {\n return 'light';\n }\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/**\n * A Deck Theme is a set of CSS variables that control CSS styling of the official widgets.\n */\nexport type DeckWidgetTheme = {\n // layout\n '--widget-margin'?: string;\n // button and button group\n '--button-size'?: string;\n '--button-corner-radius'?: string;\n '--button-background'?: string;\n '--button-stroke'?: string;\n '--button-inner-stroke'?: string;\n '--button-shadow'?: string;\n '--button-backdrop-filter'?: string;\n '--button-icon-idle'?: string;\n '--button-icon-hover'?: string;\n '--button-text'?: string;\n // inter-icon color\n '--icon-compass-north-color'?: string;\n '--icon-compass-south-color'?: string;\n // menu\n '--menu-gap'?: string;\n '--menu-background'?: string;\n '--menu-backdrop-filter'?: string;\n '--menu-border'?: string;\n '--menu-shadow'?: string;\n '--menu-text'?: string;\n '--menu-item-hover'?: string;\n // scrollbar\n '--range-step-button-size'?: string;\n '--range-track-size'?: string;\n '--range-thumb-size'?: string;\n '--range-track-color'?: string;\n '--range-thumb-color'?: string;\n '--range-decoration-active-color'?: string;\n};\n\nexport const LightTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': '#fff',\n '--button-stroke': 'rgba(255, 255, 255, 0.3)',\n '--button-inner-stroke': 'unset',\n '--button-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--button-backdrop-filter': 'unset',\n '--button-icon-idle': 'rgba(97, 97, 102, 1)',\n '--button-icon-hover': 'rgba(24, 24, 26, 1)',\n '--button-text': 'rgb(24, 24, 26, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(204, 204, 204)',\n '--menu-gap': '4px',\n '--menu-background': '#fff',\n '--menu-backdrop-filter': 'unset',\n '--menu-border': 'unset',\n '--menu-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--menu-text': 'rgb(24, 24, 26, 1)',\n '--menu-item-hover': 'rgba(0, 0, 0, 0.08)',\n '--range-step-button-size': '24px',\n '--range-track-size': '16px',\n '--range-thumb-size': '10px',\n '--range-track-color': '#d8d8e5',\n '--range-thumb-color': '#616166',\n '--range-decoration-active-color': '#f8dd50'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const DarkTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(18, 18, 20, 1)',\n '--button-stroke': 'rgba(18, 18, 20, 0.30)',\n '--button-inner-stroke': 'unset',\n '--button-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--button-backdrop-filter': 'unset',\n '--button-icon-idle': 'rgba(158, 157, 168, 1)',\n '--button-icon-hover': 'rgba(215, 214, 229, 1)',\n '--button-text': 'rgb(215, 214, 229, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(200, 199, 209)',\n '--menu-gap': '4px',\n '--menu-background': 'rgba(18, 18, 20, 1)',\n '--menu-backdrop-filter': 'unset',\n '--menu-border': 'unset',\n '--menu-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--menu-text': 'rgb(215, 214, 229, 1)',\n '--menu-item-hover': 'rgba(255, 255, 255, 0.1)',\n '--range-step-button-size': '24px',\n '--range-track-size': '16px',\n '--range-thumb-size': '10px',\n '--range-track-color': '#2c2c30',\n '--range-thumb-color': '#9e9da8',\n '--range-decoration-active-color': '#dd7d2c'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const LightGlassTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(255, 255, 255, 0.6)',\n '--button-stroke': 'rgba(255, 255, 255, 0.3)',\n '--button-inner-stroke': '1px solid rgba(255, 255, 255, 0.6)',\n '--button-shadow':\n '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--button-backdrop-filter': 'blur(4px)',\n '--button-icon-idle': 'rgba(97, 97, 102, 1)',\n '--button-icon-hover': 'rgba(24, 24, 26, 1)',\n '--button-text': 'rgb(24, 24, 26, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(204, 204, 204)',\n '--menu-gap': '4px',\n '--menu-background': 'rgba(255, 255, 255, 0.6)',\n '--menu-backdrop-filter': 'blur(4px)',\n '--menu-border': '1px solid rgba(255, 255, 255, 0.6)',\n '--menu-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--menu-text': 'rgb(24, 24, 26, 1)',\n '--menu-item-hover': 'rgba(0, 0, 0, 0.08)',\n '--range-step-button-size': '24px',\n '--range-track-size': '16px',\n '--range-thumb-size': '10px',\n '--range-track-color': 'rgba(215, 214, 229, 0.3)',\n '--range-thumb-color': 'rgba(97, 97, 102, 1)',\n '--range-decoration-active-color': 'rgba(255, 215, 0, 0.6)'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const DarkGlassTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(18, 18, 20, 0.75)',\n '--button-stroke': 'rgba(18, 18, 20, 0.30)',\n '--button-inner-stroke': '1px solid rgba(18, 18, 20, 0.75)',\n '--button-shadow':\n '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--button-backdrop-filter': 'blur(4px)',\n '--button-icon-idle': 'rgba(158, 157, 168, 1)',\n '--button-icon-hover': 'rgba(215, 214, 229, 1)',\n '--button-text': 'rgb(215, 214, 229, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(200, 199, 209)',\n '--menu-gap': '4px',\n '--menu-background': 'rgba(18, 18, 20, 0.75)',\n '--menu-backdrop-filter': 'blur(4px)',\n '--menu-border': '1px solid rgba(18, 18, 20, 0.75)',\n '--menu-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--menu-text': 'rgb(215, 214, 229, 1)',\n '--menu-item-hover': 'rgba(255, 255, 255, 0.1)',\n '--range-step-button-size': '24px',\n '--range-track-size': '16px',\n '--range-thumb-size': '10px',\n '--range-track-color': 'rgba(24, 24, 26, 0.3)',\n '--range-thumb-color': 'rgba(158, 157, 168, 1)',\n '--range-decoration-active-color': 'rgba(255, 145, 0, 0.6)'\n} as const satisfies Required<DeckWidgetTheme>;\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, Layer, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the LoadingWidget */\nexport type LoadingWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Tooltip message when loading */\n label?: string;\n /**\n * Callback when the loading state changes.\n * Called when layers transition between loading and loaded states.\n */\n onLoadingChange?: (loading: boolean) => void;\n};\n\n/**\n * A non-interactive widget that shows a loading spinner if any layers are loading data\n */\nexport class LoadingWidget extends Widget<LoadingWidgetProps> {\n static defaultProps: Required<LoadingWidgetProps> = {\n ...Widget.defaultProps,\n id: 'loading',\n placement: 'top-left',\n viewId: null,\n label: 'Loading layer data',\n onLoadingChange: () => {}\n };\n\n className = 'deck-widget-loading';\n placement: WidgetPlacement = 'top-left';\n loading = true;\n\n constructor(props: LoadingWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<LoadingWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n // TODO(ibgreen) - this should not be a button, but styling is so nested that it is easier to reuse this component.\n this.loading && (\n <IconButton\n className=\"deck-widget-spinner\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />\n ),\n rootElement\n );\n }\n\n onRedraw({layers}: {layers: Layer[]}): void {\n const loading = layers.some(layer => !layer.isLoaded);\n if (loading !== this.loading) {\n this.loading = loading;\n\n // Call callback when loading state changes\n this.props.onLoadingChange?.(loading);\n\n this.updateHTML();\n }\n }\n\n // TODO(ibgreen) - this should not be a button, see above.\n handleClick() {}\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, type WidgetPlacement, type WidgetProps} from '@deck.gl/core';\nimport {luma} from '@luma.gl/core';\nimport {render, type JSX} from 'preact';\nimport {useEffect, useState} from 'preact/hooks';\nimport type {Stats, Stat} from '@probe.gl/stats';\nimport {IconButton} from './lib/components/icon-button';\n\nconst DEFAULT_COUNT_FORMATTER = (stat: Stat): string => `${stat.name}: ${stat.count}`;\n\nfunction formatTime(time: number): string {\n return time < 1000 ? `${time.toFixed(2)}ms` : `${(time / 1000).toFixed(2)}s`;\n}\n\nfunction formatMemory(bytes: number): string {\n const mb = bytes / 1e6;\n return `${mb.toFixed(1)} MB`;\n}\n\nexport const DEFAULT_FORMATTERS: Record<string, (stat: Stat) => string> = {\n count: DEFAULT_COUNT_FORMATTER,\n averageTime: (stat: Stat) => `${stat.name}: ${formatTime(stat.getAverageTime())}`,\n totalTime: (stat: Stat) => `${stat.name}: ${formatTime(stat.time)}`,\n fps: (stat: Stat) => `${stat.name}: ${Math.round(stat.getHz())}fps`,\n memory: (stat: Stat) => `${stat.name}: ${formatMemory(stat.count)}`\n};\n\nexport type StatsWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Type of stats to display. */\n type?: 'deck' | 'luma' | 'device' | 'custom';\n /** Expand the stats UI by default.\n * @default false\n */\n initialExpanded?: boolean;\n /** Stats object to visualize. */\n stats?: Stats;\n /** Title shown in the header of the pop-up. Defaults to stats.id. */\n title?: string;\n /** How many redraws to wait between updates. */\n framesPerUpdate?: number;\n /** Custom formatters for stat values. */\n formatters?: Record<string, string | ((stat: Stat) => string)>;\n /** Whether to reset particular stats after each update. */\n resetOnUpdate?: Record<string, boolean>;\n /**\n * Controlled expanded state. When provided, the widget is in controlled mode.\n */\n expanded?: boolean;\n /**\n * Callback when the expanded state changes (user clicks header).\n * In controlled mode, use this to update the expanded prop.\n */\n onExpandedChange?: (expanded: boolean) => void;\n};\n\n/** Displays probe.gl stats in a floating pop-up. */\nexport class StatsWidget extends Widget<StatsWidgetProps> {\n static defaultProps: Required<StatsWidgetProps> = {\n ...Widget.defaultProps,\n type: 'deck',\n placement: 'top-left',\n viewId: null,\n initialExpanded: false,\n stats: undefined!,\n title: 'Stats',\n framesPerUpdate: 1,\n formatters: {},\n resetOnUpdate: {},\n id: 'stats',\n expanded: undefined!,\n onExpandedChange: () => {}\n };\n\n className = 'deck-widget-stats';\n placement = 'top-left' as WidgetPlacement;\n\n private _counter = 0;\n private _formatters: Record<string, (stat: Stat) => string>;\n private _resetOnUpdate: Record<string, boolean>;\n private _expanded: boolean = false;\n\n /**\n * Returns the current expanded state.\n * In controlled mode, returns the expanded prop.\n * In uncontrolled mode, returns the internal state.\n */\n getExpanded(): boolean {\n return this.props.expanded ?? this._expanded;\n }\n\n constructor(props: StatsWidgetProps = {}) {\n super(props);\n this._formatters = {...DEFAULT_FORMATTERS};\n this._resetOnUpdate = {...this.props.resetOnUpdate};\n this._expanded = Boolean(props.initialExpanded);\n this.setProps(props);\n }\n\n setProps(props: Partial<StatsWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n if (props.formatters) {\n for (const name in props.formatters) {\n const f = props.formatters[name];\n this._formatters[name] =\n typeof f === 'string' ? DEFAULT_FORMATTERS[f] || DEFAULT_COUNT_FORMATTER : f;\n }\n }\n if (props.resetOnUpdate) {\n this._resetOnUpdate = {...props.resetOnUpdate};\n }\n super.setProps(props);\n }\n\n onRemove() {\n if (this.rootElement) {\n // Make sure all preact hooks are finalized\n render(null, this.rootElement);\n }\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const isExpanded = this.getExpanded();\n if (!isExpanded) {\n render(<FpsIcon getFps={this._getFps} onClick={this._toggleExpanded} />, rootElement);\n return;\n }\n\n const stats = this._getStats();\n const title = this.props.title || ('id' in stats ? stats.id : null) || 'Stats';\n const deviceLabel = this._getDeviceLabel();\n const items: JSX.Element[] = [];\n\n if (stats) {\n stats.forEach(stat => {\n const lines = this._getLines(stat).split('\\n');\n if (this._resetOnUpdate && this._resetOnUpdate[stat.name]) {\n stat.reset();\n }\n lines.forEach((line, i) => {\n items.push(\n <div key={`${stat.name}-${i}`} style={{whiteSpace: 'pre'}}>\n {line}\n </div>\n );\n });\n });\n }\n\n render(\n <div className=\"deck-widget-stats-container\" style={{cursor: 'default'}}>\n <div\n className=\"deck-widget-stats-header\"\n style={{cursor: 'pointer', pointerEvents: 'auto'}}\n onClick={this._toggleExpanded}\n >\n <b>{title}</b>\n {deviceLabel && <span className=\"deck-widget-stats-device\">{deviceLabel}</span>}\n <button className=\"deck-widget-dropdown-button\">\n <span className=\"deck-widget-dropdown-icon open\" />\n </button>\n </div>\n <div className=\"deck-widget-stats-content\">{items}</div>\n </div>,\n rootElement\n );\n }\n\n onRedraw(): void {\n if (this.getExpanded()) {\n const framesPerUpdate = Math.max(1, this.props.framesPerUpdate || 1);\n if (this._counter++ % framesPerUpdate === 0) {\n this.updateHTML();\n }\n }\n }\n\n protected _getStats(): Stats | [key: string, value: number][] {\n switch (this.props.type) {\n case 'deck':\n // @ts-expect-error metrics is protected\n const metrics = this.deck?.metrics ?? {};\n return Object.entries(metrics);\n case 'luma':\n return Array.from(luma.stats.stats.values())[0];\n case 'device':\n // @ts-expect-error is protected\n const device = this.deck?.device;\n const stats = device?.statsManager.stats.values();\n return stats ? Array.from(stats)[0] : [];\n case 'custom':\n return this.props.stats;\n default:\n throw new Error(`Unknown stats type: ${this.props.type}`);\n }\n }\n\n protected _toggleExpanded = (): void => {\n const nextExpanded = !this.getExpanded();\n\n // Always call callback if provided\n this.props.onExpandedChange?.(nextExpanded);\n\n // Only update internal state if uncontrolled\n if (this.props.expanded === undefined) {\n this._expanded = nextExpanded;\n this.updateHTML();\n }\n // In controlled mode, parent will update expanded prop which triggers updateHTML via setProps\n };\n\n protected _getFps = (): number => {\n // @ts-expect-error metrics is protected\n return Math.round(this.deck?.metrics.fps ?? 0);\n };\n\n protected _getDeviceLabel(): string | null {\n // @ts-expect-error device is protected\n const deviceType = this.deck?.device?.type;\n if (!deviceType) {\n return null;\n }\n switch (deviceType) {\n case 'webgpu':\n return 'WebGPU';\n case 'webgl':\n return 'WebGL';\n default:\n return String(deviceType);\n }\n }\n\n protected _getLines(stat: Stat | [key: string, value: number]): string {\n if ('count' in stat) {\n const formatter =\n this._formatters[stat.name] || this._formatters[stat.type || ''] || DEFAULT_COUNT_FORMATTER;\n return formatter(stat);\n }\n const [key, value] = stat;\n const formattedValue = key.endsWith('Memory')\n ? formatMemory(value)\n : key.includes('Time')\n ? formatTime(value)\n : `${value.toFixed(2)}`;\n\n return `${key}: ${formattedValue}`;\n }\n}\n\nfunction FpsIcon({getFps, onClick}: {getFps: () => number; onClick: () => void}) {\n const [fps, setFps] = useState(getFps());\n useEffect(() => {\n const onUpdate = () => {\n setFps(getFps());\n timer = requestAnimationFrame(onUpdate);\n };\n let timer = requestAnimationFrame(onUpdate);\n return () => {\n cancelAnimationFrame(timer);\n };\n }, [getFps]);\n\n return (\n <IconButton onClick={onClick}>\n <div className=\"text\">\n FPS\n <br />\n {fps}\n </div>\n </IconButton>\n );\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Navigation widgets\nexport {ZoomWidget} from './zoom-widget';\nexport {ResetViewWidget} from './reset-view-widget';\nexport {GimbalWidget} from './gimbal-widget';\n\n// Geospatial widgets\nexport {CompassWidget} from './compass-widget';\nexport {ScaleWidget as _ScaleWidget} from './scale-widget';\nexport {GeocoderWidget as _GeocoderWidget} from './geocoder-widget';\n\n// View widgets\nexport {FullscreenWidget} from './fullscreen-widget';\nexport {SplitterWidget as _SplitterWidget} from './splitter-widget';\n\n// Information widgets\nexport {InfoWidget} from './info-widget';\nexport {PopupWidget} from './popup-widget';\nexport {ContextMenuWidget} from './context-menu-widget';\nexport {ScrollbarWidget} from './scrollbar-widget';\n\n// Control widgets\nexport {IconWidget} from './icon-widget';\nexport {ToggleWidget} from './toggle-widget';\nexport {SelectorWidget} from './selector-widget';\nexport {TimelineWidget as _TimelineWidget} from './timeline-widget';\n\n// Utility widgets\nexport {ScreenshotWidget} from './screenshot-widget';\nexport {ThemeWidget} from './theme-widget';\nexport {LoadingWidget} from './loading-widget';\nexport {StatsWidget as _StatsWidget} from './stats-widget';\n\nexport type {FullscreenWidgetProps} from './fullscreen-widget';\nexport type {CompassWidgetProps} from './compass-widget';\nexport type {ZoomWidgetProps} from './zoom-widget';\nexport type {ScreenshotWidgetProps} from './screenshot-widget';\nexport type {ResetViewWidgetProps} from './reset-view-widget';\nexport type {GeocoderWidgetProps} from './geocoder-widget';\nexport type {LoadingWidgetProps} from './loading-widget';\nexport type {IconWidgetProps} from './icon-widget';\nexport type {ToggleWidgetProps} from './toggle-widget';\nexport type {ScaleWidgetProps} from './scale-widget';\nexport type {ThemeWidgetProps} from './theme-widget';\nexport type {InfoWidgetProps} from './info-widget';\nexport type {PopupWidgetProps} from './popup-widget';\nexport type {StatsWidgetProps} from './stats-widget';\nexport type {ContextMenuWidgetProps} from './context-menu-widget';\nexport type {SplitterWidgetProps} from './splitter-widget';\nexport type {TimelineWidgetProps} from './timeline-widget';\nexport type {SelectorWidgetProps} from './selector-widget';\nexport type {GimbalWidgetProps} from './gimbal-widget';\nexport type {ContentBounds, ScrollbarWidgetProps, ScrollbarDecoration} from './scrollbar-widget';\n\nexport {LightTheme, DarkTheme, LightGlassTheme, DarkGlassTheme} from './themes';\nexport type {DeckWidgetTheme} from './themes';\n\n// Experimental preact components\nexport {ButtonGroup as _ButtonGroup, type ButtonGroupProps} from './lib/components/button-group';\nexport {IconButton as _IconButton, type IconButtonProps} from './lib/components/icon-button';\nexport {\n DropdownMenu as _DropdownMenu,\n type DropdownMenuProps,\n SimpleMenu as _SimpleMenu,\n type SimpleMenuProps\n} from './lib/components/dropdown-menu';\nexport {\n RangeInput as _RangeInput,\n type RangeInputProps,\n type RangeInputDecoration\n} from './lib/components/range-input';\n\n// Experimental geocoders. May be removed, use at your own risk!\nexport {type Geocoder} from './lib/geocode/geocoder';\nexport {\n GoogleGeocoder as _GoogleGeocoder,\n MapboxGeocoder as _MapboxGeocoder,\n OpenCageGeocoder as _OpenCageGeocoder,\n CoordinatesGeocoder as _CoordinatesGeocoder,\n CurrentLocationGeocoder as _CurrentLocationGeocoder\n} from './lib/geocode/geocoders';\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, FlyToInterpolator, LinearInterpolator, OrthographicView} from '@deck.gl/core';\nimport type {WidgetProps, WidgetPlacement, OrthographicViewState} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {ButtonGroup} from './lib/components/button-group';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type ZoomWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Button orientation. */\n orientation?: 'vertical' | 'horizontal';\n /** Tooltip message on zoom in button. */\n zoomInLabel?: string;\n /** Tooltip message on zoom out button. */\n zoomOutLabel?: string;\n /** Zoom transition duration in ms. 0 disables the transition */\n transitionDuration?: number;\n /** Which axes to apply zoom to. One of 'X', 'Y' or 'all'.\n * Only effective if the current view is OrthographicView.\n */\n zoomAxis?: 'X' | 'Y' | 'all';\n /**\n * Callback when zoom buttons are clicked.\n * Called for each viewport that will be zoomed.\n */\n onZoom?: (params: {\n /** The view being zoomed */\n viewId: string;\n /** Zoom direction: +1 for zoom in, -1 for zoom out */\n delta: number;\n /** The new zoom level */\n zoom: number;\n /** The new zoom level of the X axis, if using OrthographicView */\n zoomX?: number;\n /** The new zoom level of the Y axis, if using OrthographicView */\n zoomY?: number;\n }) => void;\n};\n\nexport class ZoomWidget extends Widget<ZoomWidgetProps> {\n static defaultProps: Required<ZoomWidgetProps> = {\n ...Widget.defaultProps,\n id: 'zoom',\n placement: 'top-left',\n orientation: 'vertical',\n transitionDuration: 200,\n zoomInLabel: 'Zoom In',\n zoomOutLabel: 'Zoom Out',\n zoomAxis: 'all',\n viewId: null,\n onZoom: () => {}\n };\n\n className = 'deck-widget-zoom';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ZoomWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ZoomWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const ui = (\n <ButtonGroup orientation={this.props.orientation}>\n <IconButton\n onClick={() => this.handleZoomIn()}\n label={this.props.zoomInLabel}\n className=\"deck-widget-zoom-in\"\n />\n <IconButton\n onClick={() => this.handleZoomOut()}\n label={this.props.zoomOutLabel}\n className=\"deck-widget-zoom-out\"\n />\n </ButtonGroup>\n );\n render(ui, rootElement);\n }\n\n isOrthographicView(viewId: string): boolean {\n const deck = this.deck;\n const view = deck?.isInitialized && deck.getView(viewId);\n return view instanceof OrthographicView;\n }\n\n handleZoom(viewId: string, delta: number) {\n // Respect minZoom/maxZoom constraints from the view state\n const viewState = this.getViewState(viewId);\n const newViewState: Record<string, unknown> = {};\n\n if (this.isOrthographicView(viewId)) {\n const {zoomAxis} = this.props;\n const {zoomX, minZoomX, maxZoomX, zoomY, minZoomY, maxZoomY} = normalizeOrthographicViewState(\n viewState as any\n );\n let nextZoom: number;\n let nextZoomY: number;\n if (zoomAxis === 'X') {\n nextZoom = clamp(zoomX + delta, minZoomX, maxZoomX);\n nextZoomY = zoomY;\n } else if (zoomAxis === 'Y') {\n nextZoom = zoomX;\n nextZoomY = clamp(zoomY + delta, minZoomY, maxZoomY);\n } else {\n const clampedDelta = clamp(\n delta,\n Math.max(minZoomX - zoomX, minZoomY - zoomY),\n Math.min(maxZoomX - zoomX, maxZoomY - zoomY)\n );\n nextZoom = zoomX + clampedDelta;\n nextZoomY = zoomY + clampedDelta;\n }\n newViewState.zoom = [nextZoom, nextZoomY];\n newViewState.zoomX = nextZoom;\n newViewState.zoomY = nextZoomY;\n // Call callback\n this.props.onZoom?.({\n viewId,\n delta,\n // `zoom` will not match the new state if using 2D zoom. Deprecated behavior for backward compatibility.\n zoom: zoomAxis === 'Y' ? nextZoomY : nextZoom,\n zoomX: nextZoom,\n zoomY: nextZoomY\n });\n } else {\n const {zoom = 0, minZoom, maxZoom} = viewState as any;\n const nextZoom = clamp(zoom + delta, minZoom, maxZoom);\n newViewState.zoom = nextZoom;\n // Call callback\n this.props.onZoom?.({\n viewId,\n delta,\n zoom: nextZoom\n });\n }\n\n const nextViewState: Record<string, unknown> = {\n ...viewState,\n ...newViewState\n };\n if (this.props.transitionDuration > 0) {\n nextViewState.transitionDuration = this.props.transitionDuration;\n nextViewState.transitionInterpolator =\n 'latitude' in nextViewState\n ? new FlyToInterpolator()\n : new LinearInterpolator({\n transitionProps: 'zoomX' in newViewState ? ['zoomX', 'zoomY'] : ['zoom']\n });\n }\n this.setViewState(viewId, nextViewState);\n }\n\n handleZoomIn() {\n for (const viewId of this.viewIds) {\n this.handleZoom(viewId, 1);\n }\n }\n\n handleZoomOut() {\n for (const viewId of this.viewIds) {\n this.handleZoom(viewId, -1);\n }\n }\n}\n\nfunction clamp(zoom: number, minZoom: number, maxZoom: number): number {\n return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;\n}\n\nfunction normalizeOrthographicViewState({\n zoom = 0,\n zoomX,\n zoomY,\n minZoom = -Infinity,\n maxZoom = Infinity,\n minZoomX = minZoom,\n maxZoomX = maxZoom,\n minZoomY = minZoom,\n maxZoomY = maxZoom\n}: OrthographicViewState): {\n zoomX: number;\n zoomY: number;\n minZoomX: number;\n maxZoomX: number;\n minZoomY: number;\n maxZoomY: number;\n} {\n zoomX = zoomX ?? (Array.isArray(zoom) ? zoom[0] : zoom);\n zoomY = zoomY ?? (Array.isArray(zoom) ? zoom[1] : zoom);\n return {zoomX, zoomY, minZoomX, minZoomY, maxZoomX, maxZoomY};\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren} from 'preact';\n\nexport type ButtonGroupProps = {\n children: ComponentChildren;\n orientation: 'vertical' | 'horizontal';\n};\n\n/** Renders a group of buttons with Widget CSS */\nexport const ButtonGroup = (props: ButtonGroupProps) => {\n const {children, orientation = 'horizontal'} = props;\n return <div className={`deck-widget-button-group ${orientation}`}>{children}</div>;\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren, JSX} from 'preact';\nimport {useMemo} from 'preact/hooks';\nimport {getCSSMask} from '../data-url';\n\nexport type IconButtonProps = {\n className?: string;\n icon?: string;\n label?: string;\n color?: string;\n style?: JSX.CSSProperties;\n onClick?: JSX.MouseEventHandler<HTMLButtonElement>;\n children?: ComponentChildren;\n};\n\n/** Renders a button component with widget CSS */\nexport const IconButton = (props: IconButtonProps) => {\n const {className = '', style, color, icon, label, onClick, children} = props;\n\n const iconStyle = useMemo(() => {\n const css: JSX.CSSProperties | undefined = getCSSMask(icon);\n if (!color) return css;\n return {...css, backgroundColor: color};\n }, [color, icon]);\n\n return (\n <div className=\"deck-widget-button\" style={style}>\n <button\n className={`deck-widget-icon-button ${className}`}\n type=\"button\"\n onClick={onClick}\n title={label}\n >\n {children ? children : <div className=\"deck-widget-icon\" style={iconStyle} />}\n </button>\n </div>\n );\n};\n", "export function getCSSMask(imageUrl: string | null | undefined) {\n if (!imageUrl) return undefined;\n const cssUrl = `url(\"${imageUrl.replace(/\"/g, `'`)}\")`;\n return {maskImage: cssUrl, WebkitMaskImage: cssUrl};\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport type {ViewStateMap, View} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** @note Mirrors an internal calss in deck.gl/core. We can easily redefine it here */\ntype ViewOrViews = View | View[] | null;\n\n/** Properties for the ResetViewWidget */\nexport type ResetViewWidgetProps<ViewsT extends ViewOrViews = null> = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** Tooltip message */\n label?: string;\n /** The initial view state to reset the view to. Defaults to deck.props.initialViewState */\n initialViewState?: ViewStateMap<ViewsT>;\n /** View to interact with. Required when using multiple views. */\n viewId?: string | null;\n /**\n * Callback when the reset view button is clicked.\n */\n onReset?: (params: {\n /** The view being reset */\n viewId: string;\n /** The view state being reset to */\n viewState: Record<string, unknown>;\n }) => void;\n};\n\n/**\n * A button widget that resets the view state of deck to an initial state.\n */\nexport class ResetViewWidget<ViewsT extends ViewOrViews = null> extends Widget<\n ResetViewWidgetProps<ViewsT>,\n ViewsT\n> {\n static defaultProps: Required<ResetViewWidgetProps> = {\n ...Widget.defaultProps,\n id: 'reset-view',\n placement: 'top-left',\n label: 'Reset View',\n initialViewState: undefined!,\n viewId: null,\n onReset: () => {}\n };\n\n className = 'deck-widget-reset-view';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ResetViewWidgetProps<ViewsT> = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ResetViewWidgetProps<ViewsT>>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n className=\"deck-widget-reset-focus\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />,\n rootElement\n );\n }\n\n handleClick() {\n const initialViewState = this.props.initialViewState || this.deck?.props.initialViewState;\n this.resetViewState(initialViewState);\n }\n\n resetViewState(viewState?: ViewStateMap<ViewsT>) {\n for (const viewId of this.viewIds) {\n const nextViewState = {\n ...(viewState?.[viewId] ?? viewState)\n // only works for geospatial?\n // transitionDuration: this.props.transitionDuration,\n // transitionInterpolator: new FlyToInterpolator()\n };\n\n // Call callback\n this.props.onReset?.({viewId, viewState: nextViewState as Record<string, unknown>});\n\n this.setViewState(viewId, nextViewState);\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, LinearInterpolator} from '@deck.gl/core';\nimport type {Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\n\nexport type GimbalWidgetProps = WidgetProps & {\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message. */\n label?: string;\n /** Width of gimbal lines. */\n strokeWidth?: number;\n /** Transition duration in ms when resetting rotation. */\n transitionDuration?: number;\n /**\n * Callback when the gimbal reset button is clicked.\n * Called for each viewport that will be reset.\n */\n onReset?: (params: {\n /** The view being reset */\n viewId: string;\n /** The new rotationOrbit value (0) */\n rotationOrbit: number;\n /** The new rotationX value (0) */\n rotationX: number;\n }) => void;\n};\n\nexport class GimbalWidget extends Widget<GimbalWidgetProps> {\n static defaultProps: Required<GimbalWidgetProps> = {\n ...Widget.defaultProps,\n id: 'gimbal',\n placement: 'top-left',\n viewId: null,\n label: 'Gimbal',\n strokeWidth: 1.5,\n transitionDuration: 200,\n onReset: () => {}\n };\n\n className = 'deck-widget-gimbal';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: GimbalWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<GimbalWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const viewId = this.viewId || Object.values(this.viewports)[0]?.id || 'default-view';\n const widgetViewport = this.viewports[viewId];\n const {rotationOrbit, rotationX} = this.getNormalizedRotation(widgetViewport);\n // Note - we use CSS 3D transforms instead of SVG 2D transforms\n const ui = (\n <div className=\"deck-widget-button\" style={{perspective: 100, pointerEvents: 'auto'}}>\n <button\n type=\"button\"\n onClick={() => {\n for (const viewport of Object.values(this.viewports)) {\n this.resetOrbitView(viewport);\n }\n }}\n title={this.props.label}\n style={{position: 'relative', width: 26, height: 26}}\n >\n {/* Outer ring */}\n <svg\n className=\"gimbal-outer-ring\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 26 26\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `rotateY(${rotationOrbit}deg)`\n }}\n >\n <circle\n cx=\"13\"\n cy=\"13\"\n r=\"10\"\n stroke=\"var(--icon-gimbal-outer-color, rgb(68, 92, 204))\"\n strokeWidth={this.props.strokeWidth}\n fill=\"none\"\n />\n </svg>\n\n {/* Inner ring */}\n <svg\n className=\"gimbal-inner-ring\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 26 26\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `rotateX(${rotationX}deg)`\n }}\n >\n <circle\n cx=\"13\"\n cy=\"13\"\n r=\"7\"\n stroke=\"var(--icon-gimbal-inner-color, rgb(240, 92, 68))\"\n strokeWidth={this.props.strokeWidth}\n fill=\"none\"\n />\n </svg>\n </button>\n </div>\n );\n\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n this.viewports[viewport.id] = viewport;\n this.updateHTML();\n }\n\n resetOrbitView(viewport?: Viewport) {\n const viewId = this.viewId || viewport?.id || 'OrbitView';\n const viewState = this.getViewState(viewId);\n if ('rotationOrbit' in viewState || 'rotationX' in viewState) {\n // Call callback\n this.props.onReset?.({viewId, rotationOrbit: 0, rotationX: 0});\n\n const nextViewState = {\n ...viewState,\n rotationOrbit: 0,\n rotationX: 0,\n transitionDuration: this.props.transitionDuration,\n transitionInterpolator: new LinearInterpolator({\n transitionProps: ['rotationOrbit', 'rotationX']\n })\n };\n this.setViewState(viewId, nextViewState);\n }\n }\n\n getNormalizedRotation(viewport?: Viewport): {rotationOrbit: number; rotationX: number} {\n const viewId = this.viewId || viewport?.id || 'OrbitView';\n const viewState = this.getViewState(viewId);\n const [rz, rx] = this.getRotation(viewState);\n const rotationOrbit = normalizeAndClampAngle(rz);\n const rotationX = normalizeAndClampAngle(rx);\n return {rotationOrbit, rotationX};\n }\n\n getRotation(viewState?: any): [number, number] {\n if (viewState && ('rotationOrbit' in viewState || 'rotationX' in viewState)) {\n return [-(viewState.rotationOrbit || 0), viewState.rotationX || 0];\n }\n return [0, 0];\n }\n}\n\nfunction normalizeAndClampAngle(angle: number): number {\n // Bring angle into [-180, 180]\n let normalized = ((((angle + 180) % 360) + 360) % 360) - 180;\n\n // Avoid rotating the gimbal rings to close to 90 degrees as they will visually disappear\n const AVOID_ANGLE_DELTA = 10;\n const distanceFrom90 = normalized - 90;\n if (Math.abs(distanceFrom90) < AVOID_ANGLE_DELTA) {\n if (distanceFrom90 < AVOID_ANGLE_DELTA) {\n normalized = 90 + AVOID_ANGLE_DELTA;\n } else if (distanceFrom90 > -AVOID_ANGLE_DELTA) {\n normalized = 90 - AVOID_ANGLE_DELTA;\n }\n }\n // Clamp to [-80, 80]\n return normalized; // Math.max(-80, Math.min(80, normalized));\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, FlyToInterpolator, WebMercatorViewport, _GlobeViewport} from '@deck.gl/core';\nimport type {Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\n\nexport type CompassWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message. */\n label?: string;\n /** Bearing and pitch reset transition duration in ms. */\n transitionDuration?: number;\n /**\n * Callback when the compass reset button is clicked.\n * Called for each viewport that will be reset.\n */\n onReset?: (params: {\n /** The view being reset */\n viewId: string;\n /** The new bearing value (0) */\n bearing: number;\n /** The new pitch value (0 if bearing was already 0) */\n pitch: number;\n }) => void;\n};\n\nexport class CompassWidget extends Widget<CompassWidgetProps> {\n static defaultProps: Required<CompassWidgetProps> = {\n ...Widget.defaultProps,\n id: 'compass',\n placement: 'top-left',\n viewId: null,\n label: 'Reset Compass',\n transitionDuration: 200,\n onReset: () => {}\n };\n\n className = 'deck-widget-compass';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: CompassWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<CompassWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const viewId = this.viewId || Object.values(this.viewports)[0]?.id;\n const widgetViewport = this.viewports[viewId];\n const [rz, rx] = this.getRotation(widgetViewport);\n\n const ui = (\n <div className=\"deck-widget-button\" style={{perspective: 100}}>\n <button\n type=\"button\"\n onClick={() => {\n for (const viewport of Object.values(this.viewports)) {\n this.handleCompassReset(viewport);\n }\n }}\n title={this.props.label}\n style={{transform: `rotateX(${rx}deg)`}}\n >\n <svg fill=\"none\" width=\"100%\" height=\"100%\" viewBox=\"0 0 26 26\">\n <g transform={`rotate(${rz},13,13)`}>\n <path\n d=\"M10 13.0001L12.9999 5L15.9997 13.0001H10Z\"\n fill=\"var(--icon-compass-north-color, rgb(240, 92, 68))\"\n />\n <path\n d=\"M16.0002 12.9999L13.0004 21L10.0005 12.9999H16.0002Z\"\n fill=\"var(--icon-compass-south-color, rgb(204, 204, 204))\"\n />\n </g>\n </svg>\n </button>\n </div>\n );\n\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n // no need to update if viewport is the same\n if (!viewport.equals(this.viewports[viewport.id])) {\n this.viewports[viewport.id] = viewport;\n this.updateHTML();\n }\n }\n\n getRotation(viewport?: Viewport) {\n if (viewport instanceof WebMercatorViewport) {\n return [-viewport.bearing, viewport.pitch];\n } else if (viewport instanceof _GlobeViewport) {\n return [0, Math.max(-80, Math.min(80, viewport.latitude))];\n }\n return [0, 0];\n }\n\n handleCompassReset(viewport: Viewport) {\n const viewId = this.viewId || viewport.id;\n if (viewport instanceof WebMercatorViewport) {\n const viewState = this.getViewState(viewId);\n const resetPitch = this.getRotation(viewport)[0] === 0;\n const nextBearing = 0;\n const nextPitch = resetPitch ? 0 : viewport.pitch;\n\n // Call callback\n this.props.onReset?.({viewId, bearing: nextBearing, pitch: nextPitch});\n\n const nextViewState = {\n ...viewState,\n bearing: nextBearing,\n ...(resetPitch ? {pitch: nextPitch} : {}),\n transitionDuration: this.props.transitionDuration,\n transitionInterpolator: new FlyToInterpolator()\n };\n this.setViewState(viewId, nextViewState);\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\n\nexport type ScaleWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** Label for the scale widget */\n label?: string;\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n};\n\n/**\n * A scale widget that displays a Google Maps\u2013like scale indicator.\n * Instead of text inside a div, this widget renders an SVG that contains a horizontal line\n * with two vertical tick marks (extending upward from the line only) and a pretty distance label\n * positioned to the left of the line. The horizontal line\u2019s length is computed from a \u201Cnice\u201D\n * candidate distance (e.g. 200, 500, 1000 m, etc.) so that its pixel width is between 100 and 200.\n */\nexport class ScaleWidget extends Widget<ScaleWidgetProps> {\n static defaultProps: Required<ScaleWidgetProps> = {\n ...Widget.defaultProps,\n id: 'scale',\n placement: 'bottom-left',\n label: 'Scale',\n viewId: null\n };\n\n className = 'deck-widget-scale';\n placement: WidgetPlacement = 'bottom-left';\n\n // The pixel width of the scale line (computed from a candidate distance)\n scaleWidth: number = 10;\n // The candidate distance (in meters) corresponding to the scale line length.\n scaleValue: number = 0;\n // The formatted distance label (e.g. \"200 m\" or \"1.0 km\")\n scaleText: string = '';\n\n constructor(props: ScaleWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ScaleWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n // Reserve space for the text label (to the left of the horizontal line)\n const lineOffsetX = 50;\n // Overall SVG width includes the left offset plus the computed scale line width.\n const svgWidth = lineOffsetX + this.scaleWidth;\n const tickHeight = 10; // vertical tick extends upward by 10 pixels from the horizontal line\n render(\n <svg\n className=\"deck-widget-scale\"\n width={svgWidth}\n height={30}\n style={{overflow: 'visible', background: 'transparent'}}\n onClick={this.handleClick.bind(this)}\n >\n {/* Pretty distance label positioned to the left of the horizontal line */}\n <text\n x={lineOffsetX + 5}\n y=\"10\"\n textAnchor=\"end\"\n alignmentBaseline=\"middle\"\n style={{fontSize: '16px', fill: 'black', fontWeight: 'bold', fontFamily: 'sans-serif'}}\n >\n {this.scaleText}\n </text>\n {/* Horizontal line */}\n <line\n x1={lineOffsetX}\n y1=\"15\"\n x2={lineOffsetX + this.scaleWidth}\n y2=\"15\"\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n {/* Left vertical tick (extending upward from the horizontal line) */}\n <line\n x1={lineOffsetX}\n y1=\"15\"\n x2={lineOffsetX}\n y2={15 - tickHeight}\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n {/* Right vertical tick (extending upward from the horizontal line) */}\n <line\n x1={lineOffsetX + this.scaleWidth}\n y1=\"15\"\n x2={lineOffsetX + this.scaleWidth}\n y2={15 - tickHeight}\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n </svg>,\n rootElement\n );\n }\n\n onViewportChange(viewport: Viewport): void {\n // Only handle geospatial viewports (which contain latitude)\n if (!('latitude' in viewport)) return;\n\n const {latitude, zoom} = viewport as {latitude: number; zoom: number};\n const metersPerPixel = getMetersPerPixel(latitude, zoom);\n const {candidate, candidatePixels} = computeScaleCandidate(metersPerPixel);\n\n this.scaleValue = candidate;\n this.scaleWidth = candidatePixels;\n // Format the candidate distance for display (using km if >= 1000 m)\n if (candidate >= 1000) {\n this.scaleText = `${(candidate / 1000).toFixed(1)} km`;\n } else {\n this.scaleText = `${candidate} m`;\n }\n this.updateHTML();\n }\n\n handleClick(): void {}\n}\n\n/**\n * Compute the meters per pixel at a given latitude and zoom level.\n *\n * @param latitude - The current latitude.\n * @param zoom - The current zoom level.\n * @returns The number of meters per pixel.\n */\nfunction getMetersPerPixel(latitude: number, zoom: number): number {\n const earthCircumference = 40075016.686;\n return (earthCircumference * Math.cos((latitude * Math.PI) / 180)) / Math.pow(2, zoom + 8);\n}\n\n/**\n * Compute a \"nice\" scale candidate such that the scale bar width in pixels is between 100 and 200.\n * The candidate distance (in meters) will be one of a set of round numbers (100, 200, 500, 1000, 2000, 5000, etc.).\n *\n * @param metersPerPixel - The number of meters per pixel at the current zoom/latitude.\n * @returns An object containing the candidate distance and its width in pixels.\n */\nfunction computeScaleCandidate(metersPerPixel: number): {\n candidate: number;\n candidatePixels: number;\n} {\n const minPixels = 100;\n const maxPixels = 200;\n const targetPixels = (minPixels + maxPixels) / 2;\n const targetDistance = targetPixels * metersPerPixel;\n\n const exponent = Math.floor(Math.log10(targetDistance));\n const base = Math.pow(10, exponent);\n const multipliers = [1, 2, 5];\n\n let candidate = multipliers[0] * base;\n let candidatePixels = candidate / metersPerPixel;\n\n for (let i = 0; i < multipliers.length; i++) {\n const currentCandidate = multipliers[i] * base;\n const currentPixels = currentCandidate / metersPerPixel;\n if (currentPixels >= minPixels && currentPixels <= maxPixels) {\n candidate = currentCandidate;\n candidatePixels = currentPixels;\n break;\n }\n if (currentPixels > maxPixels) {\n candidate = i > 0 ? multipliers[i - 1] * base : currentCandidate;\n candidatePixels = candidate / metersPerPixel;\n break;\n }\n if (i === multipliers.length - 1 && currentPixels < minPixels) {\n candidate = multipliers[0] * base * 10;\n candidatePixels = candidate / metersPerPixel;\n }\n }\n return {candidate, candidatePixels};\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {FlyToInterpolator, LinearInterpolator} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {DropdownMenu, type MenuItem} from './lib/components/dropdown-menu';\nimport {type Geocoder} from './lib/geocode/geocoder';\nimport {GeocoderHistory} from './lib/geocode/geocoder-history';\nimport {\n GoogleGeocoder,\n MapboxGeocoder,\n OpenCageGeocoder,\n CoordinatesGeocoder,\n CurrentLocationGeocoder\n} from './lib/geocode/geocoders';\n\n/** @todo - is the the best we can do? */\ntype ViewState = Record<string, unknown>;\n\nconst CURRENT_LOCATION = 'current';\n\n// Location pin icon (from Google Material Symbols)\nconst LOCATION_ICON = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M480-480q33 0 56.5-23.5T560-560q0-33-23.5-56.5T480-640q-33 0-56.5 23.5T400-560q0 33 23.5 56.5T480-480Zm0 294q122-112 181-203.5T720-552q0-109-69.5-178.5T480-800q-101 0-170.5 69.5T240-552q0 71 59 162.5T480-186Zm0 106Q319-217 239.5-334.5T160-552q0-150 96.5-239T480-880q127 0 223.5 89T800-552q0 100-79.5 217.5T480-80Z'/%3E%3C/svg%3E`;\n\nconst CURRENT_LOCATION_ITEM: MenuItem = {\n label: 'Current location',\n value: CURRENT_LOCATION,\n icon: LOCATION_ICON\n};\n\n/** Properties for the GeocoderWidget */\nexport type GeocoderWidgetProps = WidgetProps & {\n viewId?: string | null;\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** Tooltip message */\n label?: string;\n /** View state reset transition duration in ms. 0 disables the transition */\n transitionDuration?: number;\n /** Geocoding service selector, for declarative usage */\n geocoder?: 'google' | 'mapbox' | 'opencage' | 'coordinates' | 'custom';\n /** Custom geocoding service (Used when geocoder = 'custom') */\n customGeocoder?: Geocoder;\n /** API key used for geocoding services */\n apiKey?: string;\n /** Whether to use geolocation @note Experimental*/\n _geolocation?: boolean;\n /**\n * Callback when a location is geocoded and the view will navigate to it.\n */\n onGeocode?: (params: {\n /** The view being updated */\n viewId: string;\n /** The geocoded coordinates */\n coordinates: {longitude: number; latitude: number; zoom?: number};\n }) => void;\n};\n\n/**\n * A widget that display a text box that lets user type in a location\n * and a button that moves the view to that location.\n * @todo For now only supports coordinates, Could be extended with location service integrations.\n */\nexport class GeocoderWidget extends Widget<GeocoderWidgetProps> {\n static defaultProps: Required<GeocoderWidgetProps> = {\n ...Widget.defaultProps,\n id: 'geocoder',\n viewId: null,\n placement: 'top-left',\n label: 'Geocoder',\n transitionDuration: 200,\n geocoder: 'coordinates',\n customGeocoder: CoordinatesGeocoder,\n apiKey: '',\n _geolocation: false,\n onGeocode: () => {}\n };\n\n className = 'deck-widget-geocoder';\n placement: WidgetPlacement = 'top-left';\n\n geocodeHistory = new GeocoderHistory({});\n addressText: string = '';\n geocoder: Geocoder = CoordinatesGeocoder;\n isGettingLocation: boolean = false;\n\n constructor(props: GeocoderWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<GeocoderWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n this.geocoder = getGeocoder(this.props);\n if (this.geocoder.requiresApiKey && !this.props.apiKey) {\n throw new Error(`API key is required for the ${this.geocoder.name} geocoder`);\n }\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const menuItems: MenuItem[] = this.props._geolocation\n ? [CURRENT_LOCATION_ITEM, ...this.geocodeHistory.addressHistory]\n : [...this.geocodeHistory.addressHistory];\n render(\n <div className=\"deck-widget-geocoder\">\n <input\n className=\"deck-widget-geocoder-input\"\n type=\"text\"\n placeholder={\n this.isGettingLocation\n ? 'Finding your location...'\n : (this.geocoder.placeholderLocation ?? 'Enter address or location')\n }\n value={this.geocodeHistory.addressText}\n // @ts-expect-error event type\n onInput={e => this.setInput(e.target?.value || '')}\n onKeyPress={this.handleKeyPress}\n />\n <DropdownMenu menuItems={menuItems} onSelect={this.handleSelect} />\n {this.geocodeHistory.errorText && (\n <div className=\"deck-widget-geocoder-error\">{this.geocodeHistory.errorText}</div>\n )}\n </div>,\n rootElement\n );\n }\n\n setInput = (text: string) => {\n this.addressText = text;\n };\n\n handleKeyPress = e => {\n if (e.key === 'Enter') {\n this.handleSubmit();\n }\n };\n\n handleSelect = (value: string) => {\n if (value === CURRENT_LOCATION) {\n // Don't put \"current\" in the text field, just trigger geolocation\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.getCurrentLocation();\n } else {\n this.setInput(value);\n this.handleSubmit();\n }\n };\n\n /** Sync wrapper for async geocode() */\n handleSubmit = () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.geocode(this.addressText);\n };\n\n /** Get current location via browser geolocation API */\n getCurrentLocation = async () => {\n this.isGettingLocation = true;\n if (this.rootElement) {\n this.updateHTML();\n }\n\n try {\n const coordinates = await CurrentLocationGeocoder.geocode();\n if (coordinates) {\n this.flyTo(coordinates);\n }\n } catch (error) {\n this.geocodeHistory.errorText = error instanceof Error ? error.message : 'Location error';\n } finally {\n this.isGettingLocation = false;\n if (this.rootElement) {\n this.updateHTML();\n }\n }\n };\n\n /** Perform geocoding */\n geocode: (address: string) => Promise<void> = async address => {\n const coordinates = await this.geocodeHistory.geocode(\n this.geocoder,\n this.addressText,\n this.props.apiKey\n );\n // Re-render to show updated history or error (guard against torn-down widget)\n if (this.rootElement) {\n this.updateHTML();\n }\n if (coordinates) {\n this.flyTo(coordinates);\n }\n };\n\n flyTo(viewState: ViewState) {\n for (const viewId of this.viewIds) {\n // Call callback with geocoded coordinates\n if ('longitude' in viewState && 'latitude' in viewState) {\n this.props.onGeocode?.({\n viewId,\n coordinates: {\n longitude: viewState.longitude as number,\n latitude: viewState.latitude as number,\n zoom: viewState.zoom as number | undefined\n }\n });\n }\n\n const currentViewState = this.getViewState(viewId);\n const nextViewState: ViewState = {\n ...currentViewState,\n ...viewState\n };\n if (this.props.transitionDuration > 0) {\n nextViewState.transitionDuration = this.props.transitionDuration;\n nextViewState.transitionInterpolator =\n 'latitude' in nextViewState ? new FlyToInterpolator() : new LinearInterpolator();\n }\n this.setViewState(viewId, nextViewState);\n }\n }\n}\n\nfunction getGeocoder(props: {geocoder?: string; customGeocoder?: Geocoder}): Geocoder {\n switch (props.geocoder) {\n case 'google':\n return GoogleGeocoder;\n case 'mapbox':\n return MapboxGeocoder;\n case 'opencage':\n return OpenCageGeocoder;\n case 'coordinates':\n return CoordinatesGeocoder;\n case 'custom':\n if (!props.customGeocoder) {\n throw new Error('Custom geocoder is not defined');\n }\n return props.customGeocoder;\n default:\n throw new Error(`Unknown geocoder: ${props.geocoder}`);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type JSX, type ComponentChild} from 'preact';\nimport {useState, useRef, useEffect} from 'preact/hooks';\nimport {getCSSMask} from '../data-url';\n\nexport type MenuItem =\n | string\n | {\n value?: string;\n label: string;\n icon?: string;\n onSelect?: () => void;\n };\n\nexport type DropdownMenuProps = {\n menuItems: MenuItem[];\n onSelect?: (value: string) => void;\n style?: Partial<CSSStyleDeclaration>;\n};\n\nfunction getMenuItemValue(item: MenuItem): string | undefined {\n return typeof item === 'string' ? item : item.value;\n}\n\nfunction getMenuItemLabel(item: MenuItem): string {\n return typeof item === 'string' ? item : item.label;\n}\n\nfunction getMenuItemIcon(item: MenuItem): string | undefined {\n return typeof item === 'string' ? undefined : item.icon;\n}\n\nexport const DropdownMenu = (props: DropdownMenuProps) => {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <SimpleMenu\n {...props}\n style={{...props.style, position: 'absolute'}}\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n trigger={\n <button className=\"deck-widget-dropdown-button\" onClick={() => setIsOpen(!isOpen)}>\n <span className={`deck-widget-dropdown-icon ${isOpen ? 'open' : ''}`} />\n </button>\n }\n />\n );\n};\n\nexport type SimpleMenuProps = DropdownMenuProps & {\n trigger?: ComponentChild;\n isOpen: boolean;\n onClose: () => void;\n};\n\nexport const SimpleMenu = (props: SimpleMenuProps) => {\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n props.onClose();\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, []);\n\n const handleSelect = (value: string | undefined, item: MenuItem) => {\n if (value) {\n if (typeof item === 'object') {\n item.onSelect?.();\n }\n props.onSelect?.(value);\n props.onClose();\n }\n };\n\n // Don't render anything if there are no menu items\n if (props.menuItems.length === 0) {\n return null;\n }\n\n return (\n <div className=\"deck-widget-dropdown-container\" ref={dropdownRef}>\n {props.trigger}\n {props.isOpen && (\n <ul className=\"deck-widget-dropdown-menu\" style={props.style as JSX.CSSProperties}>\n {props.menuItems.map((item, i) => {\n const value = getMenuItemValue(item);\n const icon = getMenuItemIcon(item);\n return (\n <li\n className={`deck-widget-dropdown-item ${value ? '' : 'disabled'}`}\n key={i}\n onClick={() => handleSelect(value, item)}\n >\n {icon && (\n <span className=\"deck-widget-dropdown-item-icon\" style={getCSSMask(icon)} />\n )}\n {getMenuItemLabel(item)}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type Geocoder} from './geocoder';\n\nconst CURRENT_LOCATION = 'current';\nconst LOCAL_STORAGE_KEY = 'deck-geocoder-history';\n\nexport type GeocoderHistoryProps = {\n maxEntries?: number;\n};\n\n/**\n * An internal, experimental helper class for storing a list of locations in local storage.\n * @todo Remove the UI related state.\n */\nexport class GeocoderHistory {\n props: Required<GeocoderHistoryProps>;\n addressText = '';\n errorText = '';\n addressHistory: string[] = [];\n\n constructor(props: GeocoderHistoryProps) {\n this.props = {maxEntries: 5, ...props};\n this.addressHistory = this.loadPreviousAddresses();\n }\n\n /** PErform geocoding */\n async geocode(geocoder: Geocoder, address: string, apiKey: string) {\n this.errorText = '';\n this.addressText = address;\n try {\n const coordinates = await geocoder.geocode(address, apiKey);\n if (coordinates) {\n this.storeAddress(this.addressText);\n return coordinates;\n }\n this.errorText = 'Invalid address';\n } catch (error) {\n this.errorText = `${(error as Error).message}`;\n }\n return null;\n }\n\n loadPreviousAddresses(): string[] {\n try {\n const stored = window.localStorage.getItem(LOCAL_STORAGE_KEY);\n const list = stored && JSON.parse(stored);\n const addresses = Array.isArray(list)\n ? list.filter((v): v is string => typeof v === 'string')\n : [];\n return addresses;\n } catch {\n // ignore\n }\n return [];\n }\n\n storeAddress(address: string) {\n const cleaned = address.trim();\n if (!cleaned || cleaned === CURRENT_LOCATION) {\n return;\n }\n const deduped = [cleaned, ...this.addressHistory.filter(a => a !== cleaned)];\n this.addressHistory = deduped.slice(0, this.props.maxEntries);\n try {\n window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.addressHistory));\n } catch {\n // ignore\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type Geocoder} from './geocoder';\n\nconst GOOGLE_URL = 'https://maps.googleapis.com/maps/api/geocode/json';\nconst MAPBOX_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places';\nconst OPENCAGE_API_URL = 'https://api.opencagedata.com/geocode/v1/json';\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from Google\n * @see https://developers.google.com/maps/documentation/geocoding/get-api-key\n */\nexport const GoogleGeocoder = {\n name: 'google',\n requiresApiKey: true,\n async geocode(\n address: string,\n apiKey: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const json = await fetchJson(`${GOOGLE_URL}?address=${encodedAddress}&key=${apiKey}`);\n\n switch (json.status) {\n case 'OK':\n const loc = json.results.length > 0 && json.results[0].geometry.location;\n return loc ? {longitude: loc.lng, latitude: loc.lat} : null;\n default:\n throw new Error(`Google Geocoder failed: ${json.status}`);\n }\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from Mapbox\n * @see https://docs.mapbox.com/api/search/geocoding/\n */\nexport const MapboxGeocoder = {\n name: 'google',\n requiresApiKey: true,\n async geocode(\n address: string,\n apiKey: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const json = await fetchJson(`${MAPBOX_URL}/${encodedAddress}.json?access_token=${apiKey}`);\n\n if (Array.isArray(json.features) && json.features.length > 0) {\n const center = json.features[0].center;\n if (Array.isArray(center) && center.length >= 2) {\n return {longitude: center[0], latitude: center[1]};\n }\n }\n return null;\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from OpenCageData\n * @see https://opencagedata.com/api\n */\nexport const OpenCageGeocoder = {\n name: 'opencage',\n requiresApiKey: true,\n async geocode(\n address: string,\n key: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const data = await fetchJson(`${OPENCAGE_API_URL}?q=${encodedAddress}&key=${key}`);\n if (Array.isArray(data.results) && data.results.length > 0) {\n const geometry = data.results[0].geometry;\n return {longitude: geometry.lng, latitude: geometry.lat};\n }\n return null;\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder adapter that wraps the browser's geolocation API. Always returns the user's current location.\n * @note Not technically a geocoder, but a geolocation service that provides a source of locations.\n * @note The user must allow location access for this to work.\n */\nexport const CurrentLocationGeocoder = {\n name: 'current',\n requiresApiKey: false,\n /** Attempt to call browsers geolocation API */\n async geocode(): Promise<{longitude: number; latitude: number} | null> {\n if (!navigator.geolocation) {\n throw new Error('Geolocation not supported');\n }\n return new Promise((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(\n /** @see https://developer.mozilla.org/docs/Web/API/GeolocationPosition */\n (position: GeolocationPosition) => {\n const {longitude, latitude} = position.coords;\n resolve({longitude, latitude});\n },\n /** @see https://developer.mozilla.org/docs/Web/API/GeolocationPositionError */\n (error: GeolocationPositionError) => reject(new Error(error.message))\n );\n });\n }\n} as const satisfies Geocoder;\n\n/** Fetch JSON, catching HTTP errors */\nasync function fetchJson(url: string): Promise<any> {\n let response: Response;\n try {\n response = await fetch(url);\n } catch (error) {\n // Annoyingly, fetch reports some errors (e.g. CORS) using excpetions, not response.ok\n throw new Error(`CORS error? ${error}. ${url}: `);\n }\n if (!response.ok) {\n throw new Error(`${response.statusText}. ${url}: `);\n }\n const data = await response.json();\n if (!data) {\n throw new Error(`No data returned. ${url}`);\n }\n return data;\n}\n\n/**\n * Parse a coordinate string.\n * Supports comma- or semicolon-separated values.\n * Heuristically determines which value is longitude and which is latitude.\n */\nexport const CoordinatesGeocoder = {\n name: 'coordinates',\n requiresApiKey: false,\n placeholderLocation: `-122.45, 37.8 or 37\u00B048'N, 122\u00B027'W`,\n async geocode(address: string): Promise<{longitude: number; latitude: number} | null> {\n return parseCoordinates(address) || null;\n }\n} as const satisfies Geocoder;\n\n/**\n * Parse an input string for coordinates.\n * Supports comma- or semicolon-separated values.\n * Heuristically determines which value is longitude and which is latitude.\n */\nfunction parseCoordinates(input) {\n input = input.trim();\n const parts = input.split(/[,;]/).map(p => p.trim());\n if (parts.length < 2) return null;\n const first = parseCoordinatePart(parts[0]);\n const second = parseCoordinatePart(parts[1]);\n if (first === null || second === null) return null;\n if (Math.abs(first) > 90 && Math.abs(second) > 90) {\n return null;\n }\n // Use a heuristic:\n // If one number exceeds 90 in absolute value, it's likely a longitude.\n if (Math.abs(first) > 90) {\n return {longitude: first, latitude: second};\n }\n if (Math.abs(second) > 90) {\n return {longitude: second, latitude: first};\n }\n // If both are <= 90, assume order: latitude, longitude.\n return {latitude: first, longitude: second};\n}\n\n/**\n * Parse a single coordinate part (which may be in decimal or DMS format).\n */\nfunction parseCoordinatePart(s: string): number | null {\n s = s.trim();\n // If the string contains a degree symbol or similar markers, use DMS parsing.\n if (s.includes('\u00B0') || s.includes(\"'\") || s.includes('\"')) {\n const value = dmsToDecimal(s);\n return isNaN(value) ? null : value;\n }\n // Otherwise, check for a cardinal letter and remove it.\n let sign = 1;\n if (/[SW]/i.test(s)) sign = -1;\n s = s.replace(/[NSEW]/gi, '');\n const value = parseFloat(s);\n return isNaN(value) ? null : sign * value;\n}\n\n/** Convert a DMS string (e.g. \"37\u00B048'00\\\"N\") to decimal degrees. */\nfunction dmsToDecimal(s: string): number {\n // A simple regex to extract degrees, minutes, seconds and direction.\n const regex = /(-?\\d+)[\u00B0d]\\s*(\\d+)?['\u2032m]?\\s*(\\d+(?:\\.\\d+)?)?[\\\"\u2033s]?\\s*([NSEW])?/i;\n const match = s.match(regex);\n if (!match) return NaN;\n const degrees = parseFloat(match[1]) || 0;\n const minutes = parseFloat(match[2]) || 0;\n const seconds = parseFloat(match[3]) || 0;\n const direction = match[4] || '';\n const sign = degrees < 0 ? -1 : 1;\n let dec = Math.abs(degrees) + minutes / 60 + seconds / 3600;\n if (/[SW]/i.test(direction)) {\n dec = -dec;\n } else {\n dec = sign * dec;\n }\n return dec;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport {log, Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {IconButton} from './lib/components/icon-button';\n\n/* eslint-enable max-len */\n\nexport type FullscreenWidgetProps = WidgetProps & {\n id?: string;\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message when out of fullscreen. */\n enterLabel?: string;\n /** Tooltip message when fullscreen. */\n exitLabel?: string;\n /**\n * A compatible DOM element which should be made full screen. By default, the map container element will be made full screen.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#Compatible_elements\n */\n container?: HTMLElement;\n /**\n * Callback when fullscreen state changes (via user click or browser fullscreen events).\n */\n onFullscreenChange?: (fullscreen: boolean) => void;\n};\n\nexport class FullscreenWidget extends Widget<FullscreenWidgetProps> {\n static defaultProps: Required<FullscreenWidgetProps> = {\n ...Widget.defaultProps,\n id: 'fullscreen',\n placement: 'top-left',\n viewId: null,\n enterLabel: 'Enter Fullscreen',\n exitLabel: 'Exit Fullscreen',\n container: undefined!,\n onFullscreenChange: () => {}\n };\n\n className = 'deck-widget-fullscreen';\n placement: WidgetPlacement = 'top-left';\n fullscreen: boolean = false;\n\n constructor(props: FullscreenWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n onAdd(): void {\n document.addEventListener('fullscreenchange', this.onFullscreenChange.bind(this));\n }\n\n onRemove() {\n document.removeEventListener('fullscreenchange', this.onFullscreenChange.bind(this));\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const isFullscreen = this.getFullscreen();\n render(\n <IconButton\n onClick={() => {\n this.handleClick().catch(err => log.error(err)());\n }}\n label={isFullscreen ? this.props.exitLabel : this.props.enterLabel}\n className={isFullscreen ? 'deck-widget-fullscreen-exit' : 'deck-widget-fullscreen-enter'}\n />,\n rootElement\n );\n }\n\n setProps(props: Partial<FullscreenWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n getContainer() {\n return this.props.container || this.deck?.props.parent || this.deck?.getCanvas()?.parentElement;\n }\n\n getFullscreen(): boolean {\n return this.fullscreen;\n }\n\n onFullscreenChange() {\n const fullscreen = document.fullscreenElement === this.getContainer();\n if (fullscreen !== this.fullscreen) {\n this.fullscreen = fullscreen;\n this.props.onFullscreenChange?.(fullscreen);\n this.updateHTML();\n }\n }\n\n async handleClick() {\n const isFullscreen = this.getFullscreen();\n if (isFullscreen) {\n await this.exitFullscreen();\n } else {\n await this.requestFullscreen();\n }\n // Note: updateHTML is called by onFullscreenChange event handler\n }\n\n async requestFullscreen() {\n const container = this.getContainer();\n if (container?.requestFullscreen) {\n await container.requestFullscreen({navigationUI: 'hide'});\n } else {\n this.togglePseudoFullscreen();\n }\n }\n\n async exitFullscreen() {\n if (document.exitFullscreen) {\n await document.exitFullscreen();\n } else {\n this.togglePseudoFullscreen();\n }\n }\n\n togglePseudoFullscreen() {\n this.getContainer()?.classList.toggle('deck-pseudo-fullscreen');\n // No fullscreenchange event fires for pseudo-fullscreen, so manually update state\n this.fullscreen = !this.fullscreen;\n this.props.onFullscreenChange?.(this.fullscreen);\n this.updateHTML();\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {JSX, render} from 'preact';\nimport {useState, useRef, useEffect} from 'preact/hooks';\nimport {\n Widget,\n _deepEqual as deepEqual,\n type Deck,\n type WidgetProps,\n type View\n} from '@deck.gl/core';\n\nexport type ViewLayout = {\n /** Stacking orientation of the sub views */\n orientation: 'vertical' | 'horizontal';\n /** Initial instances that describe the sub views.\n * x, y, width and height of the views' props will be overwritten by the SplitterWidget as split changes. */\n views: [view1: View | ViewLayout, view2: View | ViewLayout];\n /** The ratio of view1's share over the whole available height (vertical) or width (horizontal). Between 0-1.\n * @default 0.5\n */\n initialSplit?: number;\n /** Whether the split can be changed by dragging the border between the two views.\n * @default true\n */\n editable?: boolean;\n /** Min value of the split\n * @default 0.05\n */\n minSplit?: number;\n /** Max value of the split\n * @default 0.95\n */\n maxSplit?: number;\n};\n\ntype ManagedViewLayout = {\n id: number;\n orientation: 'vertical' | 'horizontal';\n views: [view1: View | ManagedViewLayout, view2: View | ManagedViewLayout];\n split: number;\n editable: boolean;\n minSplit: number;\n maxSplit: number;\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\nfunction parseViewLayout(root: ViewLayout): ManagedViewLayout[] {\n const layoutsById: ManagedViewLayout[] = [];\n const isViewLayout = (v: View | ViewLayout): v is ViewLayout => 'views' in v;\n function createManagedViewLayout(l: ViewLayout): ManagedViewLayout {\n const id = layoutsById.length;\n const minSplit = l.minSplit ?? 0.05;\n const maxSplit = l.maxSplit ?? 0.95;\n const split = Math.min(Math.max(l.initialSplit ?? 0.5, minSplit), maxSplit);\n const managed: ManagedViewLayout = {\n id,\n orientation: l.orientation,\n views: l.views as [view1: View | ManagedViewLayout, view2: View | ManagedViewLayout],\n split,\n editable: l.editable ?? true,\n minSplit,\n maxSplit,\n x: 0,\n y: 0,\n width: 0,\n height: 0\n };\n layoutsById.push(managed);\n managed.views = [\n isViewLayout(l.views[0]) ? createManagedViewLayout(l.views[0]) : l.views[0],\n isViewLayout(l.views[1]) ? createManagedViewLayout(l.views[1]) : l.views[1]\n ];\n return managed;\n }\n createManagedViewLayout(root);\n return layoutsById;\n}\n\nfunction evaluateViews(root: ManagedViewLayout): View[] {\n const views: View[] = [];\n function evaluateViewLayout(\n l: ManagedViewLayout,\n x: number,\n y: number,\n width: number,\n height: number\n ) {\n l.x = x;\n l.y = y;\n l.width = width;\n l.height = height;\n\n const child1X = x;\n const child1Y = y;\n let child1Width = width;\n let child1Height = height;\n let child2X = x;\n let child2Y = y;\n let child2Width = width;\n let child2Height = height;\n\n if (l.orientation === 'horizontal') {\n child1Width = width * l.split;\n child2X = x + child1Width;\n child2Width = width - child1Width;\n } else {\n child1Height = height * l.split;\n child2Y = y + child1Height;\n child2Height = height - child1Height;\n }\n\n const [view1, view2] = l.views;\n if ('views' in view1) {\n evaluateViewLayout(view1, child1X, child1Y, child1Width, child1Height);\n } else {\n views.push(\n view1.clone({\n x: `${child1X}%`,\n y: `${child1Y}%`,\n width: `${child1Width}%`,\n height: `${child1Height}%`\n })\n );\n }\n\n if ('views' in view2) {\n evaluateViewLayout(view2, child2X, child2Y, child2Width, child2Height);\n } else {\n views.push(\n view2.clone({\n x: `${child2X}%`,\n y: `${child2Y}%`,\n width: `${child2Width}%`,\n height: `${child2Height}%`\n })\n );\n }\n }\n\n evaluateViewLayout(root, 0, 0, 100, 100);\n return views;\n}\n\n/** Properties for the SplitterWidget */\nexport type SplitterWidgetProps<ViewsT extends View[] = View[]> = WidgetProps & {\n /** Stacking views descriptor */\n viewLayout: ViewLayout;\n /** Callback invoked when the splitter is dragged with the new split value */\n onChange?: (views: ViewsT) => void;\n /** Callback invoked when dragging starts */\n onDragStart?: () => void;\n /** Callback invoked when dragging ends */\n onDragEnd?: () => void;\n};\n\n/**\n * A draggable splitter widget that appears as a vertical or horizontal line\n * across the deck.gl canvas. It positions itself based on the split percentage\n * of the first view and provides callbacks when dragged.\n */\nexport class SplitterWidget<ViewsT extends View[] = View[]> extends Widget<\n SplitterWidgetProps<ViewsT>,\n ViewsT\n> {\n static defaultProps: Required<SplitterWidgetProps> = {\n ...Widget.defaultProps,\n id: 'splitter-widget',\n viewLayout: undefined!,\n onChange: () => {},\n onDragStart: () => {},\n onDragEnd: () => {}\n };\n\n className = 'deck-widget-splitter';\n placement = 'fill' as const;\n viewLayouts!: ManagedViewLayout[];\n /** evaluated from the current viewLayouts */\n views!: ViewsT;\n /** views set in the last update */\n lastViews?: ViewsT;\n needsUpdate = true;\n\n constructor(props: SplitterWidgetProps<ViewsT>) {\n super(props);\n this.viewLayouts = parseViewLayout(this.props.viewLayout);\n }\n\n setProps(props: Partial<SplitterWidgetProps<ViewsT>>) {\n if (props.viewLayout && !deepEqual(props.viewLayout, this.props.viewLayout, -1)) {\n this.viewLayouts = parseViewLayout(props.viewLayout);\n this.views = undefined!;\n }\n super.setProps(props);\n }\n\n onRedraw() {\n // Actually update DOM\n super.updateHTML();\n }\n\n // Usually widgets rerender their DOM elements here\n // In this case we need the widget UI to synchronize with deck view states\n // so we update deck props here and rerender DOM in the next onRedraw\n updateHTML() {\n if (!this.views) {\n // viewLayouts has changed, re-evaluate\n this.views = evaluateViews(this.viewLayouts[0]) as ViewsT;\n // we send a copy to the callback so that externally set views can be differentiated from internal\n this.props.onChange(this.views.slice() as ViewsT);\n }\n // This method is called inside deck.setProps > widgetManager.setProps > widget.setProps\n // Calling deck.setProps immediately would cause infinite loop\n requestAnimationFrame(() => {\n this.doUpdate();\n });\n }\n\n private doUpdate() {\n if (this.deck) {\n const deckViews = this.deck.props.views;\n const isManagedExternally =\n // is not empty\n deckViews &&\n // is not set by us\n deckViews !== this.lastViews;\n\n if (!isManagedExternally && this.lastViews !== this.views) {\n this.lastViews = this.views;\n this.deck.setProps({views: this.views});\n }\n }\n }\n\n private onChange(newSplit: number, layout: ManagedViewLayout) {\n layout.split = newSplit;\n // layout has updated, re-evaluate\n this.views = evaluateViews(this.viewLayouts[0]) as ViewsT;\n // we send a copy to the callback so that externally set views can be differentiated from internal\n this.props.onChange(this.views.slice() as ViewsT);\n this.doUpdate();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <>\n {this.viewLayouts.map(\n layout =>\n layout.editable && (\n <Splitter\n {...layout}\n onChange={newSplit => this.onChange(newSplit, layout)}\n onDragStart={() => this.props.onDragStart()}\n onDragEnd={() => this.props.onDragStart()}\n />\n )\n )}\n </>,\n rootElement\n );\n }\n}\n\n/**\n * A functional component that renders a draggable splitter line.\n * It computes its position based on the provided split percentage and\n * updates it during mouse drag events.\n */\nfunction Splitter({\n orientation,\n x,\n y,\n width,\n height,\n split,\n minSplit,\n maxSplit,\n onChange,\n onDragStart,\n onDragEnd\n}: {\n orientation: 'vertical' | 'horizontal';\n x: number;\n y: number;\n width: number;\n height: number;\n split: number;\n minSplit: number;\n maxSplit: number;\n onChange?: (newSplit: number) => void;\n onDragStart?: () => void;\n onDragEnd?: () => void;\n}) {\n const [dragging, setDragging] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!dragging) {\n return undefined;\n }\n\n const handleDragging = (event: PointerEvent) => {\n if (!containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n let newSplit: number;\n if (orientation === 'horizontal') {\n newSplit = (event.clientX - rect.left) / rect.width;\n } else {\n newSplit = (event.clientY - rect.top) / rect.height;\n }\n // Clamp newSplit between 5% and 95%\n newSplit = Math.min(Math.max(newSplit, minSplit), maxSplit);\n onChange?.(newSplit);\n };\n\n const handleDragEnd = () => {\n onDragEnd?.();\n setDragging(false);\n };\n\n document.addEventListener('pointermove', handleDragging);\n document.addEventListener('pointerup', handleDragEnd);\n document.addEventListener('pointerleave', handleDragEnd);\n\n return () => {\n document.removeEventListener('pointermove', handleDragging);\n document.removeEventListener('pointerup', handleDragEnd);\n document.removeEventListener('pointerleave', handleDragEnd);\n };\n }, [dragging]);\n\n const handleDragStart = (event: PointerEvent) => {\n setDragging(true);\n onDragStart?.();\n event.preventDefault();\n };\n\n // The splitter line style based on orientation and the current split percentage.\n const splitterStyle: JSX.CSSProperties =\n orientation === 'horizontal' ? {left: `${split * 100}%`} : {top: `${split * 100}%`};\n\n // Container style to fill the entire deck.gl canvas.\n const containerStyle: JSX.CSSProperties = {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: `${width}%`,\n height: `${height}%`\n };\n\n return (\n <div ref={containerRef} style={containerStyle}>\n <div\n className={`deck-widget-splitter-handle deck-widget-splitter-handle--${orientation} ${dragging ? 'active' : ''}`}\n style={splitterStyle}\n onPointerDown={handleDragStart} // Use the appropriate Preact event type.\n />\n </div>\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, PickingInfo, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render, JSX} from 'preact';\nimport {Popover, type PopoverProps} from './lib/components/popover';\nimport {UserContent} from './lib/components/user-content';\n\nexport type TooltipContent = {\n /** Anchor of the popup in world coordinates, e.g. [longitude, latitude].\n * If not supplied, default to the mouse position where the popup was triggered.\n */\n position?: number[];\n /** Text content to display in the popup */\n text?: string;\n /** HTML content to display in the popup. If supplied, `text` is ignored. */\n html?: string;\n /** HTML element to attach inside the popup. */\n element?: HTMLElement | null;\n /** Custom class name to add to the popup */\n className?: string;\n /** CSS style overrides of the popup */\n style?: Partial<CSSStyleDeclaration>;\n};\n\nexport type InfoWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Determines the interaction mode of the widget */\n mode: 'click' | 'hover';\n /** Function to generate the popup contents from the selected element */\n getTooltip?: (\n info: PickingInfo,\n widget: InfoWidget\n ) => TooltipContent | string | null | undefined;\n /** Position popup relative to the anchor.\n * @default 'right'\n */\n placement?: PopoverProps['placement'];\n /** Pixel offset\n * @default 10\n */\n offset?: PopoverProps['offset'];\n /**\n * Show an arrow pointing at the anchor. Optionally accepts a pixel size.\n * @default 10\n */\n arrow?: PopoverProps['arrow'];\n};\n\nexport class InfoWidget extends Widget<InfoWidgetProps> {\n static defaultProps: Required<InfoWidgetProps> = {\n ...Widget.defaultProps,\n id: 'info',\n viewId: null,\n mode: 'hover',\n getTooltip: undefined!,\n placement: 'right',\n offset: 10,\n arrow: 10\n };\n\n className = 'deck-widget-info';\n placement = 'fill' as const;\n viewport?: Viewport;\n tooltip: Required<TooltipContent> | null = null;\n\n constructor(props: InfoWidgetProps) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<InfoWidgetProps>) {\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onAdd({deck}: {deck: Deck<any>; viewId: string | null}) {\n this.deck = deck;\n }\n\n onRemove() {\n // Invoke clean up of preact hooks\n if (this.rootElement) {\n render(null, this.rootElement);\n }\n }\n\n onViewportChange(viewport) {\n this.viewport = viewport;\n this.updateHTML();\n }\n\n onHover(info: PickingInfo): void {\n if (this.props.mode === 'hover') {\n this.tooltip = this._getTooltip(info);\n }\n }\n\n onClick(info: PickingInfo): void {\n if (this.props.mode === 'click') {\n this.tooltip = this._getTooltip(info);\n }\n }\n\n protected _getTooltip(info: PickingInfo): Required<TooltipContent> | null {\n if (!this.props.getTooltip) return null;\n\n const content = this.props.getTooltip(info, this) ?? null;\n if (content === null) return null;\n const normalizedTooltip: TooltipContent =\n typeof content === 'string' ? {text: content} : content;\n\n const position = normalizedTooltip.position || info.coordinate;\n if (!position) return null;\n\n return {\n position,\n text: '',\n html: '',\n element: null,\n className: '',\n style: {},\n ...normalizedTooltip\n };\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n if (!this.viewport || this.tooltip === null) {\n render(null, rootElement);\n return;\n }\n const style: Partial<CSSStyleDeclaration> = {\n ...this.props.style,\n ...this.tooltip.style\n };\n // Project the clicked geographic coordinate to canvas (x, y)\n const [x, y] = this.viewport.project(this.tooltip.position);\n\n // Render the popup container with a content box and a placeholder for the arrow.\n // The container is positioned absolutely (initially at 0,0) and will be repositioned after measuring.\n const ui = (\n <Popover\n x={x}\n y={y}\n placement={this.props.placement}\n arrow={this.props.arrow}\n arrowColor=\"var(--menu-background, #fff)\"\n offset={this.props.offset}\n >\n <UserContent\n className={`deck-widget-popup-content ${this.tooltip.className} ${this.props.className}`}\n style={style as JSX.CSSProperties}\n html={this.tooltip.html}\n text={this.tooltip.text}\n element={this.tooltip.element}\n />\n </Popover>\n );\n render(ui, rootElement);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport type {JSX, ComponentChildren} from 'preact';\nimport {useRef, useEffect, useMemo} from 'preact/hooks';\nimport {\n computePosition,\n flip,\n shift,\n offset,\n arrow,\n autoUpdate,\n type Placement,\n type ComputePositionConfig\n} from '@floating-ui/dom';\n\nexport type PopoverProps = {\n /** Anchor x */\n x: number;\n /** Anchor y */\n y: number;\n /** Position content relative to the anchor.\n * @default 'right'\n */\n placement?: Placement;\n /** Pixel offset\n * @default 0\n */\n offset?: number;\n /**\n * Show an arrow pointing at the anchor. Optionally accepts a pixel size.\n * @default false\n */\n arrow?: false | number | [width: number, height: number];\n /**\n * CSS color of the arrow\n * @default 'white'\n */\n arrowColor?: string;\n /** Content of the popover */\n children: ComponentChildren;\n};\n\nexport const Popover = ({\n x,\n y,\n placement = 'right',\n offset: pixelOffset = 0,\n arrow: arrowSize = false,\n arrowColor = 'white',\n children\n}: PopoverProps) => {\n const anchorRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const arrowRef = useRef<HTMLDivElement>(null);\n const updaterRef = useRef<() => void>();\n\n updaterRef.current = () => {\n if (!anchorRef.current || !contentRef.current) return;\n\n const arrowWidth = Array.isArray(arrowSize) ? arrowSize[0] : arrowSize || 0;\n const arrowHeight = Array.isArray(arrowSize) ? arrowSize[1] : arrowSize || 0;\n const padding = pixelOffset + Math.max(arrowHeight, arrowWidth);\n\n const middleware: ComputePositionConfig['middleware'] = placement.includes('-')\n ? [offset(padding), flip(), shift()]\n : [offset(padding), shift(), flip()];\n if (arrowRef.current) middleware.push(arrow({element: arrowRef.current}));\n computePosition(anchorRef.current, contentRef.current, {\n placement,\n strategy: 'fixed',\n middleware\n }).then(popoverPos => {\n if (contentRef.current) {\n Object.assign(contentRef.current.style, {\n left: `${popoverPos.x}px`,\n top: `${popoverPos.y}px`\n });\n }\n\n const arrowData = popoverPos.middlewareData.arrow;\n if (arrowData && arrowRef.current) {\n const arrowStyle = createArrow(arrowWidth, arrowHeight, arrowColor, popoverPos.placement);\n arrowStyle.transform = `translate(${arrowData.x || 0}px, ${arrowData.y || 0}px)`;\n Object.assign(arrowRef.current.style, arrowStyle);\n }\n });\n };\n\n useMemo(() => {\n updaterRef.current?.();\n }, [x, y, placement, arrowSize, pixelOffset]);\n\n useEffect(() => {\n // initial mount\n const anchor = anchorRef.current;\n const content = contentRef.current;\n if (!anchor || !content) {\n return undefined;\n }\n content.style.visibility = 'visible';\n const cleanup = autoUpdate(anchor, content, () => updaterRef.current?.());\n return () => {\n cleanup();\n };\n }, []);\n\n return (\n <div style={{position: 'absolute', left: x, top: y}} ref={anchorRef}>\n <div\n className=\"deck-widget deck-widget-popover\"\n style={{position: 'fixed', visibility: 'hidden', pointerEvents: 'none'}}\n ref={contentRef}\n >\n {Boolean(arrowSize) && (\n <div\n className=\"deck-widget-popover-arrow\"\n style={{position: 'absolute'}}\n ref={arrowRef}\n />\n )}\n {children}\n </div>\n </div>\n );\n};\n\nfunction createArrow(\n width: number,\n height: number,\n color: string,\n placement: Placement\n): JSX.CSSProperties {\n const result: JSX.CSSProperties = {\n width: 0,\n height: 0,\n top: '',\n bottom: '',\n left: '',\n right: ''\n };\n if (placement.startsWith('bottom')) {\n result.borderLeft = `${width / 2}px solid transparent`;\n result.borderRight = `${width / 2}px solid transparent`;\n result.borderBottom = `${height}px solid ${color}`;\n result.borderTop = '';\n result.top = `${-height}px`;\n } else if (placement.startsWith('top')) {\n result.borderLeft = `${width / 2}px solid transparent`;\n result.borderRight = `${width / 2}px solid transparent`;\n result.borderTop = `${height}px solid ${color}`;\n result.borderBottom = '';\n result.bottom = `${-height}px`;\n } else if (placement.startsWith('right')) {\n result.borderTop = `${width / 2}px solid transparent`;\n result.borderBottom = `${width / 2}px solid transparent`;\n result.borderRight = `${height}px solid ${color}`;\n result.borderLeft = '';\n result.left = `${-height}px`;\n } else if (placement.startsWith('left')) {\n result.borderTop = `${width / 2}px solid transparent`;\n result.borderBottom = `${width / 2}px solid transparent`;\n result.borderLeft = `${height}px solid ${color}`;\n result.borderRight = '';\n result.right = `${-height}px`;\n }\n return result;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport type {JSX, ComponentChildren} from 'preact';\nimport {useEffect, useRef} from 'preact/hooks';\n\nexport type UserContentProps = JSX.HTMLAttributes<HTMLDivElement> & {\n text?: string;\n html?: string;\n element?: HTMLElement | null;\n};\n\nexport const UserContent = ({text, html, element, ...props}: UserContentProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (containerRef.current && element) {\n containerRef.current.append(element);\n }\n return () => {\n element?.remove();\n };\n }, [element]);\n\n return (\n <div ref={containerRef} {...props} dangerouslySetInnerHTML={html ? {__html: html} : undefined}>\n {text}\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render, JSX} from 'preact';\nimport {Popover, type PopoverProps} from './lib/components/popover';\nimport {UserContent} from './lib/components/user-content';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type PopupContent = {\n text?: string;\n html?: string;\n element?: HTMLElement | null;\n};\n\nexport type PopupWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Content to display at the anchor. Opens the popup if clicked. */\n marker?: PopupContent | null;\n /** Content to display in the popup */\n content: string | PopupContent;\n /** Whether the pop up is open by default\n * @default true\n */\n defaultIsOpen?: boolean;\n /** Anchor of the popup in world coordinates, e.g. [longitude, latitude]. */\n position: number[];\n /** Position popup relative to the anchor.\n * @default 'right'\n */\n placement?: PopoverProps['placement'];\n /** Pixel offset\n * @default 10\n */\n offset?: PopoverProps['offset'];\n /**\n * Show an arrow pointing at the anchor. Optionally accepts a pixel size.\n * @default 10\n */\n arrow?: PopoverProps['arrow'];\n /** Whether to show a close button in the popup\n * @default true\n */\n closeButton?: boolean;\n /** Close the popup if clicked outside\n * @default false\n */\n closeOnClickOutside?: boolean;\n /** Callback when popup is opened/closed */\n onOpenChange?: (isOpen: boolean) => void;\n};\n\nexport class PopupWidget extends Widget<PopupWidgetProps> {\n static defaultProps: Required<PopupWidgetProps> = {\n ...Widget.defaultProps,\n id: 'info',\n viewId: null,\n position: [0, 0],\n marker: null,\n defaultIsOpen: true,\n content: '',\n placement: 'right',\n offset: 10,\n arrow: 10,\n closeButton: true,\n closeOnClickOutside: false,\n onOpenChange: () => {}\n };\n\n className = 'deck-widget-popup';\n placement = 'fill' as const;\n viewport?: Viewport;\n isOpen: boolean;\n\n constructor(props: PopupWidgetProps) {\n super(props);\n this.setProps(this.props);\n this.isOpen = this.props.defaultIsOpen;\n }\n\n setProps(props: Partial<PopupWidgetProps>) {\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onAdd({deck}: {deck: Deck<any>; viewId: string | null}) {\n this.deck = deck;\n }\n\n onRemove() {\n // Invoke clean up of preact hooks\n if (this.rootElement) {\n render(null, this.rootElement);\n }\n }\n\n onViewportChange(viewport) {\n this.viewport = viewport;\n this.updateHTML();\n }\n\n onClick() {\n if (this.props.closeOnClickOutside) {\n this._setIsOpen(false);\n }\n }\n\n protected _setIsOpen(isOpen: boolean) {\n if (this.isOpen === isOpen) return;\n this.isOpen = isOpen;\n this.props.onOpenChange?.(isOpen);\n this.updateHTML();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n if (!this.viewport) {\n render(null, rootElement);\n return;\n }\n const {marker, content, style} = this.props;\n // Project the clicked geographic coordinate to canvas (x, y)\n const [x, y] = this.viewport.project(this.props.position);\n\n // Render the popup container with a content box and a placeholder for the arrow.\n // The container is positioned absolutely (initially at 0,0) and will be repositioned after measuring.\n const ui = (\n <div>\n {marker && (\n <div className=\"deck-widget-popup-marker\" style={{left: x, top: y}}>\n <UserContent {...marker} onClick={() => this._setIsOpen(true)} />\n </div>\n )}\n {this.isOpen && (\n <Popover\n x={x}\n y={y}\n placement={this.props.placement}\n arrow={this.props.arrow}\n arrowColor=\"var(--menu-background, #fff)\"\n offset={this.props.offset}\n >\n <div\n className={`deck-widget-popup-content ${this.props.className}`}\n style={style as JSX.CSSProperties}\n >\n {this.props.closeButton && (\n <div\n className=\"deck-widget-popup-controls\"\n style={{width: '100%', display: 'flex', justifyContent: 'end'}}\n >\n <IconButton\n className=\"deck-widget-popup-close-button\"\n onClick={() => this._setIsOpen(false)}\n />\n </div>\n )}\n <UserContent {...(typeof content === 'string' ? {text: content} : content)} />\n </div>\n </Popover>\n )}\n </div>\n );\n render(ui, rootElement);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, PickingInfo, WidgetProps} from '@deck.gl/core';\nimport {render, type JSX} from 'preact';\nimport {SimpleMenu, type MenuItem} from './lib/components/dropdown-menu';\nimport {Popover, type PopoverProps} from './lib/components/popover';\n\nexport type ContextMenuWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Menu items for the menu. */\n menuItems?: MenuItem[];\n /** Callback to provide menu items for the menu given the picked object. Overrides `menuItems` */\n getMenuItems?: (info: PickingInfo, widget: ContextMenuWidget) => MenuItem[] | null;\n /** Callback when a menu item is selected */\n onMenuItemSelected?: (value: string, pickInfo: PickingInfo | null) => void;\n /** Position menu relative to the anchor.\n * @default 'bottom-start'\n */\n placement?: PopoverProps['placement'];\n /** Pixel offset\n * @default 10\n */\n offset?: PopoverProps['offset'];\n /**\n * Show an arrow pointing at the anchor. Optionally accepts a pixel size.\n * @default false\n */\n arrow?: PopoverProps['arrow'];\n};\n\nexport class ContextMenuWidget extends Widget<ContextMenuWidgetProps> {\n static defaultProps: Required<ContextMenuWidgetProps> = {\n ...Widget.defaultProps,\n id: 'context',\n viewId: null,\n menuItems: [],\n getMenuItems: undefined!,\n onMenuItemSelected: () => {},\n placement: 'bottom-start',\n offset: 10,\n arrow: false\n };\n\n className = 'deck-widget-context-menu';\n placement = 'fill' as const;\n\n menu: {\n items: MenuItem[];\n pickInfo: PickingInfo;\n } | null = null;\n\n constructor(props: ContextMenuWidgetProps) {\n super(props);\n this.setProps(this.props);\n }\n\n onAdd({deck}: {deck: Deck<any>}) {\n deck.getCanvas()?.addEventListener('contextmenu', event => this.handleContextMenu(event));\n }\n\n handleContextMenu(srcEvent: MouseEvent) {\n const targetRect = (srcEvent.target as HTMLElement).getBoundingClientRect();\n const x = srcEvent.clientX - targetRect.x;\n const y = srcEvent.clientY - targetRect.y;\n\n const pickInfo = this.deck?.pickObject({x, y}) || {\n x,\n y,\n picked: false,\n layer: null,\n color: null,\n index: -1,\n pixelRatio: 1\n };\n const menuItems = this.props.getMenuItems?.(pickInfo, this) || this.props.menuItems;\n this.menu =\n menuItems.length > 0\n ? {\n items: menuItems,\n pickInfo\n }\n : null;\n srcEvent.preventDefault();\n this.updateHTML();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n if (!this.menu) {\n render(null, rootElement);\n return;\n }\n const {items, pickInfo} = this.menu;\n\n const style = {\n pointerEvents: 'auto',\n position: 'static',\n ...this.props.style\n };\n\n const ui = (\n <Popover\n x={pickInfo.x}\n y={pickInfo.y}\n placement={this.props.placement}\n arrow={this.props.arrow}\n arrowColor=\"var(--menu-background, #fff)\"\n offset={this.props.offset}\n >\n <SimpleMenu\n menuItems={items}\n onSelect={value => this.props.onMenuItemSelected(value, pickInfo)}\n style={style}\n isOpen\n onClose={() => this.hide()}\n />\n </Popover>\n );\n render(ui, rootElement);\n }\n\n hide() {\n this.menu = null;\n this.updateHTML();\n }\n}\n", "import {Widget} from '@deck.gl/core';\nimport type {Position, Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {RangeInput, type RangeInputDecoration} from './lib/components/range-input';\n\nexport type ScrollbarOrientation = 'vertical' | 'horizontal';\n\nexport type ContentBounds = [min: Position, max: Position];\n\nexport type ScrollbarDecoration = {\n contentBounds: ContentBounds;\n color: string;\n title?: string;\n /** Callback when the decoration is clicked. Return `true` to mark the event as handled, and prevent the default behavior. */\n onClick?: (evt: MouseEvent) => boolean;\n};\n\nconst clamp = (value: number, min: number, max: number) => {\n if (value < min) {\n return min;\n }\n if (value > max) {\n return max;\n }\n return value;\n};\n\nexport type ScrollbarWidgetProps = WidgetProps & {\n /** The full extent of the scrollable content, in world coordinates.\n * The widget relies on this value to calculate the position and size of the slider button and track.\n * If not supplied, the scrollbar will always be hidden.\n */\n contentBounds?: ContentBounds | null;\n placement?: WidgetPlacement;\n viewId?: string | null;\n /** Direction of the scrollbar. `'horizontal'` scrolls the camera along the X axis, and `'vertical'` scrolls the camera along the Y axis.\n * @default 'vertical'\n */\n orientation?: ScrollbarOrientation;\n /* Pixels scrolled when clicked on the step buttons.\n * @default 1/10 of the viewport size\n */\n stepSize?: number | null;\n /* Pixels scrolled when clicked on the track.\n * @default 100% of the viewport size\n */\n pageSize?: number | null;\n /** Label of the step button at the start.\n * @default 'Scroll left' | 'Scroll up'\n */\n startButtonAriaLabel?: string;\n /** Label of the end button at the start.\n * @default 'Scroll right' | 'Scroll down'\n */\n endButtonAriaLabel?: string;\n /** If `true`, mouse wheel events over the canvas will be intercepted by this scrollbar.\n * Useful when simulating the native scrollbar's behavior.\n * @default false\n */\n captureWheel?: boolean;\n /** Custom markers to overlay on the track. */\n decorations?: ScrollbarDecoration[];\n};\n\ntype ScrollbarWidgetRequiredProps = Required<ScrollbarWidgetProps>;\n\n/** A scrollbar widget to be used with OrthographicView */\nexport class ScrollbarWidget extends Widget<ScrollbarWidgetProps> {\n static override defaultProps: ScrollbarWidgetRequiredProps = {\n ...Widget.defaultProps,\n contentBounds: null,\n placement: 'top-right',\n viewId: null,\n orientation: 'vertical',\n stepSize: null,\n pageSize: null,\n startButtonAriaLabel: '',\n endButtonAriaLabel: '',\n captureWheel: false,\n decorations: []\n };\n\n override className = 'deck-widget-scrollbar';\n\n placement: WidgetPlacement = 'fill';\n\n private viewport?: Viewport;\n private contentSize = 0;\n private viewportSize = 0;\n private scrollOffset = 0;\n\n constructor(props: ScrollbarWidgetProps) {\n const resolved = {\n ...ScrollbarWidget.defaultProps,\n ...props\n } as ScrollbarWidgetRequiredProps;\n super(resolved);\n this.viewId = resolved.viewId ?? null;\n }\n\n override onViewportChange(viewport: Viewport) {\n this.viewport = viewport;\n this.onRenderHTML();\n }\n\n override onRenderHTML(): void {\n const element = this.rootElement;\n if (!element) {\n return;\n }\n\n element.dataset.placement = this.props.placement;\n const viewport = this.viewport;\n this.updateViewport(viewport);\n\n const clampedOffset = this.getClampedOffset();\n const wheelTarget = this.getWheelEventTarget(this.props.captureWheel ? 'global' : 'local');\n const decorations = this.getDecorations(viewport);\n const isVertical = this.isVertical();\n const startLabel =\n this.props.startButtonAriaLabel ?? (isVertical ? 'Scroll up' : 'Scroll left');\n const endLabel = this.props.endButtonAriaLabel ?? (isVertical ? 'Scroll down' : 'Scroll right');\n\n const ui = (\n <RangeInput\n min={0}\n max={Math.max(0, this.contentSize)}\n step={this.getEffectiveStep()}\n pageSize={this.getEffectivePage()}\n value={[clampedOffset, clampedOffset + this.viewportSize]}\n orientation={this.props.orientation}\n stepButtons\n startButtonAriaLabel={startLabel}\n endButtonAriaLabel={endLabel}\n eventTarget={wheelTarget}\n decorations={decorations}\n onChange={this.handleRangeChange}\n />\n );\n\n render(ui, element);\n }\n\n override onRemove(): void {\n if (this.rootElement) {\n render(null, this.rootElement);\n }\n super.onRemove();\n }\n\n private getContentBounds(viewId: string): ContentBounds | null {\n return this.props.contentBounds ?? this.deck?.getView(viewId)?.controller?.maxBounds ?? null;\n }\n\n private updateViewport(viewport?: Viewport): void {\n if (!viewport) {\n this.contentSize = 0;\n this.scrollOffset = 0;\n this.viewportSize = 0;\n return;\n }\n\n const contentBounds = this.getContentBounds(viewport.id);\n const isVertical = this.isVertical();\n const projectedBounds = contentBounds\n ? projectBounds(contentBounds, viewport, isVertical)\n : ([0, 0] as [number, number]);\n\n this.contentSize = projectedBounds[1] - projectedBounds[0];\n this.scrollOffset = -projectedBounds[0];\n this.viewportSize = isVertical ? viewport.height : viewport.width;\n }\n\n private getDecorations(viewport?: Viewport): RangeInputDecoration[] {\n const {decorations = []} = this.props;\n if (!viewport || decorations.length === 0) {\n return [];\n }\n const contentBounds = this.getContentBounds(viewport.id);\n if (!contentBounds) {\n return [];\n }\n\n const isVertical = this.isVertical();\n const [contentStart] = projectBounds(contentBounds, viewport, isVertical);\n\n return decorations.map(decoration => {\n const [start, end] = projectBounds(decoration.contentBounds, viewport, isVertical);\n const onClick = decoration.onClick\n ? (e: MouseEvent) => {\n const handled = decoration.onClick?.(e);\n if (handled) {\n e.stopPropagation();\n e.preventDefault();\n }\n }\n : undefined;\n return {\n position: [start - contentStart, end - contentStart],\n element: (\n <div\n style={{\n pointerEvents: onClick ? 'all' : 'none',\n width: '100%',\n height: '100%',\n backgroundColor: decoration.color\n }}\n title={decoration.title}\n onClick={onClick}\n />\n )\n };\n });\n }\n\n private getWheelEventTarget(mode: 'global' | 'local' | null) {\n if (mode === null) return null;\n if (mode === 'local') return this.rootElement;\n\n return this.deck?.props.parent || this.deck?.getCanvas()?.parentElement || this.rootElement;\n }\n\n private getMaxScroll(): number {\n return Math.max(0, this.contentSize - this.viewportSize);\n }\n\n private getClampedOffset(): number {\n const maxScroll = this.getMaxScroll();\n return clamp(this.scrollOffset, 0, maxScroll);\n }\n\n private isVertical(): boolean {\n return this.props.orientation !== 'horizontal';\n }\n\n private getEffectiveStep(): number {\n if (typeof this.props.stepSize === 'number' && !Number.isNaN(this.props.stepSize)) {\n return this.props.stepSize;\n }\n return Math.max(1, this.viewportSize / 10 || 1);\n }\n\n private getEffectivePage(): number {\n if (typeof this.props.pageSize === 'number' && !Number.isNaN(this.props.pageSize)) {\n return this.props.pageSize;\n }\n return this.viewportSize;\n }\n\n private emitScroll(next: number): void {\n const maxScroll = this.getMaxScroll();\n const target = clamp(Math.round(next), 0, maxScroll);\n const viewport = this.viewport;\n if (viewport && target !== this.getClampedOffset()) {\n const pixel = viewport.project(viewport.position) as [number, number];\n if (this.isVertical()) {\n pixel[1] -= target - this.scrollOffset;\n } else {\n pixel[0] -= target - this.scrollOffset;\n }\n const {target: newTarget} = viewport.panByPosition(viewport.position, pixel);\n\n // @ts-expect-error Using private method temporary until there's a public one\n this.deck._onViewStateChange({\n viewId: viewport.id,\n viewState: {\n ...this.getViewState(viewport.id),\n target: newTarget\n },\n interactionState: {}\n });\n }\n }\n\n private handleRangeChange = (nextValue: [number, number]) => {\n this.emitScroll(nextValue[0]);\n };\n}\n\nfunction projectBounds(\n bounds: ContentBounds,\n viewport: Viewport,\n isVertical: boolean\n): [min: number, max: number] {\n return bounds\n .map(([x, y]) => viewport.project([x, y, 0]))\n .reduce(\n (range: [number, number], [x, y]) => {\n const value = isVertical ? y : x;\n range[0] = Math.min(range[0], value);\n range[1] = Math.max(range[1], value);\n return range;\n },\n [Infinity, -Infinity]\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport type {JSX} from 'preact';\nimport {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'preact/hooks';\n\nexport type RangeInputDecoration = {\n position: [start: number, end: number];\n element: JSX.Element;\n};\n\nexport type RangeInputProps = {\n className?: string;\n min: number;\n max: number;\n step: number;\n value: [start: number, end: number];\n orientation: 'horizontal' | 'vertical';\n pageSize?: number;\n /** Show step buttons at ends */\n stepButtons?: boolean;\n startButtonAriaLabel?: string;\n endButtonAriaLabel?: string;\n /** Target element for wheel and keyboard events.\n * If not supplied, falls back to the root element of the input.\n */\n eventTarget?: HTMLElement | null;\n decorations?: RangeInputDecoration[];\n onChange?: (nextValue: [start: number, end: number]) => void;\n};\n\ntype DragState = {\n pointerId: number;\n startCoord: number;\n startRatio: number;\n min: number;\n max: number;\n maxStart: number;\n};\n\nconst wheelListenerOptions: AddEventListenerOptions = {passive: false};\n\nconst clamp = (value: number, min: number, max: number) => {\n if (value < min) {\n return min;\n }\n if (value > max) {\n return max;\n }\n return value;\n};\n\nconst getTrackDimension = (track: HTMLDivElement | null, vertical: boolean) => {\n if (!track || !track.firstElementChild) {\n return [0, 0];\n }\n const rect = track.firstElementChild.getBoundingClientRect();\n if (vertical) {\n return [rect.top, rect.height];\n }\n return vertical ? [rect.top, rect.height] : [rect.left, rect.width];\n};\n\nconst getEffectiveStep = (step: number, range: number) => {\n if (typeof step === 'number' && !Number.isNaN(step) && step > 0) {\n return step;\n }\n return Math.max(1, range / 10 || 1);\n};\n\nconst getEffectivePage = (pageSize: number | undefined, rangeSize: number) => {\n if (typeof pageSize === 'number' && !Number.isNaN(pageSize) && pageSize > 0) {\n return pageSize;\n }\n return Math.max(1, rangeSize || 1);\n};\n\nexport function RangeInput(props: RangeInputProps) {\n const {\n className = '',\n min,\n max,\n step,\n value,\n orientation,\n pageSize,\n stepButtons = false,\n startButtonAriaLabel,\n endButtonAriaLabel,\n eventTarget,\n decorations = [],\n onChange\n } = props;\n\n const vertical = orientation !== 'horizontal';\n const rootRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const thumbRef = useRef<HTMLDivElement>(null);\n const dragStateRef = useRef<DragState | null>(null);\n const [trackLength, setTrackLength] = useState(0);\n\n const range = max - min;\n const rangeSize = Math.max(0, value[1] - value[0]);\n const maxStart = Math.max(0, range - rangeSize);\n const clampedStart = clamp(value[0], min, min + maxStart);\n\n const {thumbLength, thumbOffset} = useMemo(() => {\n if (trackLength <= 0 || range <= 0) {\n return {thumbLength: 0, thumbOffset: 0};\n }\n\n if (range <= rangeSize) {\n return {thumbLength: 1, thumbOffset: 0};\n }\n\n const nextThumbLength = rangeSize / range;\n const travel = Math.max(0, 1 - nextThumbLength);\n const ratio = maxStart <= 0 ? 0 : clamp((clampedStart - min) / maxStart, 0, 1);\n\n return {\n thumbLength: Math.max(0, Math.min(nextThumbLength, 1)),\n thumbOffset: travel * ratio\n };\n }, [trackLength, range, rangeSize, maxStart, clampedStart, min]);\n\n const emitRange = useCallback(\n (nextStart: number) => {\n if (!onChange) {\n return;\n }\n const clamped = clamp(nextStart, min, min + maxStart);\n onChange([clamped, clamped + rangeSize]);\n },\n [onChange, min, maxStart, rangeSize]\n );\n\n const handleStepNegative = useCallback(\n (event: MouseEvent) => {\n event.stopPropagation();\n emitRange(clampedStart - getEffectiveStep(step, range));\n },\n [emitRange, clampedStart, step, range]\n );\n\n const handleStepPositive = useCallback(\n (event: MouseEvent) => {\n event.stopPropagation();\n emitRange(clampedStart + getEffectiveStep(step, range));\n },\n [emitRange, clampedStart, step, range]\n );\n\n const handleTrackClick = useCallback(\n (event: MouseEvent) => {\n if (event.button !== 0) {\n return;\n }\n const target = event.target as HTMLElement | null;\n if (target?.dataset.scrollbarThumb === 'true') {\n return;\n }\n\n const track = trackRef.current;\n if (!track) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n const [trackStart] = getTrackDimension(track, vertical);\n const coordinate = vertical ? event.clientY - trackStart : event.clientX - trackStart;\n const span = Math.max(1, 1 - thumbLength) * trackLength;\n const thumbCenter = (thumbLength / 2) * trackLength;\n const ratio = span <= 0 ? 0 : clamp((coordinate - thumbCenter) / span, 0, 1);\n emitRange(min + ratio * maxStart);\n },\n [vertical, trackLength, thumbLength, emitRange, min, maxStart]\n );\n\n const handleThumbPointerDown = (event: PointerEvent) => {\n if (event.button !== 0) {\n return;\n }\n const track = trackRef.current;\n if (!track) {\n return;\n }\n\n dragStateRef.current = {\n pointerId: event.pointerId,\n startCoord: vertical ? event.clientY : event.clientX,\n startRatio: thumbOffset,\n min,\n max,\n maxStart\n };\n\n (event.currentTarget as HTMLDivElement).setPointerCapture(event.pointerId);\n event.preventDefault();\n event.stopPropagation();\n };\n\n const handleThumbPointerMove = useCallback(\n (event: PointerEvent) => {\n const state = dragStateRef.current;\n if (!state || state.pointerId !== event.pointerId) {\n return;\n }\n\n const [trackStart, trackLength] = getTrackDimension(trackRef.current, vertical);\n const coordinate = vertical ? event.clientY : event.clientX;\n const delta = coordinate - state.startCoord;\n\n const ratio = state.startRatio + delta / trackLength;\n\n const nextStart = clamp(ratio * (state.max - state.min), 0, state.maxStart) + state.min;\n emitRange(nextStart);\n event.preventDefault();\n },\n [emitRange, vertical]\n );\n\n const handleThumbPointerUp = useCallback((event: PointerEvent) => {\n const state = dragStateRef.current;\n if (state && state.pointerId === event.pointerId) {\n dragStateRef.current = null;\n thumbRef.current?.releasePointerCapture(event.pointerId);\n event.preventDefault();\n }\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowUp':\n case 'ArrowLeft':\n if ((vertical && event.key === 'ArrowUp') || (!vertical && event.key === 'ArrowLeft')) {\n emitRange(clampedStart - getEffectiveStep(step, range));\n event.preventDefault();\n }\n break;\n case 'ArrowDown':\n case 'ArrowRight':\n if (\n (vertical && event.key === 'ArrowDown') ||\n (!vertical && event.key === 'ArrowRight')\n ) {\n emitRange(clampedStart + getEffectiveStep(step, range));\n event.preventDefault();\n }\n break;\n case 'PageUp':\n emitRange(clampedStart - getEffectivePage(pageSize, rangeSize));\n event.preventDefault();\n break;\n case 'PageDown':\n emitRange(clampedStart + getEffectivePage(pageSize, rangeSize));\n event.preventDefault();\n break;\n case 'Home':\n emitRange(min);\n event.preventDefault();\n break;\n case 'End':\n emitRange(min + maxStart);\n event.preventDefault();\n break;\n default:\n break;\n }\n },\n [vertical, emitRange, clampedStart, step, range, pageSize, rangeSize, min, maxStart]\n );\n\n const handleWheel = useCallback(\n (event: WheelEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n if (maxStart === 0) {\n return;\n }\n\n let delta = vertical ? event.deltaY : event.deltaX;\n if (!vertical && delta === 0) {\n delta = event.deltaY;\n }\n\n if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n delta *= getEffectiveStep(step, range);\n } else if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n delta *= getEffectivePage(pageSize, rangeSize);\n }\n\n if (delta === 0) {\n return;\n }\n\n emitRange(clampedStart + delta);\n },\n [emitRange, clampedStart, maxStart, vertical, step, range, pageSize, rangeSize]\n );\n\n useLayoutEffect(() => {\n setTrackLength(getTrackDimension(trackRef.current, vertical)[1]);\n }, [vertical]);\n\n useLayoutEffect(() => {\n const track = trackRef.current;\n if (!track) {\n return undefined;\n }\n\n const update = () => {\n setTrackLength(getTrackDimension(track, vertical)[1]);\n };\n\n update();\n\n if (typeof ResizeObserver !== 'undefined') {\n const observer = new ResizeObserver(update);\n observer.observe(track);\n return () => observer.disconnect();\n }\n\n if (typeof window !== 'undefined') {\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }\n\n return undefined;\n }, [vertical]);\n\n useEffect(() => {\n const eventRoot = eventTarget ?? rootRef.current;\n if (!eventRoot) return undefined;\n\n eventRoot.addEventListener('keydown', handleKeyDown);\n eventRoot.addEventListener('wheel', handleWheel, wheelListenerOptions);\n return () => {\n eventRoot.removeEventListener('keydown', handleKeyDown);\n eventRoot.removeEventListener('wheel', handleWheel, wheelListenerOptions);\n };\n }, [eventTarget, handleKeyDown, handleWheel]);\n\n const decorationElements = useMemo(() => {\n if (!decorations.length || range <= 0) {\n return [];\n }\n\n return decorations.map((decoration, index) => {\n const [start, end] = decoration.position;\n const startRatio = (start - min) / range;\n const endRatio = (end - min) / range;\n const offsetPct = Math.round(startRatio * 1000) / 10;\n const sizePct = Math.max(0, Math.round((endRatio - startRatio) * 1000) / 10);\n const style = vertical\n ? {\n left: '0',\n width: '100%',\n top: `${offsetPct}%`,\n height: `${sizePct}%`\n }\n : {\n top: '0',\n height: '100%',\n left: `${offsetPct}%`,\n width: `${sizePct}%`\n };\n\n return (\n <div key={`decoration-${index}`} className=\"deck-widget-range__decoration\" style={style}>\n {decoration.element}\n </div>\n );\n });\n }, [decorations, range, min, vertical]);\n\n return (\n <div\n ref={rootRef}\n tabIndex={0}\n role=\"scrollbar\"\n aria-valuemin={min}\n aria-valuemax={min + maxStart}\n aria-valuenow={clampedStart}\n aria-orientation={orientation}\n className={`${className} deck-widget-range deck-widget-range--${orientation} ${maxStart === 0 ? 'deck-widget-range--disabled' : ''}`}\n >\n {stepButtons && (\n <button\n type=\"button\"\n className=\"deck-widget-range__button deck-widget-range__button--start\"\n aria-label={startButtonAriaLabel}\n disabled={clampedStart <= min}\n onClick={handleStepNegative}\n >\n <span className=\"deck-widget-icon\" />\n </button>\n )}\n <div className=\"deck-widget-range__track\" ref={trackRef} onClick={handleTrackClick}>\n <div className=\"deck-widget-range__decorations\">{decorationElements}</div>\n <div\n className=\"deck-widget-range__thumb\"\n data-scrollbar-thumb=\"true\"\n ref={thumbRef}\n style={\n vertical\n ? {height: `${thumbLength * 100}%`, top: `${thumbOffset * 100}%`}\n : {width: `${thumbLength * 100}%`, left: `${thumbOffset * 100}%`}\n }\n onPointerDown={handleThumbPointerDown}\n onPointerMove={handleThumbPointerMove}\n onPointerUp={handleThumbPointerUp}\n onPointerCancel={handleThumbPointerUp}\n />\n </div>\n {stepButtons && (\n <button\n type=\"button\"\n className=\"deck-widget-range__button deck-widget-range__button--end\"\n aria-label={endButtonAriaLabel}\n disabled={clampedStart >= min + maxStart}\n onClick={handleStepPositive}\n >\n <span className=\"deck-widget-icon\" />\n </button>\n )}\n </div>\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render, type JSX} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type IconWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Data url to display as icon */\n icon: string;\n /** Tooltip label */\n label?: string;\n /** Icon color, a CSS Color string */\n color?: string;\n /** Callback when the widget is clicked */\n onClick?: () => void;\n};\n\n/**\n * A generic widget that displays a button with icon or text content.\n */\nexport class IconWidget extends Widget<IconWidgetProps> {\n static defaultProps: Required<IconWidgetProps> = {\n ...Widget.defaultProps,\n id: 'icon',\n placement: 'top-left',\n viewId: null,\n icon: '',\n label: '',\n color: '',\n onClick: undefined!\n };\n\n className = '';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: IconWidgetProps) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<IconWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {className, style, icon, color, label, onClick} = this.props;\n\n render(\n <IconButton\n className={className}\n style={style as JSX.CSSProperties}\n color={color}\n icon={icon}\n label={label}\n onClick={onClick}\n />,\n rootElement\n );\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render, type JSX} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type ToggleWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** If the toggle is checked when first added */\n initialChecked?: boolean;\n /** Data url to display as icon */\n icon: string;\n /** Data url to display as icon when it is checked */\n onIcon?: string;\n /** Tooltip label */\n label?: string;\n /** Tooltip label when it is checked */\n onLabel?: string;\n /** Icon color, a CSS Color string */\n color?: string;\n /** Icon color when it is checked, a CSS Color string */\n onColor?: string;\n /** Callback when the widget is clicked */\n onChange?: (checked: boolean) => void;\n};\n\n/**\n * A generic widget that displays a button with icon or text content.\n */\nexport class ToggleWidget extends Widget<ToggleWidgetProps> {\n static defaultProps: Required<ToggleWidgetProps> = {\n ...Widget.defaultProps,\n id: 'icon',\n placement: 'top-left',\n viewId: null,\n initialChecked: false,\n icon: '',\n onIcon: undefined!,\n label: '',\n onLabel: undefined!,\n color: '',\n onColor: undefined!,\n onChange: undefined!\n };\n\n className = 'deck-widget-toggle';\n placement: WidgetPlacement = 'top-left';\n checked: boolean;\n\n constructor(props: ToggleWidgetProps) {\n super(props);\n this.checked = this.props.initialChecked;\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ToggleWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {\n className,\n style,\n icon,\n label,\n color,\n onIcon = icon,\n onLabel = label,\n onColor = color\n } = this.props;\n const on = this.checked;\n\n rootElement.dataset.checked = String(on);\n\n render(\n <IconButton\n className={className}\n style={style as JSX.CSSProperties}\n icon={on ? onIcon : icon}\n label={on ? onLabel : label}\n color={on ? onColor : color}\n onClick={this._toggle}\n />,\n rootElement\n );\n }\n\n private _toggle = () => {\n this.checked = !this.checked;\n this.props.onChange?.(this.checked);\n this.updateHTML();\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {render} from 'preact';\nimport {Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {SimpleMenu, type MenuItem} from './lib/components/dropdown-menu';\nimport {Popover, type PopoverProps} from './lib/components/popover';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type SelectorWidgetOption<ValueT = string> = {\n value: ValueT;\n icon: string;\n label?: string;\n};\n\n/** Properties for the ViewSelectorWidget */\nexport type SelectorWidgetProps<ValueT = string> = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n options: SelectorWidgetOption<ValueT>[];\n /** The initial value. Default to the first option. */\n initialValue?: ValueT;\n /** Callback invoked when the value changes */\n onChange?: (value: ValueT) => void;\n};\n\n/**\n * A widget that renders a popup menu for selecting a view mode.\n * It displays a button with the current view mode icon. Clicking the button\n * toggles a popup that shows three icons for:\n * - Single view\n * - Two views, split horizontally\n * - Two views, split vertically\n */\nexport class SelectorWidget<ValueT = string> extends Widget<SelectorWidgetProps<ValueT>> {\n static defaultProps: Required<SelectorWidgetProps> = {\n ...Widget.defaultProps,\n id: 'view-selector',\n placement: 'top-left',\n viewId: null,\n initialValue: '',\n options: [],\n onChange: () => {}\n };\n\n className = 'deck-widget-selector';\n placement: WidgetPlacement = 'top-left';\n value: ValueT;\n isOpen: {x: number; y: number; placement: PopoverProps['placement']} | false = false;\n\n constructor(props: SelectorWidgetProps<ValueT>) {\n super(props);\n this.value = this.props.initialValue;\n this.setProps(this.props);\n }\n\n setProps(props: Partial<SelectorWidgetProps<ValueT>>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement) {\n const selectedOption =\n this.props.options.find(opt => opt.value === this.value) ?? this.props.options[0];\n\n render(\n <div>\n <IconButton\n icon={selectedOption.icon}\n label={selectedOption.label}\n onClick={this._toggleMenu}\n />\n {this.isOpen && (\n <Popover {...this.isOpen}>\n <SimpleMenu\n isOpen\n style={{pointerEvents: 'auto', position: 'static'}}\n menuItems={this.props.options as MenuItem[]}\n onSelect={this._handleSelectMode}\n onClose={this._toggleMenu}\n />\n </Popover>\n )}\n </div>,\n rootElement\n );\n }\n\n private _toggleMenu = () => {\n if (this.isOpen) {\n this.isOpen = false;\n } else if (this.rootElement) {\n this.isOpen = {\n x: this.rootElement.offsetLeft,\n y: this.rootElement.offsetTop,\n placement: this.props.placement.includes('right') ? 'left-start' : 'right-start'\n };\n }\n this.updateHTML();\n };\n\n private _handleSelectMode = (value: string) => {\n this.value = value as ValueT;\n this.props.onChange(value as ValueT);\n this.updateHTML();\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, type WidgetPlacement, type WidgetProps} from '@deck.gl/core';\nimport type {Timeline} from '@luma.gl/engine';\nimport {render} from 'preact';\nimport {IconButton} from './lib/components/icon-button';\nimport {RangeInput} from './lib/components/range-input';\n\nexport type TimelineWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Timeline instance to manipulate. */\n timeline?: Timeline | null;\n /** Slider timeRange [min, max]. */\n timeRange?: [number, number];\n /** Slider step.\n * @default 1\n */\n step?: number;\n /** Initial slider value for uncontrolled usage.\n * @default `timeRange[0]`\n */\n initialTime?: number;\n /**\n * Controlled time value. When provided, the widget is in controlled mode\n * for the time slider.\n */\n time?: number;\n /** Callback when time value changes (via slider or playback). */\n onTimeChange?: (value: number) => void;\n /** Start playing automatically\n * @default false\n */\n autoPlay?: boolean;\n /** Start from the beginning whentime reaches the end\n * @default false\n */\n loop?: boolean;\n /** Play interval in milliseconds.\n * @default 1000\n */\n playInterval?: number;\n /**\n * Controlled playing state. When provided, the widget is in controlled mode\n * for play/pause.\n */\n playing?: boolean;\n /**\n * Callback when play/pause button is clicked.\n * In controlled mode, use this to update the playing prop.\n */\n onPlayingChange?: (playing: boolean) => void;\n /** Callback to get label from time value */\n formatLabel?: (value: number) => string;\n};\n\nexport class TimelineWidget extends Widget<TimelineWidgetProps> {\n id = 'timeline';\n className = 'deck-widget-timeline';\n placement: WidgetPlacement = 'fill';\n\n private _playing = false;\n private timerId: number | null = null;\n currentTime: number;\n\n /**\n * Returns the current time value.\n * In controlled mode, returns the time prop.\n * In uncontrolled mode, returns the internal state.\n */\n getTime(): number {\n return this.props.time ?? this.currentTime;\n }\n\n /**\n * Returns the current playing state.\n * In controlled mode, returns the playing prop.\n * In uncontrolled mode, returns the internal state.\n */\n getPlaying(): boolean {\n return this.props.playing ?? this._playing;\n }\n\n static defaultProps: Required<TimelineWidgetProps> = {\n ...Widget.defaultProps,\n id: 'timeline',\n placement: 'bottom-left',\n viewId: null,\n timeline: null,\n timeRange: [0, 100],\n step: 1,\n initialTime: undefined!,\n time: undefined!,\n onTimeChange: () => {},\n autoPlay: false,\n loop: false,\n playInterval: 1000,\n playing: undefined!,\n onPlayingChange: () => {},\n formatLabel: String\n };\n\n constructor(props: TimelineWidgetProps = {}) {\n super(props);\n this.currentTime = this.props.initialTime ?? this.props.timeRange[0];\n // In controlled mode, sync Timeline to the controlled time prop\n const syncTime = this.props.time ?? this.currentTime;\n this.props.timeline?.setTime(syncTime);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<TimelineWidgetProps>): void {\n const {playing: prevPlaying, time: prevTime} = this.props;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n\n // Sync Timeline object when controlled time prop changes\n if (props.time !== undefined && props.time !== prevTime) {\n this.props.timeline?.setTime(props.time);\n }\n\n // Handle controlled playing state changes\n if (props.playing !== undefined && props.playing !== prevPlaying) {\n if (props.playing && !this._playing) {\n this._startTimer();\n } else if (!props.playing && this._playing) {\n this._stopTimer();\n }\n }\n }\n\n onAdd(): void {\n this._playing = false;\n this.timerId = null;\n if (this.props.autoPlay) {\n if (this.props.playing !== undefined) {\n // In controlled mode, notify parent instead of starting directly\n this.props.onPlayingChange?.(true);\n } else {\n this.play();\n }\n }\n }\n\n onRemove(): void {\n this.stop();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {timeRange, step, formatLabel} = this.props;\n const isPlaying = this.getPlaying();\n const currentTime = this.getTime();\n\n rootElement.dataset.placement = this.props.placement;\n\n render(\n <div className=\"deck-widget-button-group\">\n {isPlaying ? (\n <IconButton\n label=\"Pause\"\n className=\"deck-widget-timeline-pause\"\n onClick={this.handlePlayPause}\n />\n ) : (\n <IconButton\n label=\"Play\"\n className=\"deck-widget-timeline-play\"\n onClick={this.handlePlayPause}\n />\n )}\n <RangeInput\n min={timeRange[0]}\n max={timeRange[1]}\n orientation=\"horizontal\"\n step={step}\n value={[currentTime, currentTime]}\n onChange={this.handleTimeChange}\n decorations={[\n {\n position: [currentTime, currentTime + step],\n element: (\n <div className=\"deck-widget-timeline-label deck-widget-timeline-label--current\">\n {formatLabel(currentTime)}\n </div>\n )\n }\n ]}\n />\n </div>,\n rootElement\n );\n }\n\n private handlePlayPause = (): void => {\n const isPlaying = this.getPlaying();\n const nextPlaying = !isPlaying;\n\n // Always call callback if provided\n this.props.onPlayingChange?.(nextPlaying);\n\n // Only update internal state if uncontrolled\n if (this.props.playing === undefined) {\n if (nextPlaying) {\n this.play();\n } else {\n this.stop();\n }\n }\n // In controlled mode, parent will update playing prop which triggers start/stop via setProps\n };\n\n private handleTimeChange = ([value]: [number, number]): void => {\n // Always call callback\n this.props.onTimeChange(value);\n\n // Only update internal state if uncontrolled\n if (this.props.time === undefined) {\n this.currentTime = value;\n this.props.timeline?.setTime(value);\n this.updateHTML();\n }\n // In controlled mode, parent will update time prop which triggers updateHTML via setProps\n };\n\n public play(): void {\n this._playing = true;\n const {\n timeRange: [min, max]\n } = this.props;\n // In uncontrolled mode, reset to start if at end\n if (this.props.time === undefined && this.getTime() >= max) {\n this.currentTime = min;\n this.props.onTimeChange(min);\n this.props.timeline?.setTime(min);\n }\n this.updateHTML();\n this.tick();\n }\n\n public stop(): void {\n this._stopTimer();\n this.updateHTML();\n }\n\n /** Start the playback timer (used internally) */\n private _startTimer(): void {\n this._playing = true;\n this.tick();\n }\n\n /** Stop the playback timer (used internally) */\n private _stopTimer(): void {\n this._playing = false;\n if (this.timerId !== null) {\n window.clearTimeout(this.timerId);\n this.timerId = null;\n }\n }\n\n private tick = (): void => {\n const {\n timeRange: [min, max],\n step,\n loop\n } = this.props;\n if (step > 0) {\n const currentTime = this.getTime();\n let next = Math.round(currentTime / step) * step + step;\n if (next > max) {\n if (currentTime < max) {\n next = max;\n } else if (loop) {\n next = min;\n } else {\n next = max;\n this._playing = false;\n this.props.onPlayingChange?.(false);\n }\n }\n\n // Always call callback\n this.props.onTimeChange(next);\n\n // Only update internal state if uncontrolled\n if (this.props.time === undefined) {\n this.currentTime = next;\n this.props.timeline?.setTime(next);\n }\n this.updateHTML();\n }\n if (this._playing) {\n this.timerId = window.setTimeout(this.tick, this.props.playInterval);\n } else {\n this.timerId = null;\n }\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the ScreenshotWidget */\nexport type ScreenshotWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message */\n label?: string;\n /** Filename to save to */\n filename?: string;\n /** Image format */\n imageFormat?: 'image/png' | 'image/jpeg';\n /** Callback, if defined user overrides the capture logic */\n onCapture?: (widget: ScreenshotWidget) => void;\n};\n\n/**\n * A button widget that captures a screenshot of the current canvas and downloads it as a (png) file.\n * @note only captures canvas contents, not HTML DOM or CSS styles\n */\nexport class ScreenshotWidget extends Widget<ScreenshotWidgetProps> {\n static defaultProps: Required<ScreenshotWidgetProps> = {\n ...Widget.defaultProps,\n id: 'screenshot',\n placement: 'top-left',\n viewId: null,\n label: 'Screenshot',\n filename: 'screenshot.png',\n imageFormat: 'image/png',\n onCapture: undefined!\n };\n\n className = 'deck-widget-screenshot';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ScreenshotWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ScreenshotWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n className=\"deck-widget-camera\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />,\n rootElement\n );\n }\n\n handleClick() {\n // Allow user to override the capture logic\n if (this.props.onCapture) {\n this.props.onCapture(this);\n return;\n }\n const dataURL = this.captureScreenToDataURL(this.props.imageFormat);\n if (dataURL) {\n this.downloadDataURL(dataURL, this.props.filename);\n }\n }\n\n /** @note only captures canvas contents, not HTML DOM or CSS styles */\n captureScreenToDataURL(imageFormat: string): string | undefined {\n const canvas = this.deck?.getCanvas();\n return canvas?.toDataURL(imageFormat);\n }\n\n /** Download a data URL */\n downloadDataURL(dataURL: string, filename: string): void {\n const link = document.createElement('a');\n link.href = dataURL;\n link.download = filename;\n link.click();\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log, _deepEqual as deepEqual, _applyStyles as applyStyles} from '@deck.gl/core';\nimport {Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\n// import {useCallback} from 'preact/hooks';\nimport {IconButton} from './lib/components/icon-button';\nimport type {DeckWidgetTheme} from './themes';\nimport {LightGlassTheme, DarkGlassTheme} from './themes';\n\nexport type ThemeWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message when dark mode is selected. */\n lightModeLabel?: string;\n /** Styles for light mode theme */\n lightModeTheme?: DeckWidgetTheme;\n /** Tooltip message when light mode is selected. */\n darkModeLabel?: string;\n /** Styles for dark mode theme */\n darkModeTheme?: DeckWidgetTheme;\n /** Initial theme mode for uncontrolled usage. 'auto' reads the browser default setting */\n initialThemeMode?: 'auto' | 'light' | 'dark';\n /**\n * Controlled theme mode. When provided, the widget is in controlled mode\n * and this prop determines the current theme.\n */\n themeMode?: 'light' | 'dark';\n /**\n * Callback when the user clicks the theme toggle button.\n * In controlled mode, use this to update the themeMode prop.\n * In uncontrolled mode, this is called after the internal state updates.\n */\n onThemeModeChange?: (newMode: 'light' | 'dark') => void;\n};\n\nexport class ThemeWidget extends Widget<ThemeWidgetProps> {\n static defaultProps: Required<ThemeWidgetProps> = {\n ...Widget.defaultProps,\n id: 'theme',\n placement: 'top-left',\n viewId: null,\n lightModeLabel: 'Light Mode',\n lightModeTheme: LightGlassTheme,\n darkModeLabel: 'Dark Mode',\n darkModeTheme: DarkGlassTheme,\n initialThemeMode: 'auto',\n themeMode: undefined!,\n onThemeModeChange: () => {}\n };\n\n className = 'deck-widget-theme';\n placement: WidgetPlacement = 'top-left';\n themeMode: 'light' | 'dark' = 'dark';\n appliedTheme: DeckWidgetTheme = {};\n\n constructor(props: ThemeWidgetProps = {}) {\n super(props);\n this.themeMode = this._getInitialThemeMode();\n this.setProps(this.props);\n }\n\n // eslint-disable-next-line complexity\n setProps(props: Partial<ThemeWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {lightModeLabel, darkModeLabel} = this.props;\n const currentMode = this.getThemeMode();\n this._applyTheme(currentMode, rootElement);\n\n render(\n <IconButton\n onClick={this._handleClick.bind(this)}\n label={currentMode === 'dark' ? darkModeLabel : lightModeLabel}\n className={currentMode === 'dark' ? 'deck-widget-moon' : 'deck-widget-sun'}\n />,\n rootElement\n );\n }\n\n /**\n * Returns the current theme mode.\n * In controlled mode, returns the themeMode prop.\n * In uncontrolled mode, returns the internal state.\n */\n getThemeMode(): 'light' | 'dark' {\n return this.props.themeMode ?? this.themeMode;\n }\n\n _handleClick() {\n const currentMode = this.getThemeMode();\n const nextMode = currentMode === 'dark' ? 'light' : 'dark';\n\n // Always call callback if provided\n this.props.onThemeModeChange?.(nextMode);\n\n // Only update internal state if uncontrolled\n if (this.props.themeMode === undefined) {\n this.themeMode = nextMode;\n this.updateHTML();\n }\n // In controlled mode, parent will update themeMode prop which triggers _applyTheme via setProps\n }\n\n /** Apply theme styling without changing internal state */\n _applyTheme(themeMode: 'light' | 'dark', rootElement: HTMLElement) {\n const themeStyle = themeMode === 'dark' ? this.props.darkModeTheme : this.props.lightModeTheme;\n if (deepEqual(themeStyle, this.appliedTheme, 1)) {\n return;\n }\n const container = rootElement.closest<HTMLDivElement>('.deck-widget-container');\n if (!container) return;\n\n applyStyles(container, themeStyle);\n this.appliedTheme = themeStyle;\n\n const label = themeMode === 'dark' ? this.props.darkModeLabel : this.props.lightModeLabel;\n log.log(1, `Switched theme to ${label}`, themeStyle)();\n }\n\n /** Read browser preference */\n _getInitialThemeMode(): 'light' | 'dark' {\n const {initialThemeMode} = this.props;\n if (initialThemeMode !== 'auto') {\n return initialThemeMode;\n }\n if (typeof window === 'undefined') {\n return 'light';\n }\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/**\n * A Deck Theme is a set of CSS variables that control CSS styling of the official widgets.\n */\nexport type DeckWidgetTheme = {\n // layout\n '--widget-margin'?: string;\n // button and button group\n '--button-size'?: string;\n '--button-corner-radius'?: string;\n '--button-background'?: string;\n '--button-stroke'?: string;\n '--button-inner-stroke'?: string;\n '--button-shadow'?: string;\n '--button-backdrop-filter'?: string;\n '--button-icon-idle'?: string;\n '--button-icon-hover'?: string;\n '--button-text'?: string;\n // inter-icon color\n '--icon-compass-north-color'?: string;\n '--icon-compass-south-color'?: string;\n // menu\n '--menu-gap'?: string;\n '--menu-background'?: string;\n '--menu-backdrop-filter'?: string;\n '--menu-border'?: string;\n '--menu-shadow'?: string;\n '--menu-text'?: string;\n '--menu-item-hover'?: string;\n // scrollbar\n '--range-step-button-size'?: string;\n '--range-track-size'?: string;\n '--range-thumb-size'?: string;\n '--range-track-color'?: string;\n '--range-thumb-color'?: string;\n '--range-decoration-active-color'?: string;\n};\n\nexport const LightTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': '#fff',\n '--button-stroke': 'rgba(255, 255, 255, 0.3)',\n '--button-inner-stroke': 'unset',\n '--button-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--button-backdrop-filter': 'unset',\n '--button-icon-idle': 'rgba(97, 97, 102, 1)',\n '--button-icon-hover': 'rgba(24, 24, 26, 1)',\n '--button-text': 'rgb(24, 24, 26, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(204, 204, 204)',\n '--menu-gap': '4px',\n '--menu-background': '#fff',\n '--menu-backdrop-filter': 'unset',\n '--menu-border': 'unset',\n '--menu-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--menu-text': 'rgb(24, 24, 26, 1)',\n '--menu-item-hover': 'rgba(0, 0, 0, 0.08)',\n '--range-step-button-size': '24px',\n '--range-track-size': '16px',\n '--range-thumb-size': '10px',\n '--range-track-color': '#d8d8e5',\n '--range-thumb-color': '#616166',\n '--range-decoration-active-color': '#f8dd50'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const DarkTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(18, 18, 20, 1)',\n '--button-stroke': 'rgba(18, 18, 20, 0.30)',\n '--button-inner-stroke': 'unset',\n '--button-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--button-backdrop-filter': 'unset',\n '--button-icon-idle': 'rgba(158, 157, 168, 1)',\n '--button-icon-hover': 'rgba(215, 214, 229, 1)',\n '--button-text': 'rgb(215, 214, 229, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(200, 199, 209)',\n '--menu-gap': '4px',\n '--menu-background': 'rgba(18, 18, 20, 1)',\n '--menu-backdrop-filter': 'unset',\n '--menu-border': 'unset',\n '--menu-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--menu-text': 'rgb(215, 214, 229, 1)',\n '--menu-item-hover': 'rgba(255, 255, 255, 0.1)',\n '--range-step-button-size': '24px',\n '--range-track-size': '16px',\n '--range-thumb-size': '10px',\n '--range-track-color': '#2c2c30',\n '--range-thumb-color': '#9e9da8',\n '--range-decoration-active-color': '#dd7d2c'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const LightGlassTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(255, 255, 255, 0.6)',\n '--button-stroke': 'rgba(255, 255, 255, 0.3)',\n '--button-inner-stroke': '1px solid rgba(255, 255, 255, 0.6)',\n '--button-shadow':\n '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--button-backdrop-filter': 'blur(4px)',\n '--button-icon-idle': 'rgba(97, 97, 102, 1)',\n '--button-icon-hover': 'rgba(24, 24, 26, 1)',\n '--button-text': 'rgb(24, 24, 26, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(204, 204, 204)',\n '--menu-gap': '4px',\n '--menu-background': 'rgba(255, 255, 255, 0.6)',\n '--menu-backdrop-filter': 'blur(4px)',\n '--menu-border': '1px solid rgba(255, 255, 255, 0.6)',\n '--menu-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--menu-text': 'rgb(24, 24, 26, 1)',\n '--menu-item-hover': 'rgba(0, 0, 0, 0.08)',\n '--range-step-button-size': '24px',\n '--range-track-size': '16px',\n '--range-thumb-size': '10px',\n '--range-track-color': 'rgba(215, 214, 229, 0.3)',\n '--range-thumb-color': 'rgba(97, 97, 102, 1)',\n '--range-decoration-active-color': 'rgba(255, 215, 0, 0.6)'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const DarkGlassTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(18, 18, 20, 0.75)',\n '--button-stroke': 'rgba(18, 18, 20, 0.30)',\n '--button-inner-stroke': '1px solid rgba(18, 18, 20, 0.75)',\n '--button-shadow':\n '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--button-backdrop-filter': 'blur(4px)',\n '--button-icon-idle': 'rgba(158, 157, 168, 1)',\n '--button-icon-hover': 'rgba(215, 214, 229, 1)',\n '--button-text': 'rgb(215, 214, 229, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(200, 199, 209)',\n '--menu-gap': '4px',\n '--menu-background': 'rgba(18, 18, 20, 0.75)',\n '--menu-backdrop-filter': 'blur(4px)',\n '--menu-border': '1px solid rgba(18, 18, 20, 0.75)',\n '--menu-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--menu-text': 'rgb(215, 214, 229, 1)',\n '--menu-item-hover': 'rgba(255, 255, 255, 0.1)',\n '--range-step-button-size': '24px',\n '--range-track-size': '16px',\n '--range-thumb-size': '10px',\n '--range-track-color': 'rgba(24, 24, 26, 0.3)',\n '--range-thumb-color': 'rgba(158, 157, 168, 1)',\n '--range-decoration-active-color': 'rgba(255, 145, 0, 0.6)'\n} as const satisfies Required<DeckWidgetTheme>;\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, Layer, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the LoadingWidget */\nexport type LoadingWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Tooltip message when loading */\n label?: string;\n /**\n * Callback when the loading state changes.\n * Called when layers transition between loading and loaded states.\n */\n onLoadingChange?: (loading: boolean) => void;\n};\n\n/**\n * A non-interactive widget that shows a loading spinner if any layers are loading data\n */\nexport class LoadingWidget extends Widget<LoadingWidgetProps> {\n static defaultProps: Required<LoadingWidgetProps> = {\n ...Widget.defaultProps,\n id: 'loading',\n placement: 'top-left',\n viewId: null,\n label: 'Loading layer data',\n onLoadingChange: () => {}\n };\n\n className = 'deck-widget-loading';\n placement: WidgetPlacement = 'top-left';\n loading = true;\n\n constructor(props: LoadingWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<LoadingWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n // TODO(ibgreen) - this should not be a button, but styling is so nested that it is easier to reuse this component.\n this.loading && (\n <IconButton\n className=\"deck-widget-spinner\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />\n ),\n rootElement\n );\n }\n\n onRedraw({layers}: {layers: Layer[]}): void {\n const loading = layers.some(layer => !layer.isLoaded);\n if (loading !== this.loading) {\n this.loading = loading;\n\n // Call callback when loading state changes\n this.props.onLoadingChange?.(loading);\n\n this.updateHTML();\n }\n }\n\n // TODO(ibgreen) - this should not be a button, see above.\n handleClick() {}\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, type WidgetPlacement, type WidgetProps} from '@deck.gl/core';\nimport {luma} from '@luma.gl/core';\nimport {render, type JSX} from 'preact';\nimport {useEffect, useState} from 'preact/hooks';\nimport type {Stats, Stat} from '@probe.gl/stats';\nimport {IconButton} from './lib/components/icon-button';\n\nconst DEFAULT_COUNT_FORMATTER = (stat: Stat): string => `${stat.name}: ${stat.count}`;\n\nfunction formatTime(time: number): string {\n return time < 1000 ? `${time.toFixed(2)}ms` : `${(time / 1000).toFixed(2)}s`;\n}\n\nfunction formatMemory(bytes: number): string {\n const mb = bytes / 1e6;\n return `${mb.toFixed(1)} MB`;\n}\n\nexport const DEFAULT_FORMATTERS: Record<string, (stat: Stat) => string> = {\n count: DEFAULT_COUNT_FORMATTER,\n averageTime: (stat: Stat) => `${stat.name}: ${formatTime(stat.getAverageTime())}`,\n totalTime: (stat: Stat) => `${stat.name}: ${formatTime(stat.time)}`,\n fps: (stat: Stat) => `${stat.name}: ${Math.round(stat.getHz())}fps`,\n memory: (stat: Stat) => `${stat.name}: ${formatMemory(stat.count)}`\n};\n\nexport type StatsWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Type of stats to display. */\n type?: 'deck' | 'luma' | 'device' | 'custom';\n /** Expand the stats UI by default.\n * @default false\n */\n initialExpanded?: boolean;\n /** Stats object to visualize. */\n stats?: Stats;\n /** Title shown in the header of the pop-up. Defaults to stats.id. */\n title?: string;\n /** How many redraws to wait between updates. */\n framesPerUpdate?: number;\n /** Custom formatters for stat values. */\n formatters?: Record<string, string | ((stat: Stat) => string)>;\n /** Whether to reset particular stats after each update. */\n resetOnUpdate?: Record<string, boolean>;\n /**\n * Controlled expanded state. When provided, the widget is in controlled mode.\n */\n expanded?: boolean;\n /**\n * Callback when the expanded state changes (user clicks header).\n * In controlled mode, use this to update the expanded prop.\n */\n onExpandedChange?: (expanded: boolean) => void;\n};\n\n/** Displays probe.gl stats in a floating pop-up. */\nexport class StatsWidget extends Widget<StatsWidgetProps> {\n static defaultProps: Required<StatsWidgetProps> = {\n ...Widget.defaultProps,\n type: 'deck',\n placement: 'top-left',\n viewId: null,\n initialExpanded: false,\n stats: undefined!,\n title: 'Stats',\n framesPerUpdate: 1,\n formatters: {},\n resetOnUpdate: {},\n id: 'stats',\n expanded: undefined!,\n onExpandedChange: () => {}\n };\n\n className = 'deck-widget-stats';\n placement = 'top-left' as WidgetPlacement;\n\n private _counter = 0;\n private _formatters: Record<string, (stat: Stat) => string>;\n private _resetOnUpdate: Record<string, boolean>;\n private _expanded: boolean = false;\n\n /**\n * Returns the current expanded state.\n * In controlled mode, returns the expanded prop.\n * In uncontrolled mode, returns the internal state.\n */\n getExpanded(): boolean {\n return this.props.expanded ?? this._expanded;\n }\n\n constructor(props: StatsWidgetProps = {}) {\n super(props);\n this._formatters = {...DEFAULT_FORMATTERS};\n this._resetOnUpdate = {...this.props.resetOnUpdate};\n this._expanded = Boolean(props.initialExpanded);\n this.setProps(props);\n }\n\n setProps(props: Partial<StatsWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n if (props.formatters) {\n for (const name in props.formatters) {\n const f = props.formatters[name];\n this._formatters[name] =\n typeof f === 'string' ? DEFAULT_FORMATTERS[f] || DEFAULT_COUNT_FORMATTER : f;\n }\n }\n if (props.resetOnUpdate) {\n this._resetOnUpdate = {...props.resetOnUpdate};\n }\n super.setProps(props);\n }\n\n onRemove() {\n if (this.rootElement) {\n // Make sure all preact hooks are finalized\n render(null, this.rootElement);\n }\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const isExpanded = this.getExpanded();\n if (!isExpanded) {\n render(<FpsIcon getFps={this._getFps} onClick={this._toggleExpanded} />, rootElement);\n return;\n }\n\n const stats = this._getStats();\n const title = this.props.title || ('id' in stats ? stats.id : null) || 'Stats';\n const deviceLabel = this._getDeviceLabel();\n const items: JSX.Element[] = [];\n\n if (stats) {\n stats.forEach(stat => {\n const lines = this._getLines(stat).split('\\n');\n if (this._resetOnUpdate && this._resetOnUpdate[stat.name]) {\n stat.reset();\n }\n lines.forEach((line, i) => {\n items.push(\n <div key={`${stat.name}-${i}`} style={{whiteSpace: 'pre'}}>\n {line}\n </div>\n );\n });\n });\n }\n\n render(\n <div className=\"deck-widget-stats-container\" style={{cursor: 'default'}}>\n <div\n className=\"deck-widget-stats-header\"\n style={{cursor: 'pointer', pointerEvents: 'auto'}}\n onClick={this._toggleExpanded}\n >\n <b>{title}</b>\n {deviceLabel && <span className=\"deck-widget-stats-device\">{deviceLabel}</span>}\n <button className=\"deck-widget-dropdown-button\">\n <span className=\"deck-widget-dropdown-icon open\" />\n </button>\n </div>\n <div className=\"deck-widget-stats-content\">{items}</div>\n </div>,\n rootElement\n );\n }\n\n onRedraw(): void {\n if (this.getExpanded()) {\n const framesPerUpdate = Math.max(1, this.props.framesPerUpdate || 1);\n if (this._counter++ % framesPerUpdate === 0) {\n this.updateHTML();\n }\n }\n }\n\n protected _getStats(): Stats | [key: string, value: number][] {\n switch (this.props.type) {\n case 'deck':\n // @ts-expect-error metrics is protected\n const metrics = this.deck?.metrics ?? {};\n return Object.entries(metrics);\n case 'luma':\n return Array.from(luma.stats.stats.values())[0];\n case 'device':\n // @ts-expect-error is protected\n const device = this.deck?.device;\n const stats = device?.statsManager.stats.values();\n return stats ? Array.from(stats)[0] : [];\n case 'custom':\n return this.props.stats;\n default:\n throw new Error(`Unknown stats type: ${this.props.type}`);\n }\n }\n\n protected _toggleExpanded = (): void => {\n const nextExpanded = !this.getExpanded();\n\n // Always call callback if provided\n this.props.onExpandedChange?.(nextExpanded);\n\n // Only update internal state if uncontrolled\n if (this.props.expanded === undefined) {\n this._expanded = nextExpanded;\n this.updateHTML();\n }\n // In controlled mode, parent will update expanded prop which triggers updateHTML via setProps\n };\n\n protected _getFps = (): number => {\n // @ts-expect-error metrics is protected\n return Math.round(this.deck?.metrics.fps ?? 0);\n };\n\n protected _getDeviceLabel(): string | null {\n // @ts-expect-error device is protected\n const deviceType = this.deck?.device?.type;\n if (!deviceType) {\n return null;\n }\n switch (deviceType) {\n case 'webgpu':\n return 'WebGPU';\n case 'webgl':\n return 'WebGL';\n default:\n return String(deviceType);\n }\n }\n\n protected _getLines(stat: Stat | [key: string, value: number]): string {\n if ('count' in stat) {\n const formatter =\n this._formatters[stat.name] || this._formatters[stat.type || ''] || DEFAULT_COUNT_FORMATTER;\n return formatter(stat);\n }\n const [key, value] = stat;\n const formattedValue = key.endsWith('Memory')\n ? formatMemory(value)\n : key.includes('Time')\n ? formatTime(value)\n : `${value.toFixed(2)}`;\n\n return `${key}: ${formattedValue}`;\n }\n}\n\nfunction FpsIcon({getFps, onClick}: {getFps: () => number; onClick: () => void}) {\n const [fps, setFps] = useState(getFps());\n useEffect(() => {\n const onUpdate = () => {\n setFps(getFps());\n timer = requestAnimationFrame(onUpdate);\n };\n let timer = requestAnimationFrame(onUpdate);\n return () => {\n cancelAnimationFrame(timer);\n };\n }, [getFps]);\n\n return (\n <IconButton onClick={onClick}>\n <div className=\"text\">\n FPS\n <br />\n {fps}\n </div>\n </IconButton>\n );\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["_jsx", "_jsx", "_jsxs", "_jsx", "import_preact", "import_core", "_jsx", "import_core", "import_preact", "_jsx", "_jsxs", "import_core", "import_preact", "_jsx", "_jsxs", "import_preact", "import_core", "_jsxs", "_jsx", "import_core", "import_preact", "import_hooks", "_jsx", "_jsxs", "value", "CURRENT_LOCATION", "_jsxs", "_jsx", "import_core", "import_preact", "_jsx", "import_preact", "import_hooks", "import_core", "deepEqual", "_jsx", "_Fragment", "import_core", "import_preact", "import_hooks", "_jsx", "_jsxs", "import_hooks", "_jsx", "_jsx", "import_core", "import_preact", "_jsxs", "_jsx", "import_core", "import_preact", "_jsx", "import_core", "import_preact", "import_hooks", "clamp", "trackLength", "_jsx", "_jsxs", "clamp", "_jsx", "import_preact", "import_core", "_jsx", "import_preact", "import_core", "_jsx", "import_preact", "import_core", "_jsxs", "_jsx", "import_core", "import_preact", "_a", "_jsxs", "_jsx", "import_preact", "import_core", "_jsx", "import_core", "import_preact", "_jsx", "deepEqual", "applyStyles", "import_preact", "import_core", "_jsx", "import_core", "import_preact", "import_hooks", "_jsx", "_jsxs"]
7
7
  }