@strapi/upload 5.51.1 → 5.52.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/dist/admin/components/AssetCard/VideoPreview.js +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.mjs +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
- package/dist/admin/components/TableList/TableList.js +1 -1
- package/dist/admin/components/TableList/TableList.js.map +1 -1
- package/dist/admin/components/TableList/TableList.mjs +1 -1
- package/dist/admin/components/TableList/TableList.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +21 -4
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +21 -4
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
- package/dist/admin/future/App.js +3 -3
- package/dist/admin/future/App.js.map +1 -1
- package/dist/admin/future/App.mjs +4 -4
- package/dist/admin/future/App.mjs.map +1 -1
- package/dist/admin/future/components/BetaNotice.js +72 -0
- package/dist/admin/future/components/BetaNotice.js.map +1 -0
- package/dist/admin/future/components/BetaNotice.mjs +70 -0
- package/dist/admin/future/components/BetaNotice.mjs.map +1 -0
- package/dist/admin/future/components/Drawer.js +18 -3
- package/dist/admin/future/components/Drawer.js.map +1 -1
- package/dist/admin/future/components/Drawer.mjs +18 -3
- package/dist/admin/future/components/Drawer.mjs.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.js +200 -27
- package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.mjs +203 -30
- package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
- package/dist/admin/future/hooks/useAIMetadataEnabled.js +39 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.js.map +1 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.mjs +37 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.mjs.map +1 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.js +35 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.js.map +1 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs +33 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/AssetsPage.js +453 -170
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +454 -171
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js +46 -0
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs +44 -0
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +325 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +323 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +110 -46
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +110 -46
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +95 -67
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +95 -68
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +94 -26
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +96 -28
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +112 -0
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +110 -0
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +172 -56
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +175 -59
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +188 -138
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +191 -141
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +123 -76
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +126 -79
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BusyOverlay.js +36 -0
- package/dist/admin/future/pages/Assets/components/BusyOverlay.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs +34 -0
- package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js +193 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs +191 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js +131 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs +129 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +45 -18
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +46 -19
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +28 -31
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +28 -31
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +10 -15
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +10 -15
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js +13 -3
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +13 -3
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/EmptyState.js +62 -3
- package/dist/admin/future/pages/Assets/components/EmptyState.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/EmptyState.mjs +62 -4
- package/dist/admin/future/pages/Assets/components/EmptyState.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterBadges.js +417 -0
- package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +415 -0
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.js +453 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +447 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +144 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +142 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +50 -16
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +52 -18
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +125 -148
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +127 -150
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/SortMenu.js +21 -32
- package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs +22 -33
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js +40 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs +38 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +21 -5
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +21 -5
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js +47 -0
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs +44 -0
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +33 -12
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +33 -12
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +222 -45
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +223 -46
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js +75 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs +73 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.js +168 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs +162 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js +201 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs +198 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/listQueryKey.js +2 -2
- package/dist/admin/future/pages/Assets/utils/listQueryKey.js.map +1 -1
- package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs +2 -2
- package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs.map +1 -1
- package/dist/admin/future/services/api.js +187 -28
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +187 -30
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/assets.js +40 -17
- package/dist/admin/future/services/assets.js.map +1 -1
- package/dist/admin/future/services/assets.mjs +40 -17
- package/dist/admin/future/services/assets.mjs.map +1 -1
- package/dist/admin/future/services/folders.js +66 -19
- package/dist/admin/future/services/folders.js.map +1 -1
- package/dist/admin/future/services/folders.mjs +66 -20
- package/dist/admin/future/services/folders.mjs.map +1 -1
- package/dist/admin/future/services/settings.js +10 -3
- package/dist/admin/future/services/settings.js.map +1 -1
- package/dist/admin/future/services/settings.mjs +10 -3
- package/dist/admin/future/services/settings.mjs.map +1 -1
- package/dist/admin/future/store/uploadProgress.js +109 -2
- package/dist/admin/future/store/uploadProgress.js.map +1 -1
- package/dist/admin/future/store/uploadProgress.mjs +105 -3
- package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
- package/dist/admin/future/utils/buildDragSetFromSelection.js +7 -5
- package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -1
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs +7 -5
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.js +12 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +12 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -1
- package/dist/admin/future/utils/getRelationId.js +24 -0
- package/dist/admin/future/utils/getRelationId.js.map +1 -0
- package/dist/admin/future/utils/getRelationId.mjs +22 -0
- package/dist/admin/future/utils/getRelationId.mjs.map +1 -0
- package/dist/admin/future/utils/isEventFromWithin.js +14 -0
- package/dist/admin/future/utils/isEventFromWithin.js.map +1 -0
- package/dist/admin/future/utils/isEventFromWithin.mjs +12 -0
- package/dist/admin/future/utils/isEventFromWithin.mjs.map +1 -0
- package/dist/admin/future/utils/itemLocations.js +40 -0
- package/dist/admin/future/utils/itemLocations.js.map +1 -0
- package/dist/admin/future/utils/itemLocations.mjs +36 -0
- package/dist/admin/future/utils/itemLocations.mjs.map +1 -0
- package/dist/admin/future/utils/itemSource.js +36 -0
- package/dist/admin/future/utils/itemSource.js.map +1 -0
- package/dist/admin/future/utils/itemSource.mjs +32 -0
- package/dist/admin/future/utils/itemSource.mjs.map +1 -0
- package/dist/admin/future/utils/searchQueryParam.js +11 -0
- package/dist/admin/future/utils/searchQueryParam.js.map +1 -0
- package/dist/admin/future/utils/searchQueryParam.mjs +9 -0
- package/dist/admin/future/utils/searchQueryParam.mjs.map +1 -0
- package/dist/admin/hooks/useSelectionState.js +2 -4
- package/dist/admin/hooks/useSelectionState.js.map +1 -1
- package/dist/admin/hooks/useSelectionState.mjs +2 -4
- package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
- package/dist/admin/index.js +11 -17
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +12 -18
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/shared/constants.js +43 -0
- package/dist/admin/shared/constants.js.map +1 -0
- package/dist/admin/shared/constants.mjs +38 -0
- package/dist/admin/shared/constants.mjs.map +1 -0
- package/dist/admin/src/future/App.d.ts +1 -1
- package/dist/admin/src/future/components/BetaNotice.d.ts +11 -0
- package/dist/admin/src/future/components/Drawer.d.ts +5 -1
- package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
- package/dist/admin/src/future/hooks/useMediaLibraryPermissions.d.ts +21 -0
- package/dist/admin/src/future/pages/Assets/components/ActionsMenuContent.d.ts +33 -0
- package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +24 -0
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.d.ts +7 -1
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +16 -0
- package/dist/admin/src/future/pages/Assets/components/AssetsSearchInput.d.ts +5 -0
- package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +21 -1
- package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +17 -6
- package/dist/admin/src/future/pages/Assets/components/BusyOverlay.d.ts +9 -0
- package/dist/admin/src/future/pages/Assets/components/DateRangeCalendar.d.ts +8 -0
- package/dist/admin/src/future/pages/Assets/components/DeleteItemsDialog.d.ts +27 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +18 -3
- package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +2 -1
- package/dist/admin/src/future/pages/Assets/components/DropZone/UploadDropZoneContext.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/components/EmptyState.d.ts +18 -1
- package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +8 -0
- package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +26 -0
- package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +20 -0
- package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
- package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +13 -4
- package/dist/admin/src/future/pages/Assets/components/SortMenu.d.ts +6 -0
- package/dist/admin/src/future/pages/Assets/hooks/useAssetSearch.d.ts +12 -0
- package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/hooks/useBusyAssets.d.ts +38 -0
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +27 -3
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteScrollSentinel.d.ts +41 -0
- package/dist/admin/src/future/pages/Assets/hooks/useListFilters.d.ts +69 -0
- package/dist/admin/src/future/pages/Assets/utils/buildAssetFilters.d.ts +46 -0
- package/dist/admin/src/future/pages/Assets/utils/listQueryKey.d.ts +3 -4
- package/dist/admin/src/future/services/api.d.ts +53 -5
- package/dist/admin/src/future/services/assets.d.ts +9 -1
- package/dist/admin/src/future/services/folders.d.ts +9 -1
- package/dist/admin/src/future/services/settings.d.ts +2 -2
- package/dist/admin/src/future/store/uploadProgress.d.ts +83 -1
- package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +4 -3
- package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +7 -1
- package/dist/admin/src/future/utils/getRelationId.d.ts +11 -0
- package/dist/admin/src/future/utils/isEventFromWithin.d.ts +11 -0
- package/dist/admin/src/future/utils/itemLocations.d.ts +31 -0
- package/dist/admin/src/future/utils/itemSource.d.ts +22 -0
- package/dist/admin/src/future/utils/searchQueryParam.d.ts +7 -0
- package/dist/admin/src/hooks/useAiAvailability.d.ts +1 -1
- package/dist/admin/src/hooks/useEditAsset.d.ts +4 -4
- package/dist/admin/src/hooks/useEditFolder.d.ts +4 -4
- package/dist/admin/src/hooks/useSettings.d.ts +1 -0
- package/dist/admin/src/hooks/useTracking.d.ts +1 -1
- package/dist/admin/src/hooks/useUpload.d.ts +1 -1
- package/dist/admin/translations/en.json.js +73 -2
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +73 -2
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/urlYupSchema.js +33 -9
- package/dist/admin/utils/urlYupSchema.js.map +1 -1
- package/dist/admin/utils/urlYupSchema.mjs +33 -9
- package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
- package/dist/server/config.js +13 -5
- package/dist/server/config.js.map +1 -1
- package/dist/server/config.mjs +13 -5
- package/dist/server/config.mjs.map +1 -1
- package/dist/server/constants.js.map +1 -1
- package/dist/server/constants.mjs.map +1 -1
- package/dist/server/controllers/admin-file.js +30 -0
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +30 -0
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-settings.js +20 -2
- package/dist/server/controllers/admin-settings.js.map +1 -1
- package/dist/server/controllers/admin-settings.mjs +21 -3
- package/dist/server/controllers/admin-settings.mjs.map +1 -1
- package/dist/server/controllers/content-api.js +1 -2
- package/dist/server/controllers/content-api.js.map +1 -1
- package/dist/server/controllers/content-api.mjs +2 -2
- package/dist/server/controllers/content-api.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/ai-metadata.js +12 -0
- package/dist/server/controllers/validation/admin/ai-metadata.js.map +1 -0
- package/dist/server/controllers/validation/admin/ai-metadata.mjs +10 -0
- package/dist/server/controllers/validation/admin/ai-metadata.mjs.map +1 -0
- package/dist/server/controllers/validation/admin/settings.js +4 -1
- package/dist/server/controllers/validation/admin/settings.js.map +1 -1
- package/dist/server/controllers/validation/admin/settings.mjs +1 -1
- package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
- package/dist/server/routes/admin.js +18 -0
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +18 -0
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/ai-metadata.js +108 -11
- package/dist/server/services/ai-metadata.js.map +1 -1
- package/dist/server/services/ai-metadata.mjs +108 -11
- package/dist/server/services/ai-metadata.mjs.map +1 -1
- package/dist/server/services/file.js +86 -13
- package/dist/server/services/file.js.map +1 -1
- package/dist/server/services/file.mjs +87 -14
- package/dist/server/services/file.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js +4 -4
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +4 -4
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/shared/constants.js +43 -0
- package/dist/server/shared/constants.js.map +1 -0
- package/dist/server/shared/constants.mjs +38 -0
- package/dist/server/shared/constants.mjs.map +1 -0
- package/dist/server/src/config.d.ts +2 -0
- package/dist/server/src/config.d.ts.map +1 -1
- package/dist/server/src/constants.d.ts +2 -1
- package/dist/server/src/constants.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-file.d.ts +10 -0
- package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +1 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts +2 -0
- package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
- package/dist/server/src/controllers/validation/admin/settings.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +7 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata.d.ts +19 -0
- package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
- package/dist/server/src/services/file.d.ts +12 -2
- package/dist/server/src/services/file.d.ts.map +1 -1
- package/dist/server/src/services/image-manipulation.d.ts +0 -5
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -1
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/types.d.ts +3 -0
- package/dist/server/src/types.d.ts.map +1 -1
- package/dist/shared/constants.d.ts +35 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/contracts/files.d.ts +25 -0
- package/dist/shared/contracts/files.d.ts.map +1 -1
- package/dist/shared/contracts/settings.d.ts +7 -0
- package/package.json +10 -10
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +0 -1
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +0 -1
- package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +0 -8
|
@@ -47,6 +47,8 @@ const Overlay = styledComponents.styled(designSystem.Flex)`
|
|
|
47
47
|
border-radius: ${({ theme })=>theme.borderRadius};
|
|
48
48
|
border: 1px solid ${({ theme })=>theme.colors.neutral150};
|
|
49
49
|
background: ${({ theme })=>theme.colors.neutral0};
|
|
50
|
+
/* Focused programmatically on open (tabIndex -1) — no visible ring needed. */
|
|
51
|
+
outline: none;
|
|
50
52
|
`;
|
|
51
53
|
const HeaderBar = styledComponents.styled(designSystem.Flex)`
|
|
52
54
|
width: 100%;
|
|
@@ -56,6 +58,9 @@ const HeaderBar = styledComponents.styled(designSystem.Flex)`
|
|
|
56
58
|
background: ${({ theme })=>theme.colors.neutral0};
|
|
57
59
|
`;
|
|
58
60
|
// Fills the remaining space between header/footer; checkerboard pattern.
|
|
61
|
+
// The horizontal padding keeps the image off the viewport edges — the corner
|
|
62
|
+
// handles overhang the image by half their size, and on narrow (mobile)
|
|
63
|
+
// screens an edge-to-edge image leaves nothing to grab.
|
|
59
64
|
const Body = styledComponents.styled(designSystem.Box)`
|
|
60
65
|
width: 100%;
|
|
61
66
|
position: relative;
|
|
@@ -65,6 +70,7 @@ const Body = styledComponents.styled(designSystem.Box)`
|
|
|
65
70
|
align-items: center;
|
|
66
71
|
justify-content: center;
|
|
67
72
|
overflow: hidden;
|
|
73
|
+
padding: 0 ${({ theme })=>theme.spaces[4]};
|
|
68
74
|
background: repeating-conic-gradient(
|
|
69
75
|
${({ theme })=>theme.colors.neutral100} 0% 25%,
|
|
70
76
|
${({ theme })=>theme.colors.neutral0} 0% 50%
|
|
@@ -95,6 +101,9 @@ const CropOverlay = styledComponents.styled.div`
|
|
|
95
101
|
border: 1px dashed ${({ theme })=>theme.colors.primary600};
|
|
96
102
|
box-shadow: 0 0 0 9999px rgba(33, 33, 52, 0.5);
|
|
97
103
|
cursor: move;
|
|
104
|
+
/* Without this, touch browsers claim the gesture for scrolling and fire
|
|
105
|
+
pointercancel mid-drag — the crop drag dies while the finger is down. */
|
|
106
|
+
touch-action: none;
|
|
98
107
|
`;
|
|
99
108
|
const ResizeHandle = styledComponents.styled.button`
|
|
100
109
|
position: absolute;
|
|
@@ -106,6 +115,7 @@ const ResizeHandle = styledComponents.styled.button`
|
|
|
106
115
|
border-radius: 2px;
|
|
107
116
|
background: ${({ theme })=>theme.colors.neutral0};
|
|
108
117
|
cursor: ${({ $cursor })=>$cursor};
|
|
118
|
+
touch-action: none;
|
|
109
119
|
`;
|
|
110
120
|
const FocalPointHandle = styledComponents.styled.button`
|
|
111
121
|
position: absolute;
|
|
@@ -117,6 +127,7 @@ const FocalPointHandle = styledComponents.styled.button`
|
|
|
117
127
|
background: transparent;
|
|
118
128
|
cursor: grab;
|
|
119
129
|
padding: 0;
|
|
130
|
+
touch-action: none;
|
|
120
131
|
|
|
121
132
|
&::before {
|
|
122
133
|
content: '';
|
|
@@ -145,16 +156,24 @@ const FocalPointHandle = styledComponents.styled.button`
|
|
|
145
156
|
cursor: grabbing;
|
|
146
157
|
}
|
|
147
158
|
`;
|
|
159
|
+
// Hidden on mobile — the panel (title/hint + numeric crop & focal inputs) is
|
|
160
|
+
// too large for a phone; touch users set the crop by dragging the rectangle and
|
|
161
|
+
// focal handle directly on the image. Shown from tablet up.
|
|
148
162
|
const InfoBox = styledComponents.styled(designSystem.Box)`
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
163
|
+
display: none;
|
|
164
|
+
|
|
165
|
+
${({ theme })=>theme.breakpoints.medium} {
|
|
166
|
+
display: block;
|
|
167
|
+
position: absolute;
|
|
168
|
+
right: ${({ theme })=>theme.spaces[1]};
|
|
169
|
+
bottom: ${({ theme })=>theme.spaces[1]};
|
|
170
|
+
width: 100%;
|
|
171
|
+
max-width: 32rem;
|
|
172
|
+
padding: ${({ theme })=>theme.spaces[3]};
|
|
173
|
+
border-radius: ${({ theme })=>theme.borderRadius};
|
|
174
|
+
background: ${({ theme })=>theme.colorScheme === 'dark' ? theme.colors.neutral150 : theme.colors.neutral900};
|
|
175
|
+
z-index: 20;
|
|
176
|
+
}
|
|
158
177
|
`;
|
|
159
178
|
const FooterBar = styledComponents.styled(designSystem.Flex)`
|
|
160
179
|
width: 100%;
|
|
@@ -201,7 +220,7 @@ const BackgroundPreserveRatio = ()=>/*#__PURE__*/ jsxRuntime.jsx(BackgroundPrese
|
|
|
201
220
|
})
|
|
202
221
|
})
|
|
203
222
|
});
|
|
204
|
-
const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy })=>{
|
|
223
|
+
const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy, canSaveAsCopy })=>{
|
|
205
224
|
const { formatMessage } = reactIntl.useIntl();
|
|
206
225
|
const { toggleNotification } = strapiAdmin.useNotification();
|
|
207
226
|
// The InfoBox is a fixed dark surface in both themes, so its text can't use a
|
|
@@ -213,6 +232,14 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
|
|
|
213
232
|
const infoMutedColor = isDark ? 'neutral600' : 'neutral200';
|
|
214
233
|
const imgRef = React__namespace.useRef(null);
|
|
215
234
|
const cropAreaRef = React__namespace.useRef(null);
|
|
235
|
+
const overlayRef = React__namespace.useRef(null);
|
|
236
|
+
// FocusTrap's auto-focus lands on the first focusable element — the crop
|
|
237
|
+
// width NumberInput — which pops the keyboard on mobile the moment the
|
|
238
|
+
// editor opens. Focus the (tabIndex -1) overlay instead: keyboard users are
|
|
239
|
+
// one Tab away from the first control, Escape still reaches the trap.
|
|
240
|
+
React__namespace.useEffect(()=>{
|
|
241
|
+
overlayRef.current?.focus();
|
|
242
|
+
}, []);
|
|
216
243
|
const { init, crop, naturalSize, aspectRatio, setCropSize, setCropPosition, setAspectRatio, produceFile, width, height } = useCropImg.useCropImg();
|
|
217
244
|
const [aspectLocked, setAspectLocked] = React__namespace.useState(false);
|
|
218
245
|
// Focal point as a percentage of the crop area (matches the {x,y} contract).
|
|
@@ -220,12 +247,21 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
|
|
|
220
247
|
x: 50,
|
|
221
248
|
y: 50
|
|
222
249
|
});
|
|
223
|
-
//
|
|
224
|
-
//
|
|
225
|
-
//
|
|
250
|
+
// The crop editor reads pixels from a canvas (useCropImg -> toBlob), so its
|
|
251
|
+
// <img> must be CORS-clean and always sets crossOrigin="anonymous" (see the
|
|
252
|
+
// img below) — even for unsigned URLs, which AssetPreview leaves unset because
|
|
253
|
+
// it only displays. That difference is why the crop URL is kept DISTINCT from
|
|
254
|
+
// the thumbnail's: identical URL + different crossOrigin collide in the HTTP
|
|
255
|
+
// cache (#26581), and the crop's anonymous request could otherwise reuse the
|
|
256
|
+
// thumbnail's non-CORS cached response and taint the canvas. So the buster
|
|
257
|
+
// uses `updatedAt` where AssetPreview uses `v`, giving each its own entry
|
|
258
|
+
// (mirrors the legacy PreviewBox fix).
|
|
259
|
+
// Signed URLs get no param at all — a presigned S3 URL breaks if you add one,
|
|
260
|
+
// and on the signed side AssetPreview also loads anonymous, so the identical
|
|
261
|
+
// URL there shares one CORS-consistent entry, which is fine.
|
|
226
262
|
const rawImageUrl = files.prefixFileUrlWithBackendUrl(asset.url);
|
|
227
|
-
const cacheKey = asset.updatedAt ? new Date(asset.updatedAt).getTime() : undefined;
|
|
228
|
-
const imageUrl = cacheKey !== undefined ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}
|
|
263
|
+
const cacheKey = asset.updatedAt && !asset.isUrlSigned ? new Date(asset.updatedAt).getTime() : undefined;
|
|
264
|
+
const imageUrl = cacheKey !== undefined ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}updatedAt=${cacheKey}` : rawImageUrl;
|
|
229
265
|
const handleImageLoad = ()=>{
|
|
230
266
|
if (imgRef.current) {
|
|
231
267
|
init(imgRef.current);
|
|
@@ -242,40 +278,75 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
|
|
|
242
278
|
y: (event.clientY - rect.top) * ratioY
|
|
243
279
|
};
|
|
244
280
|
};
|
|
245
|
-
//
|
|
246
|
-
|
|
281
|
+
// Teardown for the drag currently in flight, so it can be run both on pointer
|
|
282
|
+
// release AND on unmount. Without the unmount path, closing the editor mid-drag
|
|
283
|
+
// (Escape, drawer close, a re-render dropping the overlay) would never fire a
|
|
284
|
+
// pointer event, leaking the window listeners and letting a stale `onMove`
|
|
285
|
+
// call `setCropPosition` on an unmounted component.
|
|
286
|
+
const activeDragCleanupRef = React__namespace.useRef(null);
|
|
287
|
+
React__namespace.useEffect(()=>{
|
|
288
|
+
return ()=>{
|
|
289
|
+
activeDragCleanupRef.current?.();
|
|
290
|
+
};
|
|
291
|
+
}, []);
|
|
292
|
+
// Track a pointer drag until the pointer is released or the browser cancels
|
|
293
|
+
// it. The pointer is captured so the drag follows the finger even once it
|
|
294
|
+
// leaves the (12px) handle it started on, and pointercancel is treated as
|
|
295
|
+
// release so an interrupted touch never leaves stale window listeners.
|
|
296
|
+
const trackPointerDrag = (event, onMove)=>{
|
|
247
297
|
event.preventDefault();
|
|
248
298
|
event.stopPropagation();
|
|
299
|
+
const { pointerId } = event;
|
|
300
|
+
try {
|
|
301
|
+
event.currentTarget.setPointerCapture(pointerId);
|
|
302
|
+
} catch {
|
|
303
|
+
// Unsupported environment (jsdom) — window listeners still track the drag.
|
|
304
|
+
}
|
|
305
|
+
const move = (e)=>{
|
|
306
|
+
if (e.pointerId !== pointerId) return;
|
|
307
|
+
onMove(e);
|
|
308
|
+
};
|
|
309
|
+
const cleanup = ()=>{
|
|
310
|
+
window.removeEventListener('pointermove', move);
|
|
311
|
+
window.removeEventListener('pointerup', end);
|
|
312
|
+
window.removeEventListener('pointercancel', end);
|
|
313
|
+
activeDragCleanupRef.current = null;
|
|
314
|
+
};
|
|
315
|
+
const end = (e)=>{
|
|
316
|
+
if (e.pointerId !== pointerId) return;
|
|
317
|
+
cleanup();
|
|
318
|
+
};
|
|
319
|
+
// Only one drag is ever live at a time; tear down any previous one first.
|
|
320
|
+
activeDragCleanupRef.current?.();
|
|
321
|
+
activeDragCleanupRef.current = cleanup;
|
|
322
|
+
window.addEventListener('pointermove', move);
|
|
323
|
+
window.addEventListener('pointerup', end);
|
|
324
|
+
window.addEventListener('pointercancel', end);
|
|
325
|
+
};
|
|
326
|
+
// Drag the entire crop rectangle.
|
|
327
|
+
const handleMovePointerDown = (event)=>{
|
|
249
328
|
const start = pointerToNatural(event);
|
|
250
329
|
if (!start) return;
|
|
251
330
|
const startCrop = {
|
|
252
331
|
...crop
|
|
253
332
|
};
|
|
254
|
-
|
|
333
|
+
trackPointerDrag(event, (e)=>{
|
|
255
334
|
const next = pointerToNatural(e);
|
|
256
335
|
if (!next) return;
|
|
257
336
|
setCropPosition({
|
|
258
337
|
x: startCrop.x + (next.x - start.x),
|
|
259
338
|
y: startCrop.y + (next.y - start.y)
|
|
260
339
|
});
|
|
261
|
-
};
|
|
262
|
-
const up = ()=>{
|
|
263
|
-
window.removeEventListener('pointermove', move);
|
|
264
|
-
window.removeEventListener('pointerup', up);
|
|
265
|
-
};
|
|
266
|
-
window.addEventListener('pointermove', move);
|
|
267
|
-
window.addEventListener('pointerup', up);
|
|
340
|
+
});
|
|
268
341
|
};
|
|
269
342
|
// Resize from a corner; the opposite corner stays anchored.
|
|
270
343
|
const handleResizePointerDown = (corner)=>(event)=>{
|
|
271
|
-
event.preventDefault();
|
|
272
|
-
event.stopPropagation();
|
|
273
344
|
const startCrop = {
|
|
274
345
|
...crop
|
|
275
346
|
};
|
|
276
347
|
const anchorX = corner === 'tl' || corner === 'bl' ? startCrop.x + startCrop.width : startCrop.x;
|
|
277
348
|
const anchorY = corner === 'tl' || corner === 'tr' ? startCrop.y + startCrop.height : startCrop.y;
|
|
278
|
-
|
|
349
|
+
trackPointerDrag(event, (e)=>{
|
|
279
350
|
const point = pointerToNatural(e);
|
|
280
351
|
if (!point) return;
|
|
281
352
|
const { x, y, width: w, height: h } = useCropImg.resolveCornerResize({
|
|
@@ -292,13 +363,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
|
|
|
292
363
|
width: w,
|
|
293
364
|
height: h
|
|
294
365
|
});
|
|
295
|
-
};
|
|
296
|
-
const up = ()=>{
|
|
297
|
-
window.removeEventListener('pointermove', move);
|
|
298
|
-
window.removeEventListener('pointerup', up);
|
|
299
|
-
};
|
|
300
|
-
window.addEventListener('pointermove', move);
|
|
301
|
-
window.addEventListener('pointerup', up);
|
|
366
|
+
});
|
|
302
367
|
};
|
|
303
368
|
const toggleAspectLock = ()=>{
|
|
304
369
|
setAspectLocked((locked)=>{
|
|
@@ -309,9 +374,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
|
|
|
309
374
|
};
|
|
310
375
|
// Drag the focal handle within the crop rectangle, clamped 0–100.
|
|
311
376
|
const handleFocalPointerDown = (event)=>{
|
|
312
|
-
event
|
|
313
|
-
event.stopPropagation();
|
|
314
|
-
const move = (e)=>{
|
|
377
|
+
trackPointerDrag(event, (e)=>{
|
|
315
378
|
const point = pointerToNatural(e);
|
|
316
379
|
if (!point) return;
|
|
317
380
|
// Convert pointer to a percentage of the current crop area.
|
|
@@ -321,13 +384,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
|
|
|
321
384
|
x: Math.round(Math.min(100, Math.max(0, px))),
|
|
322
385
|
y: Math.round(Math.min(100, Math.max(0, py)))
|
|
323
386
|
});
|
|
324
|
-
};
|
|
325
|
-
const up = ()=>{
|
|
326
|
-
window.removeEventListener('pointermove', move);
|
|
327
|
-
window.removeEventListener('pointerup', up);
|
|
328
|
-
};
|
|
329
|
-
window.addEventListener('pointermove', move);
|
|
330
|
-
window.addEventListener('pointerup', up);
|
|
387
|
+
});
|
|
331
388
|
};
|
|
332
389
|
const focalPxX = Math.round(focal.x / 100 * width);
|
|
333
390
|
const focalPxY = Math.round(focal.y / 100 * height);
|
|
@@ -377,7 +434,10 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
|
|
|
377
434
|
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Portal, {
|
|
378
435
|
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.FocusTrap, {
|
|
379
436
|
onEscape: onClose,
|
|
437
|
+
skipAutoFocus: true,
|
|
380
438
|
children: /*#__PURE__*/ jsxRuntime.jsxs(Overlay, {
|
|
439
|
+
ref: overlayRef,
|
|
440
|
+
tabIndex: -1,
|
|
381
441
|
children: [
|
|
382
442
|
/*#__PURE__*/ jsxRuntime.jsxs(HeaderBar, {
|
|
383
443
|
alignItems: "center",
|
|
@@ -405,6 +465,10 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
|
|
|
405
465
|
ref: imgRef,
|
|
406
466
|
src: imageUrl,
|
|
407
467
|
alt: asset.name,
|
|
468
|
+
// Always anonymous, unlike AssetPreview/AssetsGrid which gate it:
|
|
469
|
+
// the editor reads pixels via canvas (useCropImg -> toBlob), which
|
|
470
|
+
// taints on a cross-origin image loaded without CORS, so every
|
|
471
|
+
// remote image must be fetched CORS-clean.
|
|
408
472
|
crossOrigin: "anonymous",
|
|
409
473
|
onLoad: handleImageLoad,
|
|
410
474
|
draggable: false
|
|
@@ -666,7 +730,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
|
|
|
666
730
|
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
667
731
|
gap: 2,
|
|
668
732
|
children: [
|
|
669
|
-
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
|
|
733
|
+
canSaveAsCopy && /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
|
|
670
734
|
variant: "secondary",
|
|
671
735
|
onClick: ()=>handleAction('copy'),
|
|
672
736
|
loading: isBusy,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetCropEditor.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Field,\n Flex,\n FocusTrap,\n IconButton,\n NumberInput,\n Portal,\n Typography,\n} from '@strapi/design-system';\nimport { ArrowsHorizontal, ArrowsVertical, Crop, Link } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, useTheme } from 'styled-components';\n\nimport { prefixFileUrlWithBackendUrl } from '../../../../utils/files';\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { resolveCornerResize, useCropImg } from './useCropImg';\n\nimport type {\n AssetWithPopulatedCreatedBy,\n FocalPoint,\n} from '../../../../../../../shared/contracts/files';\n\nconst FOCAL_DIAMETER_REM = 5.6;\nconst HANDLE_PX = 12;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled\n * -----------------------------------------------------------------------------------------------*/\n\n// Full-viewport takeover with a small inset so the editor reads as a card.\nconst Overlay = styled(Flex)`\n position: fixed;\n z-index: 1200;\n flex-direction: column;\n top: ${({ theme }) => theme.spaces[1]};\n left: ${({ theme }) => theme.spaces[1]};\n right: ${({ theme }) => theme.spaces[1]};\n bottom: ${({ theme }) => theme.spaces[1]};\n border-radius: ${({ theme }) => theme.borderRadius};\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\nconst HeaderBar = styled(Flex)`\n width: 100%;\n gap: ${({ theme }) => theme.spaces[2]};\n padding: ${({ theme }) => `${theme.spaces[3]} ${theme.spaces[5]}`};\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\n// Fills the remaining space between header/footer; checkerboard pattern.\nconst Body = styled(Box)`\n width: 100%;\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n ${({ theme }) => theme.colors.neutral0} 0% 50%\n )\n 50% / 20px 20px;\n`;\n\n// Wrapper sized to the image's natural aspect ratio so the <img> inside fills\n// it without letterboxing. Percentage-based positioning of the crop overlay\n// then maps directly to natural-px coordinates.\nconst CropArea = styled.div<{ $aspect?: number }>`\n position: relative;\n max-width: 100%;\n max-height: 100%;\n ${({ $aspect }) => ($aspect ? `aspect-ratio: ${$aspect};` : '')}\n\n img {\n display: block;\n width: 100%;\n height: 100%;\n user-select: none;\n -webkit-user-drag: none;\n }\n`;\n\n// Crop selection rectangle, positioned by % of CropArea. Inverts the dim\n// outside via box-shadow so the focused area shows full color.\nconst CropOverlay = styled.div`\n position: absolute;\n border: 1px dashed ${({ theme }) => theme.colors.primary600};\n box-shadow: 0 0 0 9999px rgba(33, 33, 52, 0.5);\n cursor: move;\n`;\n\nconst ResizeHandle = styled.button<{ $cursor: string }>`\n position: absolute;\n width: ${HANDLE_PX}px;\n height: ${HANDLE_PX}px;\n margin: -${HANDLE_PX / 2}px;\n padding: 0;\n border: 1px solid ${({ theme }) => theme.colors.primary600};\n border-radius: 2px;\n background: ${({ theme }) => theme.colors.neutral0};\n cursor: ${({ $cursor }) => $cursor};\n`;\n\nconst FocalPointHandle = styled.button`\n position: absolute;\n width: ${FOCAL_DIAMETER_REM}rem;\n height: ${FOCAL_DIAMETER_REM}rem;\n margin: ${-FOCAL_DIAMETER_REM / 2}rem 0 0 ${-FOCAL_DIAMETER_REM / 2}rem;\n border-radius: 50%;\n border: 1px solid ${({ theme }) => theme.colors.neutral800};\n background: transparent;\n cursor: grab;\n padding: 0;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.16);\n transform: translate(-50%, -50%);\n }\n &::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: ${({ theme }) => theme.colors.neutral800};\n transform: translate(-50%, -50%);\n }\n\n &:active {\n cursor: grabbing;\n }\n`;\n\nconst InfoBox = styled(Box)`\n position: absolute;\n right: ${({ theme }) => theme.spaces[1]};\n bottom: ${({ theme }) => theme.spaces[1]};\n width: 100%;\n max-width: 32rem;\n padding: ${({ theme }) => theme.spaces[3]};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) =>\n theme.colorScheme === 'dark' ? theme.colors.neutral150 : theme.colors.neutral900};\n z-index: 20;\n`;\n\nconst FooterBar = styled(Flex)`\n width: 100%;\n justify-content: space-between;\n padding: ${({ theme }) => `${theme.spaces[3]} ${theme.spaces[5]}`};\n border-top: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\nconst FieldRow = styled(Field.Root)`\n flex-direction: row;\n align-items: center;\n`;\n\nconst FieldNumberInput = styled(NumberInput)`\n width: 8.4rem;\n`;\n\nconst LabelIcon = styled(Field.Label)`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.6rem;\n height: 1.6rem;\n`;\n\nconst BackgroundPreserveRatioContainer = styled(Box)`\n position: absolute;\n top: 50%;\n left: 0;\n transform: translateY(-50%);\n\n svg {\n display: block;\n }\n`;\n\nconst BackgroundPreserveRatio = () => (\n <BackgroundPreserveRatioContainer>\n <svg width=\"17\" height=\"49\" viewBox=\"0 0 17 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M0.5 0.5H8.5C12.9183 0.5 16.5 4.08172 16.5 8.5M0.5 48.5H8.5C12.9183 48.5 16.5 44.9183 16.5 40.5\"\n stroke=\"#666687\"\n strokeLinecap=\"round\"\n />\n </svg>\n </BackgroundPreserveRatioContainer>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCropEditor\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetCropEditorProps {\n asset: AssetWithPopulatedCreatedBy;\n isBusy?: boolean;\n onClose: () => void;\n onApply: (file: globalThis.File, focalPoint: FocalPoint) => void;\n onSaveAsCopy: (file: globalThis.File, focalPoint: FocalPoint) => void;\n}\n\ntype Corner = 'tl' | 'tr' | 'bl' | 'br';\n\nexport const AssetCropEditor = ({\n asset,\n isBusy = false,\n onClose,\n onApply,\n onSaveAsCopy,\n}: AssetCropEditorProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n // The InfoBox is a fixed dark surface in both themes, so its text can't use a\n // single neutral token (those invert with the scheme). Pick the scheme's white\n // and a muted grey explicitly.\n const theme = useTheme();\n const isDark = theme.colorScheme === 'dark';\n const infoTextColor = isDark ? 'neutral1000' : 'neutral0';\n const infoMutedColor = isDark ? 'neutral600' : 'neutral200';\n const imgRef = React.useRef<HTMLImageElement>(null);\n const cropAreaRef = React.useRef<HTMLDivElement>(null);\n\n const {\n init,\n crop,\n naturalSize,\n aspectRatio,\n setCropSize,\n setCropPosition,\n setAspectRatio,\n produceFile,\n width,\n height,\n } = useCropImg();\n\n const [aspectLocked, setAspectLocked] = React.useState(false);\n // Focal point as a percentage of the crop area (matches the {x,y} contract).\n const [focal, setFocal] = React.useState<FocalPoint>(asset.focalPoint ?? { x: 50, y: 50 });\n\n // Append `updatedAt` as a cache-buster: a replaced asset is served at the same\n // URL, so without this, reopening the editor shows the browser-cached old image\n // (mirrors AssetPreview).\n const rawImageUrl = prefixFileUrlWithBackendUrl(asset.url) as string;\n const cacheKey = asset.updatedAt ? new Date(asset.updatedAt).getTime() : undefined;\n const imageUrl =\n cacheKey !== undefined\n ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}v=${cacheKey}`\n : rawImageUrl;\n\n const handleImageLoad = () => {\n if (imgRef.current) {\n init(imgRef.current);\n }\n };\n\n // Map a pointer event to natural-px coordinates inside the image.\n const pointerToNatural = (event: PointerEvent | React.PointerEvent) => {\n const rect = cropAreaRef.current?.getBoundingClientRect();\n if (!rect || !naturalSize.width || !naturalSize.height) return null;\n const ratioX = naturalSize.width / rect.width;\n const ratioY = naturalSize.height / rect.height;\n return {\n x: (event.clientX - rect.left) * ratioX,\n y: (event.clientY - rect.top) * ratioY,\n };\n };\n\n // Drag the entire crop rectangle.\n const handleMovePointerDown = (event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const start = pointerToNatural(event);\n if (!start) return;\n const startCrop = { ...crop };\n const move = (e: PointerEvent) => {\n const next = pointerToNatural(e);\n if (!next) return;\n setCropPosition({\n x: startCrop.x + (next.x - start.x),\n y: startCrop.y + (next.y - start.y),\n });\n };\n const up = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n };\n\n // Resize from a corner; the opposite corner stays anchored.\n const handleResizePointerDown = (corner: Corner) => (event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const startCrop = { ...crop };\n const anchorX =\n corner === 'tl' || corner === 'bl' ? startCrop.x + startCrop.width : startCrop.x;\n const anchorY =\n corner === 'tl' || corner === 'tr' ? startCrop.y + startCrop.height : startCrop.y;\n const move = (e: PointerEvent) => {\n const point = pointerToNatural(e);\n if (!point) return;\n const {\n x,\n y,\n width: w,\n height: h,\n } = resolveCornerResize({\n anchorX,\n anchorY,\n point,\n aspectRatio: aspectLocked ? aspectRatio : null,\n });\n setCropPosition({ x, y });\n setCropSize({ width: w, height: h });\n };\n const up = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n };\n\n const toggleAspectLock = () => {\n setAspectLocked((locked) => {\n const next = !locked;\n setAspectRatio(next && height ? width / height : null);\n return next;\n });\n };\n\n // Drag the focal handle within the crop rectangle, clamped 0–100.\n const handleFocalPointerDown = (event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const move = (e: PointerEvent) => {\n const point = pointerToNatural(e);\n if (!point) return;\n // Convert pointer to a percentage of the current crop area.\n const px = ((point.x - crop.x) / crop.width) * 100;\n const py = ((point.y - crop.y) / crop.height) * 100;\n setFocal({\n x: Math.round(Math.min(100, Math.max(0, px))),\n y: Math.round(Math.min(100, Math.max(0, py))),\n });\n };\n const up = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n };\n\n const focalPxX = Math.round((focal.x / 100) * width);\n const focalPxY = Math.round((focal.y / 100) * height);\n\n const setFocalPx = (axis: 'x' | 'y', value: number) => {\n const dim = axis === 'x' ? width : height;\n if (!dim) return;\n const pct = Math.min(100, Math.max(0, (value / dim) * 100));\n setFocal((prev) => ({ ...prev, [axis]: Math.round(pct) }));\n };\n\n const cropPercents =\n naturalSize.width && naturalSize.height\n ? {\n left: (crop.x / naturalSize.width) * 100,\n top: (crop.y / naturalSize.height) * 100,\n width: (crop.width / naturalSize.width) * 100,\n height: (crop.height / naturalSize.height) * 100,\n }\n : null;\n\n // The crop is only usable once the image has loaded and `init()` has seeded\n // the natural size. Until then the produce/export path would reject.\n const isReady = cropPercents !== null;\n\n const handleAction = async (action: 'apply' | 'copy') => {\n if (!isReady) return;\n\n let file: globalThis.File;\n try {\n file = await produceFile(asset.name, asset.mime ?? 'image/png', asset.updatedAt);\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.export-error'),\n defaultMessage: 'Could not process the cropped image.',\n }),\n });\n return;\n }\n\n const roundedFocal = { x: Math.round(focal.x), y: Math.round(focal.y) };\n if (action === 'apply') {\n onApply(file, roundedFocal);\n } else {\n onSaveAsCopy(file, roundedFocal);\n }\n };\n\n return (\n <Portal>\n <FocusTrap onEscape={onClose}>\n <Overlay>\n <HeaderBar alignItems=\"center\">\n <Crop aria-hidden />\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {formatMessage({\n id: getTranslationKey('asset-details.crop.title'),\n defaultMessage: 'Crop & Focus area',\n })}\n </Typography>\n </HeaderBar>\n\n <Body>\n <CropArea\n ref={cropAreaRef}\n $aspect={\n naturalSize.width && naturalSize.height\n ? naturalSize.width / naturalSize.height\n : undefined\n }\n >\n <img\n ref={imgRef}\n src={imageUrl}\n alt={asset.name}\n crossOrigin=\"anonymous\"\n onLoad={handleImageLoad}\n draggable={false}\n />\n\n {cropPercents ? (\n <CropOverlay\n style={{\n left: `${cropPercents.left}%`,\n top: `${cropPercents.top}%`,\n width: `${cropPercents.width}%`,\n height: `${cropPercents.height}%`,\n }}\n onPointerDown={handleMovePointerDown}\n >\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.top-left'),\n defaultMessage: 'Resize top-left',\n })}\n $cursor=\"nwse-resize\"\n style={{ left: 0, top: 0 }}\n onPointerDown={handleResizePointerDown('tl')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.top-right'),\n defaultMessage: 'Resize top-right',\n })}\n $cursor=\"nesw-resize\"\n style={{ right: 0, top: 0 }}\n onPointerDown={handleResizePointerDown('tr')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.bottom-left'),\n defaultMessage: 'Resize bottom-left',\n })}\n $cursor=\"nesw-resize\"\n style={{ left: 0, bottom: 0 }}\n onPointerDown={handleResizePointerDown('bl')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.bottom-right'),\n defaultMessage: 'Resize bottom-right',\n })}\n $cursor=\"nwse-resize\"\n style={{ right: 0, bottom: 0 }}\n onPointerDown={handleResizePointerDown('br')}\n />\n\n <FocalPointHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-point'),\n defaultMessage: 'Focal point',\n })}\n style={{ left: `${focal.x}%`, top: `${focal.y}%` }}\n onPointerDown={handleFocalPointerDown}\n />\n </CropOverlay>\n ) : null}\n </CropArea>\n\n <InfoBox>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1} paddingBottom={3}>\n <Typography variant=\"omega\" fontWeight=\"bold\" textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.title'),\n defaultMessage: 'Crop & Focus area',\n })}\n </Typography>\n <Typography variant=\"pi\" textColor={infoMutedColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.hint'),\n defaultMessage:\n 'Set the crop area with the rectangle. Pin the always-visible area with the circle.',\n })}\n </Typography>\n </Flex>\n\n <Flex gap={6} alignItems=\"center\">\n <Flex alignItems=\"center\" gap={2}>\n <Flex direction=\"column\" gap={2}>\n <FieldRow name=\"crop-width\" gap={2}>\n <LabelIcon textColor={infoTextColor}>\n <ArrowsHorizontal />\n </LabelIcon>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.width'),\n defaultMessage: 'Width (px)',\n })}\n value={width}\n min={1}\n max={naturalSize.width || undefined}\n onValueChange={(next) => {\n if (next !== undefined) setCropSize({ width: next });\n }}\n />\n </FieldRow>\n <FieldRow name=\"crop-height\" gap={2}>\n <LabelIcon textColor={infoTextColor}>\n <ArrowsVertical />\n </LabelIcon>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.height'),\n defaultMessage: 'Height (px)',\n })}\n value={height}\n min={1}\n max={naturalSize.height || undefined}\n onValueChange={(next) => {\n if (next !== undefined) setCropSize({ height: next });\n }}\n />\n </FieldRow>\n </Flex>\n\n <Flex position=\"relative\">\n <IconButton\n label={formatMessage({\n id: getTranslationKey('asset-details.crop.aspect-lock'),\n defaultMessage: 'Lock aspect ratio',\n })}\n variant={aspectLocked ? 'secondary' : 'ghost'}\n onClick={toggleAspectLock}\n >\n <Link />\n </IconButton>\n <BackgroundPreserveRatio />\n </Flex>\n </Flex>\n\n <Flex direction=\"column\" gap={2} marginLeft={'auto'}>\n <FieldRow name=\"focal-x\" gap={2}>\n <Field.Label textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.focal-x-axis'),\n defaultMessage: 'X',\n })}\n </Field.Label>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-x'),\n defaultMessage: 'Focal point X (px)',\n })}\n value={focalPxX}\n onValueChange={(next) => {\n if (next !== undefined) setFocalPx('x', next);\n }}\n />\n </FieldRow>\n <FieldRow name=\"focal-y\" gap={2}>\n <Field.Label textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.focal-y-axis'),\n defaultMessage: 'Y',\n })}\n </Field.Label>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-y'),\n defaultMessage: 'Focal point Y (px)',\n })}\n value={focalPxY}\n onValueChange={(next) => {\n if (next !== undefined) setFocalPx('y', next);\n }}\n />\n </FieldRow>\n </Flex>\n </Flex>\n </InfoBox>\n </Body>\n\n <FooterBar alignItems=\"center\">\n <Button variant=\"tertiary\" onClick={onClose} disabled={isBusy}>\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n <Flex gap={2}>\n <Button\n variant=\"secondary\"\n onClick={() => handleAction('copy')}\n loading={isBusy}\n disabled={!isReady}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.crop.save-as-copy'),\n defaultMessage: 'Save as copy',\n })}\n </Button>\n <Button\n variant=\"default\"\n onClick={() => handleAction('apply')}\n loading={isBusy}\n disabled={!isReady}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.crop.apply'),\n defaultMessage: 'Apply',\n })}\n </Button>\n </Flex>\n </FooterBar>\n </Overlay>\n </FocusTrap>\n </Portal>\n );\n};\n"],"names":["FOCAL_DIAMETER_REM","HANDLE_PX","Overlay","styled","Flex","theme","spaces","borderRadius","colors","neutral150","neutral0","HeaderBar","Body","Box","neutral100","CropArea","div","$aspect","CropOverlay","primary600","ResizeHandle","button","$cursor","FocalPointHandle","neutral800","InfoBox","colorScheme","neutral900","FooterBar","FieldRow","Field","Root","FieldNumberInput","NumberInput","LabelIcon","Label","BackgroundPreserveRatioContainer","BackgroundPreserveRatio","_jsx","svg","width","height","viewBox","fill","xmlns","path","d","stroke","strokeLinecap","AssetCropEditor","asset","isBusy","onClose","onApply","onSaveAsCopy","formatMessage","useIntl","toggleNotification","useNotification","useTheme","isDark","infoTextColor","infoMutedColor","imgRef","React","useRef","cropAreaRef","init","crop","naturalSize","aspectRatio","setCropSize","setCropPosition","setAspectRatio","produceFile","useCropImg","aspectLocked","setAspectLocked","useState","focal","setFocal","focalPoint","x","y","rawImageUrl","prefixFileUrlWithBackendUrl","url","cacheKey","updatedAt","Date","getTime","undefined","imageUrl","includes","handleImageLoad","current","pointerToNatural","event","rect","getBoundingClientRect","ratioX","ratioY","clientX","left","clientY","top","handleMovePointerDown","preventDefault","stopPropagation","start","startCrop","move","e","next","up","window","removeEventListener","addEventListener","handleResizePointerDown","corner","anchorX","anchorY","point","w","h","resolveCornerResize","toggleAspectLock","locked","handleFocalPointerDown","px","py","Math","round","min","max","focalPxX","focalPxY","setFocalPx","axis","value","dim","pct","prev","cropPercents","isReady","handleAction","action","file","name","mime","type","message","id","getTranslationKey","defaultMessage","roundedFocal","Portal","FocusTrap","onEscape","_jsxs","alignItems","Crop","aria-hidden","Typography","variant","fontWeight","ref","img","src","alt","crossOrigin","onLoad","draggable","style","onPointerDown","aria-label","right","bottom","direction","gap","paddingBottom","textColor","ArrowsHorizontal","onValueChange","ArrowsVertical","position","IconButton","label","onClick","Link","marginLeft","Button","disabled","loading"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,MAAMA,kBAAAA,GAAqB,GAAA;AAC3B,MAAMC,SAAAA,GAAY,EAAA;AAElB;;AAEkG;AAGlG,MAAMC,OAAAA,GAAUC,uBAAAA,CAAOC,iBAAAA,CAAK;;;;OAIrB,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;QAChC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;SAChC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;UAChC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;AAC1B,iBAAA,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAME,YAAY,CAAC;oBACjC,EAAE,CAAC,EAAEF,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACC,UAAU,CAAC;cAC/C,EAAE,CAAC,EAAEJ,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;AACrD,CAAC;AAED,MAAMC,SAAAA,GAAYR,uBAAAA,CAAOC,iBAAAA,CAAK;;OAEvB,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;AAC7B,WAAA,EAAE,CAAC,EAAED,KAAK,EAAE,GAAK,CAAA,EAAGA,MAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,CAAC,EAAED,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,EAAE,CAAC;2BACzC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACC,UAAU,CAAC;cACtD,EAAE,CAAC,EAAEJ,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;AACrD,CAAC;AAED;AACA,MAAME,IAAAA,GAAOT,uBAAAA,CAAOU,gBAAAA,CAAI;;;;;;;;;;MAUlB,EAAE,CAAC,EAAER,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACM,UAAU,CAAC;MACzC,EAAE,CAAC,EAAET,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;;;AAG7C,CAAC;AAED;AACA;AACA;AACA,MAAMK,QAAAA,GAAWZ,uBAAAA,CAAOa,GAAyB;;;;AAI/C,EAAA,EAAE,CAAC,EAAEC,OAAO,EAAE,GAAMA,OAAAA,GAAU,CAAC,cAAc,EAAEA,OAAAA,CAAQ,CAAC,CAAC,GAAG,EAAA;;;;;;;;;AAS9D,CAAC;AAED;AACA;AACA,MAAMC,WAAAA,GAAcf,uBAAAA,CAAOa,GAAG;;qBAET,EAAE,CAAC,EAAEX,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACW,UAAU,CAAC;;;AAG9D,CAAC;AAED,MAAMC,YAAAA,GAAejB,uBAAAA,CAAOkB,MAA2B;;AAE9C,SAAA,EAAEpB,SAAAA,CAAU;AACX,UAAA,EAAEA,SAAAA,CAAU;AACX,WAAA,EAAEA,YAAY,CAAA,CAAE;;oBAEP,EAAE,CAAC,EAAEI,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACW,UAAU,CAAC;;cAE/C,EAAE,CAAC,EAAEd,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;AAC3C,UAAA,EAAE,CAAC,EAAEY,OAAO,EAAE,GAAKA,OAAAA,CAAQ;AACrC,CAAC;AAED,MAAMC,gBAAAA,GAAmBpB,uBAAAA,CAAOkB,MAAM;;AAE7B,SAAA,EAAErB,kBAAAA,CAAmB;AACpB,UAAA,EAAEA,kBAAAA,CAAmB;AACrB,UAAA,EAAE,CAACA,kBAAAA,GAAqB,CAAA,CAAE,QAAQ,EAAE,CAACA,qBAAqB,CAAA,CAAE;;oBAElD,EAAE,CAAC,EAAEK,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACgB,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;gBAwB7C,EAAE,CAAC,EAAEnB,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACgB,UAAU,CAAC;;;;;;;AAOzD,CAAC;AAED,MAAMC,OAAAA,GAAUtB,uBAAAA,CAAOU,gBAAAA,CAAI;;SAElB,EAAE,CAAC,EAAER,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;UAChC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;;;WAGhC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;AAC3B,iBAAA,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAME,YAAY,CAAC;AACvC,cAAA,EAAE,CAAC,EAAEF,KAAK,EAAE,GACtBA,KAAAA,CAAMqB,WAAW,KAAK,MAAA,GAASrB,KAAAA,CAAMG,MAAM,CAACC,UAAU,GAAGJ,MAAMG,MAAM,CAACmB,UAAU,CAAC;;AAErF,CAAC;AAED,MAAMC,SAAAA,GAAYzB,uBAAAA,CAAOC,iBAAAA,CAAK;;;AAGnB,WAAA,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAK,CAAA,EAAGA,MAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,CAAC,EAAED,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,EAAE,CAAC;wBAC5C,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACC,UAAU,CAAC;cACnD,EAAE,CAAC,EAAEJ,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;AACrD,CAAC;AAED,MAAMmB,QAAAA,GAAW1B,uBAAAA,CAAO2B,kBAAAA,CAAMC,IAAI,CAAC;;;AAGnC,CAAC;AAED,MAAMC,gBAAAA,GAAmB7B,uBAAAA,CAAO8B,wBAAAA,CAAY;;AAE5C,CAAC;AAED,MAAMC,SAAAA,GAAY/B,uBAAAA,CAAO2B,kBAAAA,CAAMK,KAAK,CAAC;;;;;;AAMrC,CAAC;AAED,MAAMC,gCAAAA,GAAmCjC,uBAAAA,CAAOU,gBAAAA,CAAI;;;;;;;;;AASpD,CAAC;AAED,MAAMwB,uBAAAA,GAA0B,kBAC9BC,cAAA,CAACF,gCAAAA,EAAAA;AACC,QAAA,QAAA,gBAAAE,cAAA,CAACC,KAAAA,EAAAA;YAAIC,KAAAA,EAAM,IAAA;YAAKC,MAAAA,EAAO,IAAA;YAAKC,OAAAA,EAAQ,WAAA;YAAYC,IAAAA,EAAK,MAAA;YAAOC,KAAAA,EAAM,4BAAA;AAChE,YAAA,QAAA,gBAAAN,cAAA,CAACO,MAAAA,EAAAA;gBACCC,CAAAA,EAAE,iGAAA;gBACFC,MAAAA,EAAO,SAAA;gBACPC,aAAAA,EAAc;;;;AAoBf,MAAMC,eAAAA,GAAkB,CAAC,EAC9BC,KAAK,EACLC,MAAAA,GAAS,KAAK,EACdC,OAAO,EACPC,OAAO,EACPC,YAAY,EACS,GAAA;IACrB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAC1B,MAAM,EAAEC,kBAAkB,EAAE,GAAGC,2BAAAA,EAAAA;;;;AAI/B,IAAA,MAAMrD,KAAAA,GAAQsD,yBAAAA,EAAAA;IACd,MAAMC,MAAAA,GAASvD,KAAAA,CAAMqB,WAAW,KAAK,MAAA;IACrC,MAAMmC,aAAAA,GAAgBD,SAAS,aAAA,GAAgB,UAAA;IAC/C,MAAME,cAAAA,GAAiBF,SAAS,YAAA,GAAe,YAAA;IAC/C,MAAMG,MAAAA,GAASC,gBAAAA,CAAMC,MAAM,CAAmB,IAAA,CAAA;IAC9C,MAAMC,WAAAA,GAAcF,gBAAAA,CAAMC,MAAM,CAAiB,IAAA,CAAA;IAEjD,MAAM,EACJE,IAAI,EACJC,IAAI,EACJC,WAAW,EACXC,WAAW,EACXC,WAAW,EACXC,eAAe,EACfC,cAAc,EACdC,WAAW,EACXlC,KAAK,EACLC,MAAM,EACP,GAAGkC,qBAAAA,EAAAA;AAEJ,IAAA,MAAM,CAACC,YAAAA,EAAcC,eAAAA,CAAgB,GAAGb,gBAAAA,CAAMc,QAAQ,CAAC,KAAA,CAAA;;IAEvD,MAAM,CAACC,OAAOC,QAAAA,CAAS,GAAGhB,iBAAMc,QAAQ,CAAa5B,KAAAA,CAAM+B,UAAU,IAAI;QAAEC,CAAAA,EAAG,EAAA;QAAIC,CAAAA,EAAG;AAAG,KAAA,CAAA;;;;IAKxF,MAAMC,WAAAA,GAAcC,iCAAAA,CAA4BnC,KAAAA,CAAMoC,GAAG,CAAA;IACzD,MAAMC,QAAAA,GAAWrC,KAAAA,CAAMsC,SAAS,GAAG,IAAIC,KAAKvC,KAAAA,CAAMsC,SAAS,CAAA,CAAEE,OAAO,EAAA,GAAKC,SAAAA;AACzE,IAAA,MAAMC,QAAAA,GACJL,QAAAA,KAAaI,SAAAA,GACT,CAAA,EAAGP,cAAcA,WAAAA,CAAYS,QAAQ,CAAC,GAAA,CAAA,GAAO,GAAA,GAAM,GAAA,CAAI,EAAE,EAAEN,UAAU,GACrEH,WAAAA;AAEN,IAAA,MAAMU,eAAAA,GAAkB,IAAA;QACtB,IAAI/B,MAAAA,CAAOgC,OAAO,EAAE;AAClB5B,YAAAA,IAAAA,CAAKJ,OAAOgC,OAAO,CAAA;AACrB,QAAA;AACF,IAAA,CAAA;;AAGA,IAAA,MAAMC,mBAAmB,CAACC,KAAAA,GAAAA;QACxB,MAAMC,IAAAA,GAAOhC,WAAAA,CAAY6B,OAAO,EAAEI,qBAAAA,EAAAA;QAClC,IAAI,CAACD,IAAAA,IAAQ,CAAC7B,WAAAA,CAAY7B,KAAK,IAAI,CAAC6B,WAAAA,CAAY5B,MAAM,EAAE,OAAO,IAAA;AAC/D,QAAA,MAAM2D,MAAAA,GAAS/B,WAAAA,CAAY7B,KAAK,GAAG0D,KAAK1D,KAAK;AAC7C,QAAA,MAAM6D,MAAAA,GAAShC,WAAAA,CAAY5B,MAAM,GAAGyD,KAAKzD,MAAM;QAC/C,OAAO;YACLyC,CAAAA,EAAIe,CAAAA,KAAAA,CAAMK,OAAO,GAAGJ,IAAAA,CAAKK,IAAI,IAAIH,MAAAA;YACjCjB,CAAAA,EAAIc,CAAAA,KAAAA,CAAMO,OAAO,GAAGN,IAAAA,CAAKO,GAAG,IAAIJ;AAClC,SAAA;AACF,IAAA,CAAA;;AAGA,IAAA,MAAMK,wBAAwB,CAACT,KAAAA,GAAAA;AAC7BA,QAAAA,KAAAA,CAAMU,cAAc,EAAA;AACpBV,QAAAA,KAAAA,CAAMW,eAAe,EAAA;AACrB,QAAA,MAAMC,QAAQb,gBAAAA,CAAiBC,KAAAA,CAAAA;AAC/B,QAAA,IAAI,CAACY,KAAAA,EAAO;AACZ,QAAA,MAAMC,SAAAA,GAAY;AAAE,YAAA,GAAG1C;AAAK,SAAA;AAC5B,QAAA,MAAM2C,OAAO,CAACC,CAAAA,GAAAA;AACZ,YAAA,MAAMC,OAAOjB,gBAAAA,CAAiBgB,CAAAA,CAAAA;AAC9B,YAAA,IAAI,CAACC,IAAAA,EAAM;YACXzC,eAAAA,CAAgB;gBACdU,CAAAA,EAAG4B,SAAAA,CAAU5B,CAAC,IAAI+B,KAAK/B,CAAC,GAAG2B,KAAAA,CAAM3B,CAAC,CAADA;gBACjCC,CAAAA,EAAG2B,SAAAA,CAAU3B,CAAC,IAAI8B,KAAK9B,CAAC,GAAG0B,KAAAA,CAAM1B,CAAC;AACpC,aAAA,CAAA;AACF,QAAA,CAAA;AACA,QAAA,MAAM+B,EAAAA,GAAK,IAAA;YACTC,MAAAA,CAAOC,mBAAmB,CAAC,aAAA,EAAeL,IAAAA,CAAAA;YAC1CI,MAAAA,CAAOC,mBAAmB,CAAC,WAAA,EAAaF,EAAAA,CAAAA;AAC1C,QAAA,CAAA;QACAC,MAAAA,CAAOE,gBAAgB,CAAC,aAAA,EAAeN,IAAAA,CAAAA;QACvCI,MAAAA,CAAOE,gBAAgB,CAAC,WAAA,EAAaH,EAAAA,CAAAA;AACvC,IAAA,CAAA;;IAGA,MAAMI,uBAAAA,GAA0B,CAACC,MAAAA,GAAmB,CAACtB,KAAAA,GAAAA;AACnDA,YAAAA,KAAAA,CAAMU,cAAc,EAAA;AACpBV,YAAAA,KAAAA,CAAMW,eAAe,EAAA;AACrB,YAAA,MAAME,SAAAA,GAAY;AAAE,gBAAA,GAAG1C;AAAK,aAAA;AAC5B,YAAA,MAAMoD,OAAAA,GACJD,MAAAA,KAAW,IAAA,IAAQA,MAAAA,KAAW,IAAA,GAAOT,SAAAA,CAAU5B,CAAC,GAAG4B,SAAAA,CAAUtE,KAAK,GAAGsE,SAAAA,CAAU5B,CAAC;AAClF,YAAA,MAAMuC,OAAAA,GACJF,MAAAA,KAAW,IAAA,IAAQA,MAAAA,KAAW,IAAA,GAAOT,SAAAA,CAAU3B,CAAC,GAAG2B,SAAAA,CAAUrE,MAAM,GAAGqE,SAAAA,CAAU3B,CAAC;AACnF,YAAA,MAAM4B,OAAO,CAACC,CAAAA,GAAAA;AACZ,gBAAA,MAAMU,QAAQ1B,gBAAAA,CAAiBgB,CAAAA,CAAAA;AAC/B,gBAAA,IAAI,CAACU,KAAAA,EAAO;AACZ,gBAAA,MAAM,EACJxC,CAAC,EACDC,CAAC,EACD3C,KAAAA,EAAOmF,CAAC,EACRlF,MAAAA,EAAQmF,CAAC,EACV,GAAGC,8BAAAA,CAAoB;AACtBL,oBAAAA,OAAAA;AACAC,oBAAAA,OAAAA;AACAC,oBAAAA,KAAAA;AACApD,oBAAAA,WAAAA,EAAaM,eAAeN,WAAAA,GAAc;AAC5C,iBAAA,CAAA;gBACAE,eAAAA,CAAgB;AAAEU,oBAAAA,CAAAA;AAAGC,oBAAAA;AAAE,iBAAA,CAAA;gBACvBZ,WAAAA,CAAY;oBAAE/B,KAAAA,EAAOmF,CAAAA;oBAAGlF,MAAAA,EAAQmF;AAAE,iBAAA,CAAA;AACpC,YAAA,CAAA;AACA,YAAA,MAAMV,EAAAA,GAAK,IAAA;gBACTC,MAAAA,CAAOC,mBAAmB,CAAC,aAAA,EAAeL,IAAAA,CAAAA;gBAC1CI,MAAAA,CAAOC,mBAAmB,CAAC,WAAA,EAAaF,EAAAA,CAAAA;AAC1C,YAAA,CAAA;YACAC,MAAAA,CAAOE,gBAAgB,CAAC,aAAA,EAAeN,IAAAA,CAAAA;YACvCI,MAAAA,CAAOE,gBAAgB,CAAC,WAAA,EAAaH,EAAAA,CAAAA;AACvC,QAAA,CAAA;AAEA,IAAA,MAAMY,gBAAAA,GAAmB,IAAA;AACvBjD,QAAAA,eAAAA,CAAgB,CAACkD,MAAAA,GAAAA;AACf,YAAA,MAAMd,OAAO,CAACc,MAAAA;YACdtD,cAAAA,CAAewC,IAAAA,IAAQxE,MAAAA,GAASD,KAAAA,GAAQC,MAAAA,GAAS,IAAA,CAAA;YACjD,OAAOwE,IAAAA;AACT,QAAA,CAAA,CAAA;AACF,IAAA,CAAA;;AAGA,IAAA,MAAMe,yBAAyB,CAAC/B,KAAAA,GAAAA;AAC9BA,QAAAA,KAAAA,CAAMU,cAAc,EAAA;AACpBV,QAAAA,KAAAA,CAAMW,eAAe,EAAA;AACrB,QAAA,MAAMG,OAAO,CAACC,CAAAA,GAAAA;AACZ,YAAA,MAAMU,QAAQ1B,gBAAAA,CAAiBgB,CAAAA,CAAAA;AAC/B,YAAA,IAAI,CAACU,KAAAA,EAAO;;AAEZ,YAAA,MAAMO,EAAAA,GAAOP,CAAAA,KAAAA,CAAMxC,CAAC,GAAGd,IAAAA,CAAKc,CAAC,IAAId,IAAAA,CAAK5B,KAAK,GAAI,GAAA;AAC/C,YAAA,MAAM0F,EAAAA,GAAOR,CAAAA,KAAAA,CAAMvC,CAAC,GAAGf,IAAAA,CAAKe,CAAC,IAAIf,IAAAA,CAAK3B,MAAM,GAAI,GAAA;YAChDuC,QAAAA,CAAS;gBACPE,CAAAA,EAAGiD,IAAAA,CAAKC,KAAK,CAACD,IAAAA,CAAKE,GAAG,CAAC,GAAA,EAAKF,IAAAA,CAAKG,GAAG,CAAC,CAAA,EAAGL,EAAAA,CAAAA,CAAAA,CAAAA;gBACxC9C,CAAAA,EAAGgD,IAAAA,CAAKC,KAAK,CAACD,IAAAA,CAAKE,GAAG,CAAC,GAAA,EAAKF,IAAAA,CAAKG,GAAG,CAAC,CAAA,EAAGJ,EAAAA,CAAAA,CAAAA;AAC1C,aAAA,CAAA;AACF,QAAA,CAAA;AACA,QAAA,MAAMhB,EAAAA,GAAK,IAAA;YACTC,MAAAA,CAAOC,mBAAmB,CAAC,aAAA,EAAeL,IAAAA,CAAAA;YAC1CI,MAAAA,CAAOC,mBAAmB,CAAC,WAAA,EAAaF,EAAAA,CAAAA;AAC1C,QAAA,CAAA;QACAC,MAAAA,CAAOE,gBAAgB,CAAC,aAAA,EAAeN,IAAAA,CAAAA;QACvCI,MAAAA,CAAOE,gBAAgB,CAAC,WAAA,EAAaH,EAAAA,CAAAA;AACvC,IAAA,CAAA;IAEA,MAAMqB,QAAAA,GAAWJ,KAAKC,KAAK,CAAC,KAACrD,CAAMG,CAAC,GAAG,GAAA,GAAO1C,KAAAA,CAAAA;IAC9C,MAAMgG,QAAAA,GAAWL,KAAKC,KAAK,CAAC,KAACrD,CAAMI,CAAC,GAAG,GAAA,GAAO1C,MAAAA,CAAAA;IAE9C,MAAMgG,UAAAA,GAAa,CAACC,IAAAA,EAAiBC,KAAAA,GAAAA;QACnC,MAAMC,GAAAA,GAAMF,IAAAA,KAAS,GAAA,GAAMlG,KAAAA,GAAQC,MAAAA;AACnC,QAAA,IAAI,CAACmG,GAAAA,EAAK;QACV,MAAMC,GAAAA,GAAMV,IAAAA,CAAKE,GAAG,CAAC,GAAA,EAAKF,IAAAA,CAAKG,GAAG,CAAC,CAAA,EAAG,KAACK,GAAQC,GAAAA,GAAO,GAAA,CAAA,CAAA;QACtD5D,QAAAA,CAAS,CAAC8D,QAAU;AAAE,gBAAA,GAAGA,IAAI;AAAE,gBAAA,CAACJ,IAAAA,GAAOP,IAAAA,CAAKC,KAAK,CAACS,GAAAA;aAAK,CAAA,CAAA;AACzD,IAAA,CAAA;AAEA,IAAA,MAAME,eACJ1E,WAAAA,CAAY7B,KAAK,IAAI6B,WAAAA,CAAY5B,MAAM,GACnC;AACE8D,QAAAA,IAAAA,EAAM,IAACnC,CAAKc,CAAC,GAAGb,WAAAA,CAAY7B,KAAK,GAAI,GAAA;AACrCiE,QAAAA,GAAAA,EAAK,IAACrC,CAAKe,CAAC,GAAGd,WAAAA,CAAY5B,MAAM,GAAI,GAAA;AACrCD,QAAAA,KAAAA,EAAO,IAAC4B,CAAK5B,KAAK,GAAG6B,WAAAA,CAAY7B,KAAK,GAAI,GAAA;AAC1CC,QAAAA,MAAAA,EAAQ,IAAC2B,CAAK3B,MAAM,GAAG4B,WAAAA,CAAY5B,MAAM,GAAI;KAC/C,GACA,IAAA;;;AAIN,IAAA,MAAMuG,UAAUD,YAAAA,KAAiB,IAAA;AAEjC,IAAA,MAAME,eAAe,OAAOC,MAAAA,GAAAA;AAC1B,QAAA,IAAI,CAACF,OAAAA,EAAS;QAEd,IAAIG,IAAAA;QACJ,IAAI;YACFA,IAAAA,GAAO,MAAMzE,WAAAA,CAAYxB,KAAAA,CAAMkG,IAAI,EAAElG,MAAMmG,IAAI,IAAI,WAAA,EAAanG,KAAAA,CAAMsC,SAAS,CAAA;AACjF,QAAA,CAAA,CAAE,OAAM;YACN/B,kBAAAA,CAAmB;gBACjB6F,IAAAA,EAAM,QAAA;AACNC,gBAAAA,OAAAA,EAAShG,aAAAA,CAAc;AACrBiG,oBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,iCAAA,CAAA;oBACtBC,cAAAA,EAAgB;AAClB,iBAAA;AACF,aAAA,CAAA;AACA,YAAA;AACF,QAAA;AAEA,QAAA,MAAMC,YAAAA,GAAe;AAAEzE,YAAAA,CAAAA,EAAGiD,IAAAA,CAAKC,KAAK,CAACrD,KAAAA,CAAMG,CAAC,CAAA;AAAGC,YAAAA,CAAAA,EAAGgD,IAAAA,CAAKC,KAAK,CAACrD,KAAAA,CAAMI,CAAC;AAAE,SAAA;AACtE,QAAA,IAAI+D,WAAW,OAAA,EAAS;AACtB7F,YAAAA,OAAAA,CAAQ8F,IAAAA,EAAMQ,YAAAA,CAAAA;QAChB,CAAA,MAAO;AACLrG,YAAAA,YAAAA,CAAa6F,IAAAA,EAAMQ,YAAAA,CAAAA;AACrB,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,qBACErH,cAAA,CAACsH,mBAAAA,EAAAA;AACC,QAAA,QAAA,gBAAAtH,cAAA,CAACuH,sBAAAA,EAAAA;YAAUC,QAAAA,EAAU1G,OAAAA;AACnB,YAAA,QAAA,gBAAA2G,eAAA,CAAC7J,OAAAA,EAAAA;;kCACC6J,eAAA,CAACpJ,SAAAA,EAAAA;wBAAUqJ,UAAAA,EAAW,QAAA;;0CACpB1H,cAAA,CAAC2H,UAAAA,EAAAA;gCAAKC,aAAW,EAAA;;0CACjB5H,cAAA,CAAC6H,uBAAAA,EAAAA;gCAAWC,OAAAA,EAAQ,OAAA;gCAAQC,UAAAA,EAAW,MAAA;0CACpC9G,aAAAA,CAAc;AACbiG,oCAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,0BAAA,CAAA;oCACtBC,cAAAA,EAAgB;AAClB,iCAAA;;;;kCAIJK,eAAA,CAACnJ,IAAAA,EAAAA;;0CACCmJ,eAAA,CAAChJ,QAAAA,EAAAA;gCACCuJ,GAAAA,EAAKpG,WAAAA;gCACLjD,OAAAA,EACEoD,WAAAA,CAAY7B,KAAK,IAAI6B,WAAAA,CAAY5B,MAAM,GACnC4B,WAAAA,CAAY7B,KAAK,GAAG6B,WAAAA,CAAY5B,MAAM,GACtCkD,SAAAA;;kDAGNrD,cAAA,CAACiI,KAAAA,EAAAA;wCACCD,GAAAA,EAAKvG,MAAAA;wCACLyG,GAAAA,EAAK5E,QAAAA;AACL6E,wCAAAA,GAAAA,EAAKvH,MAAMkG,IAAI;wCACfsB,WAAAA,EAAY,WAAA;wCACZC,MAAAA,EAAQ7E,eAAAA;wCACR8E,SAAAA,EAAW;;AAGZ7B,oCAAAA,YAAAA,iBACCgB,eAAA,CAAC7I,WAAAA,EAAAA;wCACC2J,KAAAA,EAAO;AACLtE,4CAAAA,IAAAA,EAAM,CAAA,EAAGwC,YAAAA,CAAaxC,IAAI,CAAC,CAAC,CAAC;AAC7BE,4CAAAA,GAAAA,EAAK,CAAA,EAAGsC,YAAAA,CAAatC,GAAG,CAAC,CAAC,CAAC;AAC3BjE,4CAAAA,KAAAA,EAAO,CAAA,EAAGuG,YAAAA,CAAavG,KAAK,CAAC,CAAC,CAAC;AAC/BC,4CAAAA,MAAAA,EAAQ,CAAA,EAAGsG,YAAAA,CAAatG,MAAM,CAAC,CAAC;AAClC,yCAAA;wCACAqI,aAAAA,EAAepE,qBAAAA;;0DAEfpE,cAAA,CAAClB,YAAAA,EAAAA;gDACCkI,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,oCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACApI,OAAAA,EAAQ,aAAA;gDACRuJ,KAAAA,EAAO;oDAAEtE,IAAAA,EAAM,CAAA;oDAAGE,GAAAA,EAAK;AAAE,iDAAA;AACzBqE,gDAAAA,aAAAA,EAAexD,uBAAAA,CAAwB,IAAA;;0DAEzChF,cAAA,CAAClB,YAAAA,EAAAA;gDACCkI,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,qCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACApI,OAAAA,EAAQ,aAAA;gDACRuJ,KAAAA,EAAO;oDAAEG,KAAAA,EAAO,CAAA;oDAAGvE,GAAAA,EAAK;AAAE,iDAAA;AAC1BqE,gDAAAA,aAAAA,EAAexD,uBAAAA,CAAwB,IAAA;;0DAEzChF,cAAA,CAAClB,YAAAA,EAAAA;gDACCkI,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,uCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACApI,OAAAA,EAAQ,aAAA;gDACRuJ,KAAAA,EAAO;oDAAEtE,IAAAA,EAAM,CAAA;oDAAG0E,MAAAA,EAAQ;AAAE,iDAAA;AAC5BH,gDAAAA,aAAAA,EAAexD,uBAAAA,CAAwB,IAAA;;0DAEzChF,cAAA,CAAClB,YAAAA,EAAAA;gDACCkI,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,wCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACApI,OAAAA,EAAQ,aAAA;gDACRuJ,KAAAA,EAAO;oDAAEG,KAAAA,EAAO,CAAA;oDAAGC,MAAAA,EAAQ;AAAE,iDAAA;AAC7BH,gDAAAA,aAAAA,EAAexD,uBAAAA,CAAwB,IAAA;;0DAGzChF,cAAA,CAACf,gBAAAA,EAAAA;gDACC+H,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,gCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACAmB,KAAAA,EAAO;AAAEtE,oDAAAA,IAAAA,EAAM,CAAA,EAAGxB,KAAAA,CAAMG,CAAC,CAAC,CAAC,CAAC;AAAEuB,oDAAAA,GAAAA,EAAK,CAAA,EAAG1B,KAAAA,CAAMI,CAAC,CAAC,CAAC;AAAE,iDAAA;gDACjD2F,aAAAA,EAAe9C;;;AAGjB,qCAAA,CAAA,GAAA;;;0CAGN+B,eAAA,CAACtI,OAAAA,EAAAA;;kDACCsI,eAAA,CAAC3J,iBAAAA,EAAAA;wCAAK8K,SAAAA,EAAU,QAAA;wCAASlB,UAAAA,EAAW,SAAA;wCAAUmB,GAAAA,EAAK,CAAA;wCAAGC,aAAAA,EAAe,CAAA;;0DACnE9I,cAAA,CAAC6H,uBAAAA,EAAAA;gDAAWC,OAAAA,EAAQ,OAAA;gDAAQC,UAAAA,EAAW,MAAA;gDAAOgB,SAAAA,EAAWxH,aAAAA;0DACtDN,aAAAA,CAAc;AACbiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,0BAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA;;0DAEFpH,cAAA,CAAC6H,uBAAAA,EAAAA;gDAAWC,OAAAA,EAAQ,IAAA;gDAAKiB,SAAAA,EAAWvH,cAAAA;0DACjCP,aAAAA,CAAc;AACbiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,yBAAA,CAAA;oDACtBC,cAAAA,EACE;AACJ,iDAAA;;;;kDAIJK,eAAA,CAAC3J,iBAAAA,EAAAA;wCAAK+K,GAAAA,EAAK,CAAA;wCAAGnB,UAAAA,EAAW,QAAA;;0DACvBD,eAAA,CAAC3J,iBAAAA,EAAAA;gDAAK4J,UAAAA,EAAW,QAAA;gDAASmB,GAAAA,EAAK,CAAA;;kEAC7BpB,eAAA,CAAC3J,iBAAAA,EAAAA;wDAAK8K,SAAAA,EAAU,QAAA;wDAASC,GAAAA,EAAK,CAAA;;0EAC5BpB,eAAA,CAAClI,QAAAA,EAAAA;gEAASuH,IAAAA,EAAK,YAAA;gEAAa+B,GAAAA,EAAK,CAAA;;kFAC/B7I,cAAA,CAACJ,SAAAA,EAAAA;wEAAUmJ,SAAAA,EAAWxH,aAAAA;AACpB,wEAAA,QAAA,gBAAAvB,cAAA,CAACgJ,sBAAAA,EAAAA,EAAAA;;kFAEHhJ,cAAA,CAACN,gBAAAA,EAAAA;AACC+I,wEAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,4EAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,0BAAA,CAAA;4EACtBC,cAAAA,EAAgB;AAClB,yEAAA,CAAA;wEACAf,KAAAA,EAAOnG,KAAAA;wEACP6F,GAAAA,EAAK,CAAA;wEACLC,GAAAA,EAAKjE,WAAAA,CAAY7B,KAAK,IAAImD,SAAAA;AAC1B4F,wEAAAA,aAAAA,EAAe,CAACtE,IAAAA,GAAAA;4EACd,IAAIA,IAAAA,KAAStB,WAAWpB,WAAAA,CAAY;gFAAE/B,KAAAA,EAAOyE;AAAK,6EAAA,CAAA;AACpD,wEAAA;;;;0EAGJ8C,eAAA,CAAClI,QAAAA,EAAAA;gEAASuH,IAAAA,EAAK,aAAA;gEAAc+B,GAAAA,EAAK,CAAA;;kFAChC7I,cAAA,CAACJ,SAAAA,EAAAA;wEAAUmJ,SAAAA,EAAWxH,aAAAA;AACpB,wEAAA,QAAA,gBAAAvB,cAAA,CAACkJ,oBAAAA,EAAAA,EAAAA;;kFAEHlJ,cAAA,CAACN,gBAAAA,EAAAA;AACC+I,wEAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,4EAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,2BAAA,CAAA;4EACtBC,cAAAA,EAAgB;AAClB,yEAAA,CAAA;wEACAf,KAAAA,EAAOlG,MAAAA;wEACP4F,GAAAA,EAAK,CAAA;wEACLC,GAAAA,EAAKjE,WAAAA,CAAY5B,MAAM,IAAIkD,SAAAA;AAC3B4F,wEAAAA,aAAAA,EAAe,CAACtE,IAAAA,GAAAA;4EACd,IAAIA,IAAAA,KAAStB,WAAWpB,WAAAA,CAAY;gFAAE9B,MAAAA,EAAQwE;AAAK,6EAAA,CAAA;AACrD,wEAAA;;;;;;kEAKN8C,eAAA,CAAC3J,iBAAAA,EAAAA;wDAAKqL,QAAAA,EAAS,UAAA;;0EACbnJ,cAAA,CAACoJ,uBAAAA,EAAAA;AACCC,gEAAAA,KAAAA,EAAOpI,aAAAA,CAAc;AACnBiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,gCAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA,CAAA;AACAU,gEAAAA,OAAAA,EAASxF,eAAe,WAAA,GAAc,OAAA;gEACtCgH,OAAAA,EAAS9D,gBAAAA;AAET,gEAAA,QAAA,gBAAAxF,cAAA,CAACuJ,UAAAA,EAAAA,EAAAA;;0EAEHvJ,cAAA,CAACD,uBAAAA,EAAAA,EAAAA;;;;;0DAIL0H,eAAA,CAAC3J,iBAAAA,EAAAA;gDAAK8K,SAAAA,EAAU,QAAA;gDAASC,GAAAA,EAAK,CAAA;gDAAGW,UAAAA,EAAY,MAAA;;kEAC3C/B,eAAA,CAAClI,QAAAA,EAAAA;wDAASuH,IAAAA,EAAK,SAAA;wDAAU+B,GAAAA,EAAK,CAAA;;AAC5B,0EAAA7I,cAAA,CAACR,mBAAMK,KAAK,EAAA;gEAACkJ,SAAAA,EAAWxH,aAAAA;0EACrBN,aAAAA,CAAc;AACbiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,iCAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA;;0EAEFpH,cAAA,CAACN,gBAAAA,EAAAA;AACC+I,gEAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,4BAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA,CAAA;gEACAf,KAAAA,EAAOJ,QAAAA;AACPgD,gEAAAA,aAAAA,EAAe,CAACtE,IAAAA,GAAAA;oEACd,IAAIA,IAAAA,KAAStB,SAAAA,EAAW8C,UAAAA,CAAW,GAAA,EAAKxB,IAAAA,CAAAA;AAC1C,gEAAA;;;;kEAGJ8C,eAAA,CAAClI,QAAAA,EAAAA;wDAASuH,IAAAA,EAAK,SAAA;wDAAU+B,GAAAA,EAAK,CAAA;;AAC5B,0EAAA7I,cAAA,CAACR,mBAAMK,KAAK,EAAA;gEAACkJ,SAAAA,EAAWxH,aAAAA;0EACrBN,aAAAA,CAAc;AACbiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,iCAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA;;0EAEFpH,cAAA,CAACN,gBAAAA,EAAAA;AACC+I,gEAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,4BAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA,CAAA;gEACAf,KAAAA,EAAOH,QAAAA;AACP+C,gEAAAA,aAAAA,EAAe,CAACtE,IAAAA,GAAAA;oEACd,IAAIA,IAAAA,KAAStB,SAAAA,EAAW8C,UAAAA,CAAW,GAAA,EAAKxB,IAAAA,CAAAA;AAC1C,gEAAA;;;;;;;;;;;;kCAQZ8C,eAAA,CAACnI,SAAAA,EAAAA;wBAAUoI,UAAAA,EAAW,QAAA;;0CACpB1H,cAAA,CAACyJ,mBAAAA,EAAAA;gCAAO3B,OAAAA,EAAQ,UAAA;gCAAWwB,OAAAA,EAASxI,OAAAA;gCAAS4I,QAAAA,EAAU7I,MAAAA;0CACpDI,aAAAA,CAAc;oCAAEiG,EAAAA,EAAI,8BAAA;oCAAgCE,cAAAA,EAAgB;AAAS,iCAAA;;0CAEhFK,eAAA,CAAC3J,iBAAAA,EAAAA;gCAAK+K,GAAAA,EAAK,CAAA;;kDACT7I,cAAA,CAACyJ,mBAAAA,EAAAA;wCACC3B,OAAAA,EAAQ,WAAA;AACRwB,wCAAAA,OAAAA,EAAS,IAAM3C,YAAAA,CAAa,MAAA,CAAA;wCAC5BgD,OAAAA,EAAS9I,MAAAA;AACT6I,wCAAAA,QAAAA,EAAU,CAAChD,OAAAA;kDAEVzF,aAAAA,CAAc;AACbiG,4CAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,iCAAA,CAAA;4CACtBC,cAAAA,EAAgB;AAClB,yCAAA;;kDAEFpH,cAAA,CAACyJ,mBAAAA,EAAAA;wCACC3B,OAAAA,EAAQ,SAAA;AACRwB,wCAAAA,OAAAA,EAAS,IAAM3C,YAAAA,CAAa,OAAA,CAAA;wCAC5BgD,OAAAA,EAAS9I,MAAAA;AACT6I,wCAAAA,QAAAA,EAAU,CAAChD,OAAAA;kDAEVzF,aAAAA,CAAc;AACbiG,4CAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,0BAAA,CAAA;4CACtBC,cAAAA,EAAgB;AAClB,yCAAA;;;;;;;;;;AAQhB;;;;"}
|
|
1
|
+
{"version":3,"file":"AssetCropEditor.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Field,\n Flex,\n FocusTrap,\n IconButton,\n NumberInput,\n Portal,\n Typography,\n} from '@strapi/design-system';\nimport { ArrowsHorizontal, ArrowsVertical, Crop, Link } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, useTheme } from 'styled-components';\n\nimport { prefixFileUrlWithBackendUrl } from '../../../../utils/files';\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { resolveCornerResize, useCropImg } from './useCropImg';\n\nimport type {\n AssetWithPopulatedCreatedBy,\n FocalPoint,\n} from '../../../../../../../shared/contracts/files';\n\nconst FOCAL_DIAMETER_REM = 5.6;\nconst HANDLE_PX = 12;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled\n * -----------------------------------------------------------------------------------------------*/\n\n// Full-viewport takeover with a small inset so the editor reads as a card.\nconst Overlay = styled(Flex)`\n position: fixed;\n z-index: 1200;\n flex-direction: column;\n top: ${({ theme }) => theme.spaces[1]};\n left: ${({ theme }) => theme.spaces[1]};\n right: ${({ theme }) => theme.spaces[1]};\n bottom: ${({ theme }) => theme.spaces[1]};\n border-radius: ${({ theme }) => theme.borderRadius};\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n /* Focused programmatically on open (tabIndex -1) — no visible ring needed. */\n outline: none;\n`;\n\nconst HeaderBar = styled(Flex)`\n width: 100%;\n gap: ${({ theme }) => theme.spaces[2]};\n padding: ${({ theme }) => `${theme.spaces[3]} ${theme.spaces[5]}`};\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\n// Fills the remaining space between header/footer; checkerboard pattern.\n// The horizontal padding keeps the image off the viewport edges — the corner\n// handles overhang the image by half their size, and on narrow (mobile)\n// screens an edge-to-edge image leaves nothing to grab.\nconst Body = styled(Box)`\n width: 100%;\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n padding: 0 ${({ theme }) => theme.spaces[4]};\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n ${({ theme }) => theme.colors.neutral0} 0% 50%\n )\n 50% / 20px 20px;\n`;\n\n// Wrapper sized to the image's natural aspect ratio so the <img> inside fills\n// it without letterboxing. Percentage-based positioning of the crop overlay\n// then maps directly to natural-px coordinates.\nconst CropArea = styled.div<{ $aspect?: number }>`\n position: relative;\n max-width: 100%;\n max-height: 100%;\n ${({ $aspect }) => ($aspect ? `aspect-ratio: ${$aspect};` : '')}\n\n img {\n display: block;\n width: 100%;\n height: 100%;\n user-select: none;\n -webkit-user-drag: none;\n }\n`;\n\n// Crop selection rectangle, positioned by % of CropArea. Inverts the dim\n// outside via box-shadow so the focused area shows full color.\nconst CropOverlay = styled.div`\n position: absolute;\n border: 1px dashed ${({ theme }) => theme.colors.primary600};\n box-shadow: 0 0 0 9999px rgba(33, 33, 52, 0.5);\n cursor: move;\n /* Without this, touch browsers claim the gesture for scrolling and fire\n pointercancel mid-drag — the crop drag dies while the finger is down. */\n touch-action: none;\n`;\n\nconst ResizeHandle = styled.button<{ $cursor: string }>`\n position: absolute;\n width: ${HANDLE_PX}px;\n height: ${HANDLE_PX}px;\n margin: -${HANDLE_PX / 2}px;\n padding: 0;\n border: 1px solid ${({ theme }) => theme.colors.primary600};\n border-radius: 2px;\n background: ${({ theme }) => theme.colors.neutral0};\n cursor: ${({ $cursor }) => $cursor};\n touch-action: none;\n`;\n\nconst FocalPointHandle = styled.button`\n position: absolute;\n width: ${FOCAL_DIAMETER_REM}rem;\n height: ${FOCAL_DIAMETER_REM}rem;\n margin: ${-FOCAL_DIAMETER_REM / 2}rem 0 0 ${-FOCAL_DIAMETER_REM / 2}rem;\n border-radius: 50%;\n border: 1px solid ${({ theme }) => theme.colors.neutral800};\n background: transparent;\n cursor: grab;\n padding: 0;\n touch-action: none;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.16);\n transform: translate(-50%, -50%);\n }\n &::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: ${({ theme }) => theme.colors.neutral800};\n transform: translate(-50%, -50%);\n }\n\n &:active {\n cursor: grabbing;\n }\n`;\n\n// Hidden on mobile — the panel (title/hint + numeric crop & focal inputs) is\n// too large for a phone; touch users set the crop by dragging the rectangle and\n// focal handle directly on the image. Shown from tablet up.\nconst InfoBox = styled(Box)`\n display: none;\n\n ${({ theme }) => theme.breakpoints.medium} {\n display: block;\n position: absolute;\n right: ${({ theme }) => theme.spaces[1]};\n bottom: ${({ theme }) => theme.spaces[1]};\n width: 100%;\n max-width: 32rem;\n padding: ${({ theme }) => theme.spaces[3]};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) =>\n theme.colorScheme === 'dark' ? theme.colors.neutral150 : theme.colors.neutral900};\n z-index: 20;\n }\n`;\n\nconst FooterBar = styled(Flex)`\n width: 100%;\n justify-content: space-between;\n padding: ${({ theme }) => `${theme.spaces[3]} ${theme.spaces[5]}`};\n border-top: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\nconst FieldRow = styled(Field.Root)`\n flex-direction: row;\n align-items: center;\n`;\n\nconst FieldNumberInput = styled(NumberInput)`\n width: 8.4rem;\n`;\n\nconst LabelIcon = styled(Field.Label)`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.6rem;\n height: 1.6rem;\n`;\n\nconst BackgroundPreserveRatioContainer = styled(Box)`\n position: absolute;\n top: 50%;\n left: 0;\n transform: translateY(-50%);\n\n svg {\n display: block;\n }\n`;\n\nconst BackgroundPreserveRatio = () => (\n <BackgroundPreserveRatioContainer>\n <svg width=\"17\" height=\"49\" viewBox=\"0 0 17 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M0.5 0.5H8.5C12.9183 0.5 16.5 4.08172 16.5 8.5M0.5 48.5H8.5C12.9183 48.5 16.5 44.9183 16.5 40.5\"\n stroke=\"#666687\"\n strokeLinecap=\"round\"\n />\n </svg>\n </BackgroundPreserveRatioContainer>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCropEditor\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetCropEditorProps {\n asset: AssetWithPopulatedCreatedBy;\n isBusy?: boolean;\n onClose: () => void;\n onApply: (file: globalThis.File, focalPoint: FocalPoint) => void;\n onSaveAsCopy: (file: globalThis.File, focalPoint: FocalPoint) => void;\n /**\n * \"Save as copy\" creates a new asset (`assets.create`), a different permission\n * from cropping in place (`assets.update`). Hidden when the user lacks it, so\n * an update-only role can't trigger a 403.\n */\n canSaveAsCopy: boolean;\n}\n\ntype Corner = 'tl' | 'tr' | 'bl' | 'br';\n\nexport const AssetCropEditor = ({\n asset,\n isBusy = false,\n onClose,\n onApply,\n onSaveAsCopy,\n canSaveAsCopy,\n}: AssetCropEditorProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n // The InfoBox is a fixed dark surface in both themes, so its text can't use a\n // single neutral token (those invert with the scheme). Pick the scheme's white\n // and a muted grey explicitly.\n const theme = useTheme();\n const isDark = theme.colorScheme === 'dark';\n const infoTextColor = isDark ? 'neutral1000' : 'neutral0';\n const infoMutedColor = isDark ? 'neutral600' : 'neutral200';\n const imgRef = React.useRef<HTMLImageElement>(null);\n const cropAreaRef = React.useRef<HTMLDivElement>(null);\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n // FocusTrap's auto-focus lands on the first focusable element — the crop\n // width NumberInput — which pops the keyboard on mobile the moment the\n // editor opens. Focus the (tabIndex -1) overlay instead: keyboard users are\n // one Tab away from the first control, Escape still reaches the trap.\n React.useEffect(() => {\n overlayRef.current?.focus();\n }, []);\n\n const {\n init,\n crop,\n naturalSize,\n aspectRatio,\n setCropSize,\n setCropPosition,\n setAspectRatio,\n produceFile,\n width,\n height,\n } = useCropImg();\n\n const [aspectLocked, setAspectLocked] = React.useState(false);\n // Focal point as a percentage of the crop area (matches the {x,y} contract).\n const [focal, setFocal] = React.useState<FocalPoint>(asset.focalPoint ?? { x: 50, y: 50 });\n\n // The crop editor reads pixels from a canvas (useCropImg -> toBlob), so its\n // <img> must be CORS-clean and always sets crossOrigin=\"anonymous\" (see the\n // img below) — even for unsigned URLs, which AssetPreview leaves unset because\n // it only displays. That difference is why the crop URL is kept DISTINCT from\n // the thumbnail's: identical URL + different crossOrigin collide in the HTTP\n // cache (#26581), and the crop's anonymous request could otherwise reuse the\n // thumbnail's non-CORS cached response and taint the canvas. So the buster\n // uses `updatedAt` where AssetPreview uses `v`, giving each its own entry\n // (mirrors the legacy PreviewBox fix).\n // Signed URLs get no param at all — a presigned S3 URL breaks if you add one,\n // and on the signed side AssetPreview also loads anonymous, so the identical\n // URL there shares one CORS-consistent entry, which is fine.\n const rawImageUrl = prefixFileUrlWithBackendUrl(asset.url) as string;\n const cacheKey =\n asset.updatedAt && !asset.isUrlSigned ? new Date(asset.updatedAt).getTime() : undefined;\n const imageUrl =\n cacheKey !== undefined\n ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}updatedAt=${cacheKey}`\n : rawImageUrl;\n\n const handleImageLoad = () => {\n if (imgRef.current) {\n init(imgRef.current);\n }\n };\n\n // Map a pointer event to natural-px coordinates inside the image.\n const pointerToNatural = (event: PointerEvent | React.PointerEvent) => {\n const rect = cropAreaRef.current?.getBoundingClientRect();\n if (!rect || !naturalSize.width || !naturalSize.height) return null;\n const ratioX = naturalSize.width / rect.width;\n const ratioY = naturalSize.height / rect.height;\n return {\n x: (event.clientX - rect.left) * ratioX,\n y: (event.clientY - rect.top) * ratioY,\n };\n };\n\n // Teardown for the drag currently in flight, so it can be run both on pointer\n // release AND on unmount. Without the unmount path, closing the editor mid-drag\n // (Escape, drawer close, a re-render dropping the overlay) would never fire a\n // pointer event, leaking the window listeners and letting a stale `onMove`\n // call `setCropPosition` on an unmounted component.\n const activeDragCleanupRef = React.useRef<(() => void) | null>(null);\n\n React.useEffect(() => {\n return () => {\n activeDragCleanupRef.current?.();\n };\n }, []);\n\n // Track a pointer drag until the pointer is released or the browser cancels\n // it. The pointer is captured so the drag follows the finger even once it\n // leaves the (12px) handle it started on, and pointercancel is treated as\n // release so an interrupted touch never leaves stale window listeners.\n const trackPointerDrag = (event: React.PointerEvent, onMove: (e: PointerEvent) => void) => {\n event.preventDefault();\n event.stopPropagation();\n const { pointerId } = event;\n try {\n event.currentTarget.setPointerCapture(pointerId);\n } catch {\n // Unsupported environment (jsdom) — window listeners still track the drag.\n }\n const move = (e: PointerEvent) => {\n if (e.pointerId !== pointerId) return;\n onMove(e);\n };\n const cleanup = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', end);\n window.removeEventListener('pointercancel', end);\n activeDragCleanupRef.current = null;\n };\n const end = (e: PointerEvent) => {\n if (e.pointerId !== pointerId) return;\n cleanup();\n };\n // Only one drag is ever live at a time; tear down any previous one first.\n activeDragCleanupRef.current?.();\n activeDragCleanupRef.current = cleanup;\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', end);\n window.addEventListener('pointercancel', end);\n };\n\n // Drag the entire crop rectangle.\n const handleMovePointerDown = (event: React.PointerEvent) => {\n const start = pointerToNatural(event);\n if (!start) return;\n const startCrop = { ...crop };\n trackPointerDrag(event, (e) => {\n const next = pointerToNatural(e);\n if (!next) return;\n setCropPosition({\n x: startCrop.x + (next.x - start.x),\n y: startCrop.y + (next.y - start.y),\n });\n });\n };\n\n // Resize from a corner; the opposite corner stays anchored.\n const handleResizePointerDown = (corner: Corner) => (event: React.PointerEvent) => {\n const startCrop = { ...crop };\n const anchorX =\n corner === 'tl' || corner === 'bl' ? startCrop.x + startCrop.width : startCrop.x;\n const anchorY =\n corner === 'tl' || corner === 'tr' ? startCrop.y + startCrop.height : startCrop.y;\n trackPointerDrag(event, (e) => {\n const point = pointerToNatural(e);\n if (!point) return;\n const {\n x,\n y,\n width: w,\n height: h,\n } = resolveCornerResize({\n anchorX,\n anchorY,\n point,\n aspectRatio: aspectLocked ? aspectRatio : null,\n });\n setCropPosition({ x, y });\n setCropSize({ width: w, height: h });\n });\n };\n\n const toggleAspectLock = () => {\n setAspectLocked((locked) => {\n const next = !locked;\n setAspectRatio(next && height ? width / height : null);\n return next;\n });\n };\n\n // Drag the focal handle within the crop rectangle, clamped 0–100.\n const handleFocalPointerDown = (event: React.PointerEvent) => {\n trackPointerDrag(event, (e) => {\n const point = pointerToNatural(e);\n if (!point) return;\n // Convert pointer to a percentage of the current crop area.\n const px = ((point.x - crop.x) / crop.width) * 100;\n const py = ((point.y - crop.y) / crop.height) * 100;\n setFocal({\n x: Math.round(Math.min(100, Math.max(0, px))),\n y: Math.round(Math.min(100, Math.max(0, py))),\n });\n });\n };\n\n const focalPxX = Math.round((focal.x / 100) * width);\n const focalPxY = Math.round((focal.y / 100) * height);\n\n const setFocalPx = (axis: 'x' | 'y', value: number) => {\n const dim = axis === 'x' ? width : height;\n if (!dim) return;\n const pct = Math.min(100, Math.max(0, (value / dim) * 100));\n setFocal((prev) => ({ ...prev, [axis]: Math.round(pct) }));\n };\n\n const cropPercents =\n naturalSize.width && naturalSize.height\n ? {\n left: (crop.x / naturalSize.width) * 100,\n top: (crop.y / naturalSize.height) * 100,\n width: (crop.width / naturalSize.width) * 100,\n height: (crop.height / naturalSize.height) * 100,\n }\n : null;\n\n // The crop is only usable once the image has loaded and `init()` has seeded\n // the natural size. Until then the produce/export path would reject.\n const isReady = cropPercents !== null;\n\n const handleAction = async (action: 'apply' | 'copy') => {\n if (!isReady) return;\n\n let file: globalThis.File;\n try {\n file = await produceFile(asset.name, asset.mime ?? 'image/png', asset.updatedAt);\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.export-error'),\n defaultMessage: 'Could not process the cropped image.',\n }),\n });\n return;\n }\n\n const roundedFocal = { x: Math.round(focal.x), y: Math.round(focal.y) };\n if (action === 'apply') {\n onApply(file, roundedFocal);\n } else {\n onSaveAsCopy(file, roundedFocal);\n }\n };\n\n return (\n <Portal>\n <FocusTrap onEscape={onClose} skipAutoFocus>\n <Overlay ref={overlayRef} tabIndex={-1}>\n <HeaderBar alignItems=\"center\">\n <Crop aria-hidden />\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {formatMessage({\n id: getTranslationKey('asset-details.crop.title'),\n defaultMessage: 'Crop & Focus area',\n })}\n </Typography>\n </HeaderBar>\n\n <Body>\n <CropArea\n ref={cropAreaRef}\n $aspect={\n naturalSize.width && naturalSize.height\n ? naturalSize.width / naturalSize.height\n : undefined\n }\n >\n <img\n ref={imgRef}\n src={imageUrl}\n alt={asset.name}\n // Always anonymous, unlike AssetPreview/AssetsGrid which gate it:\n // the editor reads pixels via canvas (useCropImg -> toBlob), which\n // taints on a cross-origin image loaded without CORS, so every\n // remote image must be fetched CORS-clean.\n crossOrigin=\"anonymous\"\n onLoad={handleImageLoad}\n draggable={false}\n />\n\n {cropPercents ? (\n <CropOverlay\n style={{\n left: `${cropPercents.left}%`,\n top: `${cropPercents.top}%`,\n width: `${cropPercents.width}%`,\n height: `${cropPercents.height}%`,\n }}\n onPointerDown={handleMovePointerDown}\n >\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.top-left'),\n defaultMessage: 'Resize top-left',\n })}\n $cursor=\"nwse-resize\"\n style={{ left: 0, top: 0 }}\n onPointerDown={handleResizePointerDown('tl')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.top-right'),\n defaultMessage: 'Resize top-right',\n })}\n $cursor=\"nesw-resize\"\n style={{ right: 0, top: 0 }}\n onPointerDown={handleResizePointerDown('tr')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.bottom-left'),\n defaultMessage: 'Resize bottom-left',\n })}\n $cursor=\"nesw-resize\"\n style={{ left: 0, bottom: 0 }}\n onPointerDown={handleResizePointerDown('bl')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.bottom-right'),\n defaultMessage: 'Resize bottom-right',\n })}\n $cursor=\"nwse-resize\"\n style={{ right: 0, bottom: 0 }}\n onPointerDown={handleResizePointerDown('br')}\n />\n\n <FocalPointHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-point'),\n defaultMessage: 'Focal point',\n })}\n style={{ left: `${focal.x}%`, top: `${focal.y}%` }}\n onPointerDown={handleFocalPointerDown}\n />\n </CropOverlay>\n ) : null}\n </CropArea>\n\n <InfoBox>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1} paddingBottom={3}>\n <Typography variant=\"omega\" fontWeight=\"bold\" textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.title'),\n defaultMessage: 'Crop & Focus area',\n })}\n </Typography>\n <Typography variant=\"pi\" textColor={infoMutedColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.hint'),\n defaultMessage:\n 'Set the crop area with the rectangle. Pin the always-visible area with the circle.',\n })}\n </Typography>\n </Flex>\n\n <Flex gap={6} alignItems=\"center\">\n <Flex alignItems=\"center\" gap={2}>\n <Flex direction=\"column\" gap={2}>\n <FieldRow name=\"crop-width\" gap={2}>\n <LabelIcon textColor={infoTextColor}>\n <ArrowsHorizontal />\n </LabelIcon>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.width'),\n defaultMessage: 'Width (px)',\n })}\n value={width}\n min={1}\n max={naturalSize.width || undefined}\n onValueChange={(next) => {\n if (next !== undefined) setCropSize({ width: next });\n }}\n />\n </FieldRow>\n <FieldRow name=\"crop-height\" gap={2}>\n <LabelIcon textColor={infoTextColor}>\n <ArrowsVertical />\n </LabelIcon>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.height'),\n defaultMessage: 'Height (px)',\n })}\n value={height}\n min={1}\n max={naturalSize.height || undefined}\n onValueChange={(next) => {\n if (next !== undefined) setCropSize({ height: next });\n }}\n />\n </FieldRow>\n </Flex>\n\n <Flex position=\"relative\">\n <IconButton\n label={formatMessage({\n id: getTranslationKey('asset-details.crop.aspect-lock'),\n defaultMessage: 'Lock aspect ratio',\n })}\n variant={aspectLocked ? 'secondary' : 'ghost'}\n onClick={toggleAspectLock}\n >\n <Link />\n </IconButton>\n <BackgroundPreserveRatio />\n </Flex>\n </Flex>\n\n <Flex direction=\"column\" gap={2} marginLeft={'auto'}>\n <FieldRow name=\"focal-x\" gap={2}>\n <Field.Label textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.focal-x-axis'),\n defaultMessage: 'X',\n })}\n </Field.Label>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-x'),\n defaultMessage: 'Focal point X (px)',\n })}\n value={focalPxX}\n onValueChange={(next) => {\n if (next !== undefined) setFocalPx('x', next);\n }}\n />\n </FieldRow>\n <FieldRow name=\"focal-y\" gap={2}>\n <Field.Label textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.focal-y-axis'),\n defaultMessage: 'Y',\n })}\n </Field.Label>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-y'),\n defaultMessage: 'Focal point Y (px)',\n })}\n value={focalPxY}\n onValueChange={(next) => {\n if (next !== undefined) setFocalPx('y', next);\n }}\n />\n </FieldRow>\n </Flex>\n </Flex>\n </InfoBox>\n </Body>\n\n <FooterBar alignItems=\"center\">\n <Button variant=\"tertiary\" onClick={onClose} disabled={isBusy}>\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n <Flex gap={2}>\n {canSaveAsCopy && (\n <Button\n variant=\"secondary\"\n onClick={() => handleAction('copy')}\n loading={isBusy}\n disabled={!isReady}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.crop.save-as-copy'),\n defaultMessage: 'Save as copy',\n })}\n </Button>\n )}\n <Button\n variant=\"default\"\n onClick={() => handleAction('apply')}\n loading={isBusy}\n disabled={!isReady}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.crop.apply'),\n defaultMessage: 'Apply',\n })}\n </Button>\n </Flex>\n </FooterBar>\n </Overlay>\n </FocusTrap>\n </Portal>\n );\n};\n"],"names":["FOCAL_DIAMETER_REM","HANDLE_PX","Overlay","styled","Flex","theme","spaces","borderRadius","colors","neutral150","neutral0","HeaderBar","Body","Box","neutral100","CropArea","div","$aspect","CropOverlay","primary600","ResizeHandle","button","$cursor","FocalPointHandle","neutral800","InfoBox","breakpoints","medium","colorScheme","neutral900","FooterBar","FieldRow","Field","Root","FieldNumberInput","NumberInput","LabelIcon","Label","BackgroundPreserveRatioContainer","BackgroundPreserveRatio","_jsx","svg","width","height","viewBox","fill","xmlns","path","d","stroke","strokeLinecap","AssetCropEditor","asset","isBusy","onClose","onApply","onSaveAsCopy","canSaveAsCopy","formatMessage","useIntl","toggleNotification","useNotification","useTheme","isDark","infoTextColor","infoMutedColor","imgRef","React","useRef","cropAreaRef","overlayRef","useEffect","current","focus","init","crop","naturalSize","aspectRatio","setCropSize","setCropPosition","setAspectRatio","produceFile","useCropImg","aspectLocked","setAspectLocked","useState","focal","setFocal","focalPoint","x","y","rawImageUrl","prefixFileUrlWithBackendUrl","url","cacheKey","updatedAt","isUrlSigned","Date","getTime","undefined","imageUrl","includes","handleImageLoad","pointerToNatural","event","rect","getBoundingClientRect","ratioX","ratioY","clientX","left","clientY","top","activeDragCleanupRef","trackPointerDrag","onMove","preventDefault","stopPropagation","pointerId","currentTarget","setPointerCapture","move","e","cleanup","window","removeEventListener","end","addEventListener","handleMovePointerDown","start","startCrop","next","handleResizePointerDown","corner","anchorX","anchorY","point","w","h","resolveCornerResize","toggleAspectLock","locked","handleFocalPointerDown","px","py","Math","round","min","max","focalPxX","focalPxY","setFocalPx","axis","value","dim","pct","prev","cropPercents","isReady","handleAction","action","file","name","mime","type","message","id","getTranslationKey","defaultMessage","roundedFocal","Portal","FocusTrap","onEscape","skipAutoFocus","_jsxs","ref","tabIndex","alignItems","Crop","aria-hidden","Typography","variant","fontWeight","img","src","alt","crossOrigin","onLoad","draggable","style","onPointerDown","aria-label","right","bottom","direction","gap","paddingBottom","textColor","ArrowsHorizontal","onValueChange","ArrowsVertical","position","IconButton","label","onClick","Link","marginLeft","Button","disabled","loading"],"mappings":"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"}
|