@babylonjs/inspector 8.38.0-preview → 8.39.0-preview

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,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useMemo, useEffect, useState, useRef, useCallback, forwardRef, createContext, useContext, isValidElement, cloneElement, Children, useLayoutEffect, createElement, Suspense, useReducer, lazy } from 'react';
2
+ import { createContext, useContext, useMemo, useEffect, useState, useRef, useCallback, forwardRef, isValidElement, cloneElement, Children, useLayoutEffect, useImperativeHandle, createElement, Suspense, useReducer, lazy } from 'react';
3
3
  import { Color3, Color4 } from '@babylonjs/core/Maths/math.color.js';
4
4
  import { Vector3, Quaternion, Matrix, Vector2, Vector4, TmpVectors } from '@babylonjs/core/Maths/math.vector.js';
5
5
  import { Observable } from '@babylonjs/core/Misc/observable.js';
@@ -107,6 +107,14 @@ import { PointerEventTypes } from '@babylonjs/core/Events/pointerEvents.js';
107
107
  import { EngineStore } from '@babylonjs/core/Engines/engineStore.js';
108
108
  import { UniqueIdGenerator } from '@babylonjs/core/Misc/uniqueIdGenerator.js';
109
109
 
110
+ const PropertyContext = createContext(undefined);
111
+ function usePropertyChangedNotifier() {
112
+ const propertyContext = useContext(PropertyContext);
113
+ return (entity, propertyKey, oldValue, newValue) => {
114
+ propertyContext?.onPropertyChanged.notifyObservers({ entity, propertyKey, oldValue, newValue });
115
+ };
116
+ }
117
+
110
118
  const InterceptorHooksMaps$1 = new WeakMap();
111
119
  /**
112
120
  * Intercepts a function on an object and allows you to add hooks that will be called during function execution.
@@ -541,6 +549,7 @@ function BoundPropertyCoreImpl(props, ref) {
541
549
  const value = useProperty(target, propertyKey);
542
550
  // Determine which specific property hook to use based on the value's type.
543
551
  const useSpecificProperty = useMemo(() => MakePropertyHook(value), [value]);
552
+ const notifyPropertyChanged = usePropertyChangedNotifier();
544
553
  // Create an inline nested component that changes when the desired specific hook type changes (since hooks can't be conditional).
545
554
  // eslint-disable-next-line @typescript-eslint/naming-convention
546
555
  const SpecificComponent = useMemo(() => {
@@ -555,8 +564,10 @@ function BoundPropertyCoreImpl(props, ref) {
555
564
  ref,
556
565
  value: convertedValue,
557
566
  onChange: (val) => {
567
+ const oldValue = target[propertyKey];
558
568
  const newValue = convertFrom ? convertFrom(val) : val;
559
569
  target[propertyKey] = newValue;
570
+ notifyPropertyChanged(target, propertyKey, oldValue, newValue);
560
571
  },
561
572
  };
562
573
  return jsx(Component, { ...propsToSend });
@@ -893,17 +904,37 @@ const useStyles$h = makeStyles({
893
904
  flexDirection: "column",
894
905
  overflow: "hidden",
895
906
  },
907
+ highlightDiv: {
908
+ borderRadius: tokens.borderRadiusLarge,
909
+ animationDuration: "1s",
910
+ animationTimingFunction: "ease-in-out",
911
+ animationIterationCount: "5",
912
+ animationFillMode: "forwards",
913
+ animationName: {
914
+ from: {
915
+ boxShadow: `inset 0 0 4px ${tokens.colorTransparentBackground}`,
916
+ },
917
+ // eslint-disable-next-line @typescript-eslint/naming-convention
918
+ "50%": {
919
+ boxShadow: `inset 0 0 12px ${tokens.colorBrandBackground}`,
920
+ },
921
+ to: {
922
+ boxShadow: `inset 0 0 4px ${tokens.colorTransparentBackground}`,
923
+ },
924
+ },
925
+ },
896
926
  });
897
927
  const AccordionSection = (props) => {
898
928
  AccordionSection.displayName = "AccordionSection";
899
929
  const classes = useStyles$h();
900
930
  return jsx("div", { className: classes.panelDiv, children: props.children });
901
931
  };
902
- const Accordion = (props) => {
932
+ const StringAccordion = Accordion$1;
933
+ const Accordion = forwardRef((props, ref) => {
903
934
  Accordion.displayName = "Accordion";
904
935
  const classes = useStyles$h();
905
936
  const { size } = useContext(ToolContext);
906
- const { children, ...rest } = props;
937
+ const { children, highlightSections, ...rest } = props;
907
938
  const validChildren = useMemo(() => {
908
939
  return (Children.map(children, (child) => {
909
940
  if (isValidElement(child)) {
@@ -924,6 +955,19 @@ const Accordion = (props) => {
924
955
  // Tracks closed items, which is needed so that when the children change, we only update the open/closed state
925
956
  // (depending on the collapseByDefault prop) for items that have not been explicitly opened or closed.
926
957
  const [closedItems, setClosedItems] = useState(validChildren.filter((child) => child.collapseByDefault).map((child) => child.title));
958
+ const internalOpenItemsRef = useRef(openItems);
959
+ // When highlight sections is requested, we temporarily override the open items, but if highlight sections is cleared,
960
+ // then we revert back to the normal open items tracking.
961
+ useLayoutEffect(() => {
962
+ if (highlightSections) {
963
+ internalOpenItemsRef.current = [...openItems];
964
+ setOpenItems([...highlightSections]);
965
+ }
966
+ else {
967
+ setOpenItems([...(internalOpenItemsRef.current ?? [])]);
968
+ internalOpenItemsRef.current = undefined;
969
+ }
970
+ }, [highlightSections]);
927
971
  useEffect(() => {
928
972
  for (const defaultOpenItem of validChildren.filter((child) => !child.collapseByDefault).map((child) => child.title)) {
929
973
  // If a child is not marked as collapseByDefault, then it should be opened by default, and
@@ -943,10 +987,11 @@ const Accordion = (props) => {
943
987
  setOpenItems((prev) => prev.filter((item) => item !== data.value));
944
988
  }
945
989
  }, []);
946
- return (jsx(Accordion$1, { className: classes.accordion, collapsible: true, multiple: true, onToggle: onToggle, openItems: openItems, ...rest, children: validChildren.map((child, index) => {
947
- return (jsxs(AccordionItem, { value: child.title, children: [jsx(AccordionHeader, { size: size, children: jsx(Subtitle2Stronger, { children: child.title }) }), jsx(AccordionPanel, { children: jsx("div", { className: classes.panelDiv, children: child.content }) }), index < validChildren.length - 1 && jsx(Divider, { inset: true, className: size === "small" ? classes.dividerSmall : classes.divider })] }, child.content.key));
990
+ return (jsx(StringAccordion, { ref: ref, className: classes.accordion, collapsible: true, multiple: true, onToggle: onToggle, openItems: openItems, ...rest, children: validChildren.map((child, index) => {
991
+ const isHighlighted = highlightSections?.includes(child.title);
992
+ return (jsxs(AccordionItem, { value: child.title, children: [jsxs("div", { className: isHighlighted ? classes.highlightDiv : undefined, children: [jsx(AccordionHeader, { size: size, children: jsx(Subtitle2Stronger, { children: child.title }) }), jsx(AccordionPanel, { children: jsx("div", { className: classes.panelDiv, children: child.content }) })] }), index < validChildren.length - 1 && jsx(Divider, { inset: true, className: size === "small" ? classes.dividerSmall : classes.divider })] }, child.content.key));
948
993
  }) }));
949
- };
994
+ });
950
995
 
951
996
  const CompactModeStorageKey = "Babylon/Settings/IsCompactMode";
952
997
  const SidePaneDockOverridesStorageKey = "Babylon/Settings/SidePaneDockOverrides";
@@ -1029,7 +1074,7 @@ const useStyles$g = makeStyles({
1029
1074
  });
1030
1075
  function ExtensibleAccordion(props) {
1031
1076
  const classes = useStyles$g();
1032
- const { children, sections, sectionContent, context } = props;
1077
+ const { children, sections, sectionContent, context, sectionsRef } = props;
1033
1078
  const defaultSections = useMemo(() => {
1034
1079
  const defaultSections = [];
1035
1080
  if (children) {
@@ -1111,7 +1156,24 @@ function ExtensibleAccordion(props) {
1111
1156
  })
1112
1157
  .filter((section) => section !== null);
1113
1158
  }, [mergedSections, mergedSectionContent, context]);
1114
- return (jsx("div", { className: classes.rootDiv, children: visibleSections.length > -1 && (jsx(CompactModeContextProvider, { children: jsxs(Accordion, { children: [...visibleSections.map((section) => {
1159
+ const [highlightSections, setHighlightSections] = useState();
1160
+ // When the context changes, clear any existing highlights.
1161
+ useLayoutEffect(() => {
1162
+ setHighlightSections(undefined);
1163
+ }, [context]);
1164
+ // This just assigns the returned object to any type of React ref, whether it is
1165
+ // a mutable ref with a 'current' property or whether it is a callback, useImperativeHandle
1166
+ // will deal with it.
1167
+ useImperativeHandle(sectionsRef, () => {
1168
+ return {
1169
+ highlightSections: (sectionsToHighlight) => {
1170
+ if (sectionsToHighlight.length > 0) {
1171
+ setHighlightSections(sectionsToHighlight);
1172
+ }
1173
+ },
1174
+ };
1175
+ }, []);
1176
+ return (jsx("div", { className: classes.rootDiv, children: visibleSections.length > -1 && (jsx(CompactModeContextProvider, { children: jsxs(Accordion, { highlightSections: highlightSections, children: [...visibleSections.map((section) => {
1115
1177
  return (jsx(AccordionSection, { title: section.identity, collapseByDefault: section.collapseByDefault, children: section.components }, section.identity));
1116
1178
  })] }) })) }));
1117
1179
  }
@@ -1940,6 +2002,10 @@ function usePane(location, layoutMode, defaultWidth, minWidth, sidePanes, onSele
1940
2002
  window.addEventListener("unload", onParentWindowUnload);
1941
2003
  disposeActions.push(() => window.removeEventListener("unload", onParentWindowUnload));
1942
2004
  }
2005
+ else {
2006
+ // If creating a child window failed (e.g. popup blocked), then just revert to docked mode.
2007
+ setUndocked(false);
2008
+ }
1943
2009
  disposeActions.push(() => childWindow?.close());
1944
2010
  }
1945
2011
  }
@@ -1983,7 +2049,7 @@ function usePane(location, layoutMode, defaultWidth, minWidth, sidePanes, onSele
1983
2049
  jsx(Portal, { mountNode: mountNode, children: jsx(RendererProvider, { renderer: renderer, targetDocument: mountNode.ownerDocument, children: jsx(Theme, { className: classes.paneContent, style: { minWidth }, targetDocument: mountNode.ownerDocument, children: corePane }) }) }));
1984
2050
  }
1985
2051
  }, [collapsed, corePane, windowState]);
1986
- return [topPaneTabList, pane, collapsed, setCollapsed];
2052
+ return [topPaneTabList, pane, collapsed, setCollapsed, undocked, setUndocked];
1987
2053
  }
1988
2054
  function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWidth = 350, rightPaneDefaultWidth = 350, rightPaneMinWidth = 350, toolbarMode = "full", sidePaneRemapper = undefined, layoutMode = "inline", } = {}) {
1989
2055
  return {
@@ -1994,6 +2060,17 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
1994
2060
  const sidePaneCollection = new ObservableCollection();
1995
2061
  const centralContentCollection = new ObservableCollection();
1996
2062
  const onSelectSidePane = new Observable(undefined, true);
2063
+ const onDockChanged = new Observable(undefined, true);
2064
+ const leftSidePaneContainerState = {
2065
+ isDocked: true,
2066
+ dock: () => onDockChanged.notifyObservers({ location: "left", dock: true }),
2067
+ undock: () => onDockChanged.notifyObservers({ location: "left", dock: false }),
2068
+ };
2069
+ const rightSidePaneContainerState = {
2070
+ isDocked: true,
2071
+ dock: () => onDockChanged.notifyObservers({ location: "right", dock: true }),
2072
+ undock: () => onDockChanged.notifyObservers({ location: "right", dock: false }),
2073
+ };
1997
2074
  const rootComponent = () => {
1998
2075
  const classes = useStyles$c();
1999
2076
  const [sidePaneDockOverrides, setSidePaneDockOverrides] = useSidePaneDockOverrides();
@@ -2119,8 +2196,32 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
2119
2196
  const bottomBarLeftItems = useMemo(() => bottomToolBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "left"), [bottomToolBarItems, coerceToolBarItemHorizontalLocation]);
2120
2197
  const bottomBarRightItems = useMemo(() => bottomToolBarItems.filter((entry) => coerceToolBarItemHorizontalLocation(entry) === "right"), [bottomToolBarItems, coerceToolBarItemHorizontalLocation]);
2121
2198
  const centralContents = useOrderedObservableCollection(centralContentCollection);
2122
- const [leftPaneTabList, leftPane, leftPaneCollapsed, setLeftPaneCollapsed] = usePane("left", layoutMode, leftPaneDefaultWidth, leftPaneMinWidth, coercedSidePanes, onSelectSidePane, sidePaneDockOperations, toolbarMode, topBarLeftItems, bottomBarLeftItems);
2123
- const [rightPaneTabList, rightPane, rightPaneCollapsed, setRightPaneCollapsed] = usePane("right", layoutMode, rightPaneDefaultWidth, rightPaneMinWidth, coercedSidePanes, onSelectSidePane, sidePaneDockOperations, toolbarMode, topBarRightItems, bottomBarRightItems);
2199
+ const [leftPaneTabList, leftPane, leftPaneCollapsed, setLeftPaneCollapsed, leftPaneUndocked, setLeftPaneUndocked] = usePane("left", layoutMode, leftPaneDefaultWidth, leftPaneMinWidth, coercedSidePanes, onSelectSidePane, sidePaneDockOperations, toolbarMode, topBarLeftItems, bottomBarLeftItems);
2200
+ useEffect(() => {
2201
+ // Propagate shorter lived React component state out to longer lived service state.
2202
+ leftSidePaneContainerState.isDocked = !leftPaneUndocked;
2203
+ }, [leftPaneUndocked]);
2204
+ const [rightPaneTabList, rightPane, rightPaneCollapsed, setRightPaneCollapsed, rightPaneUndocked, setRightPaneUndocked] = usePane("right", layoutMode, rightPaneDefaultWidth, rightPaneMinWidth, coercedSidePanes, onSelectSidePane, sidePaneDockOperations, toolbarMode, topBarRightItems, bottomBarRightItems);
2205
+ useEffect(() => {
2206
+ // Propagate shorter lived React component state out to longer lived service state.
2207
+ rightSidePaneContainerState.isDocked = !rightPaneUndocked;
2208
+ }, [rightPaneUndocked]);
2209
+ useEffect(() => {
2210
+ // If at the service level dock state change is requested, propagate to the React component state.
2211
+ const observer = onDockChanged.add(({ location, dock }) => {
2212
+ if (location === "left") {
2213
+ setLeftPaneUndocked(!dock);
2214
+ }
2215
+ else {
2216
+ setRightPaneUndocked(!dock);
2217
+ }
2218
+ });
2219
+ return () => {
2220
+ observer.remove();
2221
+ leftSidePaneContainerState.isDocked = true;
2222
+ rightSidePaneContainerState.isDocked = true;
2223
+ };
2224
+ }, [setLeftPaneUndocked, setRightPaneUndocked]);
2124
2225
  return (jsxs("div", { className: classes.mainView, children: [toolbarMode === "full" && (jsx(Fragment, { children: jsxs("div", { className: classes.barDiv, children: [leftPaneTabList, jsx(Toolbar, { location: "top", components: topToolBarItems }), rightPaneTabList] }) })), jsxs("div", { className: classes.verticallyCentralContent, children: [leftPane, jsxs("div", { className: classes.centralContent, children: [centralContents.map((entry) => (jsx(entry.component, {}, entry.key))), toolbarMode === "compact" && (jsxs(Fragment, { children: [jsx(Fade, { visible: leftPaneCollapsed, delay: 50, children: jsx("div", { className: mergeClasses(classes.expandButtonContainer, classes.expandButtonContainerLeft), children: jsx(Tooltip, { content: "Show Side Pane", relationship: "label", children: jsx(Button$1, { className: classes.expandButton, icon: jsx(PanelLeftExpandRegular, {}), onClick: () => setLeftPaneCollapsed(false) }) }) }) }), jsx(Fade, { visible: rightPaneCollapsed, delay: 50, children: jsx("div", { className: mergeClasses(classes.expandButtonContainer, classes.expandButtonContainerRight), children: jsx(Tooltip, { content: "Show Side Pane", relationship: "label", children: jsx(Button$1, { className: classes.expandButton, icon: jsx(PanelRightExpandRegular, {}), onClick: () => setRightPaneCollapsed(false) }) }) }) })] }))] }), rightPane] }), toolbarMode === "full" && (jsx(Fragment, { children: jsx("div", { className: classes.barDiv, children: jsx(Toolbar, { location: "bottom", components: bottomToolBarItems }) }) }))] }));
2125
2226
  };
2126
2227
  rootComponent.displayName = "Shell Service Root";
@@ -2139,6 +2240,9 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
2139
2240
  },
2140
2241
  addCentralContent: (entry) => centralContentCollection.add(entry),
2141
2242
  resetSidePaneLayout: () => localStorage.removeItem("Babylon/Settings/SidePaneDockOverrides"),
2243
+ leftSidePaneContainer: leftSidePaneContainerState,
2244
+ rightSidePaneContainer: rightSidePaneContainerState,
2245
+ onDockChanged,
2142
2246
  get sidePanes() {
2143
2247
  return [...sidePaneCollection.items].map((sidePaneDefinition) => {
2144
2248
  return {
@@ -2206,6 +2310,8 @@ const PropertiesServiceDefinition = {
2206
2310
  factory: (shellService, selectionService) => {
2207
2311
  const sectionsCollection = new ObservableCollection();
2208
2312
  const sectionContentCollection = new ObservableCollection();
2313
+ const onPropertyChanged = new Observable();
2314
+ const onHighlightSectionsRequested = new Observable();
2209
2315
  const registration = shellService.addSidePane({
2210
2316
  key: "Properties",
2211
2317
  title: "Properties",
@@ -2232,12 +2338,29 @@ const PropertiesServiceDefinition = {
2232
2338
  });
2233
2339
  })
2234
2340
  : [], [sectionContent, entity]);
2235
- return jsx(PropertiesPane, { sections: sections, sectionContent: applicableContent, context: entity });
2341
+ const sectionsRef = useRef(null);
2342
+ // The selected entity may be set at the same time as a highlight is requested.
2343
+ // To account for this, we need to wait for one React render to complete before
2344
+ // requesting the section highlight.
2345
+ const [pendingHighlight, setPendingHighlight] = useState();
2346
+ useEffect(() => {
2347
+ const observer = onHighlightSectionsRequested.add(setPendingHighlight);
2348
+ return () => observer.remove();
2349
+ }, []);
2350
+ useEffect(() => {
2351
+ if (pendingHighlight && sectionsRef.current) {
2352
+ sectionsRef.current.highlightSections(pendingHighlight);
2353
+ setPendingHighlight(undefined);
2354
+ }
2355
+ }, [pendingHighlight]);
2356
+ return (jsx(PropertyContext.Provider, { value: { onPropertyChanged }, children: jsx(PropertiesPane, { sections: sections, sectionContent: applicableContent, context: entity, sectionsRef: sectionsRef }) }));
2236
2357
  },
2237
2358
  });
2238
2359
  return {
2239
2360
  addSection: (section) => sectionsCollection.add(section),
2240
2361
  addSectionContent: (content) => sectionContentCollection.add(content),
2362
+ onPropertyChanged,
2363
+ highlightSections: (sectionIds) => onHighlightSectionsRequested.notifyObservers(sectionIds),
2241
2364
  dispose: () => registration.dispose(),
2242
2365
  };
2243
2366
  },
@@ -3523,7 +3646,7 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
3523
3646
  keywords: ["export", "gltf", "glb", "babylon", "exporter", "tools"],
3524
3647
  ...BabylonWebResources,
3525
3648
  author: { name: "Alex Chuber", forumUserName: "alexchuber" },
3526
- getExtensionModuleAsync: async () => await import('./exportService-B2rCoOC_.js'),
3649
+ getExtensionModuleAsync: async () => await import('./exportService-BqnzQ5KY.js'),
3527
3650
  },
3528
3651
  {
3529
3652
  name: "Capture Tools",
@@ -3531,7 +3654,7 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
3531
3654
  keywords: ["capture", "screenshot", "gif", "video", "tools"],
3532
3655
  ...BabylonWebResources,
3533
3656
  author: { name: "Alex Chuber", forumUserName: "alexchuber" },
3534
- getExtensionModuleAsync: async () => await import('./captureService-CS2uW-yq.js'),
3657
+ getExtensionModuleAsync: async () => await import('./captureService-BNAvQLVs.js'),
3535
3658
  },
3536
3659
  {
3537
3660
  name: "Import Tools",
@@ -3539,7 +3662,7 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
3539
3662
  keywords: ["import", "tools"],
3540
3663
  ...BabylonWebResources,
3541
3664
  author: { name: "Alex Chuber", forumUserName: "alexchuber" },
3542
- getExtensionModuleAsync: async () => await import('./importService-BSl7VIci.js'),
3665
+ getExtensionModuleAsync: async () => await import('./importService-Bv9STG4_.js'),
3543
3666
  },
3544
3667
  ]);
3545
3668
 
@@ -4647,7 +4770,7 @@ function MakeModularTool(options) {
4647
4770
  });
4648
4771
  // Register the extension list service (for browsing/installing extensions) if extension feeds are provided.
4649
4772
  if (extensionFeeds.length > 0) {
4650
- const { ExtensionListServiceDefinition } = await import('./extensionsListService-CyDEpF1t.js');
4773
+ const { ExtensionListServiceDefinition } = await import('./extensionsListService-CvofHYEa.js');
4651
4774
  await serviceContainer.addServiceAsync(ExtensionListServiceDefinition);
4652
4775
  }
4653
4776
  // Register the theme selector service (for selecting the theme) if theming is configured.
@@ -5469,14 +5592,23 @@ const CameraPropertiesServiceDefinition = {
5469
5592
  },
5470
5593
  };
5471
5594
 
5595
+ function IsEntityWithProperty(entity, property) {
5596
+ return !!entity && typeof entity === "object" && property in entity && entity[property] !== undefined;
5597
+ }
5598
+ function IsCommonEntity(entity) {
5599
+ return (IsEntityWithProperty(entity, "id") ||
5600
+ IsEntityWithProperty(entity, "uniqueId") ||
5601
+ IsEntityWithProperty(entity, "name") ||
5602
+ IsEntityWithProperty(entity, "getClassName"));
5603
+ }
5472
5604
  const CommonGeneralProperties = (props) => {
5473
5605
  const { commonEntity } = props;
5474
5606
  const name = useProperty(commonEntity, "name");
5475
5607
  const namePropertyDescriptor = useMemo(() => GetPropertyDescriptor(commonEntity, "name")?.[1], [commonEntity]);
5476
5608
  const isNameReadonly = !namePropertyDescriptor || IsPropertyReadonly(namePropertyDescriptor);
5477
5609
  const className = commonEntity.getClassName?.();
5478
- return (jsxs(Fragment, { children: [commonEntity.id !== undefined && jsx(StringifiedPropertyLine, { label: "ID", description: "The id of the node.", value: commonEntity.id }, "EntityId"), name !== undefined &&
5479
- (isNameReadonly ? (jsx(TextPropertyLine, { label: "Name", description: "The name of the node.", value: name }, "EntityName")) : (jsx(TextInputPropertyLine, { label: "Name", description: "The name of the node.", value: name, onChange: (newName) => (commonEntity.name = newName) }, "EntityName"))), commonEntity.uniqueId !== undefined && (jsx(StringifiedPropertyLine, { label: "Unique ID", description: "The unique id of the node.", value: commonEntity.uniqueId }, "EntityUniqueId")), className !== undefined && jsx(TextPropertyLine, { label: "Class", description: "The class of the node.", value: className }, "EntityClassName")] }));
5610
+ return (jsxs(Fragment, { children: [IsEntityWithProperty(commonEntity, "id") && jsx(StringifiedPropertyLine, { label: "ID", description: "The id of the node.", value: commonEntity.id }, "EntityId"), IsEntityWithProperty(commonEntity, "name") &&
5611
+ (isNameReadonly ? (jsx(TextPropertyLine, { label: "Name", description: "The name of the node.", value: name ?? "" }, "EntityName")) : (jsx(BoundProperty, { component: TextInputPropertyLine, label: "Name", description: "The name of the node.", target: commonEntity, propertyKey: "name" }, "EntityName"))), IsEntityWithProperty(commonEntity, "uniqueId") && (jsx(StringifiedPropertyLine, { label: "Unique ID", description: "The unique id of the node.", value: commonEntity.uniqueId }, "EntityUniqueId")), className !== undefined && jsx(TextPropertyLine, { label: "Class", description: "The class of the node.", value: className }, "EntityClassName")] }));
5480
5612
  };
5481
5613
  const DisposableGeneralProperties = (props) => {
5482
5614
  const { disposableEntity } = props;
@@ -5494,8 +5626,7 @@ const CommonPropertiesServiceDefinition = {
5494
5626
  if (entity instanceof Scene) {
5495
5627
  return false;
5496
5628
  }
5497
- const commonEntity = entity;
5498
- return commonEntity.id !== undefined || commonEntity.name !== undefined || commonEntity.uniqueId !== undefined || commonEntity.getClassName !== undefined;
5629
+ return IsCommonEntity(entity);
5499
5630
  },
5500
5631
  content: [
5501
5632
  {
@@ -8119,10 +8250,11 @@ const BaseTextureCharacteristicProperties = (props) => {
8119
8250
  const type = useProperty(internalTexture, "type") ?? NaN;
8120
8251
  const depth = useProperty(internalTexture, "depth");
8121
8252
  const useSRGBBuffer = useProperty(internalTexture, "_useSRGBBuffer");
8253
+ const samples = useProperty(internalTexture, "samples") ?? "?";
8122
8254
  const displayFormat = FindTextureFormat(format === -1 ? Constants.TEXTUREFORMAT_RGBA : format);
8123
8255
  const displayType = FindTextureType(type === -1 ? Constants.TEXTURETYPE_UNSIGNED_BYTE : type);
8124
8256
  const maxAnisotropy = texture.getScene()?.getEngine().getCaps().maxAnisotropy ?? 1;
8125
- return (jsxs(Fragment, { children: [texture.is2DArray && jsx(TextPropertyLine, { label: "Layers", value: depth?.toString() ?? "?" }), texture.is3D && jsx(TextPropertyLine, { label: "Depth", value: depth?.toString() ?? "?" }), jsx(TextPropertyLine, { label: "Format", value: displayFormat?.label ?? "unknown" }), !displayFormat?.hideType && !displayFormat?.compressed && jsx(TextPropertyLine, { label: "Type", value: displayType?.label ?? "unknown" }), !!displayFormat?.normalizable && !displayFormat?.compressed && displayType?.normalizable != undefined && (jsx(BooleanBadgePropertyLine, { label: "Normalized", value: displayType.normalizable })), jsx(BooleanBadgePropertyLine, { label: "Compressed", value: displayFormat?.compressed ?? false }), jsx(BooleanBadgePropertyLine, { label: "sRGB Buffers", value: useSRGBBuffer ?? false }), jsx(BoundProperty, { component: BooleanBadgePropertyLine, label: "Gamma Space", target: texture, propertyKey: "gammaSpace" }), jsx(BoundProperty, { component: BooleanBadgePropertyLine, label: "Has Alpha", target: texture, propertyKey: "hasAlpha" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Alpha from RGB", target: texture, propertyKey: "getAlphaFromRGB" }), jsx(BooleanBadgePropertyLine, { label: "3D", value: texture.is3D }), jsx(BooleanBadgePropertyLine, { label: "2D Array", value: texture.is2DArray }), jsx(BooleanBadgePropertyLine, { label: "Cube", value: texture.isCube }), jsx(BooleanBadgePropertyLine, { label: "Render Target", value: texture.isRenderTarget }), jsx(BooleanBadgePropertyLine, { label: "Mipmaps", value: !texture.noMipmap }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "UV Set", target: texture, propertyKey: "coordinatesIndex", min: 0, max: 3, step: 1 }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Mode", target: texture, propertyKey: "coordinatesMode", options: CoordinatesMode }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Level", target: texture, propertyKey: "level", min: 0, max: 2, step: 0.01 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Anisotropy", target: texture, propertyKey: "anisotropicFilteringLevel", min: 1, max: maxAnisotropy, step: 1 })] }));
8257
+ return (jsxs(Fragment, { children: [texture.is2DArray && jsx(TextPropertyLine, { label: "Layers", value: depth?.toString() ?? "?" }), texture.is3D && jsx(TextPropertyLine, { label: "Depth", value: depth?.toString() ?? "?" }), jsx(TextPropertyLine, { label: "Format", value: displayFormat?.label ?? "unknown" }), !displayFormat?.hideType && !displayFormat?.compressed && jsx(TextPropertyLine, { label: "Type", value: displayType?.label ?? "unknown" }), !!displayFormat?.normalizable && !displayFormat?.compressed && displayType?.normalizable != undefined && (jsx(BooleanBadgePropertyLine, { label: "Normalized", value: displayType.normalizable })), jsx(BooleanBadgePropertyLine, { label: "Compressed", value: displayFormat?.compressed ?? false }), jsx(BooleanBadgePropertyLine, { label: "sRGB Buffers", value: useSRGBBuffer ?? false }), jsx(BoundProperty, { component: BooleanBadgePropertyLine, label: "Gamma Space", target: texture, propertyKey: "gammaSpace" }), jsx(BoundProperty, { component: BooleanBadgePropertyLine, label: "Has Alpha", target: texture, propertyKey: "hasAlpha" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Alpha from RGB", target: texture, propertyKey: "getAlphaFromRGB" }), jsx(BooleanBadgePropertyLine, { label: "3D", value: texture.is3D }), jsx(BooleanBadgePropertyLine, { label: "2D Array", value: texture.is2DArray }), jsx(BooleanBadgePropertyLine, { label: "Cube", value: texture.isCube }), jsx(BooleanBadgePropertyLine, { label: "Render Target", value: texture.isRenderTarget }), jsx(BooleanBadgePropertyLine, { label: "Mipmaps", value: !texture.noMipmap }), jsx(TextPropertyLine, { label: "Samples", value: samples.toString() }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "UV Set", target: texture, propertyKey: "coordinatesIndex", min: 0, max: 3, step: 1 }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Mode", target: texture, propertyKey: "coordinatesMode", options: CoordinatesMode }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Level", target: texture, propertyKey: "level", min: 0, max: 2, step: 0.01 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Anisotropy", target: texture, propertyKey: "anisotropicFilteringLevel", min: 1, max: maxAnisotropy, step: 1 })] }));
8126
8258
  };
8127
8259
  const BaseTextureTransformProperties = (props) => {
8128
8260
  const { texture } = props;
@@ -9480,15 +9612,136 @@ function ShowInspector(scene, options = {}) {
9480
9612
  return inspectorToken;
9481
9613
  }
9482
9614
 
9615
+ // Mappings for Inspector v1 property section names to Inspector v2 section names.
9616
+ const LegacyPropertiesSectionMapping = {
9617
+ // Common sections
9618
+ ["GENERAL"]: "General",
9619
+ ["CUSTOM"]: "Custom",
9620
+ ["COMMANDS"]: "Commands",
9621
+ ["DEBUG"]: "Debug",
9622
+ ["ADVANCED"]: "Advanced",
9623
+ ["PROPERTIES"]: "Properties",
9624
+ // Transform sections
9625
+ ["TRANSFORMATIONS"]: "Transform",
9626
+ ["TRANSFORMS"]: "Transform",
9627
+ ["TRANSFORM"]: "Transform",
9628
+ // Animation sections
9629
+ ["ANIMATION"]: "Animation",
9630
+ ["ANIMATION RANGES"]: "Animation Ranges",
9631
+ ["ANIMATIONS"]: "Animation",
9632
+ ["ANIMATION GENERAL CONTROL"]: "Animation Control",
9633
+ ["CONTROLS"]: "Control",
9634
+ ["INFOS"]: "Info",
9635
+ // Camera sections
9636
+ ["COLLISIONS"]: "Collision",
9637
+ ["LIMITS"]: "Limits",
9638
+ ["BEHAVIORS"]: "Behaviors",
9639
+ // Material sections
9640
+ ["TRANSPARENCY"]: "Transparency",
9641
+ ["STENCIL"]: "Stencil",
9642
+ ["STENCIL - FRONT"]: "Stencil Front",
9643
+ ["STENCIL - BACK"]: "Stencil Back",
9644
+ ["TEXTURES"]: "Textures",
9645
+ ["LIGHTING & COLORS"]: "Lighting & Colors",
9646
+ ["LEVELS"]: "Levels",
9647
+ ["NORMAL MAP"]: "Normal Map",
9648
+ ["RENDERING"]: "Rendering",
9649
+ ["CHANNELS"]: "Channels",
9650
+ // PBR Material sections
9651
+ ["METALLIC WORKFLOW"]: "Metallic Workflow",
9652
+ ["CLEAR COAT"]: "Clear Coat",
9653
+ ["IRIDESCENCE"]: "Iridescence",
9654
+ ["ANISOTROPIC"]: "Anisotropic",
9655
+ ["SHEEN"]: "Sheen",
9656
+ ["SUBSURFACE"]: "Subsurface",
9657
+ // OpenPBR Material sections
9658
+ ["BASE"]: "Base",
9659
+ ["SPECULAR"]: "Specular",
9660
+ ["COAT"]: "Coat",
9661
+ ["FUZZ"]: "Fuzz",
9662
+ ["EMISSION"]: "Emission",
9663
+ ["THIN FILM"]: "Thin Film",
9664
+ ["GEOMETRY"]: "Geometry",
9665
+ // Sky Material
9666
+ ["SKY"]: "Sky",
9667
+ // Multi Material
9668
+ ["CHILDREN"]: "Children",
9669
+ // Mesh sections
9670
+ ["DISPLAY"]: "Display",
9671
+ ["DISPLAY OPTIONS"]: "Display Options",
9672
+ ["NODE GEOMETRY"]: "Node Geometry",
9673
+ ["MORPH TARGETS"]: "Morph Targets",
9674
+ ["PHYSICS"]: "Physics",
9675
+ ["OCCLUSIONS"]: "Occlusions",
9676
+ ["EDGE RENDERING"]: "Edge Rendering",
9677
+ ["OUTLINE & OVERLAY"]: "Outlines & Overlays",
9678
+ // Light sections
9679
+ ["SETUP"]: "Setup",
9680
+ ["SHADOWS"]: "Shadows",
9681
+ ["SHADOW GENERATOR"]: "Shadow Generator",
9682
+ // Particle System sections
9683
+ ["NODE PARTICLE EDITOR"]: "Node Particle Editor",
9684
+ ["FILE"]: "File",
9685
+ ["SNIPPET"]: "Snippet",
9686
+ ["ATTRACTORS"]: "Attractors",
9687
+ ["IMPOSTORS"]: "Impostors",
9688
+ ["EMITTER"]: "Emitter",
9689
+ ["SIZE"]: "Size",
9690
+ ["LIFETIME"]: "Lifetime",
9691
+ ["COLORS"]: "Color",
9692
+ ["ROTATION"]: "Rotation",
9693
+ ["SPRITESHEET"]: "Spritesheet",
9694
+ // Sprite sections
9695
+ ["CELLS"]: "Cells",
9696
+ ["CELL"]: "Cell",
9697
+ ["SCALE"]: "Scale",
9698
+ // Post Process sections
9699
+ ["CONFIGURATION"]: "Configuration",
9700
+ ["BLOOM"]: "Bloom",
9701
+ ["CHROMATIC ABERRATION"]: "Chromatic Aberration",
9702
+ ["DEPTH OF FIELD"]: "Depth of Field",
9703
+ ["FXAA"]: "FXAA",
9704
+ ["GLOW LAYER"]: "Glow Layer",
9705
+ ["GRAIN"]: "Grain",
9706
+ ["IMAGE PROCESSING"]: "Image Processing",
9707
+ ["SHARPEN"]: "Sharpen",
9708
+ ["OPTIONS"]: "Options",
9709
+ ["SSAO"]: "SSAO",
9710
+ ["Denoiser"]: "Denoiser",
9711
+ ["SSR"]: "SSR",
9712
+ ["Voxel Shadows"]: "Voxel Shadows",
9713
+ ["Screenspace Shadows"]: "Screenspace Shadows",
9714
+ ["Automatic thickness computation"]: "Automatic Thickness Computation",
9715
+ ["Blur"]: "Blur",
9716
+ ["Attenuations"]: "Attenuations",
9717
+ ["Color space"]: "Color Space",
9718
+ // Scene sections
9719
+ ["RENDERING MODE"]: "Rendering",
9720
+ ["ENVIRONMENT"]: "Environment",
9721
+ ["MATERIAL IMAGE PROCESSING"]: "Material Image Processing",
9722
+ // Texture sections
9723
+ ["PREVIEW"]: "Preview",
9724
+ ["ADVANCED TEXTURE PROPERTIES"]: "Advanced Texture Properties",
9725
+ // Frame Graph sections
9726
+ ["TASKS"]: "Tasks",
9727
+ // Metadata
9728
+ ["METADATA"]: "Metadata",
9729
+ ["XMP METADATA"]: "XMP Metadata",
9730
+ // Variants
9731
+ ["VARIANTS"]: "Variants",
9732
+ // Node Material
9733
+ ["INPUTS"]: "Inputs",
9734
+ };
9735
+
9483
9736
  function ConvertOptions(v1Options) {
9484
9737
  // Options not currently handled:
9485
9738
  // • enablePopup: Do users care about this one?
9486
9739
  // • enableClose: Currently Inspector v2 does not allow panes/tabs to be closed.
9487
- // • gizmoCamera: Do users care about this one?
9488
9740
  // • skipDefaultFontLoading: Probably doesn't make sense for Inspector v2 using Fluent.
9489
- // TODO:
9490
- // contextMenu
9491
- // contextMenuOverride
9741
+ // • contextMenuOverride: Currently there are no default section context menu items to override.
9742
+ // If the create extension ends up adding context menu items to match v1
9743
+ // behavior, then it should only enable that feature if contextMenuOverride
9744
+ // is not set to true.
9492
9745
  v1Options = {
9493
9746
  overlay: false,
9494
9747
  showExplorer: true,
@@ -9523,6 +9776,23 @@ function ConvertOptions(v1Options) {
9523
9776
  };
9524
9777
  serviceDefinitions.push(initialTabServiceDefinition);
9525
9778
  }
9779
+ if (v1Options.gizmoCamera) {
9780
+ const { gizmoCamera } = v1Options;
9781
+ const gizmoCameraServiceDefinition = {
9782
+ friendlyName: "Gizmo Camera (Backward Compatibility)",
9783
+ consumes: [GizmoServiceIdentity],
9784
+ factory: (gizmoService) => {
9785
+ // As a simple back compat solution, just keep the utility layer alive until Inspector is unloaded.
9786
+ // This way we don't need to keep re-assigning the gizmo camera to the utility layer if it is recreated.
9787
+ const utilityLayerRef = gizmoService.getUtilityLayer(gizmoCamera.getScene());
9788
+ utilityLayerRef.value.setRenderCamera(gizmoCamera);
9789
+ return {
9790
+ dispose: () => utilityLayerRef.dispose(),
9791
+ };
9792
+ },
9793
+ };
9794
+ serviceDefinitions.push(gizmoCameraServiceDefinition);
9795
+ }
9526
9796
  if (v1Options.additionalNodes && v1Options.additionalNodes.length > 0) {
9527
9797
  const { additionalNodes } = v1Options;
9528
9798
  const additionalNodesServiceDefinition = {
@@ -9675,22 +9945,19 @@ function ConvertOptions(v1Options) {
9675
9945
  */
9676
9946
  class Inspector {
9677
9947
  static MarkLineContainerTitleForHighlighting(title) {
9678
- throw new Error("Not Implemented");
9948
+ this.MarkMultipleLineContainerTitlesForHighlighting([title]);
9679
9949
  }
9680
9950
  static MarkMultipleLineContainerTitlesForHighlighting(titles) {
9681
- throw new Error("Not Implemented");
9951
+ this._SectionHighlighter?.(titles);
9682
9952
  }
9683
9953
  static PopupEmbed() {
9684
- // Show with embed mode on (stacked right panes) and undocked?
9685
- throw new Error("Not Implemented");
9954
+ this._PopupToggler?.("right");
9686
9955
  }
9687
9956
  static PopupSceneExplorer() {
9688
- // Show with all right panes (not stacked), scene explorer tab selected, and undocked?
9689
- throw new Error("Not Implemented");
9957
+ this._PopupToggler?.("left");
9690
9958
  }
9691
9959
  static PopupInspector() {
9692
- // Show with all right panes (not stacked), properties tab selected, and undocked?
9693
- throw new Error("Not Implemented");
9960
+ this._PopupToggler?.("right");
9694
9961
  }
9695
9962
  static get IsVisible() {
9696
9963
  return !!this._CurrentInspectorToken;
@@ -9705,7 +9972,86 @@ class Inspector {
9705
9972
  if (!scene || scene.isDisposed) {
9706
9973
  return;
9707
9974
  }
9708
- this._CurrentInspectorToken = ShowInspector(scene, ConvertOptions(userOptions));
9975
+ let options = ConvertOptions(userOptions);
9976
+ const serviceDefinitions = [];
9977
+ const popupServiceDefinition = {
9978
+ friendlyName: "Popup Service (Backward Compatibility)",
9979
+ consumes: [ShellServiceIdentity],
9980
+ factory: (shellService) => {
9981
+ this._PopupToggler = (side) => {
9982
+ const sidePaneContainer = side === "left" ? shellService.leftSidePaneContainer : shellService.rightSidePaneContainer;
9983
+ if (sidePaneContainer.isDocked) {
9984
+ sidePaneContainer.undock();
9985
+ }
9986
+ else {
9987
+ sidePaneContainer.dock();
9988
+ }
9989
+ };
9990
+ return {
9991
+ dispose: () => (this._PopupToggler = null),
9992
+ };
9993
+ },
9994
+ };
9995
+ serviceDefinitions.push(popupServiceDefinition);
9996
+ const selectionChangedServiceDefinition = {
9997
+ friendlyName: "Selection Changed Service (Backward Compatibility)",
9998
+ consumes: [SelectionServiceIdentity],
9999
+ factory: (selectionService) => {
10000
+ const selectionServiceObserver = selectionService.onSelectedEntityChanged.add(() => {
10001
+ this.OnSelectionChangeObservable.notifyObservers(selectionService.selectedEntity);
10002
+ });
10003
+ const legacyObserver = this.OnSelectionChangeObservable.add((entity) => {
10004
+ selectionService.selectedEntity = entity;
10005
+ });
10006
+ return {
10007
+ dispose: () => {
10008
+ selectionServiceObserver.remove();
10009
+ legacyObserver.remove();
10010
+ },
10011
+ };
10012
+ },
10013
+ };
10014
+ serviceDefinitions.push(selectionChangedServiceDefinition);
10015
+ const propertyChangedServiceDefinition = {
10016
+ friendlyName: "Property Changed Service (Backward Compatibility)",
10017
+ consumes: [PropertiesServiceIdentity],
10018
+ factory: (propertiesService) => {
10019
+ const observer = propertiesService.onPropertyChanged.add((changeInfo) => {
10020
+ this.OnPropertyChangedObservable.notifyObservers({
10021
+ object: changeInfo.entity,
10022
+ property: changeInfo.propertyKey.toString(),
10023
+ value: changeInfo.newValue,
10024
+ initialValue: changeInfo.oldValue,
10025
+ });
10026
+ });
10027
+ return {
10028
+ dispose: () => {
10029
+ observer.remove();
10030
+ },
10031
+ };
10032
+ },
10033
+ };
10034
+ serviceDefinitions.push(propertyChangedServiceDefinition);
10035
+ const sectionHighlighterServiceDefinition = {
10036
+ friendlyName: "Section Highlighter Service (Backward Compatibility)",
10037
+ consumes: [PropertiesServiceIdentity],
10038
+ factory: (propertiesService) => {
10039
+ this._SectionHighlighter = (sectionIds) => {
10040
+ propertiesService.highlightSections(sectionIds.map((id) => LegacyPropertiesSectionMapping[id] ?? id));
10041
+ };
10042
+ return {
10043
+ dispose: () => {
10044
+ this._SectionHighlighter = null;
10045
+ },
10046
+ };
10047
+ },
10048
+ };
10049
+ serviceDefinitions.push(sectionHighlighterServiceDefinition);
10050
+ options = {
10051
+ ...options,
10052
+ serviceDefinitions: [...(options.serviceDefinitions ?? []), ...serviceDefinitions],
10053
+ };
10054
+ this._CurrentInspectorToken = ShowInspector(scene, options);
9709
10055
  }
9710
10056
  static Hide() {
9711
10057
  this._CurrentInspectorToken?.dispose();
@@ -9713,6 +10059,8 @@ class Inspector {
9713
10059
  }
9714
10060
  }
9715
10061
  Inspector._CurrentInspectorToken = null;
10062
+ Inspector._PopupToggler = null;
10063
+ Inspector._SectionHighlighter = null;
9716
10064
  Inspector.OnSelectionChangeObservable = new Observable();
9717
10065
  Inspector.OnPropertyChangedObservable = new Observable();
9718
10066
 
@@ -9972,4 +10320,4 @@ const TextAreaPropertyLine = (props) => {
9972
10320
  };
9973
10321
 
9974
10322
  export { SettingsContextIdentity as $, useAsyncResource as A, ButtonLine as B, Collapse as C, DebugServiceIdentity as D, ExtensibleAccordion as E, FileUploadLine as F, useCompactMode as G, useSidePaneDockOverrides as H, Inspector as I, useAngleConverters as J, MakeTeachingMoment as K, Link as L, MakeLazyComponent as M, NumberDropdownPropertyLine as N, MakeDialogTeachingMoment as O, PropertiesServiceIdentity as P, InterceptFunction as Q, GetPropertyDescriptor as R, SwitchPropertyLine as S, ToolsServiceIdentity as T, IsPropertyReadonly as U, InterceptProperty as V, ObservableCollection as W, ConstructorFactory as X, SceneContextIdentity as Y, SelectionServiceIdentity as Z, SelectionServiceDefinition as _, SyncedSliderPropertyLine as a, ShowInspector as a0, AccordionSection as a1, Accordion as a2, Button as a3, Checkbox as a4, ColorPickerPopup as a5, InputHexField as a6, InputHsvField as a7, ComboBox as a8, DraggableLine as a9, Color4PropertyLine as aA, HexPropertyLine as aB, TextInputPropertyLine as aC, NumberInputPropertyLine as aD, LinkPropertyLine as aE, PropertyLine as aF, LineContainer as aG, PlaceholderPropertyLine as aH, SpinButtonPropertyLine as aI, StringifiedPropertyLine as aJ, TextAreaPropertyLine as aK, TextPropertyLine as aL, RotationVectorPropertyLine as aM, QuaternionPropertyLine as aN, Vector2PropertyLine as aO, Vector3PropertyLine as aP, Vector4PropertyLine as aQ, Dropdown as aa, NumberDropdown as ab, StringDropdown as ac, FactorGradientComponent as ad, Color3GradientComponent as ae, Color4GradientComponent as af, ColorStepGradientComponent as ag, InfoLabel as ah, List as ai, MessageBar as aj, PositionedPopover as ak, SearchBar as al, SearchBox as am, SpinButton as an, Switch as ao, SyncedSliderInput as ap, Textarea as aq, TextInput as ar, ToggleButton as as, FactorGradientList as at, Color3GradientList as au, Color4GradientList as av, Pane as aw, BooleanBadgePropertyLine as ax, CheckboxPropertyLine as ay, Color3PropertyLine as az, ShellServiceIdentity as b, MakePopoverTeachingMoment as c, TeachingMoment as d, SidePaneContainer as e, SceneExplorerServiceIdentity as f, SettingsServiceIdentity as g, StatsServiceIdentity as h, StringDropdownPropertyLine as i, BoundProperty as j, LinkToEntityPropertyLine as k, BuiltInsExtensionFeed as l, useProperty as m, useVector3Property as n, useColor3Property as o, useColor4Property as p, useQuaternionProperty as q, MakePropertyHook as r, useInterceptObservable as s, useEventfulState as t, useExtensionManager as u, useObservableState as v, useObservableCollection as w, useOrderedObservableCollection as x, usePollingObservable as y, useResource as z };
9975
- //# sourceMappingURL=index-DE0QdD6v.js.map
10323
+ //# sourceMappingURL=index-DUdNW7K3.js.map