@hai-dev/ui-kit 1.0.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/README.md +73 -0
- package/dist/Button-BjNjCLw8.js +6428 -0
- package/dist/DialogTitle-1A3dJ174.js +3258 -0
- package/dist/assets/error-upload-dialog.css +1 -0
- package/dist/assets/photo-crop-uploader.css +1 -0
- package/dist/assets/upload-button.css +1 -0
- package/dist/assets/upload-dialog.css +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +4 -0
- package/dist/components/photo-crop-uploader/components/error-upload-dialog/error-upload-dialog.d.ts +3 -0
- package/dist/components/photo-crop-uploader/components/error-upload-dialog/error-upload-dialog.js +33 -0
- package/dist/components/photo-crop-uploader/components/error-upload-dialog/index.d.ts +1 -0
- package/dist/components/photo-crop-uploader/components/error-upload-dialog/index.js +4 -0
- package/dist/components/photo-crop-uploader/components/error-upload-dialog/types.d.ts +9 -0
- package/dist/components/photo-crop-uploader/components/error-upload-dialog/types.js +1 -0
- package/dist/components/photo-crop-uploader/components/index.d.ts +3 -0
- package/dist/components/photo-crop-uploader/components/index.js +8 -0
- package/dist/components/photo-crop-uploader/components/upload-button/constants.d.ts +3 -0
- package/dist/components/photo-crop-uploader/components/upload-button/constants.js +6 -0
- package/dist/components/photo-crop-uploader/components/upload-button/index.d.ts +1 -0
- package/dist/components/photo-crop-uploader/components/upload-button/index.js +4 -0
- package/dist/components/photo-crop-uploader/components/upload-button/types.d.ts +12 -0
- package/dist/components/photo-crop-uploader/components/upload-button/types.js +1 -0
- package/dist/components/photo-crop-uploader/components/upload-button/upload-button.d.ts +3 -0
- package/dist/components/photo-crop-uploader/components/upload-button/upload-button.js +90 -0
- package/dist/components/photo-crop-uploader/components/upload-dialog/index.d.ts +1 -0
- package/dist/components/photo-crop-uploader/components/upload-dialog/index.js +4 -0
- package/dist/components/photo-crop-uploader/components/upload-dialog/types.d.ts +27 -0
- package/dist/components/photo-crop-uploader/components/upload-dialog/types.js +1 -0
- package/dist/components/photo-crop-uploader/components/upload-dialog/upload-dialog.d.ts +3 -0
- package/dist/components/photo-crop-uploader/components/upload-dialog/upload-dialog.js +123 -0
- package/dist/components/photo-crop-uploader/constants.d.ts +41 -0
- package/dist/components/photo-crop-uploader/constants.js +64 -0
- package/dist/components/photo-crop-uploader/errors/index.d.ts +2 -0
- package/dist/components/photo-crop-uploader/errors/index.js +6 -0
- package/dist/components/photo-crop-uploader/errors/photo-file.error.d.ts +7 -0
- package/dist/components/photo-crop-uploader/errors/photo-file.error.js +15 -0
- package/dist/components/photo-crop-uploader/errors/photo-size.error.d.ts +10 -0
- package/dist/components/photo-crop-uploader/errors/photo-size.error.js +19 -0
- package/dist/components/photo-crop-uploader/index.d.ts +1 -0
- package/dist/components/photo-crop-uploader/index.js +4 -0
- package/dist/components/photo-crop-uploader/locale.d.ts +2 -0
- package/dist/components/photo-crop-uploader/locale.js +47 -0
- package/dist/components/photo-crop-uploader/photo-crop-uploader.d.ts +3 -0
- package/dist/components/photo-crop-uploader/photo-crop-uploader.js +143 -0
- package/dist/components/photo-crop-uploader/photo-crop-uploder.stories.d.ts +7 -0
- package/dist/components/photo-crop-uploader/types.d.ts +33 -0
- package/dist/components/photo-crop-uploader/types.js +1 -0
- package/dist/components/photo-crop-uploader/utils/get-croped-photo.d.ts +4 -0
- package/dist/components/photo-crop-uploader/utils/get-croped-photo.js +26 -0
- package/dist/components/photo-crop-uploader/utils/get-photo-crop.d.ts +2 -0
- package/dist/components/photo-crop-uploader/utils/get-photo-crop.js +18 -0
- package/dist/components/photo-crop-uploader/utils/index.d.ts +4 -0
- package/dist/components/photo-crop-uploader/utils/index.js +10 -0
- package/dist/components/photo-crop-uploader/utils/read-photo.d.ts +3 -0
- package/dist/components/photo-crop-uploader/utils/read-photo.js +51 -0
- package/dist/components/photo-crop-uploader/utils/validate-photo-file.d.ts +3 -0
- package/dist/components/photo-crop-uploader/utils/validate-photo-file.js +24 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +6 -0
- package/dist/index-BiffjjQq.js +431 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +26 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { jsxs as K, Fragment as Q, jsx as s } from "react/jsx-runtime";
|
|
2
|
+
import { useState as a, useRef as S } from "react";
|
|
3
|
+
import "../../index-BiffjjQq.js";
|
|
4
|
+
import { c as V } from "../../Button-BjNjCLw8.js";
|
|
5
|
+
import { localizedText as W } from "./locale.js";
|
|
6
|
+
import { EN_LOCALE as Y } from "../../constants.js";
|
|
7
|
+
import { DEFAULT_MIN_DIMENSION as $, DEFAULT_ASPECT_RATIO as oo, DEFAULT_TIMEOUT as to, DEFAULT_FILE_MAX_SIZE as ro } from "./constants.js";
|
|
8
|
+
import { UploadDialog as eo } from "./components/upload-dialog/upload-dialog.js";
|
|
9
|
+
import { UploadButton as ao } from "./components/upload-button/upload-button.js";
|
|
10
|
+
import { ErrorUploadDialog as no } from "./components/error-upload-dialog/error-upload-dialog.js";
|
|
11
|
+
import { validatePhotoFile as so } from "./utils/validate-photo-file.js";
|
|
12
|
+
import { readPhoto as po } from "./utils/read-photo.js";
|
|
13
|
+
import { getPhotoCrop as io } from "./utils/get-photo-crop.js";
|
|
14
|
+
import { getCropedPhoto as lo } from "./utils/get-croped-photo.js";
|
|
15
|
+
import '../../assets/photo-crop-uploader.css';const co = "_photoCropCanvas_1i4lr_1", ho = {
|
|
16
|
+
photoCropCanvas: co
|
|
17
|
+
}, vo = (_) => {
|
|
18
|
+
const {
|
|
19
|
+
buttonClassname: U = "",
|
|
20
|
+
onStartUpload: T = () => {
|
|
21
|
+
},
|
|
22
|
+
onEndUpload: w = () => {
|
|
23
|
+
},
|
|
24
|
+
onError: v = () => {
|
|
25
|
+
},
|
|
26
|
+
onStartCrop: x = () => {
|
|
27
|
+
},
|
|
28
|
+
onEndCrop: A = () => {
|
|
29
|
+
},
|
|
30
|
+
showErrorPopup: F = !1,
|
|
31
|
+
minDimension: n = $,
|
|
32
|
+
aspectRatio: l = oo,
|
|
33
|
+
locale: e = Y,
|
|
34
|
+
timeout: I = to,
|
|
35
|
+
fileMaxSize: y = ro,
|
|
36
|
+
allowedExtensions: c,
|
|
37
|
+
allowedMimeTypes: M,
|
|
38
|
+
circular: O,
|
|
39
|
+
width: N,
|
|
40
|
+
keepSelection: R,
|
|
41
|
+
...b
|
|
42
|
+
} = _, [z, p] = a(!1), [H, h] = a(""), [i, d] = a(), m = S(null), f = S(null), [u, C] = a(!1), [E, P] = a(""), [j, g] = a(!1), D = () => {
|
|
43
|
+
p(!1);
|
|
44
|
+
}, k = () => {
|
|
45
|
+
g(!1);
|
|
46
|
+
}, B = (o) => {
|
|
47
|
+
w(o), h(o), p(!0), P("");
|
|
48
|
+
}, L = (o) => {
|
|
49
|
+
o instanceof Error && (console.warn(o.message), v(o), P(o.message), g(!0), h(""), p(!1));
|
|
50
|
+
}, X = async (o) => {
|
|
51
|
+
const r = o.target.files?.[0];
|
|
52
|
+
if (r)
|
|
53
|
+
try {
|
|
54
|
+
C(!0), T(), so(
|
|
55
|
+
r,
|
|
56
|
+
{ maxSize: y, allowedExtensions: c, allowedMimeTypes: M },
|
|
57
|
+
e
|
|
58
|
+
);
|
|
59
|
+
const t = await po(r, n, e, I);
|
|
60
|
+
B(t);
|
|
61
|
+
} catch (t) {
|
|
62
|
+
L(t);
|
|
63
|
+
} finally {
|
|
64
|
+
o.target.value = "", C(!1);
|
|
65
|
+
}
|
|
66
|
+
}, Z = (o) => {
|
|
67
|
+
const { width: r, height: t } = o.currentTarget, J = io(r, t, n, l);
|
|
68
|
+
d(J);
|
|
69
|
+
}, q = (o, r) => {
|
|
70
|
+
d(r);
|
|
71
|
+
}, G = () => {
|
|
72
|
+
const o = f.current, r = m.current;
|
|
73
|
+
if (o && r && i)
|
|
74
|
+
try {
|
|
75
|
+
x();
|
|
76
|
+
const t = lo(
|
|
77
|
+
r,
|
|
78
|
+
o,
|
|
79
|
+
i,
|
|
80
|
+
e
|
|
81
|
+
);
|
|
82
|
+
A(t), D();
|
|
83
|
+
} catch (t) {
|
|
84
|
+
t instanceof Error && (console.warn(t), L(t));
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
return /* @__PURE__ */ K(Q, { children: [
|
|
88
|
+
/* @__PURE__ */ s(
|
|
89
|
+
ao,
|
|
90
|
+
{
|
|
91
|
+
onChange: X,
|
|
92
|
+
buttonClassname: U,
|
|
93
|
+
disabled: u,
|
|
94
|
+
buttonDisabled: u,
|
|
95
|
+
locale: e,
|
|
96
|
+
width: N,
|
|
97
|
+
allowedExtensions: c,
|
|
98
|
+
...b,
|
|
99
|
+
children: W[e].upload
|
|
100
|
+
}
|
|
101
|
+
),
|
|
102
|
+
/* @__PURE__ */ s(
|
|
103
|
+
eo,
|
|
104
|
+
{
|
|
105
|
+
open: z,
|
|
106
|
+
photoCrop: i,
|
|
107
|
+
photoSource: H,
|
|
108
|
+
photoError: E,
|
|
109
|
+
onCloseDialogHandler: D,
|
|
110
|
+
onCropChange: q,
|
|
111
|
+
onPhotoCrop: G,
|
|
112
|
+
onPhotoLoad: Z,
|
|
113
|
+
imageRef: m,
|
|
114
|
+
minDimension: n,
|
|
115
|
+
aspectRatio: l,
|
|
116
|
+
locale: e,
|
|
117
|
+
circular: O,
|
|
118
|
+
keepSelection: R
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
/* @__PURE__ */ s(
|
|
122
|
+
no,
|
|
123
|
+
{
|
|
124
|
+
open: F && j,
|
|
125
|
+
photoError: E,
|
|
126
|
+
onCloseErrorDialog: k,
|
|
127
|
+
locale: e
|
|
128
|
+
}
|
|
129
|
+
),
|
|
130
|
+
/* @__PURE__ */ s(
|
|
131
|
+
"canvas",
|
|
132
|
+
{
|
|
133
|
+
className: V(ho.photoCropCanvas),
|
|
134
|
+
width: n,
|
|
135
|
+
height: n,
|
|
136
|
+
ref: f
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
] });
|
|
140
|
+
};
|
|
141
|
+
export {
|
|
142
|
+
vo as PhotoCropUploader
|
|
143
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { PhotoCropUploader } from './';
|
|
3
|
+
type PhotoCropUploaderMeta = Meta<typeof PhotoCropUploader>;
|
|
4
|
+
type PhotoCropUploaderStory = StoryObj<typeof PhotoCropUploader>;
|
|
5
|
+
declare const meta: PhotoCropUploaderMeta;
|
|
6
|
+
export default meta;
|
|
7
|
+
export declare const Base: PhotoCropUploaderStory;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
2
|
+
import { Locale } from '../../types';
|
|
3
|
+
import { BMP_IMAGE_TYPE, GIF_IMAGE_TYPE, ICO_IMAGE_TYPE, JPEG_IMAGE_TYPE, JPG_IMAGE_TYPE, MICROSOFT_ICO_IMAGE_TYPE, PNG_IMAGE_TYPE, SVG_IMAGE_TYPE, WEBP_IMAGE_TYPE, ICO_IMAGE_EXT, BMP_IMAGE_EXT, GIF_IMAGE_EXT, JPEG_IMAGE_EXT, JPG_IMAGE_EXT, PNG_IMAGE_EXT, SVG_IMAGE_EXT, WEBP_IMAGE_EXT } from './constants';
|
|
4
|
+
export type PhotoDataUrl = string;
|
|
5
|
+
export type PhotoFileSize = number;
|
|
6
|
+
export type PhotoExtension = typeof JPG_IMAGE_EXT | typeof JPEG_IMAGE_EXT | typeof PNG_IMAGE_EXT | typeof SVG_IMAGE_EXT | typeof BMP_IMAGE_EXT | typeof GIF_IMAGE_EXT | typeof WEBP_IMAGE_EXT | typeof ICO_IMAGE_EXT;
|
|
7
|
+
export type PhotoMimeType = typeof JPG_IMAGE_TYPE | typeof JPEG_IMAGE_TYPE | typeof PNG_IMAGE_TYPE | typeof SVG_IMAGE_TYPE | typeof BMP_IMAGE_TYPE | typeof GIF_IMAGE_TYPE | typeof WEBP_IMAGE_TYPE | typeof ICO_IMAGE_TYPE | typeof MICROSOFT_ICO_IMAGE_TYPE;
|
|
8
|
+
export type PhotoFileOptions = {
|
|
9
|
+
maxSize?: PhotoFileSize;
|
|
10
|
+
allowedExtensions?: PhotoExtension[];
|
|
11
|
+
allowedMimeTypes?: PhotoMimeType[];
|
|
12
|
+
};
|
|
13
|
+
export type PhotoCropUploaderCustomProps = {
|
|
14
|
+
buttonClassname?: string;
|
|
15
|
+
onStartUpload?: () => unknown;
|
|
16
|
+
onEndUpload?: (photoData: PhotoDataUrl) => unknown;
|
|
17
|
+
onError?: (error: Error) => unknown;
|
|
18
|
+
onStartCrop?: () => unknown;
|
|
19
|
+
onEndCrop?: (photoData: PhotoDataUrl) => unknown;
|
|
20
|
+
showErrorPopup?: boolean;
|
|
21
|
+
minDimension?: number;
|
|
22
|
+
aspectRatio?: number;
|
|
23
|
+
locale?: 'ru' | 'en';
|
|
24
|
+
timeout?: number;
|
|
25
|
+
fileMaxSize?: number;
|
|
26
|
+
allowedExtensions?: PhotoExtension[];
|
|
27
|
+
allowedMimeTypes?: PhotoMimeType[];
|
|
28
|
+
circular?: boolean;
|
|
29
|
+
keepSelection?: boolean;
|
|
30
|
+
width?: number;
|
|
31
|
+
};
|
|
32
|
+
export type PhotoCropUploaderProps = PhotoCropUploaderCustomProps & InputHTMLAttributes<HTMLInputElement>;
|
|
33
|
+
export type PhotoCropUploaderLocaleText = Record<Locale, Record<string, string>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { D as w } from "../../../index-BiffjjQq.js";
|
|
2
|
+
import { localizedText as x } from "../locale.js";
|
|
3
|
+
import { EN_LOCALE as O } from "../../../constants.js";
|
|
4
|
+
import { PHOTO_CANVAS_CONTEXT as f, PHOTO_SMOOTHING_QUALITY as T } from "../constants.js";
|
|
5
|
+
const H = (c, o, d, m = O) => {
|
|
6
|
+
const t = o.getContext(f);
|
|
7
|
+
if (!t)
|
|
8
|
+
throw new Error(x[m]["canvas-error"]);
|
|
9
|
+
const { width: l, height: n, naturalWidth: i, naturalHeight: a } = c, r = w(d, l, n), e = window.devicePixelRatio, h = i / l, s = a / n;
|
|
10
|
+
o.width = Math.floor(r.width * h * e), o.height = Math.floor(r.height * s * e), t.scale(e, e), t.imageSmoothingQuality = T, t.save();
|
|
11
|
+
const p = r.x * h, g = r.y * s;
|
|
12
|
+
return t.translate(-p, -g), t.drawImage(
|
|
13
|
+
c,
|
|
14
|
+
0,
|
|
15
|
+
0,
|
|
16
|
+
i,
|
|
17
|
+
a,
|
|
18
|
+
0,
|
|
19
|
+
0,
|
|
20
|
+
i,
|
|
21
|
+
a
|
|
22
|
+
), t.restore(), o.toDataURL();
|
|
23
|
+
};
|
|
24
|
+
export {
|
|
25
|
+
H as getCropedPhoto
|
|
26
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { B as I, L as E } from "../../../index-BiffjjQq.js";
|
|
2
|
+
import { DEFAULT_MIN_DIMENSION as T, DEFAULT_ASPECT_RATIO as C, PRECENT_UNIT as N } from "../constants.js";
|
|
3
|
+
const A = (o, r, t = T, c = C) => {
|
|
4
|
+
const e = t / o * 100, n = t / r * 100, p = I(
|
|
5
|
+
{
|
|
6
|
+
unit: N,
|
|
7
|
+
width: e,
|
|
8
|
+
height: n
|
|
9
|
+
},
|
|
10
|
+
c,
|
|
11
|
+
o,
|
|
12
|
+
r
|
|
13
|
+
);
|
|
14
|
+
return E(p, o, r);
|
|
15
|
+
};
|
|
16
|
+
export {
|
|
17
|
+
A as getPhotoCrop
|
|
18
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { readPhoto as t } from "./read-photo.js";
|
|
2
|
+
import { getPhotoCrop as p } from "./get-photo-crop.js";
|
|
3
|
+
import { getCropedPhoto as h } from "./get-croped-photo.js";
|
|
4
|
+
import { validatePhotoFile as x } from "./validate-photo-file.js";
|
|
5
|
+
export {
|
|
6
|
+
h as getCropedPhoto,
|
|
7
|
+
p as getPhotoCrop,
|
|
8
|
+
t as readPhoto,
|
|
9
|
+
x as validatePhotoFile
|
|
10
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { localizedText as d } from "../locale.js";
|
|
2
|
+
import { EN_LOCALE as l } from "../../../constants.js";
|
|
3
|
+
import { DEFAULT_MIN_DIMENSION as I, DEFAULT_TIMEOUT as c, MS_UNIT as p } from "../constants.js";
|
|
4
|
+
import { PhotoSizeError as v } from "../errors/photo-size.error.js";
|
|
5
|
+
const N = async (f, s = I, o = l, u = c) => new Promise(
|
|
6
|
+
(m, t) => {
|
|
7
|
+
const e = new FileReader();
|
|
8
|
+
let r = !1;
|
|
9
|
+
const E = setTimeout(() => {
|
|
10
|
+
r || (r = !0, e.abort(), t(
|
|
11
|
+
new Error(
|
|
12
|
+
`${d[o]["timeout-error"]}: ${u}${p}`
|
|
13
|
+
)
|
|
14
|
+
));
|
|
15
|
+
}, u);
|
|
16
|
+
e.addEventListener("load", () => {
|
|
17
|
+
if (r) return;
|
|
18
|
+
r = !0, clearTimeout(E);
|
|
19
|
+
const a = e.result?.toString() || "";
|
|
20
|
+
if (!a) {
|
|
21
|
+
m("");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const n = new Image();
|
|
25
|
+
n.src = a, n.addEventListener("load", () => {
|
|
26
|
+
const { naturalWidth: i, naturalHeight: L } = n;
|
|
27
|
+
if (i < s || L < s) {
|
|
28
|
+
const T = v.get(s, o);
|
|
29
|
+
t(T);
|
|
30
|
+
} else
|
|
31
|
+
m(a);
|
|
32
|
+
}), n.addEventListener("error", () => {
|
|
33
|
+
const i = new Error(d[o]["paint-error"]);
|
|
34
|
+
t(i);
|
|
35
|
+
}), n.addEventListener("abort", () => {
|
|
36
|
+
const i = new Error(d[o]["read-abort"]);
|
|
37
|
+
t(i);
|
|
38
|
+
});
|
|
39
|
+
}), e.addEventListener("error", () => {
|
|
40
|
+
r || (r = !0, clearTimeout(E), t(e.error));
|
|
41
|
+
}), e.addEventListener("abort", () => {
|
|
42
|
+
if (r) return;
|
|
43
|
+
r = !0, clearTimeout(E);
|
|
44
|
+
const a = new Error(d[o]["paint-abort"]);
|
|
45
|
+
t(a);
|
|
46
|
+
}), e.readAsDataURL(f);
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
export {
|
|
50
|
+
N as readPhoto
|
|
51
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { localizedText as i } from "../locale.js";
|
|
2
|
+
import { EN_LOCALE as x, BYTE_TO_KILOBYTE as p } from "../../../constants.js";
|
|
3
|
+
import { MB_UNIT as _, MB_FRACTION_DIGITS as $, SUPPORTED_IMAGE_EXTENSIONS as d, SUPPORTED_IMAGE_MIME_TYPES as n, MIME_TO_EXT as y } from "../constants.js";
|
|
4
|
+
import { PhotoFileError as I } from "../errors/photo-file.error.js";
|
|
5
|
+
const u = (e, t, r = x) => {
|
|
6
|
+
const o = [];
|
|
7
|
+
t?.maxSize && e.size > t.maxSize && o.push(
|
|
8
|
+
`${i[r]["large-file"]}. ${i[r]["maximum-size"]}: ${(t.maxSize / p / p).toFixed(
|
|
9
|
+
$
|
|
10
|
+
)}${_}`
|
|
11
|
+
);
|
|
12
|
+
const s = t?.allowedExtensions || d, m = "." + e.name.split(".").pop()?.toLowerCase();
|
|
13
|
+
s.includes(m) || o.push(`${i[r]["file-ext-error"]}: ${m}`);
|
|
14
|
+
const T = t?.allowedMimeTypes || n;
|
|
15
|
+
e.type && !T.includes(e.type) && o.push(`${i[r]["file-type-error"]}: ${e.type}`);
|
|
16
|
+
const E = y;
|
|
17
|
+
if (e.type && E[e.type] && (E[e.type].includes(m) || o.push(
|
|
18
|
+
`${i[r]["mime-type"]} ${e.type} ${i[r]["not-correspond-ext"]} ${m}`
|
|
19
|
+
)), o.length)
|
|
20
|
+
throw I.get(o, t);
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
u as validatePhotoFile
|
|
24
|
+
};
|