@happyvertical/smrt-images 0.30.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/AGENTS.md +48 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +92 -0
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/categorizer.d.ts +26 -0
- package/dist/categorizer.d.ts.map +1 -0
- package/dist/deriver.d.ts +33 -0
- package/dist/deriver.d.ts.map +1 -0
- package/dist/editor.d.ts +72 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/image.d.ts +53 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/images.d.ts +80 -0
- package/dist/images.d.ts.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +839 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +1179 -0
- package/dist/media-bundle-persistence.d.ts +15 -0
- package/dist/media-bundle-persistence.d.ts.map +1 -0
- package/dist/metadata.d.ts +19 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/playground.d.ts +2 -0
- package/dist/playground.d.ts.map +1 -0
- package/dist/playground.js +140 -0
- package/dist/playground.js.map +1 -0
- package/dist/prompts.d.ts +8 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/search.d.ts +42 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +561 -0
- package/dist/svelte/components/AssetsGallery.svelte +436 -0
- package/dist/svelte/components/AssetsGallery.svelte.d.ts +11 -0
- package/dist/svelte/components/AssetsGallery.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ImageEditor.svelte +485 -0
- package/dist/svelte/components/ImageEditor.svelte.d.ts +12 -0
- package/dist/svelte/components/ImageEditor.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ImageUploader.svelte +922 -0
- package/dist/svelte/components/ImageUploader.svelte.d.ts +15 -0
- package/dist/svelte/components/ImageUploader.svelte.d.ts.map +1 -0
- package/dist/svelte/i18n.d.ts +42 -0
- package/dist/svelte/i18n.d.ts.map +1 -0
- package/dist/svelte/i18n.js +46 -0
- package/dist/svelte/image-clients.d.ts +45 -0
- package/dist/svelte/image-clients.d.ts.map +1 -0
- package/dist/svelte/image-clients.js +1 -0
- package/dist/svelte/index.d.ts +14 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +21 -0
- package/dist/svelte/playground.d.ts +74 -0
- package/dist/svelte/playground.d.ts.map +1 -0
- package/dist/svelte/playground.js +105 -0
- package/dist/svelte/routes/ImageStudioRoute.svelte +194 -0
- package/dist/svelte/routes/ImageStudioRoute.svelte.d.ts +7 -0
- package/dist/svelte/routes/ImageStudioRoute.svelte.d.ts.map +1 -0
- package/dist/svelte/routes/index.d.ts +2 -0
- package/dist/svelte/routes/index.d.ts.map +1 -0
- package/dist/svelte/routes/index.js +1 -0
- package/dist/svelte/routes/shared.d.ts +25 -0
- package/dist/svelte/routes/shared.d.ts.map +1 -0
- package/dist/svelte/routes/shared.js +31 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui.d.ts +10 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +42 -0
- package/dist/ui.js.map +1 -0
- package/dist/upstream.d.ts +65 -0
- package/dist/upstream.d.ts.map +1 -0
- package/package.json +95 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ImageEditorClient, ImageLike, ImagesGalleryClient } from '../image-clients';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
apiBaseUrl?: string;
|
|
4
|
+
editorClient?: ImageEditorClient;
|
|
5
|
+
galleryClient?: ImagesGalleryClient;
|
|
6
|
+
/** @required Callback when an image is selected */
|
|
7
|
+
onSelect: (image: ImageLike | File | string) => void;
|
|
8
|
+
onCancel?: () => void;
|
|
9
|
+
allowedTabs?: ('gallery' | 'upload' | 'camera' | 'external')[];
|
|
10
|
+
enableDragToEditor?: boolean;
|
|
11
|
+
};
|
|
12
|
+
declare const ImageUploader: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
13
|
+
type ImageUploader = ReturnType<typeof ImageUploader>;
|
|
14
|
+
export default ImageUploader;
|
|
15
|
+
//# sourceMappingURL=ImageUploader.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageUploader.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ImageUploader.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,iBAAiB,EACjB,SAAS,EACT,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAGzB,KAAK,gBAAgB,GAAI;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,mDAAmD;IACnD,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;IACrD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC,EAAE,CAAC;IAC/D,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAqYF,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export declare const M: {
|
|
2
|
+
readonly 'images.assets_gallery.title': "images.assets_gallery.title";
|
|
3
|
+
readonly 'images.assets_gallery.search_placeholder': "images.assets_gallery.search_placeholder";
|
|
4
|
+
readonly 'images.assets_gallery.any_orientation': "images.assets_gallery.any_orientation";
|
|
5
|
+
readonly 'images.assets_gallery.min_width_placeholder': "images.assets_gallery.min_width_placeholder";
|
|
6
|
+
readonly 'images.assets_gallery.min_height_placeholder': "images.assets_gallery.min_height_placeholder";
|
|
7
|
+
readonly 'images.assets_gallery.no_images_found': "images.assets_gallery.no_images_found";
|
|
8
|
+
readonly 'images.image_editor.title': "images.image_editor.title";
|
|
9
|
+
readonly 'images.image_editor.no_image_selected': "images.image_editor.no_image_selected";
|
|
10
|
+
readonly 'images.image_editor.standard_tools': "images.image_editor.standard_tools";
|
|
11
|
+
readonly 'images.image_editor.ai_edit': "images.image_editor.ai_edit";
|
|
12
|
+
readonly 'images.image_editor.apply_resize': "images.image_editor.apply_resize";
|
|
13
|
+
readonly 'images.image_editor.reset_dimensions': "images.image_editor.reset_dimensions";
|
|
14
|
+
readonly 'images.image_editor.apply_crop': "images.image_editor.apply_crop";
|
|
15
|
+
readonly 'images.image_editor.convert_format': "images.image_editor.convert_format";
|
|
16
|
+
readonly 'images.image_editor.ai_powered_edit': "images.image_editor.ai_powered_edit";
|
|
17
|
+
readonly 'images.image_editor.ai_powered_edit_hint': "images.image_editor.ai_powered_edit_hint";
|
|
18
|
+
readonly 'images.image_editor.ai_prompt_placeholder': "images.image_editor.ai_prompt_placeholder";
|
|
19
|
+
readonly 'images.image_uploader.select_image': "images.image_uploader.select_image";
|
|
20
|
+
readonly 'images.image_uploader.create_variation': "images.image_uploader.create_variation";
|
|
21
|
+
readonly 'images.image_uploader.variation_hint': "images.image_uploader.variation_hint";
|
|
22
|
+
readonly 'images.image_uploader.variation_prompt_placeholder': "images.image_uploader.variation_prompt_placeholder";
|
|
23
|
+
readonly 'images.image_uploader.generating': "images.image_uploader.generating";
|
|
24
|
+
readonly 'images.image_uploader.generate_variation': "images.image_uploader.generate_variation";
|
|
25
|
+
readonly 'images.image_uploader.choose_image': "images.image_uploader.choose_image";
|
|
26
|
+
readonly 'images.image_uploader.external_url': "images.image_uploader.external_url";
|
|
27
|
+
readonly 'images.image_uploader.drag_and_drop': "images.image_uploader.drag_and_drop";
|
|
28
|
+
readonly 'images.image_uploader.browse_files': "images.image_uploader.browse_files";
|
|
29
|
+
readonly 'images.image_uploader.try_again': "images.image_uploader.try_again";
|
|
30
|
+
readonly 'images.image_uploader.starting_camera': "images.image_uploader.starting_camera";
|
|
31
|
+
readonly 'images.image_uploader.take_picture': "images.image_uploader.take_picture";
|
|
32
|
+
readonly 'images.image_uploader.external_hint': "images.image_uploader.external_hint";
|
|
33
|
+
readonly 'images.image_uploader.external_url_placeholder': "images.image_uploader.external_url_placeholder";
|
|
34
|
+
readonly 'images.image_studio_route.eyebrow': "images.image_studio_route.eyebrow";
|
|
35
|
+
readonly 'images.image_studio_route.title': "images.image_studio_route.title";
|
|
36
|
+
readonly 'images.image_studio_route.lede': "images.image_studio_route.lede";
|
|
37
|
+
readonly 'images.image_studio_route.acquire_images': "images.image_studio_route.acquire_images";
|
|
38
|
+
readonly 'images.image_studio_route.acquire_images_description': "images.image_studio_route.acquire_images_description";
|
|
39
|
+
readonly 'images.image_studio_route.browse_and_edit': "images.image_studio_route.browse_and_edit";
|
|
40
|
+
readonly 'images.image_studio_route.browse_and_edit_description': "images.image_studio_route.browse_and_edit_description";
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DZ,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { defineMessages } from '@happyvertical/smrt-ui/i18n';
|
|
2
|
+
export const M = defineMessages({
|
|
3
|
+
// AssetsGallery
|
|
4
|
+
'images.assets_gallery.title': 'Asset Gallery',
|
|
5
|
+
'images.assets_gallery.search_placeholder': 'Search images (name, alt text)...',
|
|
6
|
+
'images.assets_gallery.any_orientation': 'Any Orientation',
|
|
7
|
+
'images.assets_gallery.min_width_placeholder': 'Min Width (px)',
|
|
8
|
+
'images.assets_gallery.min_height_placeholder': 'Min Height (px)',
|
|
9
|
+
'images.assets_gallery.no_images_found': 'No images found matching your criteria.',
|
|
10
|
+
// ImageEditor
|
|
11
|
+
'images.image_editor.title': 'Image Editor',
|
|
12
|
+
'images.image_editor.no_image_selected': 'No image selected for editing.',
|
|
13
|
+
'images.image_editor.standard_tools': 'Standard Tools',
|
|
14
|
+
'images.image_editor.ai_edit': 'AI Edit',
|
|
15
|
+
'images.image_editor.apply_resize': 'Apply Resize',
|
|
16
|
+
'images.image_editor.reset_dimensions': 'Reset Dimensions',
|
|
17
|
+
'images.image_editor.apply_crop': 'Apply Crop',
|
|
18
|
+
'images.image_editor.convert_format': 'Convert Format',
|
|
19
|
+
'images.image_editor.ai_powered_edit': 'AI Powered Edit',
|
|
20
|
+
'images.image_editor.ai_powered_edit_hint': 'Describe how you want to change this image. A new derivative asset will be created.',
|
|
21
|
+
'images.image_editor.ai_prompt_placeholder': 'e.g. Change the background to a sunset...',
|
|
22
|
+
// ImageUploader
|
|
23
|
+
'images.image_uploader.select_image': 'Select Image',
|
|
24
|
+
'images.image_uploader.create_variation': 'Create Variation',
|
|
25
|
+
'images.image_uploader.variation_hint': 'Describe how this image should be changed. A new derivative will be created from the original.',
|
|
26
|
+
'images.image_uploader.variation_prompt_placeholder': 'e.g. Change the sky to show heavy rain and overcast clouds...',
|
|
27
|
+
'images.image_uploader.generating': 'Generating…',
|
|
28
|
+
'images.image_uploader.generate_variation': 'Generate Variation',
|
|
29
|
+
'images.image_uploader.choose_image': 'Choose Image',
|
|
30
|
+
'images.image_uploader.external_url': 'External URL',
|
|
31
|
+
'images.image_uploader.drag_and_drop': 'Drag and drop an image here',
|
|
32
|
+
'images.image_uploader.browse_files': 'Browse Files',
|
|
33
|
+
'images.image_uploader.try_again': 'Try Again',
|
|
34
|
+
'images.image_uploader.starting_camera': 'Starting camera...',
|
|
35
|
+
'images.image_uploader.take_picture': 'Take Picture',
|
|
36
|
+
'images.image_uploader.external_hint': 'Enter a direct URL to an image or a supported provider link.',
|
|
37
|
+
'images.image_uploader.external_url_placeholder': 'https://example.com/image.jpg',
|
|
38
|
+
// ImageStudioRoute (route)
|
|
39
|
+
'images.image_studio_route.eyebrow': 'Package Route Surface',
|
|
40
|
+
'images.image_studio_route.title': 'Image Studio',
|
|
41
|
+
'images.image_studio_route.lede': 'A package-owned route for acquiring images, browsing stored assets, and moving directly into the editor workflow.',
|
|
42
|
+
'images.image_studio_route.acquire_images': 'Acquire Images',
|
|
43
|
+
'images.image_studio_route.acquire_images_description': 'Use the uploader to test gallery selection, local uploads, camera capture, and external URLs from the same package surface downstream apps can mount.',
|
|
44
|
+
'images.image_studio_route.browse_and_edit': 'Browse And Edit',
|
|
45
|
+
'images.image_studio_route.browse_and_edit_description': 'The gallery and editor stay wired together so route consumers can see the intended package flow instead of disconnected component snapshots.',
|
|
46
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Image } from '../image';
|
|
2
|
+
export type ImageLike = Omit<Pick<Image, 'id' | 'name' | 'sourceUri' | 'mimeType' | 'description' | 'width' | 'height' | 'alt'>, 'id'> & {
|
|
3
|
+
id: string;
|
|
4
|
+
url?: string;
|
|
5
|
+
};
|
|
6
|
+
export interface ImagesGalleryQuery {
|
|
7
|
+
limit: number;
|
|
8
|
+
offset: number;
|
|
9
|
+
q?: string;
|
|
10
|
+
orientation?: 'landscape' | 'portrait' | 'square';
|
|
11
|
+
minWidth?: number;
|
|
12
|
+
minHeight?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ImagesGalleryResult {
|
|
15
|
+
items: ImageLike[];
|
|
16
|
+
}
|
|
17
|
+
export interface ImagesGalleryClient {
|
|
18
|
+
list(query: ImagesGalleryQuery): Promise<ImagesGalleryResult>;
|
|
19
|
+
}
|
|
20
|
+
export interface ImageResizeRequest {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
}
|
|
24
|
+
export interface ImageCropRequest {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
w: number;
|
|
28
|
+
h: number;
|
|
29
|
+
}
|
|
30
|
+
export interface ImageConvertRequest {
|
|
31
|
+
format: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ImageEditRequest {
|
|
34
|
+
prompt: string;
|
|
35
|
+
}
|
|
36
|
+
export interface ImageEditorResult {
|
|
37
|
+
image: ImageLike;
|
|
38
|
+
}
|
|
39
|
+
export interface ImageEditorClient {
|
|
40
|
+
resize(id: string, payload: ImageResizeRequest): Promise<ImageEditorResult>;
|
|
41
|
+
crop(id: string, payload: ImageCropRequest): Promise<ImageEditorResult>;
|
|
42
|
+
convert(id: string, payload: ImageConvertRequest): Promise<ImageEditorResult>;
|
|
43
|
+
edit(id: string, payload: ImageEditRequest): Promise<ImageEditorResult>;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=image-clients.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-clients.d.ts","sourceRoot":"","sources":["../../src/svelte/image-clients.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,MAAM,SAAS,GAAG,IAAI,CAC1B,IAAI,CACF,KAAK,EACH,IAAI,GACJ,MAAM,GACN,WAAW,GACX,UAAU,GACV,aAAa,GACb,OAAO,GACP,QAAQ,GACR,KAAK,CACR,EACD,IAAI,CACL,GAAG;IACF,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5E,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9E,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Images Module Svelte Components
|
|
3
|
+
*
|
|
4
|
+
* Optional Svelte UI components for image gallery, editing, and upload.
|
|
5
|
+
* Auto-registers components with ModuleUIRegistry on import.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import AssetsGallery from './components/AssetsGallery.svelte';
|
|
10
|
+
import ImageEditor from './components/ImageEditor.svelte';
|
|
11
|
+
import ImageUploader from './components/ImageUploader.svelte';
|
|
12
|
+
export { AssetsGallery, ImageEditor, ImageUploader };
|
|
13
|
+
export type { ImageConvertRequest, ImageCropRequest, ImageEditorClient, ImageEditorResult, ImageEditRequest, ImageLike, ImageResizeRequest, ImagesGalleryClient, ImagesGalleryQuery, ImagesGalleryResult, } from './image-clients';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,aAAa,MAAM,mCAAmC,CAAC;AAC9D,OAAO,WAAW,MAAM,iCAAiC,CAAC;AAC1D,OAAO,aAAa,MAAM,mCAAmC,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAErD,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Images Module Svelte Components
|
|
3
|
+
*
|
|
4
|
+
* Optional Svelte UI components for image gallery, editing, and upload.
|
|
5
|
+
* Auto-registers components with ModuleUIRegistry on import.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import { ModuleUIRegistry } from '@happyvertical/smrt-ui/registry';
|
|
10
|
+
import { IMAGES_MODULE_META } from '../ui.js';
|
|
11
|
+
// Import components
|
|
12
|
+
import AssetsGallery from './components/AssetsGallery.svelte';
|
|
13
|
+
import ImageEditor from './components/ImageEditor.svelte';
|
|
14
|
+
import ImageUploader from './components/ImageUploader.svelte';
|
|
15
|
+
// Export components
|
|
16
|
+
export { AssetsGallery, ImageEditor, ImageUploader };
|
|
17
|
+
// Auto-register with ModuleUIRegistry
|
|
18
|
+
ModuleUIRegistry.registerModule(IMAGES_MODULE_META);
|
|
19
|
+
ModuleUIRegistry.register('@happyvertical/smrt-images', 'assets-gallery', AssetsGallery);
|
|
20
|
+
ModuleUIRegistry.register('@happyvertical/smrt-images', 'image-editor', ImageEditor);
|
|
21
|
+
ModuleUIRegistry.register('@happyvertical/smrt-images', 'image-uploader', ImageUploader);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
packageName: string;
|
|
3
|
+
displayName: string;
|
|
4
|
+
description: string;
|
|
5
|
+
entries: ({
|
|
6
|
+
id: string;
|
|
7
|
+
title: string;
|
|
8
|
+
description: string;
|
|
9
|
+
loadComponent: () => Promise<typeof import("./components/ImageUploader.svelte")>;
|
|
10
|
+
order: number;
|
|
11
|
+
tags: string[];
|
|
12
|
+
props: {
|
|
13
|
+
allowedTabs: string[];
|
|
14
|
+
onSelect: () => undefined;
|
|
15
|
+
image?: undefined;
|
|
16
|
+
onSave?: undefined;
|
|
17
|
+
};
|
|
18
|
+
modes: {
|
|
19
|
+
mock: {
|
|
20
|
+
label: string;
|
|
21
|
+
};
|
|
22
|
+
live?: undefined;
|
|
23
|
+
};
|
|
24
|
+
} | {
|
|
25
|
+
id: string;
|
|
26
|
+
title: string;
|
|
27
|
+
description: string;
|
|
28
|
+
loadComponent: () => Promise<typeof import("./components/ImageEditor.svelte")>;
|
|
29
|
+
order: number;
|
|
30
|
+
tags: string[];
|
|
31
|
+
props: {
|
|
32
|
+
image: {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
sourceUri: string;
|
|
37
|
+
url: string;
|
|
38
|
+
mimeType: string;
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
alt: string;
|
|
42
|
+
};
|
|
43
|
+
onSave: () => undefined;
|
|
44
|
+
allowedTabs?: undefined;
|
|
45
|
+
onSelect?: undefined;
|
|
46
|
+
};
|
|
47
|
+
modes: {
|
|
48
|
+
mock: {
|
|
49
|
+
label: string;
|
|
50
|
+
};
|
|
51
|
+
live?: undefined;
|
|
52
|
+
};
|
|
53
|
+
} | {
|
|
54
|
+
id: string;
|
|
55
|
+
title: string;
|
|
56
|
+
description: string;
|
|
57
|
+
loadComponent: () => Promise<typeof import("./routes/ImageStudioRoute.svelte")>;
|
|
58
|
+
order: number;
|
|
59
|
+
tags: string[];
|
|
60
|
+
modes: {
|
|
61
|
+
live: {
|
|
62
|
+
label: string;
|
|
63
|
+
description: string;
|
|
64
|
+
props: {
|
|
65
|
+
apiBaseUrl: string;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
mock?: undefined;
|
|
69
|
+
};
|
|
70
|
+
props?: undefined;
|
|
71
|
+
})[];
|
|
72
|
+
};
|
|
73
|
+
export default _default;
|
|
74
|
+
//# sourceMappingURL=playground.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../../src/svelte/playground.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEA,wBA6DE"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { IMAGES_ROUTE_META } from './routes/shared.js';
|
|
2
|
+
const DEFAULT_IMAGES_PLAYGROUND_API_BASE_URL = '/api/v1';
|
|
3
|
+
function resolveImagesPlaygroundApiBaseUrl() {
|
|
4
|
+
const configuredViaGlobal = globalThis
|
|
5
|
+
.__SMRT_IMAGES_PLAYGROUND_API_BASE_URL__;
|
|
6
|
+
if (configuredViaGlobal) {
|
|
7
|
+
return configuredViaGlobal;
|
|
8
|
+
}
|
|
9
|
+
const browserLocation = globalThis.location;
|
|
10
|
+
if (browserLocation) {
|
|
11
|
+
const configuredViaQuery = new URLSearchParams(browserLocation.search).get('smrtImagesApiBaseUrl');
|
|
12
|
+
if (configuredViaQuery) {
|
|
13
|
+
return configuredViaQuery;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return DEFAULT_IMAGES_PLAYGROUND_API_BASE_URL;
|
|
17
|
+
}
|
|
18
|
+
function createPreviewImageUri(label, accent) {
|
|
19
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
|
|
20
|
+
<defs>
|
|
21
|
+
<linearGradient id="bg" x1="0%" x2="100%" y1="0%" y2="100%">
|
|
22
|
+
<stop offset="0%" stop-color="${accent}" />
|
|
23
|
+
<stop offset="100%" stop-color="#111827" />
|
|
24
|
+
</linearGradient>
|
|
25
|
+
</defs>
|
|
26
|
+
<rect width="1280" height="720" fill="url(#bg)" rx="40" />
|
|
27
|
+
<circle cx="1040" cy="170" r="92" fill="rgba(255,255,255,0.18)" />
|
|
28
|
+
<path d="M110 590L360 320l182 170 146-104 210 204H110z" fill="rgba(255,255,255,0.22)" />
|
|
29
|
+
<text x="92" y="118" fill="#f8fafc" font-size="60" font-family="Arial, sans-serif" font-weight="700">${label}</text>
|
|
30
|
+
<text x="92" y="662" fill="#dbeafe" font-size="30" font-family="Arial, sans-serif">SMRT Images preview</text>
|
|
31
|
+
</svg>`;
|
|
32
|
+
return `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(svg)}`;
|
|
33
|
+
}
|
|
34
|
+
const sampleImage = {
|
|
35
|
+
id: 'image-harbor-dusk',
|
|
36
|
+
name: 'Harbor Dusk',
|
|
37
|
+
description: 'Wide editorial frame used for feature headers.',
|
|
38
|
+
sourceUri: createPreviewImageUri('Harbor Dusk', '#2563eb'),
|
|
39
|
+
url: createPreviewImageUri('Harbor Dusk', '#2563eb'),
|
|
40
|
+
mimeType: 'image/jpeg',
|
|
41
|
+
width: 1280,
|
|
42
|
+
height: 720,
|
|
43
|
+
alt: 'Cargo cranes and harbor lights reflected at dusk.',
|
|
44
|
+
};
|
|
45
|
+
const loadImageEditor = () => import('./components/ImageEditor.svelte');
|
|
46
|
+
const loadImageStudioRoute = () => import('./routes/ImageStudioRoute.svelte');
|
|
47
|
+
const loadImageUploader = () => import('./components/ImageUploader.svelte');
|
|
48
|
+
export default {
|
|
49
|
+
packageName: '@happyvertical/smrt-images',
|
|
50
|
+
displayName: 'Images',
|
|
51
|
+
description: IMAGES_ROUTE_META.studio.description,
|
|
52
|
+
entries: [
|
|
53
|
+
{
|
|
54
|
+
id: 'image-uploader',
|
|
55
|
+
title: 'Image Uploader',
|
|
56
|
+
description: 'Mock-safe uploader preview for local files and external image URLs.',
|
|
57
|
+
loadComponent: loadImageUploader,
|
|
58
|
+
order: 1,
|
|
59
|
+
tags: ['uploader', 'images', 'media'],
|
|
60
|
+
props: {
|
|
61
|
+
allowedTabs: ['upload', 'external'],
|
|
62
|
+
onSelect: () => undefined,
|
|
63
|
+
},
|
|
64
|
+
modes: {
|
|
65
|
+
mock: {
|
|
66
|
+
label: 'Mock',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'image-editor',
|
|
72
|
+
title: 'Image Editor',
|
|
73
|
+
description: 'Editor controls for resizing, cropping, and AI-assisted image edits.',
|
|
74
|
+
loadComponent: loadImageEditor,
|
|
75
|
+
order: 2,
|
|
76
|
+
tags: ['editor', 'images', 'media'],
|
|
77
|
+
props: {
|
|
78
|
+
image: sampleImage,
|
|
79
|
+
onSave: () => undefined,
|
|
80
|
+
},
|
|
81
|
+
modes: {
|
|
82
|
+
mock: {
|
|
83
|
+
label: 'Mock',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'image-studio-route',
|
|
89
|
+
title: 'Image Studio Route',
|
|
90
|
+
description: 'Package-owned acquisition and editing flow backed by the generated images API.',
|
|
91
|
+
loadComponent: loadImageStudioRoute,
|
|
92
|
+
order: 3,
|
|
93
|
+
tags: ['route', 'images', 'admin'],
|
|
94
|
+
modes: {
|
|
95
|
+
live: {
|
|
96
|
+
label: 'Live',
|
|
97
|
+
description: 'Requires the images package dev server and generated routes. Override the base URL with ?smrtImagesApiBaseUrl=... or window.__SMRT_IMAGES_PLAYGROUND_API_BASE_URL__ when needed.',
|
|
98
|
+
props: {
|
|
99
|
+
apiBaseUrl: resolveImagesPlaygroundApiBaseUrl(),
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
3
|
+
import { M } from '../i18n.js';
|
|
4
|
+
import type { ImageLike } from '../image-clients.js';
|
|
5
|
+
import { AssetsGallery, ImageEditor, ImageUploader } from '../index.js';
|
|
6
|
+
|
|
7
|
+
const { t } = useI18n();
|
|
8
|
+
|
|
9
|
+
let { apiBaseUrl = '/api/v1' }: { apiBaseUrl?: string } = $props();
|
|
10
|
+
|
|
11
|
+
type StudioImage = ImageLike;
|
|
12
|
+
|
|
13
|
+
let selectedImage = $state<StudioImage | null>(null);
|
|
14
|
+
let uploaderStatus = $state('No image selected from the uploader yet.');
|
|
15
|
+
|
|
16
|
+
function isPersistedImage(value: unknown): value is StudioImage {
|
|
17
|
+
return (
|
|
18
|
+
typeof value === 'object' &&
|
|
19
|
+
value !== null &&
|
|
20
|
+
'id' in value &&
|
|
21
|
+
'name' in value
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function handleUploaderSelect(value: StudioImage | File | string) {
|
|
26
|
+
if (isPersistedImage(value)) {
|
|
27
|
+
selectedImage = value;
|
|
28
|
+
uploaderStatus = `Ready to edit “${value.name}”.`;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (value instanceof File) {
|
|
33
|
+
uploaderStatus = `Selected local file “${value.name}”. Persist it through your app flow before opening advanced edits.`;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
uploaderStatus = `Selected external image source: ${value}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function handleGallerySelect(image: StudioImage) {
|
|
41
|
+
selectedImage = image;
|
|
42
|
+
uploaderStatus = `Loaded “${image.name}” from the gallery.`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function handleEditorSave(image: StudioImage) {
|
|
46
|
+
selectedImage = image;
|
|
47
|
+
uploaderStatus = `Saved a new derivative for “${image.name}”.`;
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<div class="images-route">
|
|
52
|
+
<header class="images-route__header">
|
|
53
|
+
<div>
|
|
54
|
+
<p class="images-route__eyebrow">{t(M['images.image_studio_route.eyebrow'])}</p>
|
|
55
|
+
<h1>{t(M['images.image_studio_route.title'])}</h1>
|
|
56
|
+
<p class="images-route__lede">
|
|
57
|
+
{t(M['images.image_studio_route.lede'])}
|
|
58
|
+
</p>
|
|
59
|
+
</div>
|
|
60
|
+
</header>
|
|
61
|
+
|
|
62
|
+
<section class="images-route__uploader">
|
|
63
|
+
<div class="images-route__section-copy">
|
|
64
|
+
<h2>{t(M['images.image_studio_route.acquire_images'])}</h2>
|
|
65
|
+
<p>
|
|
66
|
+
{t(M['images.image_studio_route.acquire_images_description'])}
|
|
67
|
+
</p>
|
|
68
|
+
<p class="images-route__status">{uploaderStatus}</p>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div class="images-route__card">
|
|
72
|
+
<ImageUploader {apiBaseUrl} onSelect={handleUploaderSelect} />
|
|
73
|
+
</div>
|
|
74
|
+
</section>
|
|
75
|
+
|
|
76
|
+
<section class="images-route__workspace">
|
|
77
|
+
<div class="images-route__section-copy">
|
|
78
|
+
<h2>{t(M['images.image_studio_route.browse_and_edit'])}</h2>
|
|
79
|
+
<p>
|
|
80
|
+
{t(M['images.image_studio_route.browse_and_edit_description'])}
|
|
81
|
+
</p>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div class="images-route__workspace-grid">
|
|
85
|
+
<div class="images-route__card images-route__gallery">
|
|
86
|
+
<AssetsGallery {apiBaseUrl} onSelect={handleGallerySelect} />
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div class="images-route__card images-route__editor">
|
|
90
|
+
<ImageEditor
|
|
91
|
+
{apiBaseUrl}
|
|
92
|
+
image={selectedImage}
|
|
93
|
+
onSave={handleEditorSave}
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</section>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<style>
|
|
101
|
+
.images-route {
|
|
102
|
+
max-width: 1440px;
|
|
103
|
+
margin: 0 auto;
|
|
104
|
+
padding: 2rem;
|
|
105
|
+
display: flex;
|
|
106
|
+
flex-direction: column;
|
|
107
|
+
gap: 1.75rem;
|
|
108
|
+
color: var(--smrt-color-on-surface, #e2e8f0);
|
|
109
|
+
background:
|
|
110
|
+
radial-gradient(circle at top, color-mix(in srgb, var(--smrt-color-primary) 22%, transparent), transparent 40%),
|
|
111
|
+
var(--smrt-color-background, #020617);
|
|
112
|
+
min-height: 100vh;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.images-route__eyebrow {
|
|
116
|
+
margin: 0 0 0.5rem;
|
|
117
|
+
color: var(--smrt-color-primary, #7dd3fc);
|
|
118
|
+
font-size: var(--smrt-typography-label-medium-size, 0.75rem);
|
|
119
|
+
font-weight: var(--smrt-typography-weight-bold, 700);
|
|
120
|
+
letter-spacing: var(--smrt-typography-label-medium-tracking, 0.08em);
|
|
121
|
+
text-transform: uppercase;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.images-route__header h1,
|
|
125
|
+
.images-route__section-copy h2 {
|
|
126
|
+
margin: 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.images-route__header h1 {
|
|
130
|
+
font-size: clamp(2rem, 3vw, 2.8rem);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.images-route__lede,
|
|
134
|
+
.images-route__section-copy p {
|
|
135
|
+
margin: 0.75rem 0 0;
|
|
136
|
+
color: var(--smrt-color-on-surface-variant, #cbd5e1);
|
|
137
|
+
line-height: 1.6;
|
|
138
|
+
max-width: 60rem;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.images-route__uploader,
|
|
142
|
+
.images-route__workspace {
|
|
143
|
+
display: flex;
|
|
144
|
+
flex-direction: column;
|
|
145
|
+
gap: 1rem;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.images-route__status {
|
|
149
|
+
margin-top: 1rem;
|
|
150
|
+
padding: 0.875rem 1rem;
|
|
151
|
+
border-radius: 0.85rem;
|
|
152
|
+
background: color-mix(in srgb, var(--smrt-color-surface-container) 72%, transparent);
|
|
153
|
+
border: 1px solid color-mix(in srgb, var(--smrt-color-primary) 20%, transparent);
|
|
154
|
+
color: var(--smrt-color-on-surface, #e0f2fe);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.images-route__workspace-grid {
|
|
158
|
+
display: grid;
|
|
159
|
+
grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
|
|
160
|
+
gap: 1rem;
|
|
161
|
+
align-items: start;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.images-route__card {
|
|
165
|
+
border-radius: 1rem;
|
|
166
|
+
border: 1px solid color-mix(in srgb, var(--smrt-color-outline-variant) 18%, transparent);
|
|
167
|
+
background: color-mix(in srgb, var(--smrt-color-surface-container) 72%, transparent);
|
|
168
|
+
box-shadow: var(--smrt-elevation-5, 0 24px 60px color-mix(in srgb, var(--smrt-color-shadow) 35%, transparent));
|
|
169
|
+
overflow: hidden;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.images-route__gallery {
|
|
173
|
+
min-height: 720px;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.images-route__editor {
|
|
177
|
+
min-height: 720px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@media (max-width: 1024px) {
|
|
181
|
+
.images-route {
|
|
182
|
+
padding: 1.25rem;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.images-route__workspace-grid {
|
|
186
|
+
grid-template-columns: 1fr;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.images-route__gallery,
|
|
190
|
+
.images-route__editor {
|
|
191
|
+
min-height: 560px;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
</style>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
apiBaseUrl?: string;
|
|
3
|
+
};
|
|
4
|
+
declare const ImageStudioRoute: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
5
|
+
type ImageStudioRoute = ReturnType<typeof ImageStudioRoute>;
|
|
6
|
+
export default ImageStudioRoute;
|
|
7
|
+
//# sourceMappingURL=ImageStudioRoute.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageStudioRoute.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/routes/ImageStudioRoute.svelte.ts"],"names":[],"mappings":"AAUC,KAAK,gBAAgB,GAAI;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAmGlD,QAAA,MAAM,gBAAgB,sDAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/svelte/routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ImageStudioRoute } from './ImageStudioRoute.svelte';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SmrtRouteNavigationItem } from '@happyvertical/smrt-types';
|
|
2
|
+
export declare const IMAGES_ROUTE_IDS: {
|
|
3
|
+
readonly studio: "@happyvertical/smrt-images:studio";
|
|
4
|
+
};
|
|
5
|
+
export type ImagesRouteId = (typeof IMAGES_ROUTE_IDS)[keyof typeof IMAGES_ROUTE_IDS];
|
|
6
|
+
export type ImagesRouteNavigationItem = SmrtRouteNavigationItem;
|
|
7
|
+
export declare const IMAGES_ROUTE_META: {
|
|
8
|
+
readonly studio: {
|
|
9
|
+
id: "@happyvertical/smrt-images:studio";
|
|
10
|
+
title: string;
|
|
11
|
+
description: string;
|
|
12
|
+
defaultPath: string;
|
|
13
|
+
loadKind: undefined;
|
|
14
|
+
nav: {
|
|
15
|
+
label: string;
|
|
16
|
+
description: string;
|
|
17
|
+
icon: string;
|
|
18
|
+
order: number;
|
|
19
|
+
group: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export declare function createImagesRouteNavigation(mounts?: Partial<Record<ImagesRouteId, string>>): ImagesRouteNavigationItem[];
|
|
24
|
+
export declare const IMAGES_DEFAULT_ROUTE_NAVIGATION: SmrtRouteNavigationItem[];
|
|
25
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/svelte/routes/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,2BAA2B,CAAC;AAEnC,eAAO,MAAM,gBAAgB;;CAEnB,CAAC;AAEX,MAAM,MAAM,aAAa,GACvB,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAE3D,MAAM,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAEhE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;CAgBpB,CAAC;AAEX,wBAAgB,2BAA2B,CACzC,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAM,GAClD,yBAAyB,EAAE,CAU7B;AAED,eAAO,MAAM,+BAA+B,2BAAgC,CAAC"}
|