@terraware/web-components 5.0.27 → 5.1.1-rc.0
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.
- package/components/AntSwitch/index.js +19 -22
- package/components/Autocomplete/Autocomplete.js +106 -130
- package/components/Badge/index.js +28 -29
- package/components/BusySpinner/index.js +40 -45
- package/components/Button/Button.js +41 -47
- package/components/Checkbox.js +64 -63
- package/components/Confirm/index.js +74 -83
- package/components/DatePicker/DatePicker.js +138 -141
- package/components/DialogBox/DialogBox.js +111 -118
- package/components/Divisor.js +18 -18
- package/components/Dropdown.js +66 -94
- package/components/EditableTable/index.js +211 -271
- package/components/ErrorBox/ErrorBox.js +47 -49
- package/components/FileChooser/index.js +117 -135
- package/components/FormBottomBar/index.js +75 -84
- package/components/Icon/Icon.js +12 -20
- package/components/Icon/icons/index.js +256 -256
- package/components/IconTooltip/index.js +49 -60
- package/components/Map/MapBox.js +545 -452
- package/components/Map/MapContainer.js +25 -29
- package/components/Map/MapDateSliderControl.js +64 -64
- package/components/Map/MapDrawer.js +41 -47
- package/components/Map/MapLegend.js +176 -172
- package/components/Map/MapViewStyleControl.js +59 -63
- package/components/Map/ReactMapboxWrapper.js +3 -2
- package/components/Map/index.js +161 -180
- package/components/Map/types.js +12 -17
- package/components/Map/useMaintainLayerOrder.js +16 -26
- package/components/Markdown/index.js +25 -26
- package/components/Message/Message.js +73 -76
- package/components/MultiSelect/index.js +112 -124
- package/components/Navbar/NavFooter.js +9 -13
- package/components/Navbar/NavItem.js +70 -76
- package/components/Navbar/NavSection.js +17 -19
- package/components/Navbar/Navbar.js +39 -46
- package/components/Navbar/SubNavbar.js +9 -13
- package/components/Note.js +18 -22
- package/components/OverlayModal/OverlayModal.js +56 -63
- package/components/PageForm/index.js +33 -41
- package/components/PhotoChooser/index.js +165 -173
- package/components/PhotosCarousel/PhotoSlide.js +32 -35
- package/components/PhotosCarousel/index.js +80 -85
- package/components/PhotosCarousel/usePhotosCarousel.js +69 -76
- package/components/Pill/index.js +41 -45
- package/components/PillList/index.js +17 -24
- package/components/PlacementWrapper/index.js +38 -59
- package/components/PopoverMenu/Popover.js +68 -85
- package/components/PopoverMenu/index.js +51 -56
- package/components/PopoverMultiSelect/index.js +52 -59
- package/components/ProgressCircle/ProgressCircle.js +28 -32
- package/components/RadioButton.js +17 -19
- package/components/Select/Select.js +13 -15
- package/components/Select/SelectT.js +235 -250
- package/components/Separator/index.js +14 -17
- package/components/Size.js +0 -1
- package/components/Slider/index.js +43 -56
- package/components/Stepper/index.d.ts +33 -0
- package/components/Stepper/index.d.ts.map +1 -0
- package/components/Stepper/index.js +66 -0
- package/components/SummaryBox.js +70 -72
- package/components/Tabs/index.js +133 -135
- package/components/TextTruncated/index.js +117 -130
- package/components/Textfield/Textfield.js +158 -190
- package/components/Textfield/TruncatedTextArea.js +70 -84
- package/components/TimelineSlider/TimelineMarker.js +25 -30
- package/components/TimelineSlider/TimelineRail.js +8 -11
- package/components/TimelineSlider/index.js +64 -66
- package/components/TimelineSliderV2/ClusterBadge.js +25 -29
- package/components/TimelineSliderV2/TimelineDot.js +31 -35
- package/components/TimelineSliderV2/TimelineRail.js +8 -11
- package/components/TimelineSliderV2/index.js +121 -103
- package/components/TimelineSliderV2/layout.js +124 -147
- package/components/TimelineSliderV2/types.js +0 -1
- package/components/Tooltip/Tooltip.js +47 -56
- package/components/ViewPhotosDialog/index.js +28 -35
- package/components/VirtualWalkthrough/Annotation.js +163 -207
- package/components/VirtualWalkthrough/AnnotationEditPane.js +198 -184
- package/components/VirtualWalkthrough/AnnotationPanel.js +187 -199
- package/components/VirtualWalkthrough/Application.js +31 -34
- package/components/VirtualWalkthrough/AutoRotator.js +85 -223
- package/components/VirtualWalkthrough/BlockingSpinner.js +26 -28
- package/components/VirtualWalkthrough/BoundaryRing.js +30 -34
- package/components/VirtualWalkthrough/BoundaryWall.js +32 -36
- package/components/VirtualWalkthrough/CameraInfo.js +100 -89
- package/components/VirtualWalkthrough/ControlsInfoPane.js +254 -195
- package/components/VirtualWalkthrough/GradientSky.js +72 -73
- package/components/VirtualWalkthrough/SplatControls.js +209 -221
- package/components/VirtualWalkthrough/SplatCrop.js +21 -20
- package/components/VirtualWalkthrough/SplatFadeCrop.js +21 -20
- package/components/VirtualWalkthrough/SplatModel.js +65 -85
- package/components/VirtualWalkthrough/SplatRevealRain.js +41 -46
- package/components/VirtualWalkthrough/TfAnnotationManager.js +197 -379
- package/components/VirtualWalkthrough/TfXrNavigation.js +73 -162
- package/components/VirtualWalkthrough/VirtualWalkthroughViewer.js +438 -431
- package/components/VirtualWalkthrough/VrAnnotationPanel.js +18 -22
- package/components/VirtualWalkthrough/XrAnnotationInteraction.js +14 -17
- package/components/VirtualWalkthrough/XrExitButton.js +14 -17
- package/components/VirtualWalkthrough/XrGazeDwell.js +14 -17
- package/components/VirtualWalkthrough/XrPointerRay.js +14 -17
- package/components/VirtualWalkthrough/XrStartPose.js +67 -121
- package/components/VirtualWalkthrough/boundary-ring.js +87 -117
- package/components/VirtualWalkthrough/boundary-wall.js +175 -258
- package/components/VirtualWalkthrough/camera-adoption.js +18 -64
- package/components/VirtualWalkthrough/groundPlane.js +32 -47
- package/components/VirtualWalkthrough/gsplat-fade-crop-effect.js +35 -35
- package/components/VirtualWalkthrough/splatFormat.js +13 -47
- package/components/VirtualWalkthrough/useAdoptedCamera.js +23 -44
- package/components/VirtualWalkthrough/useRestartOnVr.js +26 -37
- package/components/VirtualWalkthrough/useXrRenderTuning.js +33 -54
- package/components/VirtualWalkthrough/vr-annotation-panel-layout.js +67 -99
- package/components/VirtualWalkthrough/vr-annotation-panel.js +403 -433
- package/components/VirtualWalkthrough/vr-annotation-scroll.js +10 -28
- package/components/VirtualWalkthrough/walkthrough-camera.js +204 -329
- package/components/VirtualWalkthrough/xr-annotation-candidate-buffer.js +39 -80
- package/components/VirtualWalkthrough/xr-annotation-candidates.js +6 -18
- package/components/VirtualWalkthrough/xr-annotation-interaction.js +31 -56
- package/components/VirtualWalkthrough/xr-annotation-targeting.js +22 -38
- package/components/VirtualWalkthrough/xr-button-arming.js +7 -17
- package/components/VirtualWalkthrough/xr-button-hold.js +22 -36
- package/components/VirtualWalkthrough/xr-exit-button-mask.js +22 -36
- package/components/VirtualWalkthrough/xr-exit-button.js +148 -207
- package/components/VirtualWalkthrough/xr-face-buttons.js +19 -29
- package/components/VirtualWalkthrough/xr-gaze-dwell-state.js +23 -34
- package/components/VirtualWalkthrough/xr-gaze-dwell.js +107 -144
- package/components/VirtualWalkthrough/xr-interactive-ui.js +12 -24
- package/components/VirtualWalkthrough/xr-pointer-ray.js +13 -20
- package/components/VirtualWalkthrough/xr-progress-pie-material.js +117 -88
- package/components/VirtualWalkthrough/xr-progress-pie.js +1 -10
- package/components/VirtualWalkthrough/xr-ray-quad.js +16 -30
- package/components/VirtualWalkthrough/xr-render-tuning.js +17 -48
- package/components/VirtualWalkthrough/xr-scene-bounds.js +21 -37
- package/components/VirtualWalkthrough/xr-start-pose.js +27 -73
- package/components/VirtualWalkthrough/xr-teleport-gesture.js +16 -42
- package/components/svg/BlobbyGrayIconImage.js +41 -39
- package/components/svg/BlobbyGrayIconImport.js +41 -39
- package/components/svg/BlobbyGrayIconUploadToTheCloud.js +41 -39
- package/components/svg/BlobbyIconCloudChecked.js +202 -164
- package/components/svg/BlobbyIconExportOrUploadPhoto.js +202 -164
- package/components/svg/BlobbyIconFolder.js +202 -164
- package/components/svg/BlobbyIconGraphReport.js +202 -164
- package/components/svg/BlobbyIconHappy.js +202 -164
- package/components/svg/BlobbyIconHeartMonitor.js +202 -164
- package/components/svg/BlobbyIconLeaf.js +202 -164
- package/components/svg/BlobbyIconLibrary.js +202 -164
- package/components/svg/BlobbyIconNursery.js +204 -166
- package/components/svg/BlobbyIconOrganization.js +202 -164
- package/components/svg/BlobbyIconParchment.js +202 -164
- package/components/svg/BlobbyIconPeople.js +202 -164
- package/components/svg/BlobbyIconSeedBank.js +202 -164
- package/components/svg/BlobbyIconSeedling.js +202 -164
- package/components/svg/BlobbyIconSeeds.js +202 -164
- package/components/svg/BlobbyIconSite.js +206 -167
- package/components/svg/BlobbyIconSparkles.js +202 -164
- package/components/svg/BlobbyIconWrench.js +202 -164
- package/components/svg/Bug.js +19 -21
- package/components/svg/Calendar.js +19 -21
- package/components/svg/CaretDown.js +19 -21
- package/components/svg/CaretLeft.js +19 -21
- package/components/svg/CaretRight.js +19 -21
- package/components/svg/CaretUp.js +19 -21
- package/components/svg/ChevronDown.js +19 -21
- package/components/svg/ChevronUp.js +19 -21
- package/components/svg/Close.js +19 -21
- package/components/svg/Critical.js +19 -21
- package/components/svg/Edit.js +202 -164
- package/components/svg/Error.js +19 -21
- package/components/svg/Filter.js +19 -21
- package/components/svg/Folder.js +19 -21
- package/components/svg/Help.js +19 -21
- package/components/svg/Home.js +19 -21
- package/components/svg/IconAdd.js +19 -21
- package/components/svg/IconArrowRight.js +21 -23
- package/components/svg/IconBusinessNetwork.js +19 -21
- package/components/svg/IconCalendar.js +19 -21
- package/components/svg/IconCancel.js +19 -21
- package/components/svg/IconChargingBattery.js +19 -21
- package/components/svg/IconChecklist.js +21 -23
- package/components/svg/IconCheckmark.js +19 -21
- package/components/svg/IconCoinInHand.js +19 -21
- package/components/svg/IconColumns.js +19 -21
- package/components/svg/IconComment.js +20 -22
- package/components/svg/IconDashboard.js +19 -21
- package/components/svg/IconDataMigration.js +19 -21
- package/components/svg/IconDocument.js +21 -23
- package/components/svg/IconDownloadFromTheCloud.js +21 -23
- package/components/svg/IconEdit.js +21 -23
- package/components/svg/IconExpand.js +21 -23
- package/components/svg/IconExport.js +19 -21
- package/components/svg/IconExternalLink.js +19 -21
- package/components/svg/IconEye.js +19 -21
- package/components/svg/IconEyeOff.js +19 -21
- package/components/svg/IconFile.js +19 -21
- package/components/svg/IconFolder.js +19 -21
- package/components/svg/IconFullScreen.js +20 -22
- package/components/svg/IconFutures.js +19 -21
- package/components/svg/IconGraphReport.js +19 -21
- package/components/svg/IconGrid.js +19 -21
- package/components/svg/IconHeartMonitor.js +19 -21
- package/components/svg/IconHelp.js +21 -23
- package/components/svg/IconHistory.js +19 -21
- package/components/svg/IconImport.js +19 -21
- package/components/svg/IconIndex.js +19 -21
- package/components/svg/IconLayers.js +19 -21
- package/components/svg/IconLibrary.js +20 -22
- package/components/svg/IconList.js +19 -21
- package/components/svg/IconLivePlant.js +19 -21
- package/components/svg/IconLocations.js +19 -21
- package/components/svg/IconMail.js +19 -21
- package/components/svg/IconManager.js +19 -21
- package/components/svg/IconMap.js +19 -21
- package/components/svg/IconMarker.js +19 -21
- package/components/svg/IconMenu.js +19 -21
- package/components/svg/IconMenuHorizontal.js +19 -21
- package/components/svg/IconModule.js +19 -21
- package/components/svg/IconMyLocation.js +19 -21
- package/components/svg/IconNote.js +21 -23
- package/components/svg/IconNursery.js +21 -23
- package/components/svg/IconOrg.js +19 -21
- package/components/svg/IconParchment.js +19 -21
- package/components/svg/IconPhoto.js +19 -21
- package/components/svg/IconPlantsFilled.js +19 -21
- package/components/svg/IconRedo.js +19 -21
- package/components/svg/IconRestorationSite.js +19 -21
- package/components/svg/IconSeedBank.js +19 -21
- package/components/svg/IconSeedling.js +19 -21
- package/components/svg/IconSettings.js +19 -21
- package/components/svg/IconSlice.js +19 -21
- package/components/svg/IconSubmit.js +19 -21
- package/components/svg/IconSubtract.js +21 -23
- package/components/svg/IconSynced.js +19 -21
- package/components/svg/IconTrashCan.js +19 -21
- package/components/svg/IconTreasureMap.js +19 -21
- package/components/svg/IconUnavailable.js +19 -21
- package/components/svg/IconUndo.js +19 -21
- package/components/svg/IconVariable.js +19 -21
- package/components/svg/IconVideo.js +30 -31
- package/components/svg/IconWifi.js +19 -21
- package/components/svg/Info.js +19 -21
- package/components/svg/Key.js +19 -21
- package/components/svg/Leaf.js +19 -21
- package/components/svg/Lock.js +19 -21
- package/components/svg/Logo.js +48 -43
- package/components/svg/MenuVertical.js +19 -21
- package/components/svg/Notification.js +19 -21
- package/components/svg/Person.js +19 -21
- package/components/svg/Plus.js +19 -21
- package/components/svg/RestorationSite.js +19 -21
- package/components/svg/Search.js +19 -21
- package/components/svg/Seeds.js +19 -21
- package/components/svg/Site.js +19 -21
- package/components/svg/Sparkles.js +19 -21
- package/components/svg/Species.js +19 -21
- package/components/svg/Species2.js +202 -164
- package/components/svg/Spinner.js +54 -48
- package/components/svg/Star.js +19 -21
- package/components/svg/Success.js +19 -21
- package/components/svg/SuccessFilled.js +19 -21
- package/components/svg/TerrawareLogoDesktop.js +55 -49
- package/components/svg/TerrawareLogoMobile.js +25 -26
- package/components/svg/Touchscreen.js +19 -21
- package/components/svg/UploadCloud.js +202 -164
- package/components/svg/Warning.js +19 -21
- package/components/svg/WelcomeClipboard.js +156 -133
- package/components/svg/index.js +129 -129
- package/components/table/EnhancedTableToolbar.js +68 -74
- package/components/table/EnhancedTableToolbarV2.js +31 -41
- package/components/table/TableCellRenderer.js +196 -231
- package/components/table/TableHeader.js +71 -73
- package/components/table/TableHeaderItem.js +97 -102
- package/components/table/density.js +18 -19
- package/components/table/index.js +350 -369
- package/components/table/sort.js +27 -52
- package/components/table/types.js +0 -1
- package/components/types/index.js +0 -1
- package/hooks/cameraEntityContext.js +2 -13
- package/hooks/useBoolean.js +17 -13
- package/hooks/useCameraPosition.js +56 -56
- package/hooks/useDevicePerformance.js +17 -17
- package/hooks/useXr.js +85 -87
- package/index.d.ts +3 -1
- package/index.d.ts.map +1 -1
- package/index.js +59 -58
- package/package.json +1 -1
- package/setupTests.js +0 -4
- package/strings/csv/en.csv +1 -0
- package/strings/csv/es.csv +1 -0
- package/strings/csv/fr.csv +1 -0
- package/strings/export.js +111 -170
- package/strings/index.js +25 -54
- package/strings/locales.js +21 -41
- package/strings/strings-en.d.ts +1 -0
- package/strings/strings-en.d.ts.map +1 -1
- package/strings/strings-en.js +50 -51
- package/strings/strings-es.d.ts +1 -0
- package/strings/strings-es.d.ts.map +1 -1
- package/strings/strings-es.js +50 -51
- package/strings/strings-fr.d.ts +1 -0
- package/strings/strings-fr.d.ts.map +1 -1
- package/strings/strings-fr.js +50 -51
- package/strings/strings-gx.d.ts +1 -0
- package/strings/strings-gx.d.ts.map +1 -1
- package/strings/strings-gx.js +50 -51
- package/style-dictionary-dist/TerrawareTheme.js +186 -186
- package/theme.js +74 -76
- package/utils/color.js +8 -15
- package/utils/date.js +42 -108
- package/utils/index.js +4 -4
- package/utils/preventDefaultEvent.js +3 -3
- package/utils/text.js +11 -11
- package/utils/useDeviceInfo.js +42 -79
- package/virtualWalkthrough.js +23 -23
package/index.js
CHANGED
|
@@ -1,58 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
export { default as
|
|
3
|
-
export { default as
|
|
4
|
-
export { default as
|
|
5
|
-
export { default as
|
|
6
|
-
export { default as
|
|
7
|
-
export { default as
|
|
8
|
-
export { default as
|
|
9
|
-
export { default as
|
|
10
|
-
export { default as
|
|
11
|
-
export { default as
|
|
12
|
-
export { default as
|
|
13
|
-
export { default as
|
|
14
|
-
export { default as
|
|
15
|
-
export { default as
|
|
16
|
-
export { default as
|
|
17
|
-
export { default as
|
|
18
|
-
export { default as
|
|
19
|
-
export { default as
|
|
20
|
-
export { default as
|
|
21
|
-
export { default as
|
|
22
|
-
export { default as
|
|
23
|
-
export { default as
|
|
24
|
-
export { default as
|
|
25
|
-
export { default as
|
|
26
|
-
export { default as
|
|
27
|
-
export { default as
|
|
28
|
-
export { default as
|
|
29
|
-
export { default as
|
|
30
|
-
export { default as
|
|
31
|
-
export { default as
|
|
32
|
-
export { default as
|
|
33
|
-
export { default as
|
|
34
|
-
export { default as
|
|
35
|
-
export { default as
|
|
36
|
-
export { default as
|
|
37
|
-
export { default as
|
|
38
|
-
export { default as
|
|
39
|
-
export { default as
|
|
40
|
-
export { default as
|
|
41
|
-
export { default as
|
|
42
|
-
export { default as
|
|
43
|
-
export { default as
|
|
44
|
-
export { default as
|
|
45
|
-
export { default as
|
|
46
|
-
export { default as
|
|
47
|
-
export { default as
|
|
48
|
-
export { default as
|
|
49
|
-
export { default as
|
|
50
|
-
export { default as
|
|
51
|
-
|
|
52
|
-
export {
|
|
53
|
-
export { default as Table } from
|
|
54
|
-
export { CellDateRenderer, default as CellRenderer } from
|
|
55
|
-
export { descendingComparator, getComparator, stableSort } from
|
|
56
|
-
export { getLocale, getStrings, setLocale, useStrings } from
|
|
57
|
-
export { findLocaleDetails, getSupportedLocales, supportedLocales } from
|
|
58
|
-
export { default as theme } from
|
|
1
|
+
import * as __rspack_external__components_svg_index_js_524d890d from "./components/svg/index.js";
|
|
2
|
+
export { default as AntSwitch } from "./components/AntSwitch/index.js";
|
|
3
|
+
export { default as Autocomplete } from "./components/Autocomplete/Autocomplete.js";
|
|
4
|
+
export { default as Badge } from "./components/Badge/index.js";
|
|
5
|
+
export { default as BusySpinner } from "./components/BusySpinner/index.js";
|
|
6
|
+
export { default as Button } from "./components/Button/Button.js";
|
|
7
|
+
export { default as Checkbox } from "./components/Checkbox.js";
|
|
8
|
+
export { default as Confirm } from "./components/Confirm/index.js";
|
|
9
|
+
export { default as DatePicker } from "./components/DatePicker/DatePicker.js";
|
|
10
|
+
export { default as DialogBox } from "./components/DialogBox/DialogBox.js";
|
|
11
|
+
export { default as Divisor } from "./components/Divisor.js";
|
|
12
|
+
export { DropdownV1, default as Dropdown } from "./components/Dropdown.js";
|
|
13
|
+
export { default as EditableTable } from "./components/EditableTable/index.js";
|
|
14
|
+
export { default as ErrorBox } from "./components/ErrorBox/ErrorBox.js";
|
|
15
|
+
export { default as FileChooser } from "./components/FileChooser/index.js";
|
|
16
|
+
export { default as FormBottomBar } from "./components/FormBottomBar/index.js";
|
|
17
|
+
export { default as Icon } from "./components/Icon/Icon.js";
|
|
18
|
+
export { default as icons } from "./components/Icon/icons/index.js";
|
|
19
|
+
export { default as IconTooltip } from "./components/IconTooltip/index.js";
|
|
20
|
+
export { default as MapComponent } from "./components/Map/index.js";
|
|
21
|
+
export { default as Message } from "./components/Message/Message.js";
|
|
22
|
+
export { default as MultiSelect } from "./components/MultiSelect/index.js";
|
|
23
|
+
export { default as NavFooter } from "./components/Navbar/NavFooter.js";
|
|
24
|
+
export { default as NavItem } from "./components/Navbar/NavItem.js";
|
|
25
|
+
export { default as NavSection } from "./components/Navbar/NavSection.js";
|
|
26
|
+
export { default as Navbar } from "./components/Navbar/Navbar.js";
|
|
27
|
+
export { default as Note } from "./components/Note.js";
|
|
28
|
+
export { default as OverlayModal } from "./components/OverlayModal/OverlayModal.js";
|
|
29
|
+
export { default as PageForm } from "./components/PageForm/index.js";
|
|
30
|
+
export { default as PhotoChooser } from "./components/PhotoChooser/index.js";
|
|
31
|
+
export { default as PhotosCarousel } from "./components/PhotosCarousel/index.js";
|
|
32
|
+
export { default as Pill } from "./components/Pill/index.js";
|
|
33
|
+
export { default as PillList } from "./components/PillList/index.js";
|
|
34
|
+
export { default as PlacementWrapper } from "./components/PlacementWrapper/index.js";
|
|
35
|
+
export { default as PopoverMenu } from "./components/PopoverMenu/index.js";
|
|
36
|
+
export { default as Popover } from "./components/PopoverMenu/Popover.js";
|
|
37
|
+
export { default as PopoverMultiSelect } from "./components/PopoverMultiSelect/index.js";
|
|
38
|
+
export { default as ProgressCircle } from "./components/ProgressCircle/ProgressCircle.js";
|
|
39
|
+
export { default as RadioButton } from "./components/RadioButton.js";
|
|
40
|
+
export { default as Select } from "./components/Select/Select.js";
|
|
41
|
+
export { default as SelectT } from "./components/Select/SelectT.js";
|
|
42
|
+
export { default as Separator } from "./components/Separator/index.js";
|
|
43
|
+
export { default as Slider } from "./components/Slider/index.js";
|
|
44
|
+
export { default as Stepper } from "./components/Stepper/index.js";
|
|
45
|
+
export { default as SummaryBox } from "./components/SummaryBox.js";
|
|
46
|
+
export { default as Tabs } from "./components/Tabs/index.js";
|
|
47
|
+
export { default as TextTruncated } from "./components/TextTruncated/index.js";
|
|
48
|
+
export { default as Textfield } from "./components/Textfield/Textfield.js";
|
|
49
|
+
export { default as TimelineSlider } from "./components/TimelineSlider/index.js";
|
|
50
|
+
export { default as TimelineSliderV2 } from "./components/TimelineSliderV2/index.js";
|
|
51
|
+
export { default as Tooltip } from "./components/Tooltip/Tooltip.js";
|
|
52
|
+
export { default as ViewPhotosDialog } from "./components/ViewPhotosDialog/index.js";
|
|
53
|
+
export { default as Table } from "./components/table/index.js";
|
|
54
|
+
export { CellDateRenderer, default as CellRenderer } from "./components/table/TableCellRenderer.js";
|
|
55
|
+
export { descendingComparator, getComparator, stableSort } from "./components/table/sort.js";
|
|
56
|
+
export { getLocale, getStrings, setLocale, useStrings } from "./strings/index.js";
|
|
57
|
+
export { findLocaleDetails, getSupportedLocales, supportedLocales } from "./strings/locales.js";
|
|
58
|
+
export { default as theme } from "./theme.js";
|
|
59
|
+
export { __rspack_external__components_svg_index_js_524d890d as Svg };
|
package/package.json
CHANGED
package/setupTests.js
CHANGED
package/strings/csv/en.csv
CHANGED
package/strings/csv/es.csv
CHANGED
package/strings/csv/fr.csv
CHANGED
package/strings/export.js
CHANGED
|
@@ -1,186 +1,127 @@
|
|
|
1
|
-
import { parse } from
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Renders the CSV string tables as TypeScript source, and finds keys in them that no source file
|
|
8
|
-
* references.
|
|
9
|
-
*
|
|
10
|
-
* This runs at build time, not at runtime. Nothing in the component runtime imports it, so its Node
|
|
11
|
-
* and CSV dependencies never reach a browser bundle. It's published rather than kept in scripts/ so
|
|
12
|
-
* that applications sharing these string tables can drive the same conversion and checks.
|
|
13
|
-
*/
|
|
1
|
+
import { parse } from "csv-parse/sync";
|
|
2
|
+
import { readFile, readdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import node_path from "node:path";
|
|
4
|
+
import { format, resolveConfig } from "prettier";
|
|
14
5
|
const GENERATED_HEADER = '/* Generated from the CSV files in csv/ by `yarn generate-strings`. Do not edit. */';
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// Skip empty "row" that is really just the terminating linefeed
|
|
26
|
-
skip_empty_lines: true
|
|
27
|
-
});
|
|
28
|
-
return rows.reduce((result, row) => {
|
|
29
|
-
result[row[0]] = row[1];
|
|
30
|
-
return result;
|
|
31
|
-
}, {});
|
|
6
|
+
const csvToStrings = (csvData)=>{
|
|
7
|
+
const rows = parse(csvData, {
|
|
8
|
+
from: 2,
|
|
9
|
+
relax_column_count_less: true,
|
|
10
|
+
skip_empty_lines: true
|
|
11
|
+
});
|
|
12
|
+
return rows.reduce((result, row)=>{
|
|
13
|
+
result[row[0]] = row[1];
|
|
14
|
+
return result;
|
|
15
|
+
}, {});
|
|
32
16
|
};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const source = `${GENERATED_HEADER}\nexport const strings = ${JSON.stringify(stringsMap, null, 2)};\n`;
|
|
41
|
-
const prettierConfig = await resolveConfig(targetPath);
|
|
42
|
-
return format(source, {
|
|
43
|
-
...prettierConfig,
|
|
44
|
-
filepath: targetPath
|
|
45
|
-
});
|
|
17
|
+
const stringsToTypeScript = async (stringsMap, targetPath)=>{
|
|
18
|
+
const source = `${GENERATED_HEADER}\nexport const strings = ${JSON.stringify(stringsMap, null, 2)};\n`;
|
|
19
|
+
const prettierConfig = await resolveConfig(targetPath);
|
|
20
|
+
return format(source, {
|
|
21
|
+
...prettierConfig,
|
|
22
|
+
filepath: targetPath
|
|
23
|
+
});
|
|
46
24
|
};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const generateGibberish = english => Object.fromEntries(Object.entries(english).map(([key, value]) => [key, value.split(' ').reverse().map(word => word.startsWith('{') ? word : Buffer.from(word, 'utf-8').toString('base64').replace(/=/g, '')).join(' ')]));
|
|
58
|
-
const exportStrings = async (englishStrings, localizedStrings, locale, targetDir, defaultToEnglish) => {
|
|
59
|
-
const stringsMap = {};
|
|
60
|
-
for (const key of Object.keys(englishStrings)) {
|
|
61
|
-
if (key in localizedStrings) {
|
|
62
|
-
stringsMap[key] = localizedStrings[key];
|
|
63
|
-
} else {
|
|
64
|
-
console.warn(`Locale ${locale} has no translation for ${key}`);
|
|
65
|
-
if (defaultToEnglish) {
|
|
66
|
-
stringsMap[key] = englishStrings[key];
|
|
67
|
-
}
|
|
25
|
+
const generateGibberish = (english)=>Object.fromEntries(Object.entries(english).map(([key, value])=>[
|
|
26
|
+
key,
|
|
27
|
+
value.split(' ').reverse().map((word)=>word.startsWith('{') ? word : Buffer.from(word, 'utf-8').toString('base64').replace(/=/g, '')).join(' ')
|
|
28
|
+
]));
|
|
29
|
+
const exportStrings = async (englishStrings, localizedStrings, locale, targetDir, defaultToEnglish)=>{
|
|
30
|
+
const stringsMap = {};
|
|
31
|
+
for (const key of Object.keys(englishStrings))if (key in localizedStrings) stringsMap[key] = localizedStrings[key];
|
|
32
|
+
else {
|
|
33
|
+
console.warn(`Locale ${locale} has no translation for ${key}`);
|
|
34
|
+
if (defaultToEnglish) stringsMap[key] = englishStrings[key];
|
|
68
35
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
36
|
+
const targetPath = node_path.resolve(targetDir, `strings-${locale}.ts`);
|
|
37
|
+
await writeFile(targetPath, await stringsToTypeScript(stringsMap, targetPath), {
|
|
38
|
+
encoding: 'utf-8'
|
|
39
|
+
});
|
|
74
40
|
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
*
|
|
81
|
-
* The filename is assumed to be the locale code with a ".csv" suffix. Converting the English file
|
|
82
|
-
* also writes the gibberish table, which is derived from English rather than translated.
|
|
83
|
-
*/
|
|
84
|
-
const convertCsvFile = async (csvPath, targetDir, defaultToEnglish = true) => {
|
|
85
|
-
if (!csvPath.endsWith('.csv')) {
|
|
86
|
-
throw new Error('Cannot convert a non-CSV file');
|
|
87
|
-
}
|
|
88
|
-
const locale = path.basename(csvPath, '.csv');
|
|
89
|
-
const stringsMap = csvToStrings(await readFile(csvPath, {
|
|
90
|
-
encoding: 'utf-8'
|
|
91
|
-
}));
|
|
92
|
-
let englishStringsMap;
|
|
93
|
-
if (locale === 'en') {
|
|
94
|
-
englishStringsMap = stringsMap;
|
|
95
|
-
} else {
|
|
96
|
-
const englishPath = path.resolve(path.dirname(csvPath), 'en.csv');
|
|
97
|
-
englishStringsMap = csvToStrings(await readFile(englishPath, {
|
|
98
|
-
encoding: 'utf-8'
|
|
41
|
+
const convertCsvFile = async (csvPath, targetDir, defaultToEnglish = true)=>{
|
|
42
|
+
if (!csvPath.endsWith('.csv')) throw new Error('Cannot convert a non-CSV file');
|
|
43
|
+
const locale = node_path.basename(csvPath, '.csv');
|
|
44
|
+
const stringsMap = csvToStrings(await readFile(csvPath, {
|
|
45
|
+
encoding: 'utf-8'
|
|
99
46
|
}));
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
47
|
+
let englishStringsMap;
|
|
48
|
+
if ('en' === locale) englishStringsMap = stringsMap;
|
|
49
|
+
else {
|
|
50
|
+
const englishPath = node_path.resolve(node_path.dirname(csvPath), 'en.csv');
|
|
51
|
+
englishStringsMap = csvToStrings(await readFile(englishPath, {
|
|
52
|
+
encoding: 'utf-8'
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
await exportStrings(englishStringsMap, stringsMap, locale, targetDir, defaultToEnglish);
|
|
56
|
+
if ('en' === locale) await exportStrings(englishStringsMap, generateGibberish(englishStringsMap), 'gx', targetDir, defaultToEnglish);
|
|
105
57
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
*/
|
|
111
|
-
const convertAllLocales = async (csvDir, stringsDir, defaultToEnglish = true) => {
|
|
112
|
-
const csvFiles = (await readdir(csvDir)).filter(filename => filename.endsWith('.csv'));
|
|
113
|
-
await Promise.all(csvFiles.map(filename => convertCsvFile(path.join(csvDir, filename), stringsDir, defaultToEnglish)));
|
|
114
|
-
return csvFiles;
|
|
58
|
+
const convertAllLocales = async (csvDir, stringsDir, defaultToEnglish = true)=>{
|
|
59
|
+
const csvFiles = (await readdir(csvDir)).filter((filename)=>filename.endsWith('.csv'));
|
|
60
|
+
await Promise.all(csvFiles.map((filename)=>convertCsvFile(node_path.join(csvDir, filename), stringsDir, defaultToEnglish)));
|
|
61
|
+
return csvFiles;
|
|
115
62
|
};
|
|
116
|
-
const DEFAULT_EXTENSIONS = [
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
63
|
+
const DEFAULT_EXTENSIONS = [
|
|
64
|
+
'.ts',
|
|
65
|
+
'.js',
|
|
66
|
+
'.tsx',
|
|
67
|
+
'.jsx'
|
|
68
|
+
];
|
|
69
|
+
const DEFAULT_EXCLUDED_DIRECTORIES = [
|
|
70
|
+
'strings'
|
|
71
|
+
];
|
|
72
|
+
const findSourceFiles = async (directory, extensions = DEFAULT_EXTENSIONS, excludedDirectories = DEFAULT_EXCLUDED_DIRECTORIES)=>{
|
|
73
|
+
const entries = await readdir(directory, {
|
|
74
|
+
withFileTypes: true
|
|
75
|
+
});
|
|
76
|
+
const nested = await Promise.all(entries.map(async (entry)=>{
|
|
77
|
+
const entryPath = node_path.join(directory, entry.name);
|
|
78
|
+
if (entry.isDirectory()) return excludedDirectories.includes(entry.name) ? [] : findSourceFiles(entryPath, extensions, excludedDirectories);
|
|
79
|
+
return extensions.includes(node_path.extname(entry.name)) ? [
|
|
80
|
+
entryPath
|
|
81
|
+
] : [];
|
|
82
|
+
}));
|
|
83
|
+
return nested.flat().sort();
|
|
130
84
|
};
|
|
131
85
|
const STRINGS_PROPERTY_ACCESS = /\bstrings\s*\??\.\s*(\w+)/g;
|
|
132
86
|
const STRINGS_INDEX_ACCESS = /\bstrings\s*(?:\?\.)?\s*\[([^\]]*)\]/g;
|
|
133
87
|
const QUOTED_KEY = /(['"`])(\w+)\1/g;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
unused.push(key);
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
return {
|
|
156
|
-
unused,
|
|
157
|
-
possiblyUnused
|
|
158
|
-
};
|
|
88
|
+
const findAccessedKeys = (source)=>[
|
|
89
|
+
...Array.from(source.matchAll(STRINGS_PROPERTY_ACCESS), (match)=>match[1]),
|
|
90
|
+
...Array.from(source.matchAll(STRINGS_INDEX_ACCESS)).flatMap((match)=>Array.from(match[1].matchAll(QUOTED_KEY), (literal)=>literal[2]))
|
|
91
|
+
];
|
|
92
|
+
const classifyKeys = (keys, sources)=>{
|
|
93
|
+
const accessedKeys = new Set(sources.flatMap(findAccessedKeys));
|
|
94
|
+
const identifiers = new Set(sources.flatMap((source)=>source.match(/\w+/g) ?? []));
|
|
95
|
+
const unused = [];
|
|
96
|
+
const possiblyUnused = [];
|
|
97
|
+
keys.forEach((key)=>{
|
|
98
|
+
if (accessedKeys.has(key)) return;
|
|
99
|
+
if (identifiers.has(key)) possiblyUnused.push(key);
|
|
100
|
+
else unused.push(key);
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
unused,
|
|
104
|
+
possiblyUnused
|
|
105
|
+
};
|
|
159
106
|
};
|
|
160
|
-
const findUnusedStrings = async ({
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const files = await findSourceFiles(sourceDir, extensions, excludedDirectories);
|
|
170
|
-
const sources = await Promise.all(files.map(file => readFile(file, {
|
|
171
|
-
encoding: 'utf-8'
|
|
172
|
-
})));
|
|
173
|
-
return classifyKeys(keys, sources);
|
|
107
|
+
const findUnusedStrings = async ({ csvPath, sourceDir, extensions, excludedDirectories })=>{
|
|
108
|
+
const keys = Object.keys(csvToStrings(await readFile(csvPath, {
|
|
109
|
+
encoding: 'utf-8'
|
|
110
|
+
})));
|
|
111
|
+
const files = await findSourceFiles(sourceDir, extensions, excludedDirectories);
|
|
112
|
+
const sources = await Promise.all(files.map((file)=>readFile(file, {
|
|
113
|
+
encoding: 'utf-8'
|
|
114
|
+
})));
|
|
115
|
+
return classifyKeys(keys, sources);
|
|
174
116
|
};
|
|
175
|
-
const formatUnusedStrings = ({
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
117
|
+
const formatUnusedStrings = ({ unused, possiblyUnused })=>{
|
|
118
|
+
const lines = 0 === unused.length ? [
|
|
119
|
+
'No unused entries found.'
|
|
120
|
+
] : [
|
|
121
|
+
'Unused entries found:',
|
|
122
|
+
...unused
|
|
123
|
+
];
|
|
124
|
+
if (possiblyUnused.length > 0) lines.push('', 'Possibly unused entries (never read from strings, but the name appears elsewhere; check manually):', ...possiblyUnused);
|
|
125
|
+
return `${lines.join('\n')}\n`;
|
|
184
126
|
};
|
|
185
|
-
|
|
186
127
|
export { classifyKeys, convertAllLocales, convertCsvFile, csvToStrings, findAccessedKeys, findSourceFiles, findUnusedStrings, formatUnusedStrings, generateGibberish, stringsToTypeScript };
|
package/strings/index.js
CHANGED
|
@@ -1,62 +1,33 @@
|
|
|
1
|
-
import { useSyncExternalStore } from
|
|
2
|
-
import { findLocaleDetails, supportedLocales } from
|
|
3
|
-
import { strings } from
|
|
4
|
-
import { strings as
|
|
5
|
-
import { strings as
|
|
6
|
-
import { strings as
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The set of strings every locale provides. The English table is the source of truth for the list
|
|
10
|
-
* of keys.
|
|
11
|
-
*/
|
|
12
|
-
|
|
1
|
+
import { useSyncExternalStore } from "react";
|
|
2
|
+
import { findLocaleDetails, supportedLocales } from "./locales.js";
|
|
3
|
+
import { strings } from "./strings-en.js";
|
|
4
|
+
import { strings as external_strings_es_js_strings } from "./strings-es.js";
|
|
5
|
+
import { strings as external_strings_fr_js_strings } from "./strings-fr.js";
|
|
6
|
+
import { strings as external_strings_gx_js_strings } from "./strings-gx.js";
|
|
13
7
|
const tables = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
en: strings,
|
|
9
|
+
es: external_strings_es_js_strings,
|
|
10
|
+
fr: external_strings_fr_js_strings,
|
|
11
|
+
gx: external_strings_gx_js_strings
|
|
18
12
|
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Locales we have a bundled string table for. A locale can be supported -- listed in a locale
|
|
22
|
-
* selector -- before its table lands, and resolving against the tables we actually have keeps
|
|
23
|
-
* `getLocale` and `getStrings` describing the same language.
|
|
24
|
-
*/
|
|
25
|
-
const localesWithTables = () => supportedLocales.filter(locale => locale.id in tables);
|
|
13
|
+
const localesWithTables = ()=>supportedLocales.filter((locale)=>locale.id in tables);
|
|
26
14
|
let currentLocale = 'en';
|
|
27
15
|
let currentStrings = strings;
|
|
28
16
|
const listeners = new Set();
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*/
|
|
36
|
-
const setLocale = locale => {
|
|
37
|
-
const resolved = findLocaleDetails(localesWithTables(), locale).id;
|
|
38
|
-
if (resolved === currentLocale) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
currentLocale = resolved;
|
|
42
|
-
currentStrings = tables[resolved] ?? strings;
|
|
43
|
-
listeners.forEach(notify => notify());
|
|
17
|
+
const setLocale = (locale)=>{
|
|
18
|
+
const resolved = findLocaleDetails(localesWithTables(), locale).id;
|
|
19
|
+
if (resolved === currentLocale) return;
|
|
20
|
+
currentLocale = resolved;
|
|
21
|
+
currentStrings = tables[resolved] ?? strings;
|
|
22
|
+
listeners.forEach((notify)=>notify());
|
|
44
23
|
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
*/
|
|
53
|
-
const getStrings = () => currentStrings;
|
|
54
|
-
const subscribe = notify => {
|
|
55
|
-
listeners.add(notify);
|
|
56
|
-
return () => {
|
|
57
|
-
listeners.delete(notify);
|
|
58
|
-
};
|
|
24
|
+
const getLocale = ()=>currentLocale;
|
|
25
|
+
const getStrings = ()=>currentStrings;
|
|
26
|
+
const subscribe = (notify)=>{
|
|
27
|
+
listeners.add(notify);
|
|
28
|
+
return ()=>{
|
|
29
|
+
listeners.delete(notify);
|
|
30
|
+
};
|
|
59
31
|
};
|
|
60
|
-
const useStrings = ()
|
|
61
|
-
|
|
32
|
+
const useStrings = ()=>useSyncExternalStore(subscribe, getStrings, getStrings);
|
|
62
33
|
export { getLocale, getStrings, setLocale, useStrings };
|
package/strings/locales.js
CHANGED
|
@@ -1,42 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
},
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Returns the locale from a list of locales that matches the user's selected language.
|
|
25
|
-
*
|
|
26
|
-
* The user's locale can include both a language and a country code, but entries in a list of
|
|
27
|
-
* languages usually don't have country codes. So we need to find the entry that is the longest
|
|
28
|
-
* prefix of the user's locale.
|
|
29
|
-
*
|
|
30
|
-
* If the locale is es-MX and the list of locales only has es, we want the es item to be selected.
|
|
31
|
-
* But if the locale is zh-CN and the list has both zh-CN and zh-TW, we want zh-CN to be selected.
|
|
32
|
-
*
|
|
33
|
-
* If none of the locales in the list matches, returns the first locale from the list. The list
|
|
34
|
-
* must not be empty.
|
|
35
|
-
*/
|
|
36
|
-
const findLocaleDetails = (locales, locale) => locales.reduce((bestMatch, candidate) =>
|
|
37
|
-
// The best match so far is only worth keeping if it's a prefix of the requested locale too.
|
|
38
|
-
// reduce() seeds with the first locale without checking it, so a leading 'en-US' would
|
|
39
|
-
// otherwise be treated as a match for 'en' and never replaced.
|
|
40
|
-
locale.startsWith(candidate.id) && (!locale.startsWith(bestMatch.id) || candidate.id.length > bestMatch.id.length) ? candidate : bestMatch);
|
|
41
|
-
|
|
1
|
+
const supportedLocales = [
|
|
2
|
+
{
|
|
3
|
+
id: 'en',
|
|
4
|
+
name: 'English'
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
id: 'es',
|
|
8
|
+
name: 'Español'
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: 'fr',
|
|
12
|
+
name: 'Français'
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'gx',
|
|
16
|
+
name: 'Gibberish',
|
|
17
|
+
inDevelopment: true
|
|
18
|
+
}
|
|
19
|
+
];
|
|
20
|
+
const getSupportedLocales = (includeInDevelopment = false)=>includeInDevelopment ? supportedLocales : supportedLocales.filter((locale)=>!locale.inDevelopment);
|
|
21
|
+
const findLocaleDetails = (locales, locale)=>locales.reduce((bestMatch, candidate)=>locale.startsWith(candidate.id) && (!locale.startsWith(bestMatch.id) || candidate.id.length > bestMatch.id.length) ? candidate : bestMatch);
|
|
42
22
|
export { findLocaleDetails, getSupportedLocales, supportedLocales };
|