@strapi/upload 5.49.0 → 5.50.1
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/ai/components/AIAssetCard.js +10 -10
- package/dist/admin/ai/components/AIAssetCard.js.map +1 -1
- package/dist/admin/ai/components/AIAssetCard.mjs +11 -11
- package/dist/admin/ai/components/AIAssetCard.mjs.map +1 -1
- package/dist/admin/ai/components/AIUploadModal.js +0 -1
- package/dist/admin/ai/components/AIUploadModal.js.map +1 -1
- package/dist/admin/ai/components/AIUploadModal.mjs +0 -1
- package/dist/admin/ai/components/AIUploadModal.mjs.map +1 -1
- package/dist/admin/components/AssetCard/AssetCard.js +3 -4
- package/dist/admin/components/AssetCard/AssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/AssetCard.mjs +4 -5
- package/dist/admin/components/AssetCard/AssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/AssetCardBase.js +0 -1
- package/dist/admin/components/AssetCard/AssetCardBase.js.map +1 -1
- package/dist/admin/components/AssetCard/AssetCardBase.mjs +0 -1
- package/dist/admin/components/AssetCard/AssetCardBase.mjs.map +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.js +0 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.mjs +0 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/UploadingAssetCard.js +3 -4
- package/dist/admin/components/AssetCard/UploadingAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/UploadingAssetCard.mjs +4 -5
- package/dist/admin/components/AssetCard/UploadingAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.js +0 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.mjs +0 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.js +0 -1
- package/dist/admin/components/AssetDialog/AssetDialog.js.map +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.mjs +0 -1
- package/dist/admin/components/AssetDialog/AssetDialog.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js +0 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs +0 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.js +0 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.mjs +0 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js +0 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs +0 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.js +0 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.js.map +1 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.mjs +0 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.mjs.map +1 -1
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.js +0 -1
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.js.map +1 -1
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs +0 -1
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs.map +1 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js +0 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js.map +1 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.mjs +0 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.mjs.map +1 -1
- package/dist/admin/components/CopyLinkButton/CopyLinkButton.js +0 -1
- package/dist/admin/components/CopyLinkButton/CopyLinkButton.js.map +1 -1
- package/dist/admin/components/CopyLinkButton/CopyLinkButton.mjs +0 -1
- package/dist/admin/components/CopyLinkButton/CopyLinkButton.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js +0 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs +0 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js +3 -3
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs +4 -4
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.js +0 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.mjs +0 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.js +0 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.mjs +0 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js +2 -3
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs +3 -4
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js +0 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs +0 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs.map +1 -1
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.js +0 -1
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.js.map +1 -1
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.mjs +0 -1
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.mjs.map +1 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.js +0 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.js.map +1 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.mjs +0 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js +3 -4
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs +4 -5
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.js +0 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.mjs +0 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js +2 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.mjs +2 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js +1 -2
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs +2 -3
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +2 -2
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +2 -2
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
- package/dist/admin/components/SortPicker/SortPicker.js +0 -1
- package/dist/admin/components/SortPicker/SortPicker.js.map +1 -1
- package/dist/admin/components/SortPicker/SortPicker.mjs +0 -1
- package/dist/admin/components/SortPicker/SortPicker.mjs.map +1 -1
- package/dist/admin/components/TableList/CellContent.js +0 -1
- package/dist/admin/components/TableList/CellContent.js.map +1 -1
- package/dist/admin/components/TableList/CellContent.mjs +0 -1
- package/dist/admin/components/TableList/CellContent.mjs.map +1 -1
- package/dist/admin/components/TableList/PreviewCell.js +3 -4
- package/dist/admin/components/TableList/PreviewCell.js.map +1 -1
- package/dist/admin/components/TableList/PreviewCell.mjs +4 -5
- package/dist/admin/components/TableList/PreviewCell.mjs.map +1 -1
- package/dist/admin/components/TableList/TableList.js +0 -1
- package/dist/admin/components/TableList/TableList.js.map +1 -1
- package/dist/admin/components/TableList/TableList.mjs +0 -1
- package/dist/admin/components/TableList/TableList.mjs.map +1 -1
- package/dist/admin/components/TableList/TableRows.js +0 -1
- package/dist/admin/components/TableList/TableRows.js.map +1 -1
- package/dist/admin/components/TableList/TableRows.mjs +0 -1
- package/dist/admin/components/TableList/TableRows.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.js +0 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.mjs +0 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js +2 -3
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs +3 -4
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +0 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +0 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js +0 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.mjs +0 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.mjs.map +1 -1
- package/dist/admin/constants.js +4 -7
- package/dist/admin/constants.js.map +1 -1
- package/dist/admin/constants.mjs +4 -7
- package/dist/admin/constants.mjs.map +1 -1
- package/dist/admin/enums.js +14 -16
- package/dist/admin/enums.js.map +1 -1
- package/dist/admin/enums.mjs +13 -15
- package/dist/admin/enums.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.js +125 -122
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +125 -122
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +700 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +678 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +134 -17
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +137 -20
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js +27 -5
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs +27 -5
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/useCropImg.js +211 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/useCropImg.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/useCropImg.mjs +188 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/useCropImg.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +50 -5
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +51 -6
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +43 -4
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +44 -5
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +195 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +192 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js +37 -0
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs +35 -0
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.js +18 -0
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.mjs +13 -0
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +97 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +94 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js +13 -4
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.mjs +13 -4
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js +6 -3
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +6 -3
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
- package/dist/admin/future/services/api.js +37 -1
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +37 -2
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/folders.js +36 -5
- package/dist/admin/future/services/folders.js.map +1 -1
- package/dist/admin/future/services/folders.mjs +36 -6
- package/dist/admin/future/services/folders.mjs.map +1 -1
- package/dist/admin/future/utils/buildBulkMovePayload.js +20 -0
- package/dist/admin/future/utils/buildBulkMovePayload.js.map +1 -0
- package/dist/admin/future/utils/buildBulkMovePayload.mjs +18 -0
- package/dist/admin/future/utils/buildBulkMovePayload.mjs.map +1 -0
- package/dist/admin/future/utils/canDropItemOnFolder.js +64 -0
- package/dist/admin/future/utils/canDropItemOnFolder.js.map +1 -0
- package/dist/admin/future/utils/canDropItemOnFolder.mjs +61 -0
- package/dist/admin/future/utils/canDropItemOnFolder.mjs.map +1 -0
- package/dist/admin/future/utils/getAssetIcon.js +4 -4
- package/dist/admin/future/utils/getAssetIcon.js.map +1 -1
- package/dist/admin/future/utils/getAssetIcon.mjs +4 -4
- package/dist/admin/future/utils/getAssetIcon.mjs.map +1 -1
- package/dist/admin/future/utils/getBulkMoveErrorMessage.js +23 -0
- package/dist/admin/future/utils/getBulkMoveErrorMessage.js.map +1 -0
- package/dist/admin/future/utils/getBulkMoveErrorMessage.mjs +21 -0
- package/dist/admin/future/utils/getBulkMoveErrorMessage.mjs.map +1 -0
- package/dist/admin/hooks/useAIMetadataJob.js +0 -1
- package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
- package/dist/admin/hooks/useAIMetadataJob.mjs +0 -1
- package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
- package/dist/admin/hooks/useAssets.js.map +1 -1
- package/dist/admin/hooks/useAssets.mjs.map +1 -1
- package/dist/admin/hooks/useBulkEdit.js +0 -1
- package/dist/admin/hooks/useBulkEdit.js.map +1 -1
- package/dist/admin/hooks/useBulkEdit.mjs +0 -1
- package/dist/admin/hooks/useBulkEdit.mjs.map +1 -1
- package/dist/admin/hooks/useBulkMove.js +0 -1
- package/dist/admin/hooks/useBulkMove.js.map +1 -1
- package/dist/admin/hooks/useBulkMove.mjs +0 -1
- package/dist/admin/hooks/useBulkMove.mjs.map +1 -1
- package/dist/admin/hooks/useBulkRemove.js +0 -1
- package/dist/admin/hooks/useBulkRemove.js.map +1 -1
- package/dist/admin/hooks/useBulkRemove.mjs +0 -1
- package/dist/admin/hooks/useBulkRemove.mjs.map +1 -1
- package/dist/admin/hooks/useEditAsset.js +0 -1
- package/dist/admin/hooks/useEditAsset.js.map +1 -1
- package/dist/admin/hooks/useEditAsset.mjs +0 -1
- package/dist/admin/hooks/useEditAsset.mjs.map +1 -1
- package/dist/admin/hooks/useEditFolder.js +4 -3
- package/dist/admin/hooks/useEditFolder.js.map +1 -1
- package/dist/admin/hooks/useEditFolder.mjs +4 -3
- package/dist/admin/hooks/useEditFolder.mjs.map +1 -1
- package/dist/admin/hooks/useFolder.js +0 -1
- package/dist/admin/hooks/useFolder.js.map +1 -1
- package/dist/admin/hooks/useFolder.mjs +0 -1
- package/dist/admin/hooks/useFolder.mjs.map +1 -1
- package/dist/admin/hooks/useFolderStructure.js +0 -1
- package/dist/admin/hooks/useFolderStructure.js.map +1 -1
- package/dist/admin/hooks/useFolderStructure.mjs +0 -1
- package/dist/admin/hooks/useFolderStructure.mjs.map +1 -1
- package/dist/admin/hooks/useUpload.js.map +1 -1
- package/dist/admin/hooks/useUpload.mjs.map +1 -1
- package/dist/admin/index.js +0 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +0 -1
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/pages/App/App.js +0 -1
- package/dist/admin/pages/App/App.js.map +1 -1
- package/dist/admin/pages/App/App.mjs +0 -1
- package/dist/admin/pages/App/App.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js +0 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs +0 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.js +0 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.mjs +0 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.mjs.map +1 -1
- package/dist/admin/pages/App/MediaLibrary.js +0 -1
- package/dist/admin/pages/App/MediaLibrary.js.map +1 -1
- package/dist/admin/pages/App/MediaLibrary.mjs +0 -1
- package/dist/admin/pages/App/MediaLibrary.mjs.map +1 -1
- package/dist/admin/pages/App/components/BulkActions.js +0 -1
- package/dist/admin/pages/App/components/BulkActions.js.map +1 -1
- package/dist/admin/pages/App/components/BulkActions.mjs +0 -1
- package/dist/admin/pages/App/components/BulkActions.mjs.map +1 -1
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.js +0 -1
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.js.map +1 -1
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.mjs +0 -1
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.mjs.map +1 -1
- package/dist/admin/pages/App/components/Filters.js +0 -1
- package/dist/admin/pages/App/components/Filters.js.map +1 -1
- package/dist/admin/pages/App/components/Filters.mjs +0 -1
- package/dist/admin/pages/App/components/Filters.mjs.map +1 -1
- package/dist/admin/pages/App/components/Header.js +0 -1
- package/dist/admin/pages/App/components/Header.js.map +1 -1
- package/dist/admin/pages/App/components/Header.mjs +0 -1
- package/dist/admin/pages/App/components/Header.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js +1 -2
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs +1 -2
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
- package/dist/admin/src/components/EditAssetDialog/PreviewBox/PreviewComponents.d.ts +11 -12
- package/dist/admin/src/components/EmptyAssets/EmptyAssets.d.ts +0 -1
- package/dist/admin/src/components/FolderCard/contexts/FolderCard.d.ts +2 -3
- package/dist/admin/src/constants.d.ts +5 -4
- package/dist/admin/src/enums.d.ts +14 -12
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.d.ts +10 -0
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/useCropImg.d.ts +48 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +12 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/DragOverlayChip.d.ts +6 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/dndIds.d.ts +4 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +51 -0
- package/dist/admin/src/future/services/api.d.ts +24 -6
- package/dist/admin/src/future/services/assets.d.ts +1 -1
- package/dist/admin/src/future/services/folders.d.ts +12 -2
- package/dist/admin/src/future/services/settings.d.ts +1 -1
- package/dist/admin/src/future/store/uploadProgress.d.ts +1 -1
- package/dist/admin/src/future/types/dnd.d.ts +22 -0
- package/dist/admin/src/future/utils/buildBulkMovePayload.d.ts +2 -0
- package/dist/admin/src/future/utils/canDropItemOnFolder.d.ts +9 -0
- package/dist/admin/src/future/utils/getBulkMoveErrorMessage.d.ts +1 -0
- package/dist/admin/src/hooks/useAIMetadataJob.d.ts +1 -1
- package/dist/admin/src/hooks/useBulkEdit.d.ts +14 -14
- package/dist/admin/src/hooks/useBulkMove.d.ts +146 -15
- package/dist/admin/src/hooks/useBulkRemove.d.ts +186 -15
- package/dist/admin/src/hooks/useCropImg.d.ts +2 -2
- package/dist/admin/src/hooks/useEditFolder.d.ts +7 -6
- package/dist/admin/src/hooks/useModalQueryParams.d.ts +5 -5
- package/dist/admin/src/hooks/usePersistentState.d.ts +0 -1
- package/dist/admin/src/hooks/useSettings.d.ts +5 -5
- package/dist/admin/src/hooks/useTracking.d.ts +1 -1
- package/dist/admin/src/pages/App/ConfigureTheView/state/actions.d.ts +1 -1
- package/dist/admin/src/pages/App/ConfigureTheView/state/init.d.ts +1 -1
- package/dist/admin/src/utils/getBreadcrumbDataML.d.ts +1 -1
- package/dist/admin/src/utils/getFolderParents.d.ts +3 -3
- package/dist/admin/src/utils/icons.d.ts +2 -1
- package/dist/admin/src/utils/rawFileToAsset.d.ts +1 -1
- package/dist/admin/src/utils/urlsToAssets.d.ts +2 -10
- package/dist/admin/translations/en.json.js +28 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +28 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/translations/ja.json.js +175 -0
- package/dist/admin/translations/ja.json.js.map +1 -1
- package/dist/admin/translations/ja.json.mjs +175 -0
- package/dist/admin/translations/ja.json.mjs.map +1 -1
- package/dist/admin/translations/pl.json.js +54 -29
- package/dist/admin/translations/pl.json.js.map +1 -1
- package/dist/admin/translations/pl.json.mjs +54 -29
- package/dist/admin/translations/pl.json.mjs.map +1 -1
- package/dist/admin/utils/icons.js +5 -5
- package/dist/admin/utils/icons.js.map +1 -1
- package/dist/admin/utils/icons.mjs +6 -6
- package/dist/admin/utils/icons.mjs.map +1 -1
- package/dist/admin/utils/typeFromMime.js +9 -9
- package/dist/admin/utils/typeFromMime.js.map +1 -1
- package/dist/admin/utils/typeFromMime.mjs +10 -10
- package/dist/admin/utils/typeFromMime.mjs.map +1 -1
- package/dist/admin/utils/urlsToAssets.js +1 -2
- package/dist/admin/utils/urlsToAssets.js.map +1 -1
- package/dist/admin/utils/urlsToAssets.mjs +1 -2
- package/dist/admin/utils/urlsToAssets.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +3 -2
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +3 -2
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/controllers/content-api.js +6 -5
- package/dist/server/controllers/content-api.js.map +1 -1
- package/dist/server/controllers/content-api.mjs +6 -5
- package/dist/server/controllers/content-api.mjs.map +1 -1
- package/dist/server/src/controllers/admin-file.d.ts +4 -12
- package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-folder.d.ts +2 -2
- package/dist/server/src/controllers/admin-settings.d.ts +2 -2
- package/dist/server/src/controllers/admin-upload.d.ts +3 -3
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/content-api.d.ts +2 -2
- package/dist/server/src/controllers/content-api.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +14 -23
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/find-entity-and-check-permissions.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/folders.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/configureView.d.ts +1 -1
- package/dist/server/src/controllers/validation/admin/folder-file.d.ts +1 -1
- package/dist/server/src/controllers/validation/admin/folder-file.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/folder.d.ts +2 -2
- package/dist/server/src/controllers/validation/admin/folder.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
- package/dist/server/src/controllers/validation/admin/upload.d.ts +1 -1
- package/dist/server/src/controllers/validation/admin/upload.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/utils.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/content-api/upload.d.ts.map +1 -1
- package/dist/server/src/controllers/view-configuration.d.ts +1 -1
- package/dist/server/src/graphql.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +36 -53
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/middlewares/upload.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata-jobs.d.ts +1 -1
- package/dist/server/src/services/ai-metadata-jobs.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
- package/dist/server/src/services/extensions/utils.d.ts.map +1 -1
- package/dist/server/src/services/file.d.ts +2 -2
- package/dist/server/src/services/file.d.ts.map +1 -1
- package/dist/server/src/services/folder.d.ts +1 -1
- package/dist/server/src/services/folder.d.ts.map +1 -1
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +22 -30
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/metrics.d.ts.map +1 -1
- package/dist/server/src/services/provider.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts +1 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/dist/server/src/services/weekly-metrics.d.ts.map +1 -1
- package/dist/server/src/types.d.ts +4 -3
- package/dist/server/src/types.d.ts.map +1 -1
- package/dist/server/src/utils/cron.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/server/src/utils/mime-validation.d.ts.map +1 -1
- package/dist/server/utils/mime-validation.js +3 -1
- package/dist/server/utils/mime-validation.js.map +1 -1
- package/dist/server/utils/mime-validation.mjs +3 -1
- package/dist/server/utils/mime-validation.mjs.map +1 -1
- package/package.json +11 -10
- package/dist/admin/future/enums.js +0 -12
- package/dist/admin/future/enums.js.map +0 -1
- package/dist/admin/future/enums.mjs +0 -10
- package/dist/admin/future/enums.mjs.map +0 -1
- package/dist/admin/src/future/enums.d.ts +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetPreview.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/AssetPreview.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Flex, Loader, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { AssetType } from '../../../../enums';\nimport { prefixFileUrlWithBackendUrl } from '../../../../utils/files';\nimport { getAssetIcon } from '../../../../utils/getAssetIcon';\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport type {\n File,\n AssetWithPopulatedCreatedBy,\n} from '../../../../../../../shared/contracts/files';\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n aspect-ratio: 16 / 9;\n max-height: 24rem;\n overflow: hidden;\n border-radius: ${({ theme }) => theme.borderRadius};\n padding: ${({ theme }) => theme.spaces[3]};\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst AssetContainer = styled(Flex)`\n justify-content: center;\n position: relative;\n z-index: 2;\n width: 100%;\n height: 100%;\n`;\n\nconst StyledImage = styled.img`\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n`;\n\n/**\n * Top-right overlay slot for image actions (crop / rotate). Sits above the\n * image (z-index 3 > AssetContainer 2) so the buttons stay clickable.\n */\nconst ActionsOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n right: ${({ theme }) => theme.spaces[3]};\n z-index: 3;\n`;\n\nconst StyledVideo = styled.video`\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n`;\n\nconst StyledAudio = styled.audio`\n width: 100%;\n`;\n\nconst StyledPdfIframe = styled.iframe`\n width: 100%;\n height: 100%;\n min-height: 200px;\n border: none;\n`;\n\nconst IconFallback = styled(Flex)`\n height: 100%;\n aspect-ratio: 1;\n width: auto;\n max-width: 100%;\n margin: 0 auto;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral150};\n`;\n\nconst LoaderOverlay = styled(Flex)`\n position: absolute;\n inset: 0;\n z-index: 1;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * AssetLoader\n * -----------------------------------------------------------------------------------------------*/\n\nconst AssetLoader = () => {\n const { formatMessage } = useIntl();\n return (\n <LoaderOverlay justifyContent=\"center\" alignItems=\"center\">\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </LoaderOverlay>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreviewContent\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetPreviewProps {\n asset: File | AssetWithPopulatedCreatedBy;\n actions?: React.ReactNode;\n isLoading?: boolean;\n}\n\nexport const AssetPreview = ({ asset, actions, isLoading = false }: AssetPreviewProps) => {\n const { formatMessage } = useIntl();\n const { alternativeText, ext, mime, url, updatedAt } = asset;\n // Append the asset's `updatedAt` as a cache-buster so a freshly replaced\n // file (often served at the same URL) shows the new content instead of the\n // browser-cached old version.\n const cacheKey = updatedAt ? new Date(updatedAt).getTime() : undefined;\n const appendCacheBuster = (raw: string | undefined) => {\n if (!raw || cacheKey === undefined) return raw;\n return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;\n };\n const mediaUrl = appendCacheBuster(prefixFileUrlWithBackendUrl(url));\n\n const [isMediaLoaded, setIsMediaLoaded] = React.useState(false);\n React.useEffect(() => {\n setIsMediaLoaded(false);\n }, [mediaUrl]);\n\n if (mime?.includes(AssetType.Image)) {\n const imageUrl = appendCacheBuster(prefixFileUrlWithBackendUrl(url));\n\n if (imageUrl) {\n return (\n <PreviewContainer>\n {(!isMediaLoaded || isLoading) && <AssetLoader />}\n {actions ? <ActionsOverlay>{actions}</ActionsOverlay> : null}\n <AssetContainer>\n <StyledImage\n src={imageUrl}\n alt={alternativeText || asset.name || ''}\n onLoad={() => setIsMediaLoaded(true)}\n onError={() => setIsMediaLoaded(true)}\n />\n </AssetContainer>\n </PreviewContainer>\n );\n }\n }\n\n if (mime?.includes(AssetType.Video) && mediaUrl) {\n return (\n <PreviewContainer>\n {!isMediaLoaded && <AssetLoader />}\n <AssetContainer>\n <StyledVideo\n src={mediaUrl}\n controls\n title={asset.name}\n onLoadedData={() => setIsMediaLoaded(true)}\n onError={() => setIsMediaLoaded(true)}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.videoNotSupported'),\n defaultMessage: 'Your browser does not support the video tag.',\n })}\n </StyledVideo>\n </AssetContainer>\n </PreviewContainer>\n );\n }\n\n if (mime?.includes(AssetType.Audio) && mediaUrl) {\n return (\n <PreviewContainer>\n {!isMediaLoaded && <AssetLoader />}\n <AssetContainer>\n <Flex\n width=\"100%\"\n padding={4}\n justifyContent=\"center\"\n alignItems=\"center\"\n height=\"100%\"\n minHeight=\"12rem\"\n >\n <StyledAudio\n src={mediaUrl}\n controls\n onLoadedData={() => setIsMediaLoaded(true)}\n onError={() => setIsMediaLoaded(true)}\n />\n </Flex>\n </AssetContainer>\n </PreviewContainer>\n );\n }\n\n const isPdf =\n ext?.toLowerCase() === 'pdf' || ext?.toLowerCase() === '.pdf' || mime === 'application/pdf';\n if (isPdf && mediaUrl) {\n return (\n <PreviewContainer>\n {!isMediaLoaded && <AssetLoader />}\n <AssetContainer>\n <StyledPdfIframe\n src={`${mediaUrl}#toolbar=0`}\n title={asset.name}\n onLoad={() => setIsMediaLoaded(true)}\n />\n </AssetContainer>\n </PreviewContainer>\n );\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n return (\n <PreviewContainer>\n <IconFallback\n justifyContent=\"center\"\n alignItems=\"center\"\n gap={1}\n direction=\"column\"\n hasRadius\n >\n <DocIcon width={24} height={24} />\n <Typography variant=\"pi\">\n {formatMessage({\n id: getTranslationKey('asset-details.noPreview'),\n defaultMessage: 'No preview available',\n })}\n </Typography>\n </IconFallback>\n </PreviewContainer>\n );\n};\n"],"names":["PreviewContainer","styled","Box","theme","borderRadius","spaces","colors","neutral100","AssetContainer","Flex","StyledImage","img","ActionsOverlay","StyledVideo","video","StyledAudio","audio","StyledPdfIframe","iframe","IconFallback","neutral500","neutral150","LoaderOverlay","AssetLoader","formatMessage","useIntl","_jsx","justifyContent","alignItems","Loader","id","defaultMessage","AssetPreview","asset","actions","isLoading","alternativeText","ext","mime","url","updatedAt","cacheKey","Date","getTime","undefined","appendCacheBuster","raw","includes","mediaUrl","prefixFileUrlWithBackendUrl","isMediaLoaded","setIsMediaLoaded","React","useState","useEffect","AssetType","Image","imageUrl","_jsxs","src","alt","name","onLoad","onError","Video","controls","title","onLoadedData","getTranslationKey","Audio","width","padding","height","minHeight","isPdf","toLowerCase","DocIcon","getAssetIcon","gap","direction","hasRadius","Typography","variant"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetPreview.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/AssetPreview.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Flex, Loader, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../../../../enums';\nimport { prefixFileUrlWithBackendUrl } from '../../../../utils/files';\nimport { getAssetIcon } from '../../../../utils/getAssetIcon';\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport type {\n File,\n AssetWithPopulatedCreatedBy,\n} from '../../../../../../../shared/contracts/files';\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n aspect-ratio: 16 / 9;\n max-height: 24rem;\n overflow: hidden;\n border-radius: ${({ theme }) => theme.borderRadius};\n padding: ${({ theme }) => theme.spaces[3]};\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst AssetContainer = styled(Flex)`\n justify-content: center;\n position: relative;\n z-index: 2;\n width: 100%;\n height: 100%;\n`;\n\nconst StyledImage = styled.img`\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n`;\n\n/**\n * Top-right overlay slot for image actions (crop). Sits above the\n * image (z-index 3 > AssetContainer 2) so the buttons stay clickable.\n */\nconst ActionsOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n right: ${({ theme }) => theme.spaces[3]};\n z-index: 3;\n`;\n\nconst StyledVideo = styled.video`\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n`;\n\nconst StyledAudio = styled.audio`\n width: 100%;\n`;\n\nconst StyledPdfIframe = styled.iframe`\n width: 100%;\n height: 100%;\n min-height: 200px;\n border: none;\n`;\n\nconst IconFallback = styled(Flex)`\n height: 100%;\n aspect-ratio: 1;\n width: auto;\n max-width: 100%;\n margin: 0 auto;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral150};\n`;\n\nconst LoaderOverlay = styled(Flex)`\n position: absolute;\n inset: 0;\n z-index: 1;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * AssetLoader\n * -----------------------------------------------------------------------------------------------*/\n\nconst AssetLoader = () => {\n const { formatMessage } = useIntl();\n return (\n <LoaderOverlay justifyContent=\"center\" alignItems=\"center\">\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </LoaderOverlay>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreviewContent\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetPreviewProps {\n asset: File | AssetWithPopulatedCreatedBy;\n actions?: React.ReactNode;\n isLoading?: boolean;\n}\n\nexport const AssetPreview = ({ asset, actions, isLoading = false }: AssetPreviewProps) => {\n const { formatMessage } = useIntl();\n const { alternativeText, ext, mime, url, updatedAt } = asset;\n // Append the asset's `updatedAt` as a cache-buster so a freshly replaced\n // file (often served at the same URL) shows the new content instead of the\n // browser-cached old version.\n const cacheKey = updatedAt ? new Date(updatedAt).getTime() : undefined;\n const appendCacheBuster = (raw: string | undefined) => {\n if (!raw || cacheKey === undefined) return raw;\n return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;\n };\n const mediaUrl = appendCacheBuster(prefixFileUrlWithBackendUrl(url));\n\n const [isMediaLoaded, setIsMediaLoaded] = React.useState(false);\n React.useEffect(() => {\n setIsMediaLoaded(false);\n }, [mediaUrl]);\n\n const imageRef = React.useRef<HTMLImageElement>(null);\n React.useEffect(() => {\n const image = imageRef.current;\n if (!image) return;\n const recompute = () => {\n const parent = image.parentElement;\n if (!parent) return;\n const c = parent.getBoundingClientRect();\n // offsetWidth/Height = pre-transform layout box (transforms ignored).\n const w = image.offsetWidth;\n const h = image.offsetHeight;\n if (!w || !h || !c.width || !c.height) return;\n };\n recompute();\n const ro = new ResizeObserver(recompute);\n ro.observe(image);\n if (image.parentElement) ro.observe(image.parentElement);\n return () => ro.disconnect();\n }, [isMediaLoaded]);\n\n if (mime?.includes(ASSET_TYPES.Image)) {\n const imageUrl = appendCacheBuster(prefixFileUrlWithBackendUrl(url));\n\n if (imageUrl) {\n return (\n <PreviewContainer>\n {(!isMediaLoaded || isLoading) && <AssetLoader />}\n {actions ? <ActionsOverlay>{actions}</ActionsOverlay> : null}\n <AssetContainer>\n <StyledImage\n ref={imageRef}\n src={imageUrl}\n alt={alternativeText || asset.name || ''}\n onLoad={() => setIsMediaLoaded(true)}\n onError={() => setIsMediaLoaded(true)}\n />\n </AssetContainer>\n </PreviewContainer>\n );\n }\n }\n\n if (mime?.includes(ASSET_TYPES.Video) && mediaUrl) {\n return (\n <PreviewContainer>\n {!isMediaLoaded && <AssetLoader />}\n <AssetContainer>\n <StyledVideo\n src={mediaUrl}\n controls\n title={asset.name}\n onLoadedData={() => setIsMediaLoaded(true)}\n onError={() => setIsMediaLoaded(true)}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.videoNotSupported'),\n defaultMessage: 'Your browser does not support the video tag.',\n })}\n </StyledVideo>\n </AssetContainer>\n </PreviewContainer>\n );\n }\n\n if (mime?.includes(ASSET_TYPES.Audio) && mediaUrl) {\n return (\n <PreviewContainer>\n {!isMediaLoaded && <AssetLoader />}\n <AssetContainer>\n <Flex\n width=\"100%\"\n padding={4}\n justifyContent=\"center\"\n alignItems=\"center\"\n height=\"100%\"\n minHeight=\"12rem\"\n >\n <StyledAudio\n src={mediaUrl}\n controls\n onLoadedData={() => setIsMediaLoaded(true)}\n onError={() => setIsMediaLoaded(true)}\n />\n </Flex>\n </AssetContainer>\n </PreviewContainer>\n );\n }\n\n const isPdf =\n ext?.toLowerCase() === 'pdf' || ext?.toLowerCase() === '.pdf' || mime === 'application/pdf';\n if (isPdf && mediaUrl) {\n return (\n <PreviewContainer>\n {!isMediaLoaded && <AssetLoader />}\n <AssetContainer>\n <StyledPdfIframe\n src={`${mediaUrl}#toolbar=0`}\n title={asset.name}\n onLoad={() => setIsMediaLoaded(true)}\n />\n </AssetContainer>\n </PreviewContainer>\n );\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n return (\n <PreviewContainer>\n <IconFallback\n justifyContent=\"center\"\n alignItems=\"center\"\n gap={1}\n direction=\"column\"\n hasRadius\n >\n <DocIcon width={24} height={24} />\n <Typography variant=\"pi\">\n {formatMessage({\n id: getTranslationKey('asset-details.noPreview'),\n defaultMessage: 'No preview available',\n })}\n </Typography>\n </IconFallback>\n </PreviewContainer>\n );\n};\n"],"names":["PreviewContainer","styled","Box","theme","borderRadius","spaces","colors","neutral100","AssetContainer","Flex","StyledImage","img","ActionsOverlay","StyledVideo","video","StyledAudio","audio","StyledPdfIframe","iframe","IconFallback","neutral500","neutral150","LoaderOverlay","AssetLoader","formatMessage","useIntl","_jsx","justifyContent","alignItems","Loader","id","defaultMessage","AssetPreview","asset","actions","isLoading","alternativeText","ext","mime","url","updatedAt","cacheKey","Date","getTime","undefined","appendCacheBuster","raw","includes","mediaUrl","prefixFileUrlWithBackendUrl","isMediaLoaded","setIsMediaLoaded","React","useState","useEffect","imageRef","useRef","image","current","recompute","parent","parentElement","c","getBoundingClientRect","w","offsetWidth","h","offsetHeight","width","height","ro","ResizeObserver","observe","disconnect","ASSET_TYPES","Image","imageUrl","_jsxs","ref","src","alt","name","onLoad","onError","Video","controls","title","onLoadedData","getTranslationKey","Audio","padding","minHeight","isPdf","toLowerCase","DocIcon","getAssetIcon","gap","direction","hasRadius","Typography","variant"],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
function _interopNamespace(e) {
|
|
6
|
+
if (e && e.__esModule) return e;
|
|
7
|
+
var n = Object.create(null);
|
|
8
|
+
if (e) {
|
|
9
|
+
Object.keys(e).forEach(function (k) {
|
|
10
|
+
if (k !== 'default') {
|
|
11
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
12
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return e[k]; }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
n.default = e;
|
|
20
|
+
return Object.freeze(n);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
24
|
+
|
|
25
|
+
const QUALITY = 1;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a corner-resize drag into a crop rect, keeping the opposite corner
|
|
28
|
+
* (`anchor`) fixed. When `aspectRatio` is set, one dimension is snapped to the
|
|
29
|
+
* ratio first (driven by whichever axis the pointer pushed furthest), then the
|
|
30
|
+
* position is derived from the anchor — so a locked resize never drifts the
|
|
31
|
+
* anchored corner. Pure (no clamping to image bounds; the caller clamps).
|
|
32
|
+
*/ const resolveCornerResize = ({ anchorX, anchorY, point, aspectRatio })=>{
|
|
33
|
+
let width = Math.abs(point.x - anchorX);
|
|
34
|
+
let height = Math.abs(point.y - anchorY);
|
|
35
|
+
if (aspectRatio) {
|
|
36
|
+
if (width / aspectRatio >= height) {
|
|
37
|
+
height = width / aspectRatio;
|
|
38
|
+
} else {
|
|
39
|
+
width = height * aspectRatio;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const x = point.x < anchorX ? anchorX - width : anchorX;
|
|
43
|
+
const y = point.y < anchorY ? anchorY - height : anchorY;
|
|
44
|
+
return {
|
|
45
|
+
x,
|
|
46
|
+
y,
|
|
47
|
+
width,
|
|
48
|
+
height
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Custom crop state + file producer. Replaces a cropperjs-based version: the
|
|
53
|
+
* crop rectangle is stored in natural-image pixels (so it stays locked across
|
|
54
|
+
* window resizes), and `AssetCropEditor` overlays a div sized by
|
|
55
|
+
* (cropNatural × displayRatio). produceFile draws the natural-px crop region
|
|
56
|
+
* straight to a canvas.
|
|
57
|
+
*/ const useCropImg = ()=>{
|
|
58
|
+
const [naturalSize, setNaturalSize] = React__namespace.useState({
|
|
59
|
+
width: 0,
|
|
60
|
+
height: 0
|
|
61
|
+
});
|
|
62
|
+
const [crop, setCrop] = React__namespace.useState({
|
|
63
|
+
x: 0,
|
|
64
|
+
y: 0,
|
|
65
|
+
width: 0,
|
|
66
|
+
height: 0
|
|
67
|
+
});
|
|
68
|
+
const [aspectRatio, setAspectRatioState] = React__namespace.useState(null);
|
|
69
|
+
const imageRef = React__namespace.useRef(null);
|
|
70
|
+
/**
|
|
71
|
+
* Call from the <img> onLoad handler. Captures the natural dimensions and
|
|
72
|
+
* seeds the crop to the full image (auto-crop area = 1).
|
|
73
|
+
*/ const init = React__namespace.useCallback((image)=>{
|
|
74
|
+
imageRef.current = image;
|
|
75
|
+
const next = {
|
|
76
|
+
width: image.naturalWidth,
|
|
77
|
+
height: image.naturalHeight
|
|
78
|
+
};
|
|
79
|
+
setNaturalSize(next);
|
|
80
|
+
setCrop({
|
|
81
|
+
x: 0,
|
|
82
|
+
y: 0,
|
|
83
|
+
width: next.width,
|
|
84
|
+
height: next.height
|
|
85
|
+
});
|
|
86
|
+
}, []);
|
|
87
|
+
const clamp = (value, min, max)=>Math.min(max, Math.max(min, value));
|
|
88
|
+
/** Update crop dimensions, clamping to remain inside the image bounds. */ const setCropSize = React__namespace.useCallback((next)=>{
|
|
89
|
+
setCrop((prev)=>{
|
|
90
|
+
const maxW = naturalSize.width - prev.x;
|
|
91
|
+
const maxH = naturalSize.height - prev.y;
|
|
92
|
+
let width = next.width !== undefined ? clamp(next.width, 1, maxW) : prev.width;
|
|
93
|
+
let height = next.height !== undefined ? clamp(next.height, 1, maxH) : prev.height;
|
|
94
|
+
if (aspectRatio) {
|
|
95
|
+
// When aspect locked, the axis the user is editing wins; the other
|
|
96
|
+
// axis follows. If both changed in one call, prefer width.
|
|
97
|
+
if (next.width !== undefined) {
|
|
98
|
+
height = clamp(width / aspectRatio, 1, maxH);
|
|
99
|
+
} else if (next.height !== undefined) {
|
|
100
|
+
width = clamp(height * aspectRatio, 1, maxW);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
...prev,
|
|
105
|
+
width,
|
|
106
|
+
height
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
}, [
|
|
110
|
+
naturalSize.width,
|
|
111
|
+
naturalSize.height,
|
|
112
|
+
aspectRatio
|
|
113
|
+
]);
|
|
114
|
+
/** Update crop origin, clamping so the crop stays inside the image. */ const setCropPosition = React__namespace.useCallback((next)=>{
|
|
115
|
+
setCrop((prev)=>{
|
|
116
|
+
const x = next.x !== undefined ? clamp(next.x, 0, naturalSize.width - prev.width) : prev.x;
|
|
117
|
+
const y = next.y !== undefined ? clamp(next.y, 0, naturalSize.height - prev.height) : prev.y;
|
|
118
|
+
return {
|
|
119
|
+
...prev,
|
|
120
|
+
x,
|
|
121
|
+
y
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
}, [
|
|
125
|
+
naturalSize.width,
|
|
126
|
+
naturalSize.height
|
|
127
|
+
]);
|
|
128
|
+
/** Lock or release the crop aspect ratio. Pass `null` to free it. */ const setAspectRatio = React__namespace.useCallback((ratio)=>{
|
|
129
|
+
setAspectRatioState(ratio);
|
|
130
|
+
if (ratio) {
|
|
131
|
+
setCrop((prev)=>{
|
|
132
|
+
// Bring the current rect into the requested ratio without escaping
|
|
133
|
+
// the image bounds.
|
|
134
|
+
const maxW = naturalSize.width - prev.x;
|
|
135
|
+
const maxH = naturalSize.height - prev.y;
|
|
136
|
+
let width = prev.width;
|
|
137
|
+
let height = width / ratio;
|
|
138
|
+
if (height > maxH) {
|
|
139
|
+
height = maxH;
|
|
140
|
+
width = height * ratio;
|
|
141
|
+
}
|
|
142
|
+
if (width > maxW) {
|
|
143
|
+
width = maxW;
|
|
144
|
+
height = width / ratio;
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
...prev,
|
|
148
|
+
width: Math.round(width),
|
|
149
|
+
height: Math.round(height)
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}, [
|
|
154
|
+
naturalSize.width,
|
|
155
|
+
naturalSize.height
|
|
156
|
+
]);
|
|
157
|
+
/**
|
|
158
|
+
* Draw the crop region from the loaded image element straight to a canvas
|
|
159
|
+
* and produce a File. The image must be CORS-clean (set crossOrigin on the
|
|
160
|
+
* <img>); otherwise canvas.toBlob throws on tainted canvas.
|
|
161
|
+
*/ const produceFile = React__namespace.useCallback((name, mimeType, lastModifiedDate)=>new Promise((resolve, reject)=>{
|
|
162
|
+
const image = imageRef.current;
|
|
163
|
+
if (!image) {
|
|
164
|
+
reject(new Error('Image not ready: call init() before produceFile().'));
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const canvas = document.createElement('canvas');
|
|
168
|
+
canvas.width = Math.max(1, Math.round(crop.width));
|
|
169
|
+
canvas.height = Math.max(1, Math.round(crop.height));
|
|
170
|
+
const context = canvas.getContext('2d');
|
|
171
|
+
if (!context) {
|
|
172
|
+
reject(new Error('Could not get a 2D canvas context to crop the image.'));
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
context.drawImage(image, crop.x, crop.y, crop.width, crop.height, 0, 0, canvas.width, canvas.height);
|
|
176
|
+
canvas.toBlob((blob)=>{
|
|
177
|
+
if (!blob) {
|
|
178
|
+
reject(new Error('Could not export the cropped image to a blob.'));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
resolve(new File([
|
|
182
|
+
blob
|
|
183
|
+
], name, {
|
|
184
|
+
type: mimeType,
|
|
185
|
+
lastModified: lastModifiedDate ? new Date(lastModifiedDate).getTime() : Date.now()
|
|
186
|
+
}));
|
|
187
|
+
}, mimeType, QUALITY);
|
|
188
|
+
}), [
|
|
189
|
+
crop.x,
|
|
190
|
+
crop.y,
|
|
191
|
+
crop.width,
|
|
192
|
+
crop.height
|
|
193
|
+
]);
|
|
194
|
+
return {
|
|
195
|
+
init,
|
|
196
|
+
crop,
|
|
197
|
+
naturalSize,
|
|
198
|
+
aspectRatio,
|
|
199
|
+
setCropSize,
|
|
200
|
+
setCropPosition,
|
|
201
|
+
setAspectRatio,
|
|
202
|
+
produceFile,
|
|
203
|
+
// Round-aware getters for the px inputs.
|
|
204
|
+
width: Math.round(crop.width),
|
|
205
|
+
height: Math.round(crop.height)
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
exports.resolveCornerResize = resolveCornerResize;
|
|
210
|
+
exports.useCropImg = useCropImg;
|
|
211
|
+
//# sourceMappingURL=useCropImg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCropImg.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/useCropImg.ts"],"sourcesContent":["import * as React from 'react';\n\nconst QUALITY = 1;\n\ninterface NaturalSize {\n width: number;\n height: number;\n}\n\nexport interface CropRect {\n /** Origin in natural-px from the image top-left. */\n x: number;\n y: number;\n /** Crop area dimensions in natural px. */\n width: number;\n height: number;\n}\n\n/**\n * Resolve a corner-resize drag into a crop rect, keeping the opposite corner\n * (`anchor`) fixed. When `aspectRatio` is set, one dimension is snapped to the\n * ratio first (driven by whichever axis the pointer pushed furthest), then the\n * position is derived from the anchor — so a locked resize never drifts the\n * anchored corner. Pure (no clamping to image bounds; the caller clamps).\n */\nexport const resolveCornerResize = ({\n anchorX,\n anchorY,\n point,\n aspectRatio,\n}: {\n anchorX: number;\n anchorY: number;\n point: { x: number; y: number };\n aspectRatio: number | null;\n}): CropRect => {\n let width = Math.abs(point.x - anchorX);\n let height = Math.abs(point.y - anchorY);\n\n if (aspectRatio) {\n if (width / aspectRatio >= height) {\n height = width / aspectRatio;\n } else {\n width = height * aspectRatio;\n }\n }\n\n const x = point.x < anchorX ? anchorX - width : anchorX;\n const y = point.y < anchorY ? anchorY - height : anchorY;\n\n return { x, y, width, height };\n};\n\n/**\n * Custom crop state + file producer. Replaces a cropperjs-based version: the\n * crop rectangle is stored in natural-image pixels (so it stays locked across\n * window resizes), and `AssetCropEditor` overlays a div sized by\n * (cropNatural × displayRatio). produceFile draws the natural-px crop region\n * straight to a canvas.\n */\nexport const useCropImg = () => {\n const [naturalSize, setNaturalSize] = React.useState<NaturalSize>({ width: 0, height: 0 });\n const [crop, setCrop] = React.useState<CropRect>({ x: 0, y: 0, width: 0, height: 0 });\n const [aspectRatio, setAspectRatioState] = React.useState<number | null>(null);\n const imageRef = React.useRef<HTMLImageElement | null>(null);\n\n /**\n * Call from the <img> onLoad handler. Captures the natural dimensions and\n * seeds the crop to the full image (auto-crop area = 1).\n */\n const init = React.useCallback((image: HTMLImageElement) => {\n imageRef.current = image;\n const next: NaturalSize = { width: image.naturalWidth, height: image.naturalHeight };\n setNaturalSize(next);\n setCrop({ x: 0, y: 0, width: next.width, height: next.height });\n }, []);\n\n const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));\n\n /** Update crop dimensions, clamping to remain inside the image bounds. */\n const setCropSize = React.useCallback(\n (next: Partial<Pick<CropRect, 'width' | 'height'>>) => {\n setCrop((prev) => {\n const maxW = naturalSize.width - prev.x;\n const maxH = naturalSize.height - prev.y;\n let width = next.width !== undefined ? clamp(next.width, 1, maxW) : prev.width;\n let height = next.height !== undefined ? clamp(next.height, 1, maxH) : prev.height;\n\n if (aspectRatio) {\n // When aspect locked, the axis the user is editing wins; the other\n // axis follows. If both changed in one call, prefer width.\n if (next.width !== undefined) {\n height = clamp(width / aspectRatio, 1, maxH);\n } else if (next.height !== undefined) {\n width = clamp(height * aspectRatio, 1, maxW);\n }\n }\n\n return { ...prev, width, height };\n });\n },\n [naturalSize.width, naturalSize.height, aspectRatio]\n );\n\n /** Update crop origin, clamping so the crop stays inside the image. */\n const setCropPosition = React.useCallback(\n (next: Partial<Pick<CropRect, 'x' | 'y'>>) => {\n setCrop((prev) => {\n const x = next.x !== undefined ? clamp(next.x, 0, naturalSize.width - prev.width) : prev.x;\n const y =\n next.y !== undefined ? clamp(next.y, 0, naturalSize.height - prev.height) : prev.y;\n return { ...prev, x, y };\n });\n },\n [naturalSize.width, naturalSize.height]\n );\n\n /** Lock or release the crop aspect ratio. Pass `null` to free it. */\n const setAspectRatio = React.useCallback(\n (ratio: number | null) => {\n setAspectRatioState(ratio);\n if (ratio) {\n setCrop((prev) => {\n // Bring the current rect into the requested ratio without escaping\n // the image bounds.\n const maxW = naturalSize.width - prev.x;\n const maxH = naturalSize.height - prev.y;\n let width = prev.width;\n let height = width / ratio;\n if (height > maxH) {\n height = maxH;\n width = height * ratio;\n }\n if (width > maxW) {\n width = maxW;\n height = width / ratio;\n }\n return { ...prev, width: Math.round(width), height: Math.round(height) };\n });\n }\n },\n [naturalSize.width, naturalSize.height]\n );\n\n /**\n * Draw the crop region from the loaded image element straight to a canvas\n * and produce a File. The image must be CORS-clean (set crossOrigin on the\n * <img>); otherwise canvas.toBlob throws on tainted canvas.\n */\n const produceFile = React.useCallback(\n (name: string, mimeType: string, lastModifiedDate?: string): Promise<globalThis.File> =>\n new Promise((resolve, reject) => {\n const image = imageRef.current;\n if (!image) {\n reject(new Error('Image not ready: call init() before produceFile().'));\n return;\n }\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, Math.round(crop.width));\n canvas.height = Math.max(1, Math.round(crop.height));\n const context = canvas.getContext('2d');\n if (!context) {\n reject(new Error('Could not get a 2D canvas context to crop the image.'));\n return;\n }\n context.drawImage(\n image,\n crop.x,\n crop.y,\n crop.width,\n crop.height,\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error('Could not export the cropped image to a blob.'));\n return;\n }\n resolve(\n new File([blob], name, {\n type: mimeType,\n lastModified: lastModifiedDate ? new Date(lastModifiedDate).getTime() : Date.now(),\n })\n );\n },\n mimeType,\n QUALITY\n );\n }),\n [crop.x, crop.y, crop.width, crop.height]\n );\n\n return {\n init,\n crop,\n naturalSize,\n aspectRatio,\n setCropSize,\n setCropPosition,\n setAspectRatio,\n produceFile,\n // Round-aware getters for the px inputs.\n width: Math.round(crop.width),\n height: Math.round(crop.height),\n };\n};\n"],"names":["QUALITY","resolveCornerResize","anchorX","anchorY","point","aspectRatio","width","Math","abs","x","height","y","useCropImg","naturalSize","setNaturalSize","React","useState","crop","setCrop","setAspectRatioState","imageRef","useRef","init","useCallback","image","current","next","naturalWidth","naturalHeight","clamp","value","min","max","setCropSize","prev","maxW","maxH","undefined","setCropPosition","setAspectRatio","ratio","round","produceFile","name","mimeType","lastModifiedDate","Promise","resolve","reject","Error","canvas","document","createElement","context","getContext","drawImage","toBlob","blob","File","type","lastModified","Date","getTime","now"],"mappings":"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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
const QUALITY = 1;
|
|
4
|
+
/**
|
|
5
|
+
* Resolve a corner-resize drag into a crop rect, keeping the opposite corner
|
|
6
|
+
* (`anchor`) fixed. When `aspectRatio` is set, one dimension is snapped to the
|
|
7
|
+
* ratio first (driven by whichever axis the pointer pushed furthest), then the
|
|
8
|
+
* position is derived from the anchor — so a locked resize never drifts the
|
|
9
|
+
* anchored corner. Pure (no clamping to image bounds; the caller clamps).
|
|
10
|
+
*/ const resolveCornerResize = ({ anchorX, anchorY, point, aspectRatio })=>{
|
|
11
|
+
let width = Math.abs(point.x - anchorX);
|
|
12
|
+
let height = Math.abs(point.y - anchorY);
|
|
13
|
+
if (aspectRatio) {
|
|
14
|
+
if (width / aspectRatio >= height) {
|
|
15
|
+
height = width / aspectRatio;
|
|
16
|
+
} else {
|
|
17
|
+
width = height * aspectRatio;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const x = point.x < anchorX ? anchorX - width : anchorX;
|
|
21
|
+
const y = point.y < anchorY ? anchorY - height : anchorY;
|
|
22
|
+
return {
|
|
23
|
+
x,
|
|
24
|
+
y,
|
|
25
|
+
width,
|
|
26
|
+
height
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Custom crop state + file producer. Replaces a cropperjs-based version: the
|
|
31
|
+
* crop rectangle is stored in natural-image pixels (so it stays locked across
|
|
32
|
+
* window resizes), and `AssetCropEditor` overlays a div sized by
|
|
33
|
+
* (cropNatural × displayRatio). produceFile draws the natural-px crop region
|
|
34
|
+
* straight to a canvas.
|
|
35
|
+
*/ const useCropImg = ()=>{
|
|
36
|
+
const [naturalSize, setNaturalSize] = React.useState({
|
|
37
|
+
width: 0,
|
|
38
|
+
height: 0
|
|
39
|
+
});
|
|
40
|
+
const [crop, setCrop] = React.useState({
|
|
41
|
+
x: 0,
|
|
42
|
+
y: 0,
|
|
43
|
+
width: 0,
|
|
44
|
+
height: 0
|
|
45
|
+
});
|
|
46
|
+
const [aspectRatio, setAspectRatioState] = React.useState(null);
|
|
47
|
+
const imageRef = React.useRef(null);
|
|
48
|
+
/**
|
|
49
|
+
* Call from the <img> onLoad handler. Captures the natural dimensions and
|
|
50
|
+
* seeds the crop to the full image (auto-crop area = 1).
|
|
51
|
+
*/ const init = React.useCallback((image)=>{
|
|
52
|
+
imageRef.current = image;
|
|
53
|
+
const next = {
|
|
54
|
+
width: image.naturalWidth,
|
|
55
|
+
height: image.naturalHeight
|
|
56
|
+
};
|
|
57
|
+
setNaturalSize(next);
|
|
58
|
+
setCrop({
|
|
59
|
+
x: 0,
|
|
60
|
+
y: 0,
|
|
61
|
+
width: next.width,
|
|
62
|
+
height: next.height
|
|
63
|
+
});
|
|
64
|
+
}, []);
|
|
65
|
+
const clamp = (value, min, max)=>Math.min(max, Math.max(min, value));
|
|
66
|
+
/** Update crop dimensions, clamping to remain inside the image bounds. */ const setCropSize = React.useCallback((next)=>{
|
|
67
|
+
setCrop((prev)=>{
|
|
68
|
+
const maxW = naturalSize.width - prev.x;
|
|
69
|
+
const maxH = naturalSize.height - prev.y;
|
|
70
|
+
let width = next.width !== undefined ? clamp(next.width, 1, maxW) : prev.width;
|
|
71
|
+
let height = next.height !== undefined ? clamp(next.height, 1, maxH) : prev.height;
|
|
72
|
+
if (aspectRatio) {
|
|
73
|
+
// When aspect locked, the axis the user is editing wins; the other
|
|
74
|
+
// axis follows. If both changed in one call, prefer width.
|
|
75
|
+
if (next.width !== undefined) {
|
|
76
|
+
height = clamp(width / aspectRatio, 1, maxH);
|
|
77
|
+
} else if (next.height !== undefined) {
|
|
78
|
+
width = clamp(height * aspectRatio, 1, maxW);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
...prev,
|
|
83
|
+
width,
|
|
84
|
+
height
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}, [
|
|
88
|
+
naturalSize.width,
|
|
89
|
+
naturalSize.height,
|
|
90
|
+
aspectRatio
|
|
91
|
+
]);
|
|
92
|
+
/** Update crop origin, clamping so the crop stays inside the image. */ const setCropPosition = React.useCallback((next)=>{
|
|
93
|
+
setCrop((prev)=>{
|
|
94
|
+
const x = next.x !== undefined ? clamp(next.x, 0, naturalSize.width - prev.width) : prev.x;
|
|
95
|
+
const y = next.y !== undefined ? clamp(next.y, 0, naturalSize.height - prev.height) : prev.y;
|
|
96
|
+
return {
|
|
97
|
+
...prev,
|
|
98
|
+
x,
|
|
99
|
+
y
|
|
100
|
+
};
|
|
101
|
+
});
|
|
102
|
+
}, [
|
|
103
|
+
naturalSize.width,
|
|
104
|
+
naturalSize.height
|
|
105
|
+
]);
|
|
106
|
+
/** Lock or release the crop aspect ratio. Pass `null` to free it. */ const setAspectRatio = React.useCallback((ratio)=>{
|
|
107
|
+
setAspectRatioState(ratio);
|
|
108
|
+
if (ratio) {
|
|
109
|
+
setCrop((prev)=>{
|
|
110
|
+
// Bring the current rect into the requested ratio without escaping
|
|
111
|
+
// the image bounds.
|
|
112
|
+
const maxW = naturalSize.width - prev.x;
|
|
113
|
+
const maxH = naturalSize.height - prev.y;
|
|
114
|
+
let width = prev.width;
|
|
115
|
+
let height = width / ratio;
|
|
116
|
+
if (height > maxH) {
|
|
117
|
+
height = maxH;
|
|
118
|
+
width = height * ratio;
|
|
119
|
+
}
|
|
120
|
+
if (width > maxW) {
|
|
121
|
+
width = maxW;
|
|
122
|
+
height = width / ratio;
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
...prev,
|
|
126
|
+
width: Math.round(width),
|
|
127
|
+
height: Math.round(height)
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}, [
|
|
132
|
+
naturalSize.width,
|
|
133
|
+
naturalSize.height
|
|
134
|
+
]);
|
|
135
|
+
/**
|
|
136
|
+
* Draw the crop region from the loaded image element straight to a canvas
|
|
137
|
+
* and produce a File. The image must be CORS-clean (set crossOrigin on the
|
|
138
|
+
* <img>); otherwise canvas.toBlob throws on tainted canvas.
|
|
139
|
+
*/ const produceFile = React.useCallback((name, mimeType, lastModifiedDate)=>new Promise((resolve, reject)=>{
|
|
140
|
+
const image = imageRef.current;
|
|
141
|
+
if (!image) {
|
|
142
|
+
reject(new Error('Image not ready: call init() before produceFile().'));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const canvas = document.createElement('canvas');
|
|
146
|
+
canvas.width = Math.max(1, Math.round(crop.width));
|
|
147
|
+
canvas.height = Math.max(1, Math.round(crop.height));
|
|
148
|
+
const context = canvas.getContext('2d');
|
|
149
|
+
if (!context) {
|
|
150
|
+
reject(new Error('Could not get a 2D canvas context to crop the image.'));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
context.drawImage(image, crop.x, crop.y, crop.width, crop.height, 0, 0, canvas.width, canvas.height);
|
|
154
|
+
canvas.toBlob((blob)=>{
|
|
155
|
+
if (!blob) {
|
|
156
|
+
reject(new Error('Could not export the cropped image to a blob.'));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
resolve(new File([
|
|
160
|
+
blob
|
|
161
|
+
], name, {
|
|
162
|
+
type: mimeType,
|
|
163
|
+
lastModified: lastModifiedDate ? new Date(lastModifiedDate).getTime() : Date.now()
|
|
164
|
+
}));
|
|
165
|
+
}, mimeType, QUALITY);
|
|
166
|
+
}), [
|
|
167
|
+
crop.x,
|
|
168
|
+
crop.y,
|
|
169
|
+
crop.width,
|
|
170
|
+
crop.height
|
|
171
|
+
]);
|
|
172
|
+
return {
|
|
173
|
+
init,
|
|
174
|
+
crop,
|
|
175
|
+
naturalSize,
|
|
176
|
+
aspectRatio,
|
|
177
|
+
setCropSize,
|
|
178
|
+
setCropPosition,
|
|
179
|
+
setAspectRatio,
|
|
180
|
+
produceFile,
|
|
181
|
+
// Round-aware getters for the px inputs.
|
|
182
|
+
width: Math.round(crop.width),
|
|
183
|
+
height: Math.round(crop.height)
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export { resolveCornerResize, useCropImg };
|
|
188
|
+
//# sourceMappingURL=useCropImg.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCropImg.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/useCropImg.ts"],"sourcesContent":["import * as React from 'react';\n\nconst QUALITY = 1;\n\ninterface NaturalSize {\n width: number;\n height: number;\n}\n\nexport interface CropRect {\n /** Origin in natural-px from the image top-left. */\n x: number;\n y: number;\n /** Crop area dimensions in natural px. */\n width: number;\n height: number;\n}\n\n/**\n * Resolve a corner-resize drag into a crop rect, keeping the opposite corner\n * (`anchor`) fixed. When `aspectRatio` is set, one dimension is snapped to the\n * ratio first (driven by whichever axis the pointer pushed furthest), then the\n * position is derived from the anchor — so a locked resize never drifts the\n * anchored corner. Pure (no clamping to image bounds; the caller clamps).\n */\nexport const resolveCornerResize = ({\n anchorX,\n anchorY,\n point,\n aspectRatio,\n}: {\n anchorX: number;\n anchorY: number;\n point: { x: number; y: number };\n aspectRatio: number | null;\n}): CropRect => {\n let width = Math.abs(point.x - anchorX);\n let height = Math.abs(point.y - anchorY);\n\n if (aspectRatio) {\n if (width / aspectRatio >= height) {\n height = width / aspectRatio;\n } else {\n width = height * aspectRatio;\n }\n }\n\n const x = point.x < anchorX ? anchorX - width : anchorX;\n const y = point.y < anchorY ? anchorY - height : anchorY;\n\n return { x, y, width, height };\n};\n\n/**\n * Custom crop state + file producer. Replaces a cropperjs-based version: the\n * crop rectangle is stored in natural-image pixels (so it stays locked across\n * window resizes), and `AssetCropEditor` overlays a div sized by\n * (cropNatural × displayRatio). produceFile draws the natural-px crop region\n * straight to a canvas.\n */\nexport const useCropImg = () => {\n const [naturalSize, setNaturalSize] = React.useState<NaturalSize>({ width: 0, height: 0 });\n const [crop, setCrop] = React.useState<CropRect>({ x: 0, y: 0, width: 0, height: 0 });\n const [aspectRatio, setAspectRatioState] = React.useState<number | null>(null);\n const imageRef = React.useRef<HTMLImageElement | null>(null);\n\n /**\n * Call from the <img> onLoad handler. Captures the natural dimensions and\n * seeds the crop to the full image (auto-crop area = 1).\n */\n const init = React.useCallback((image: HTMLImageElement) => {\n imageRef.current = image;\n const next: NaturalSize = { width: image.naturalWidth, height: image.naturalHeight };\n setNaturalSize(next);\n setCrop({ x: 0, y: 0, width: next.width, height: next.height });\n }, []);\n\n const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));\n\n /** Update crop dimensions, clamping to remain inside the image bounds. */\n const setCropSize = React.useCallback(\n (next: Partial<Pick<CropRect, 'width' | 'height'>>) => {\n setCrop((prev) => {\n const maxW = naturalSize.width - prev.x;\n const maxH = naturalSize.height - prev.y;\n let width = next.width !== undefined ? clamp(next.width, 1, maxW) : prev.width;\n let height = next.height !== undefined ? clamp(next.height, 1, maxH) : prev.height;\n\n if (aspectRatio) {\n // When aspect locked, the axis the user is editing wins; the other\n // axis follows. If both changed in one call, prefer width.\n if (next.width !== undefined) {\n height = clamp(width / aspectRatio, 1, maxH);\n } else if (next.height !== undefined) {\n width = clamp(height * aspectRatio, 1, maxW);\n }\n }\n\n return { ...prev, width, height };\n });\n },\n [naturalSize.width, naturalSize.height, aspectRatio]\n );\n\n /** Update crop origin, clamping so the crop stays inside the image. */\n const setCropPosition = React.useCallback(\n (next: Partial<Pick<CropRect, 'x' | 'y'>>) => {\n setCrop((prev) => {\n const x = next.x !== undefined ? clamp(next.x, 0, naturalSize.width - prev.width) : prev.x;\n const y =\n next.y !== undefined ? clamp(next.y, 0, naturalSize.height - prev.height) : prev.y;\n return { ...prev, x, y };\n });\n },\n [naturalSize.width, naturalSize.height]\n );\n\n /** Lock or release the crop aspect ratio. Pass `null` to free it. */\n const setAspectRatio = React.useCallback(\n (ratio: number | null) => {\n setAspectRatioState(ratio);\n if (ratio) {\n setCrop((prev) => {\n // Bring the current rect into the requested ratio without escaping\n // the image bounds.\n const maxW = naturalSize.width - prev.x;\n const maxH = naturalSize.height - prev.y;\n let width = prev.width;\n let height = width / ratio;\n if (height > maxH) {\n height = maxH;\n width = height * ratio;\n }\n if (width > maxW) {\n width = maxW;\n height = width / ratio;\n }\n return { ...prev, width: Math.round(width), height: Math.round(height) };\n });\n }\n },\n [naturalSize.width, naturalSize.height]\n );\n\n /**\n * Draw the crop region from the loaded image element straight to a canvas\n * and produce a File. The image must be CORS-clean (set crossOrigin on the\n * <img>); otherwise canvas.toBlob throws on tainted canvas.\n */\n const produceFile = React.useCallback(\n (name: string, mimeType: string, lastModifiedDate?: string): Promise<globalThis.File> =>\n new Promise((resolve, reject) => {\n const image = imageRef.current;\n if (!image) {\n reject(new Error('Image not ready: call init() before produceFile().'));\n return;\n }\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, Math.round(crop.width));\n canvas.height = Math.max(1, Math.round(crop.height));\n const context = canvas.getContext('2d');\n if (!context) {\n reject(new Error('Could not get a 2D canvas context to crop the image.'));\n return;\n }\n context.drawImage(\n image,\n crop.x,\n crop.y,\n crop.width,\n crop.height,\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error('Could not export the cropped image to a blob.'));\n return;\n }\n resolve(\n new File([blob], name, {\n type: mimeType,\n lastModified: lastModifiedDate ? new Date(lastModifiedDate).getTime() : Date.now(),\n })\n );\n },\n mimeType,\n QUALITY\n );\n }),\n [crop.x, crop.y, crop.width, crop.height]\n );\n\n return {\n init,\n crop,\n naturalSize,\n aspectRatio,\n setCropSize,\n setCropPosition,\n setAspectRatio,\n produceFile,\n // Round-aware getters for the px inputs.\n width: Math.round(crop.width),\n height: Math.round(crop.height),\n };\n};\n"],"names":["QUALITY","resolveCornerResize","anchorX","anchorY","point","aspectRatio","width","Math","abs","x","height","y","useCropImg","naturalSize","setNaturalSize","React","useState","crop","setCrop","setAspectRatioState","imageRef","useRef","init","useCallback","image","current","next","naturalWidth","naturalHeight","clamp","value","min","max","setCropSize","prev","maxW","maxH","undefined","setCropPosition","setAspectRatio","ratio","round","produceFile","name","mimeType","lastModifiedDate","Promise","resolve","reject","Error","canvas","document","createElement","context","getContext","drawImage","toBlob","blob","File","type","lastModified","Date","getTime","now"],"mappings":";;AAEA,MAAMA,OAAAA,GAAU,CAAA;AAgBhB;;;;;;AAMC,IACM,MAAMC,mBAAAA,GAAsB,CAAC,EAClCC,OAAO,EACPC,OAAO,EACPC,KAAK,EACLC,WAAW,EAMZ,GAAA;AACC,IAAA,IAAIC,QAAQC,IAAAA,CAAKC,GAAG,CAACJ,KAAAA,CAAMK,CAAC,GAAGP,OAAAA,CAAAA;AAC/B,IAAA,IAAIQ,SAASH,IAAAA,CAAKC,GAAG,CAACJ,KAAAA,CAAMO,CAAC,GAAGR,OAAAA,CAAAA;AAEhC,IAAA,IAAIE,WAAAA,EAAa;QACf,IAAIC,KAAAA,GAAQD,eAAeK,MAAAA,EAAQ;AACjCA,YAAAA,MAAAA,GAASJ,KAAAA,GAAQD,WAAAA;QACnB,CAAA,MAAO;AACLC,YAAAA,KAAAA,GAAQI,MAAAA,GAASL,WAAAA;AACnB,QAAA;AACF,IAAA;AAEA,IAAA,MAAMI,IAAIL,KAAAA,CAAMK,CAAC,GAAGP,OAAAA,GAAUA,UAAUI,KAAAA,GAAQJ,OAAAA;AAChD,IAAA,MAAMS,IAAIP,KAAAA,CAAMO,CAAC,GAAGR,OAAAA,GAAUA,UAAUO,MAAAA,GAASP,OAAAA;IAEjD,OAAO;AAAEM,QAAAA,CAAAA;AAAGE,QAAAA,CAAAA;AAAGL,QAAAA,KAAAA;AAAOI,QAAAA;AAAO,KAAA;AAC/B;AAEA;;;;;;UAOaE,UAAAA,GAAa,IAAA;AACxB,IAAA,MAAM,CAACC,WAAAA,EAAaC,cAAAA,CAAe,GAAGC,KAAAA,CAAMC,QAAQ,CAAc;QAAEV,KAAAA,EAAO,CAAA;QAAGI,MAAAA,EAAQ;AAAE,KAAA,CAAA;AACxF,IAAA,MAAM,CAACO,IAAAA,EAAMC,OAAAA,CAAQ,GAAGH,KAAAA,CAAMC,QAAQ,CAAW;QAAEP,CAAAA,EAAG,CAAA;QAAGE,CAAAA,EAAG,CAAA;QAAGL,KAAAA,EAAO,CAAA;QAAGI,MAAAA,EAAQ;AAAE,KAAA,CAAA;AACnF,IAAA,MAAM,CAACL,WAAAA,EAAac,mBAAAA,CAAoB,GAAGJ,KAAAA,CAAMC,QAAQ,CAAgB,IAAA,CAAA;IACzE,MAAMI,QAAAA,GAAWL,KAAAA,CAAMM,MAAM,CAA0B,IAAA,CAAA;AAEvD;;;AAGC,MACD,MAAMC,IAAAA,GAAOP,KAAAA,CAAMQ,WAAW,CAAC,CAACC,KAAAA,GAAAA;AAC9BJ,QAAAA,QAAAA,CAASK,OAAO,GAAGD,KAAAA;AACnB,QAAA,MAAME,IAAAA,GAAoB;AAAEpB,YAAAA,KAAAA,EAAOkB,MAAMG,YAAY;AAAEjB,YAAAA,MAAAA,EAAQc,MAAMI;AAAc,SAAA;QACnFd,cAAAA,CAAeY,IAAAA,CAAAA;QACfR,OAAAA,CAAQ;YAAET,CAAAA,EAAG,CAAA;YAAGE,CAAAA,EAAG,CAAA;AAAGL,YAAAA,KAAAA,EAAOoB,KAAKpB,KAAK;AAAEI,YAAAA,MAAAA,EAAQgB,KAAKhB;AAAO,SAAA,CAAA;AAC/D,IAAA,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAMmB,KAAAA,GAAQ,CAACC,KAAAA,EAAeC,GAAAA,EAAaC,GAAAA,GAAgBzB,IAAAA,CAAKwB,GAAG,CAACC,GAAAA,EAAKzB,IAAAA,CAAKyB,GAAG,CAACD,GAAAA,EAAKD,KAAAA,CAAAA,CAAAA;AAEvF,+EACA,MAAMG,WAAAA,GAAclB,KAAAA,CAAMQ,WAAW,CACnC,CAACG,IAAAA,GAAAA;AACCR,QAAAA,OAAAA,CAAQ,CAACgB,IAAAA,GAAAA;AACP,YAAA,MAAMC,IAAAA,GAAOtB,WAAAA,CAAYP,KAAK,GAAG4B,KAAKzB,CAAC;AACvC,YAAA,MAAM2B,IAAAA,GAAOvB,WAAAA,CAAYH,MAAM,GAAGwB,KAAKvB,CAAC;AACxC,YAAA,IAAIL,KAAAA,GAAQoB,IAAAA,CAAKpB,KAAK,KAAK+B,SAAAA,GAAYR,KAAAA,CAAMH,IAAAA,CAAKpB,KAAK,EAAE,CAAA,EAAG6B,IAAAA,CAAAA,GAAQD,IAAAA,CAAK5B,KAAK;AAC9E,YAAA,IAAII,MAAAA,GAASgB,IAAAA,CAAKhB,MAAM,KAAK2B,SAAAA,GAAYR,KAAAA,CAAMH,IAAAA,CAAKhB,MAAM,EAAE,CAAA,EAAG0B,IAAAA,CAAAA,GAAQF,IAAAA,CAAKxB,MAAM;AAElF,YAAA,IAAIL,WAAAA,EAAa;;;gBAGf,IAAIqB,IAAAA,CAAKpB,KAAK,KAAK+B,SAAAA,EAAW;oBAC5B3B,MAAAA,GAASmB,KAAAA,CAAMvB,KAAAA,GAAQD,WAAAA,EAAa,CAAA,EAAG+B,IAAAA,CAAAA;AACzC,gBAAA,CAAA,MAAO,IAAIV,IAAAA,CAAKhB,MAAM,KAAK2B,SAAAA,EAAW;oBACpC/B,KAAAA,GAAQuB,KAAAA,CAAMnB,MAAAA,GAASL,WAAAA,EAAa,CAAA,EAAG8B,IAAAA,CAAAA;AACzC,gBAAA;AACF,YAAA;YAEA,OAAO;AAAE,gBAAA,GAAGD,IAAI;AAAE5B,gBAAAA,KAAAA;AAAOI,gBAAAA;AAAO,aAAA;AAClC,QAAA,CAAA,CAAA;IACF,CAAA,EACA;AAACG,QAAAA,WAAAA,CAAYP,KAAK;AAAEO,QAAAA,WAAAA,CAAYH,MAAM;AAAEL,QAAAA;AAAY,KAAA,CAAA;AAGtD,4EACA,MAAMiC,eAAAA,GAAkBvB,KAAAA,CAAMQ,WAAW,CACvC,CAACG,IAAAA,GAAAA;AACCR,QAAAA,OAAAA,CAAQ,CAACgB,IAAAA,GAAAA;AACP,YAAA,MAAMzB,IAAIiB,IAAAA,CAAKjB,CAAC,KAAK4B,SAAAA,GAAYR,MAAMH,IAAAA,CAAKjB,CAAC,EAAE,CAAA,EAAGI,YAAYP,KAAK,GAAG4B,KAAK5B,KAAK,CAAA,GAAI4B,KAAKzB,CAAC;AAC1F,YAAA,MAAME,IACJe,IAAAA,CAAKf,CAAC,KAAK0B,SAAAA,GAAYR,MAAMH,IAAAA,CAAKf,CAAC,EAAE,CAAA,EAAGE,YAAYH,MAAM,GAAGwB,KAAKxB,MAAM,CAAA,GAAIwB,KAAKvB,CAAC;YACpF,OAAO;AAAE,gBAAA,GAAGuB,IAAI;AAAEzB,gBAAAA,CAAAA;AAAGE,gBAAAA;AAAE,aAAA;AACzB,QAAA,CAAA,CAAA;IACF,CAAA,EACA;AAACE,QAAAA,WAAAA,CAAYP,KAAK;AAAEO,QAAAA,WAAAA,CAAYH;AAAO,KAAA,CAAA;AAGzC,0EACA,MAAM6B,cAAAA,GAAiBxB,KAAAA,CAAMQ,WAAW,CACtC,CAACiB,KAAAA,GAAAA;QACCrB,mBAAAA,CAAoBqB,KAAAA,CAAAA;AACpB,QAAA,IAAIA,KAAAA,EAAO;AACTtB,YAAAA,OAAAA,CAAQ,CAACgB,IAAAA,GAAAA;;;AAGP,gBAAA,MAAMC,IAAAA,GAAOtB,WAAAA,CAAYP,KAAK,GAAG4B,KAAKzB,CAAC;AACvC,gBAAA,MAAM2B,IAAAA,GAAOvB,WAAAA,CAAYH,MAAM,GAAGwB,KAAKvB,CAAC;gBACxC,IAAIL,KAAAA,GAAQ4B,KAAK5B,KAAK;AACtB,gBAAA,IAAII,SAASJ,KAAAA,GAAQkC,KAAAA;AACrB,gBAAA,IAAI9B,SAAS0B,IAAAA,EAAM;oBACjB1B,MAAAA,GAAS0B,IAAAA;AACT9B,oBAAAA,KAAAA,GAAQI,MAAAA,GAAS8B,KAAAA;AACnB,gBAAA;AACA,gBAAA,IAAIlC,QAAQ6B,IAAAA,EAAM;oBAChB7B,KAAAA,GAAQ6B,IAAAA;AACRzB,oBAAAA,MAAAA,GAASJ,KAAAA,GAAQkC,KAAAA;AACnB,gBAAA;gBACA,OAAO;AAAE,oBAAA,GAAGN,IAAI;oBAAE5B,KAAAA,EAAOC,IAAAA,CAAKkC,KAAK,CAACnC,KAAAA,CAAAA;oBAAQI,MAAAA,EAAQH,IAAAA,CAAKkC,KAAK,CAAC/B,MAAAA;AAAQ,iBAAA;AACzE,YAAA,CAAA,CAAA;AACF,QAAA;IACF,CAAA,EACA;AAACG,QAAAA,WAAAA,CAAYP,KAAK;AAAEO,QAAAA,WAAAA,CAAYH;AAAO,KAAA,CAAA;AAGzC;;;;AAIC,MACD,MAAMgC,WAAAA,GAAc3B,KAAAA,CAAMQ,WAAW,CACnC,CAACoB,IAAAA,EAAcC,QAAAA,EAAkBC,gBAAAA,GAC/B,IAAIC,OAAAA,CAAQ,CAACC,OAAAA,EAASC,MAAAA,GAAAA;YACpB,MAAMxB,KAAAA,GAAQJ,SAASK,OAAO;AAC9B,YAAA,IAAI,CAACD,KAAAA,EAAO;AACVwB,gBAAAA,MAAAA,CAAO,IAAIC,KAAAA,CAAM,oDAAA,CAAA,CAAA;AACjB,gBAAA;AACF,YAAA;YACA,MAAMC,MAAAA,GAASC,QAAAA,CAASC,aAAa,CAAC,QAAA,CAAA;YACtCF,MAAAA,CAAO5C,KAAK,GAAGC,IAAAA,CAAKyB,GAAG,CAAC,GAAGzB,IAAAA,CAAKkC,KAAK,CAACxB,IAAAA,CAAKX,KAAK,CAAA,CAAA;YAChD4C,MAAAA,CAAOxC,MAAM,GAAGH,IAAAA,CAAKyB,GAAG,CAAC,GAAGzB,IAAAA,CAAKkC,KAAK,CAACxB,IAAAA,CAAKP,MAAM,CAAA,CAAA;YAClD,MAAM2C,OAAAA,GAAUH,MAAAA,CAAOI,UAAU,CAAC,IAAA,CAAA;AAClC,YAAA,IAAI,CAACD,OAAAA,EAAS;AACZL,gBAAAA,MAAAA,CAAO,IAAIC,KAAAA,CAAM,sDAAA,CAAA,CAAA;AACjB,gBAAA;AACF,YAAA;YACAI,OAAAA,CAAQE,SAAS,CACf/B,KAAAA,EACAP,IAAAA,CAAKR,CAAC,EACNQ,IAAAA,CAAKN,CAAC,EACNM,IAAAA,CAAKX,KAAK,EACVW,IAAAA,CAAKP,MAAM,EACX,CAAA,EACA,GACAwC,MAAAA,CAAO5C,KAAK,EACZ4C,MAAAA,CAAOxC,MAAM,CAAA;YAEfwC,MAAAA,CAAOM,MAAM,CACX,CAACC,IAAAA,GAAAA;AACC,gBAAA,IAAI,CAACA,IAAAA,EAAM;AACTT,oBAAAA,MAAAA,CAAO,IAAIC,KAAAA,CAAM,+CAAA,CAAA,CAAA;AACjB,oBAAA;AACF,gBAAA;AACAF,gBAAAA,OAAAA,CACE,IAAIW,IAAAA,CAAK;AAACD,oBAAAA;AAAK,iBAAA,EAAEd,IAAAA,EAAM;oBACrBgB,IAAAA,EAAMf,QAAAA;AACNgB,oBAAAA,YAAAA,EAAcf,mBAAmB,IAAIgB,IAAAA,CAAKhB,kBAAkBiB,OAAO,EAAA,GAAKD,KAAKE,GAAG;AAClF,iBAAA,CAAA,CAAA;AAEJ,YAAA,CAAA,EACAnB,QAAAA,EACA5C,OAAAA,CAAAA;QAEJ,CAAA,CAAA,EACF;AAACiB,QAAAA,IAAAA,CAAKR,CAAC;AAAEQ,QAAAA,IAAAA,CAAKN,CAAC;AAAEM,QAAAA,IAAAA,CAAKX,KAAK;AAAEW,QAAAA,IAAAA,CAAKP;AAAO,KAAA,CAAA;IAG3C,OAAO;AACLY,QAAAA,IAAAA;AACAL,QAAAA,IAAAA;AACAJ,QAAAA,WAAAA;AACAR,QAAAA,WAAAA;AACA4B,QAAAA,WAAAA;AACAK,QAAAA,eAAAA;AACAC,QAAAA,cAAAA;AACAG,QAAAA,WAAAA;;AAEApC,QAAAA,KAAAA,EAAOC,IAAAA,CAAKkC,KAAK,CAACxB,IAAAA,CAAKX,KAAK,CAAA;AAC5BI,QAAAA,MAAAA,EAAQH,IAAAA,CAAKkC,KAAK,CAACxB,IAAAA,CAAKP,MAAM;AAChC,KAAA;AACF;;;;"}
|