{"version":3,"file":"styles.css","mappings":"AAqLA,gBAEA,mBAMA,oDACA,uDACA,2DANA,sBAGA,4CAIA,eAVA,aAKA,YAHA,uBASA,wCAPA,UAQA,CAEA,+BACA,sDACA,CAEA,gBACA,YACA,CCpGA,gBAaA,oDANA,wBADA,4BAEA,sBACA,uDACA,2DARA,sBAEA,YACA,gBAJA,kBAUA,wCARA,UAWA,CAEA,gDAMA,SACA,OAJA,kBAEA,QADA,KAIA,CAEA,gBACA,WACA,WACA,CAEA,gBACA,4DAKA,CAHA,+BACA,0DACA,CAGA,gBAEA,mBAEA,wBACA,sBAJA,aAEA,sBAGA,CAEA,gBACA,mCACA,CAEA,gBACA,kBAEA,UADA,OAEA,CAEA,gBAEA,YADA,UAEA,CAEA,gBAGA,SACA,OACA,UAJA,kBACA,QAIA,8BAKA,CAHA,+BACA,SACA,CCoMA,gBAGA,cACA,uBAHA,aACA,cAGA,CAEA,gBACA,aACA","sources":["webpack://@square/maker/./src/components/ImageUploader/src/ImagePicker.vue","webpack://@square/maker/./src/components/ImageUploader/src/ImageSelection.vue","webpack://@square/maker/./src/components/ImageUploader/src/ImageUploader.vue"],"sourcesContent":["<template>\n\t<div\n\t\t:class=\"{\n\t\t\t[$s.ImagePickerInputContainer]: true,\n\t\t\t[$s.isDragged]: dragged,\n\t\t}\"\n\t\trole=\"button\"\n\t\ttabindex=\"0\"\n\t\t@click=\"$refs.input.click()\"\n\t\t@keydown.space.enter.prevent=\"$refs.input.click()\"\n\t\t@drop.prevent=\"handleDrop($event)\"\n\t\t@dragenter.prevent=\"setDragged(true)\"\n\t\t@dragover.prevent=\"setDragged(true)\"\n\t\t@dragleave.prevent=\"setDragged(false)\"\n\t>\n\t\t<input\n\t\t\tref=\"input\"\n\t\t\t:class=\"$s.ImagePickerInput\"\n\t\t\ttype=\"file\"\n\t\t\tv-bind=\"$attrs\"\n\t\t\t@change=\"addImages\"\n\t\t>\n\t\t<m-icon\n\t\t\tv-if=\"dragged\"\n\t\t\tname=\"arrowUp\"\n\t\t\tsize=\"large\"\n\t\t/>\n\t\t<m-icon\n\t\t\tv-else\n\t\t\tname=\"plus\"\n\t\t\tsize=\"medium\"\n\t\t/>\n\t</div>\n</template>\n\n<script>\nimport { MIcon } from '@square/maker/components/Icon';\nimport {\n\tisEqual,\n\tuniqWith,\n\tescapeRegExp,\n\tpartition,\n} from 'lodash';\n\nconst getEntry = (item) => {\n\tif (item.getAsEntry) {\n\t\treturn item.getAsEntry();\n\t}\n\n\tif (item.webkitGetAsEntry) {\n\t\treturn item.webkitGetAsEntry();\n\t}\n\n\treturn undefined;\n};\n\nconst getEntryFile = (entry) => new Promise((resolve, reject) => {\n\tentry.file(resolve, reject);\n});\nconst readEntries =\t(reader) => new Promise((resolve, reject) => {\n\treader.readEntries(resolve, reject);\n});\n\nconst getAllEntries = async (reader, aggregated = []) => {\n\tconst entries = await readEntries(reader);\n\tif (entries.length === 0) {\n\t\treturn aggregated;\n\t}\n\n\treturn getAllEntries(reader, aggregated.concat(entries));\n};\n\nasync function traverseEntry(entry) {\n\tif (entry) {\n\t\ttry {\n\t\t\tif (entry.isFile) {\n\t\t\t\treturn await getEntryFile(entry);\n\t\t\t}\n\n\t\t\tif (entry.isDirectory) {\n\t\t\t\tconst entries = await getAllEntries(entry.createReader());\n\n\t\t\t\treturn Promise.all(entries.map((innerEntry) => traverseEntry(innerEntry)));\n\t\t\t}\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nexport default {\n\tcomponents: {\n\t\tMIcon,\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tdragged: false,\n\t\t};\n\t},\n\n\tmethods: {\n\t\taddImages(fileEvent) {\n\t\t\tthis.emitFiles([...fileEvent.target.files]);\n\t\t},\n\n\t\tsetDragged(dragged) {\n\t\t\tthis.dragged = dragged;\n\t\t},\n\n\t\tasync handleDrop(event) {\n\t\t\tthis.setDragged(false);\n\n\t\t\tif (event.dataTransfer.items) {\n\t\t\t\tconst fileEntries = await Promise.all(\n\t\t\t\t\t[...event.dataTransfer.items]\n\t\t\t\t\t\t.map((item) => traverseEntry(getEntry(item))),\n\t\t\t\t);\n\n\t\t\t\tconst wBuffers = await Promise.all(\n\t\t\t\t\tfileEntries\n\t\t\t\t\t\t.filter((entry) => Boolean(entry))\n\t\t\t\t\t\t.flat(Infinity).map(\n\t\t\t\t\t\t\t(file) => file.arrayBuffer().then((buffer) => ({ file, buffer })),\n\t\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\tconst files = uniqWith(wBuffers, isEqual).map((f) => f.file);\n\n\t\t\t\tthis.validateAndEmit(files);\n\t\t\t} else {\n\t\t\t\tthis.validateAndEmit(event.dataTransfer.files);\n\t\t\t}\n\t\t},\n\n\t\tvalidateFile(file) {\n\t\t\tconst { accept } = this.$attrs;\n\n\t\t\tif (!accept) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst fileType = file.type;\n\n\t\t\treturn accept\n\t\t\t\t.split(',')\n\t\t\t\t.map((acceptedType) => acceptedType.trim())\n\t\t\t\t.some((acceptedType) => {\n\t\t\t\t\tif (acceptedType[0] === '.') {\n\t\t\t\t\t\treturn new RegExp(`${escapeRegExp(acceptedType)}$`, 'i').test(file.name);\n\t\t\t\t\t}\n\n\t\t\t\t\t// MIME\n\t\t\t\t\tconst isMime = acceptedType.match(/^.+\\/.+$/);\n\t\t\t\t\tif (isMime) {\n\t\t\t\t\t\tif (acceptedType === '*/*') {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn new RegExp(escapeRegExp(acceptedType).replace(/\\\\\\*/g, '.+')).test(fileType);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn acceptedType === fileType;\n\t\t\t\t});\n\t\t},\n\n\t\tvalidateAndEmit(files) {\n\t\t\tconst [validFiles] = partition(files, this.validateFile);\n\t\t\tthis.emitFiles(validFiles);\n\t\t},\n\n\t\temitFiles(files) {\n\t\t\tthis.$emit('image-picker:add-images', files);\n\t\t},\n\t},\n};\n</script>\n\n<style module=\"$s\">\n.ImagePickerInputContainer {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbox-sizing: border-box;\n\twidth: 96px;\n\theight: 96px;\n\tcolor: $maker-color-neutral-20;\n\tbackground-color: $maker-color-background;\n\tborder: 1px solid $maker-color-neutral-20;\n\tborder-radius: $maker-shape-default-border-radius;\n\tcursor: pointer;\n\ttransition: background-color 150ms linear;\n}\n\n.ImagePickerInputContainer.isDragged {\n\tbackground-color: $maker-color-neutral-10;\n}\n\n.ImagePickerInput {\n\tdisplay: none;\n}\n</style>\n","<template>\n\t<div\n\t\t:class=\"{\n\t\t\t[$s.ImageSelectionContainer]: true,\n\t\t\t[$s.ImageSelectionContainerError]: isError\n\t\t}\"\n\t\trole=\"img\"\n\t>\n\t\t<!-- Actual Image (hidden if not displayable) -->\n\t\t<div\n\t\t\t:class=\"$s.ImageDisplay\"\n\t\t\t:style=\"imageDisplayStyles\"\n\t\t/>\n\n\t\t<!-- Filter (greyed if loading, gradient when loaded) -->\n\t\t<div\n\t\t\t:class=\"{\n\t\t\t\t[$s.ImageFilter]: true,\n\t\t\t\t[$s.IsLoading]: isUploading\n\t\t\t}\"\n\t\t/>\n\n\t\t<!-- Loading spinner -->\n\t\t<div\n\t\t\tv-if=\"isUploading\"\n\t\t\t:class=\"$s.ImageSelectionLoaderContainer\"\n\t\t>\n\t\t\t<m-loading :class=\"$s.ImageSelectionLoader\" />\n\t\t</div>\n\n\t\t<!-- Loading progress -->\n\t\t<m-progress-bar\n\t\t\t:class=\"{\n\t\t\t\t[$s.ImageSelectionProgressContainer]: true,\n\t\t\t\t[$s.IsLoading]: isUploading,\n\t\t\t}\"\n\t\t\t:progress=\"progress\"\n\t\t\tsize=\"xsmall\"\n\t\t/>\n\n\t\t<m-button\n\t\t\tv-if=\"!isUploading\"\n\t\t\tsize=\"small\"\n\t\t\tcolor=\"#ffffff\"\n\t\t\t:class=\"$s.TopRight\"\n\t\t\t@click=\"$emit('removeImage')\"\n\t\t>\n\t\t\t<m-icon\n\t\t\t\t:class=\"$s.ImageSelectionRemoveIcon\"\n\t\t\t\tname=\"close\"\n\t\t\t/>\n\t\t</m-button>\n\t</div>\n</template>\n\n<script>\nimport { MButton } from '@square/maker/components/Button';\nimport { MLoading } from '@square/maker/components/Loading';\nimport { MProgressBar } from '@square/maker/components/ProgressBar';\nimport { MIcon } from '@square/maker/components/Icon';\n\nexport default {\n\tcomponents: {\n\t\tMButton,\n\t\tMLoading,\n\t\tMProgressBar,\n\t\tMIcon,\n\t},\n\n\tprops: {\n\t\tprogress: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0,\n\t\t},\n\t\turl: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t\tisUploading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\tisError: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tcomputed: {\n\t\timageDisplayStyles() {\n\t\t\treturn {\n\t\t\t\tbackgroundImage: `url(\"${this.url}\")`,\n\t\t\t\tbackgroundRepeat: 'no-repeat',\n\t\t\t\tbackgroundPosition: 'center',\n\t\t\t\tbackgroundSize: 'cover',\n\t\t\t};\n\t\t},\n\t},\n};\n</script>\n\n<style module=\"$s\">\n.ImageSelectionContainer {\n\tposition: relative;\n\tbox-sizing: border-box;\n\twidth: 96px;\n\theight: 96px;\n\toverflow: hidden;\n\tbackground-repeat: no-repeat;\n\tbackground-position: center;\n\tbackground-size: cover;\n\tborder: 1px solid $maker-color-neutral-20;\n\tborder-radius: $maker-shape-default-border-radius;\n\ttransition: background-image linear 150ms;\n\n\t--color-error: $maker-color-error-fill;\n}\n\n.ImageDisplay,\n.ImageFilter,\n.ImageSelectionLoaderContainer {\n\tposition: absolute;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n}\n\n.ImageIcon {\n\theight: 65%;\n\topacity: 0.95;\n}\n\n.ImageFilter {\n\tbackground-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 50%);\n\n\t&.IsLoading {\n\t\tbackground-image: linear-gradient(0deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5));\n\t}\n}\n\n.ImageSelectionLoaderContainer {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground-position: center;\n\tbackground-size: cover;\n}\n\n.ImageSelectionContainerError {\n\tborder: 1px solid var(--color-error);\n}\n\n.TopRight {\n\tposition: absolute;\n\ttop: 8px;\n\tright: 8px;\n}\n\n.ImageSelectionRemoveIcon {\n\twidth: 16px;\n\theight: 16px;\n}\n\n.ImageSelectionProgressContainer {\n\tposition: absolute;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\topacity: 0;\n\ttransition: opacity 150ms linear;\n\n\t&.IsLoading {\n\t\topacity: 1;\n\t}\n}\n</style>\n","<template>\n\t<div :class=\"$s.ImageUploaderContainer\">\n\t\t<image-picker\n\t\t\tv-if=\"canUploadImage\"\n\t\t\t:class=\"$s.ImageUploaderItem\"\n\t\t\t:multiple=\"canUploadMultiple\"\n\t\t\t:accept=\"accept\"\n\t\t\t@image-picker:add-images=\"addImages\"\n\t\t/>\n\t\t<image-selection\n\t\t\tv-for=\"image of images\"\n\t\t\t:key=\"image.id\"\n\t\t\t:progress=\"image.progress\"\n\t\t\t:url=\"image.url\"\n\t\t\t:is-uploading=\"isUploadingImage(image)\"\n\t\t\t:is-error=\"isImageWithError(image)\"\n\t\t\t:class=\"$s.ImageUploaderItem\"\n\t\t\t@removeImage=\"removeImage(image.id)\"\n\t\t/>\n\t</div>\n</template>\n\n<script>\nimport ImagePicker from './ImagePicker.vue';\nimport ImageSelection from './ImageSelection.vue';\nimport { IMAGE_SELECTOR_STATUSES } from './constants';\n\nconst MAX_PROGRESS = 100;\nconst ID_INCREMENT = 1;\nconst NO_MORE_IMAGES_COUNT = 0;\n\nexport default {\n\tname: 'MImageUploader',\n\n\tcomponents: {\n\t\tImagePicker,\n\t\tImageSelection,\n\t},\n\n\tprops: {\n\t\t// Not disabling and breaking the line causes the doc generator to break.\n\t\t/* eslint-disable max-len */\n\t\t/**\n\t\t * Function called to trigger an upload. Called immediately on image selection, provided max size and max number image constraints are met.\n\t\t*/\n\t\t/* eslint-enable max-len */\n\t\tuploadHandler: {\n\t\t\ttype: Function,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * The maximum number of images allowed to be selected.\n\t\t */\n\t\tmaxImages: {\n\t\t\ttype: Number,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * The maximum file size allowed (in bytes)\n\t\t */\n\t\tmaxSize: {\n\t\t\ttype: Number,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Allowed file types, must be an image type (eg image/jpeg)\n\t\t */\n\t\taccept: {\n\t\t\ttype: String,\n\t\t\tdefault: 'image/*',\n\t\t\tvalidator: (accept) => accept.startsWith('image/'),\n\t\t},\n\t},\n\n\tdata: () => ({\n\t\timages: [],\n\t\tnextID: 0,\n\t}),\n\n\tcomputed: {\n\t\tcanUploadImage() {\n\t\t\tif (this.maxImages === undefined) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn this.images.length < this.maxImages;\n\t\t},\n\t\tremainingImagesCount() {\n\t\t\tif (!this.canUploadImage) {\n\t\t\t\treturn NO_MORE_IMAGES_COUNT;\n\t\t\t}\n\n\t\t\treturn this.maxImages - this.images.length;\n\t\t},\n\n\t\tcanUploadMultiple() {\n\t\t\t// eslint-disable-next-line no-magic-numbers\n\t\t\treturn !this.maxImages || this.maxImages > 1;\n\t\t},\n\t},\n\n\twatch: {\n\t\timages: {\n\t\t\tdeep: true,\n\t\t\thandler() {\n\t\t\t\tthis.updateImages();\n\t\t\t},\n\t\t\timmediate: true,\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Processes images selected by the picker, ensuring the number of images\n\t\t * is not above the max, passes them to the formatter, and then triggers the upload.\n\t\t *\n\t\t * @param {Array} images a list of Files\n\t\t */\n\t\tasync addImages(images) {\n\t\t\tif (!this.canUploadImage) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst imagesToUpload = images.length > this.remainingImagesCount\n\t\t\t\t// eslint-disable-next-line no-magic-numbers\n\t\t\t\t? images.slice(0, this.remainingImagesCount)\n\t\t\t\t: images;\n\n\t\t\tconst formattedImages = await this.formatImages(imagesToUpload);\n\t\t\tthis.images = [...this.images, ...formattedImages];\n\t\t\tformattedImages.forEach((image) => this.handleImageUpload(image));\n\t\t},\n\n\t\t/**\n\t\t * Transforms a list of image Files into a standard object with status/upload attributes\n\t\t *\n\t\t * @param {Array} images a list of Files\n\t\t */\n\t\tasync formatImages(images) {\n\t\t\tconst formattedImages = images\n\t\t\t\t.map((image) => {\n\t\t\t\t\tthis.nextID += ID_INCREMENT;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: this.nextID,\n\t\t\t\t\t\tfile: image,\n\t\t\t\t\t\tstatus: IMAGE_SELECTOR_STATUSES.UPLOADING,\n\t\t\t\t\t\tprogress: 0,\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\tthis.buildImageURLs(formattedImages);\n\n\t\t\treturn formattedImages;\n\t\t},\n\n\t\t/**\n\t\t * Transforms an image File into a base64 URL. Used to display on the UI.\n\t\t *\n\t\t * @param {Object} image formatted image object\n\t\t */\n\t\tbuildImageURLs(images) {\n\t\t\timages.forEach((image) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.$set(image, 'url', window.URL.createObjectURL(image.file));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.$set(image, 'fileReadError', true);\n\t\t\t\t\tthis.setImageError(image, error);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\t/**\n\t\t * Starts the upload process for a formatted image. First checks to make sure an image\n\t\t * fits the filesize limit, and then calls the upload handler function (if present).\n\t\t *\n\t\t * @param {Object} image a formatted image object\n\t\t */\n\t\tasync handleImageUpload(image) {\n\t\t\tthis.validateImageSize(image);\n\n\t\t\tif (!this.isImageValid(image)) {\n\t\t\t\tthis.setImageFailed(image);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!this.uploadHandler) {\n\t\t\t\tthis.setImageComplete(image);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst response = await this.uploadHandler({\n\t\t\t\t\timageFile: image.file,\n\t\t\t\t\tsetImageProgress: (progress) => this.setImageProgress(image, progress),\n\t\t\t\t});\n\t\t\t\tthis.setImageComplete(image, response);\n\t\t\t} catch (error) {\n\t\t\t\tthis.setImageFailed(image, error);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Removes an image from the list\n\t\t *\n\t\t * @param {String} imageID id of a formatted image object\n\t\t */\n\t\tremoveImage(imageID) {\n\t\t\tthis.images = this.images.filter(({ id }) => id !== imageID);\n\t\t},\n\n\t\t/**\n\t\t * Validates image file size (if set)\n\t\t *\n\t\t * @param i{Object} mage image record to be validated\n\t\t */\n\t\tvalidateImageSize(image) {\n\t\t\tif (this.maxSize && image.file.size > this.maxSize) {\n\t\t\t\tthis.$set(image, 'fileTooLarge', true);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Checks if a file meets validation (max-size)\n\t\t *\n\t\t * @param {Object} image image record to be validated\n\t\t *\n\t\t * @returns {Boolean} true if valid, false if not\n\t\t */\n\t\tisImageValid(image) {\n\t\t\treturn !image.fileTooLarge && !image.fileReadError;\n\t\t},\n\n\t\t/**\n\t\t * Sets image state after an upload is completed\n\t\t *\n\t\t * @param {Object} image image record to be updated\n\t\t * @param {Object} apiResponse return value of upload handler callback\n\t\t */\n\t\tsetImageComplete(image, apiResponse) {\n\t\t\tif (apiResponse) {\n\t\t\t\tthis.setImageApiResponse(image, apiResponse);\n\t\t\t}\n\n\t\t\tthis.setImageStatus(image, IMAGE_SELECTOR_STATUSES.COMPLETE);\n\t\t\tthis.setImageProgress(image, MAX_PROGRESS);\n\t\t},\n\n\t\t/**\n\t\t * Sets image state after an upload has failed\n\t\t *\n\t\t * @param {Object} image image record to be updated\n\t\t * @param {Object} apiResponse thrown error from upload handler callback\n\t\t */\n\t\tsetImageFailed(image, error) {\n\t\t\tif (error) {\n\t\t\t\tthis.setImageError(image, error);\n\t\t\t}\n\n\t\t\tthis.setImageStatus(image, IMAGE_SELECTOR_STATUSES.ERROR);\n\t\t\tthis.setImageProgress(image, MAX_PROGRESS);\n\t\t},\n\n\t\t/**\n\t\t * Sets image status\n\t\t *\n\t\t * @param {Object} image image record to be updated\n\t\t * @param {String} status new status for image\n\t\t */\n\t\tsetImageStatus(image, status) {\n\t\t\tthis.$set(image, 'status', status);\n\t\t},\n\n\t\t/**\n\t\t * Sets image progress\n\t\t *\n\t\t * @param {Object} image image record to be updated\n\t\t * @param {Number} progress new progress for image\n\t\t */\n\t\tsetImageProgress(image, progress) {\n\t\t\tthis.$set(image, 'progress', progress);\n\t\t},\n\n\t\t/**\n\t\t * Sets image API response\n\t\t *\n\t\t * @param {Object} image image record to be updated\n\t\t * @param {String} apiResponse API response from upload of the image\n\t\t */\n\t\tsetImageApiResponse(image, apiResponse) {\n\t\t\tthis.$set(image, 'apiResponse', apiResponse);\n\t\t},\n\n\t\t/**\n\t\t * Sets image error\n\t\t *\n\t\t * @param {Object} image image record to be updated\n\t\t * @param {String} error error thrown by image upload\n\t\t */\n\t\tsetImageError(image, error) {\n\t\t\tthis.$set(image, 'error', error);\n\t\t},\n\n\t\timagesForStatus(status) {\n\t\t\treturn this.images.filter((image) => image.status === status);\n\t\t},\n\n\t\tsanitizeOutputImages(images) {\n\t\t\treturn images.map((image) => ({\n\t\t\t\tid: image.id,\n\t\t\t\tstatus: image.status,\n\t\t\t\tfile: image.file,\n\t\t\t\tapiResponse: image.apiResponse,\n\t\t\t\terror: image.error,\n\t\t\t\tfileTooLarge: image.fileTooLarge,\n\t\t\t\tfileReadError: image.fileReadError,\n\t\t\t}));\n\t\t},\n\n\t\tupdateImages() {\n\t\t\t/**\n\t\t\t * Update to list of images\n\t\t\t *\n\t\t\t * @property {Array} images list of all images in uploader\n\t\t\t */\n\t\t\tthis.$emit('image-uploader:change', this.sanitizeOutputImages(this.images));\n\n\t\t\t/**\n\t\t\t * Update to list of images that are currently uploading\n\t\t\t *\n\t\t\t * @property {Array} images list of uploading images in uploader\n\t\t\t */\n\t\t\tthis.$emit(\n\t\t\t\t'image-uploader:uploading',\n\t\t\t\tthis.sanitizeOutputImages(this.imagesForStatus(IMAGE_SELECTOR_STATUSES.UPLOADING)),\n\t\t\t);\n\n\t\t\t/**\n\t\t\t * Update to list of images with an error\n\t\t\t *\n\t\t\t * @property {Array} images list of failed images in uploader\n\t\t\t */\n\t\t\tthis.$emit(\n\t\t\t\t'image-uploader:error',\n\t\t\t\tthis.sanitizeOutputImages(this.imagesForStatus(IMAGE_SELECTOR_STATUSES.ERROR)),\n\t\t\t);\n\n\t\t\t/**\n\t\t\t * Update to list of images that have successfully uploaded\n\t\t\t *\n\t\t\t * @property {Array} images list of uploaded images in uploader\n\t\t\t */\n\t\t\tthis.$emit(\n\t\t\t\t'image-uploader:complete',\n\t\t\t\tthis.sanitizeOutputImages(this.imagesForStatus(IMAGE_SELECTOR_STATUSES.COMPLETE)),\n\t\t\t);\n\t\t},\n\n\t\tisUploadingImage(image) {\n\t\t\treturn image.status === IMAGE_SELECTOR_STATUSES.UPLOADING;\n\t\t},\n\n\t\tisImageWithError(image) {\n\t\t\treturn image.status === IMAGE_SELECTOR_STATUSES.ERROR;\n\t\t},\n\t},\n};\n</script>\n\n<style module=\"$s\">\n.ImageUploaderContainer {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 16px;\n\talign-items: flex-start;\n}\n\n.ImageUploaderItem {\n\tflex-shrink: 0;\n}\n</style>\n"],"names":[],"sourceRoot":""}