{"version":3,"file":"photos-node_modules_vue-material-design-icons_AccountBoxMultipleOutline_vue-src_components_FaceCover_vue.js?v=0d661f3d969665d43113","mappings":"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","sources":["webpack:///photos/src/mixins/FaceCoverMixin.js","webpack:///photos/src/mixins/FetchFacesMixin.js","webpack:///photos/src/components/FaceCover.vue?vue&type=style&index=0&id=53f3a852&prod&lang=scss&scoped=true&","webpack:///photos/node_modules/vue-material-design-icons/AccountBoxMultipleOutline.vue","webpack:///photos/node_modules/vue-material-design-icons/AccountBoxMultipleOutline.vue?vue&type=script&lang=js&","webpack://photos/./node_modules/vue-material-design-icons/AccountBoxMultipleOutline.vue?a4da","webpack:///photos/node_modules/vue-material-design-icons/AccountBoxMultipleOutline.vue?vue&type=template&id=6bcc1fce&","webpack://photos/./src/components/FaceCover.vue?a1ab","webpack:///photos/src/components/FaceCover.vue","webpack:///photos/src/components/FaceCover.vue?vue&type=script&lang=js&","webpack://photos/./src/components/FaceCover.vue?6820","webpack://photos/./src/components/FaceCover.vue?d6a7"],"sourcesContent":["/**\n * @copyright Copyright (c) 2022 Marcel Klehr \n *\n * @author Marcel Klehr \n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see .\n *\n */\n\nimport { mapGetters } from 'vuex'\n\nexport default {\n\tname: 'FaceCoverMixin',\n\n\tcomputed: {\n\t\t...mapGetters([\n\t\t\t'faces',\n\t\t\t'facesFiles',\n\t\t\t'files',\n\t\t]),\n\t},\n\n\tmethods: {\n\t\tgetFaceCover(faceName) {\n\t\t\t// Give high scores for faces that intersect with the edge of the picture (with a margin of half the face size)\n\t\t\tconst scoreFacePosition = (faceDetection) => {\n\t\t\t\treturn Math.max(0, -1 * (faceDetection.x - faceDetection.width * 0.5))\n\t\t\t\t+ Math.max(0, -1 * (faceDetection.y - faceDetection.height * 0.5))\n\t\t\t\t+ Math.max(0, -1 * (1 - (faceDetection.x + faceDetection.width) - faceDetection.width * 0.5))\n\t\t\t\t+ Math.max(0, -1 * (1 - (faceDetection.y + faceDetection.height) - faceDetection.height * 0.5))\n\t\t\t}\n\n\t\t\treturn (this.facesFiles[faceName] || [])\n\t\t\t\t.slice(0, 25)\n\t\t\t\t.map(fileId => this.files[fileId])\n\t\t\t\t// sort larges face first\n\t\t\t\t.sort((a, b) =>\n\t\t\t\t\tb.faceDetections.find(d => d.title === faceName).width\n\t\t\t\t\t- a.faceDetections.find(d => d.title === faceName).width\n\t\t\t\t)\n\t\t\t\t// sort fewest face detections first\n\t\t\t\t.sort((a, b) =>\n\t\t\t\t\ta.faceDetections.length\n\t\t\t\t\t- b.faceDetections.length\n\t\t\t\t)\n\t\t\t\t// Sort faces that are at the edge last\n\t\t\t\t.sort((a, b) =>\n\t\t\t\t\tscoreFacePosition(a.faceDetections.find(d => d.title === faceName))\n\t\t\t\t\t- scoreFacePosition(b.faceDetections.find(d => d.title === faceName))\n\t\t\t\t)[0]\n\t\t},\n\n\t\t/**\n\t\t * This will produce an inline style to apply to images\n\t\t * to zoom toward the detected face\n\t\t *\n\t\t * @param faceName\n\t\t * @return {{}|{transform: string, width: string, transformOrigin: string}}\n\t\t */\n\t\tgetCoverStyle(faceName) {\n\t\t\tconst cover = this.getFaceCover(faceName)\n\t\t\tif (!cover) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst detections = cover.faceDetections\n\n\t\t\tconst detection = detections.find(detection => detection.title === faceName)\n\n\t\t\t// Zoom into the picture so that the face fills the --photos-face-width box nicely\n\t\t\t// if the face is larger than the image, we don't zoom out (reason for the Math.max)\n\t\t\tconst zoom = Math.max(1, (1 / detection.width) * 0.4)\n\n\t\t\tconst horizontalCenterOfFace = (detection.x + detection.width / 2) * 100\n\t\t\tconst verticalCenterOfFace = (detection.y + detection.height / 2) * 100\n\n\t\t\treturn {\n\t\t\t\t// We assume that the image is inside a div with width: var(--photos-face-width)\n\t\t\t\twidth: '100%',\n\t\t\t\t// we translate the image so that the center of the detected face is in the center of the --photos-face-width box\n\t\t\t\t// and add the zoom\n\t\t\t\ttransform: `translate(calc( var(--photos-face-width)/2 - ${horizontalCenterOfFace}% ), calc( var(--photos-face-width)/2 - ${verticalCenterOfFace}% )) scale(${zoom})`,\n\t\t\t\t// this is necessary for the zoom to zoom toward the center of the face\n\t\t\t\ttransformOrigin: `${horizontalCenterOfFace}% ${verticalCenterOfFace}%`,\n\t\t\t}\n\t\t},\n\t},\n}\n","/**\n * @copyright Copyright (c) 2022 Louis Chemineau \n *\n * @author Louis Chemineau \n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see .\n *\n */\n\nimport { mapActions, mapGetters } from 'vuex'\n\nimport { showError } from '@nextcloud/dialogs'\nimport { getCurrentUser } from '@nextcloud/auth'\n\nimport client from '../services/DavClient.js'\nimport logger from '../services/logger.js'\nimport DavRequest from '../services/DavRequest'\nimport { genFileInfo } from '../utils/fileUtils'\nimport AbortControllerMixin from './AbortControllerMixin'\nimport he from 'he'\n\nexport default {\n\tname: 'FetchFacesMixin',\n\n\tdata() {\n\t\treturn {\n\t\t\terrorFetchingFaces: null,\n\t\t\tloadingFaces: false,\n\t\t\terrorFetchingFiles: null,\n\t\t\tloadingFiles: false,\n\t\t}\n\t},\n\n\tmixins: [\n\t\tAbortControllerMixin,\n\t],\n\n\tasync beforeMount() {\n\t\tthis.fetchFaces()\n\t},\n\n\tcomputed: {\n\t\t...mapGetters([\n\t\t\t'faces',\n\t\t]),\n\t},\n\n\tmethods: {\n\t\t...mapActions([\n\t\t\t'appendFiles',\n\t\t]),\n\n\t\tasync fetchFaces() {\n\t\t\tif (this.loadingFaces) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (Object.keys(this.faces).length) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tthis.loadingFaces = true\n\t\t\t\tthis.errorFetchingFaces = null\n\n\t\t\t\tconst { data: faces } = await client.getDirectoryContents(`/recognize/${getCurrentUser()?.uid}/faces/`, {\n\t\t\t\t\tdata: DavRequest,\n\t\t\t\t\tdetails: true,\n\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t})\n\t\t\t\tthis.$store.dispatch('addFaces', { faces })\n\t\t\t\tlogger.debug(`[FetchFacesMixin] Fetched ${faces.length} new faces: `, faces)\n\t\t\t} catch (error) {\n\t\t\t\tif (error.response && error.response.status) {\n\t\t\t\t\tif (error.response.status === 404) {\n\t\t\t\t\t\tthis.errorFetchingFaces = 404\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.errorFetchingFaces = error\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlogger.error(t('photos', 'Failed to fetch faces list.'), { error })\n\t\t\t\tshowError(t('photos', 'Failed to fetch faces list.'))\n\t\t\t} finally {\n\t\t\t\tthis.loadingFaces = false\n\t\t\t}\n\t\t},\n\n\t\tasync fetchFaceContent(faceName, force) {\n\t\t\tif (this.loadingFiles) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (!force && this.facesFiles[faceName] && this.facesFiles[faceName].length) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tthis.errorFetchingFiles = null\n\t\t\t\tthis.loadingFiles = true\n\n\t\t\t\tlet { data: fetchedFiles } = await client.getDirectoryContents(\n\t\t\t\t\t`/recognize/${getCurrentUser()?.uid}/faces/${faceName}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tdata: DavRequest,\n\t\t\t\t\t\tdetails: true,\n\t\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tfetchedFiles = fetchedFiles\n\t\t\t\t\t.map(file => genFileInfo(file))\n\t\t\t\t\t.map(file => ({ ...file, filename: he.decode(file.realpath).replace(`/${getCurrentUser().uid}/files`, `/files/${getCurrentUser().uid}`) }))\n\t\t\t\t\t.map(file => ({ ...file, faceDetections: JSON.parse(he.decode(file.faceDetections)) }))\n\n\t\t\t\tconst fileIds = fetchedFiles.map(file => '' + file.fileid)\n\n\t\t\t\tthis.appendFiles(fetchedFiles)\n\n\t\t\t\tif (fetchedFiles.length > 0) {\n\t\t\t\t\tawait this.$store.commit('addFilesToFace', { faceName, fileIdsToAdd: fileIds })\n\t\t\t\t}\n\n\t\t\t\tlogger.debug(`[FetchFacesMixin] Fetched ${fileIds.length} new files: `, fileIds)\n\t\t\t} catch (error) {\n\t\t\t\tif (error.response && error.response.status) {\n\t\t\t\t\tif (error.response.status === 404) {\n\t\t\t\t\t\tthis.errorFetchingFiles = 404\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.errorFetchingFiles = error\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// cancelled request, moving on...\n\t\t\t\tlogger.error('Error fetching face files', { error })\n\t\t\t} finally {\n\t\t\t\tthis.loadingFiles = false\n\t\t\t}\n\t\t},\n\t},\n}\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".face-cover[data-v-53f3a852]{display:flex;flex-direction:column;padding:10px;border-radius:var(--border-radius-large)}.face-cover__crop-container[data-v-53f3a852]{overflow:hidden;width:128px;height:128px;border-radius:128px;position:relative;background:var(--color-background-darker);--photos-face-width: 128px}@media only screen and (max-width: 1020px){.face-cover__crop-container[data-v-53f3a852]{width:95px;height:95px;--photos-face-width: 95px}}.face-cover[data-v-53f3a852]:hover,.face-cover[data-v-53f3a852]:focus{background:var(--color-background-hover)}.face-cover__details[data-v-53f3a852]{display:flex;flex-direction:column;width:128px;margin-top:4px;text-align:center}@media only screen and (max-width: 1020px){.face-cover__details[data-v-53f3a852]{width:95px}}.face-cover__details__first-line[data-v-53f3a852]{display:flex;height:2em;overflow:hidden;text-overflow:ellipsis}.face-cover__details__second-line[data-v-53f3a852]{margin-top:6px;color:var(--color-text-maxcontrast)}.face-cover__details__name[data-v-53f3a852]{flex-grow:1;margin:0}.face-cover--small *[data-v-53f3a852]{font-size:15px !important}.face-cover--small .face-cover__details[data-v-53f3a852]{width:60px !important}.face-cover--small .face-cover__crop-container[data-v-53f3a852]{width:60px !important;height:60px !important;--photos-face-width: 60px !important}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/FaceCover.vue\"],\"names\":[],\"mappings\":\"AAEA,6BACC,YAAA,CACA,qBAAA,CACA,YAAA,CACA,wCAAA,CAEA,6CACC,eAAA,CACA,WAAA,CACA,YAAA,CACA,mBAAA,CACA,iBAAA,CACA,yCAAA,CACA,0BAAA,CAEA,2CATD,6CAUE,UAAA,CACA,WAAA,CACA,yBAAA,CAAA,CAIF,sEACC,wCAAA,CAGD,sCACC,YAAA,CACA,qBAAA,CACA,WAAA,CACA,cAAA,CACA,iBAAA,CAEA,2CAPD,sCAQE,UAAA,CAAA,CAGD,kDACC,YAAA,CACA,UAAA,CACA,eAAA,CACA,sBAAA,CAGD,mDACC,cAAA,CACA,mCAAA,CAGD,4CACC,WAAA,CACA,QAAA,CAMF,sCACC,yBAAA,CAED,yDACC,qBAAA,CAED,gEACC,qBAAA,CACA,sBAAA,CACA,oCAAA\",\"sourcesContent\":[\"$sizes: (\\\"400\\\": (\\\"count\\\": 3, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"700\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"1024\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1280\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1440\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"1600\\\": (\\\"count\\\": 6, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2048\\\": (\\\"count\\\": 7, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2560\\\": (\\\"count\\\": 8, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"3440\\\": (\\\"count\\\": 9, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"max\\\": (\\\"count\\\": 10, \\\"marginTop\\\": 88, \\\"marginW\\\": 88));\\n\\n.face-cover {\\n\\tdisplay: flex;\\n\\tflex-direction: column;\\n\\tpadding: 10px;\\n\\tborder-radius: var(--border-radius-large);\\n\\n\\t&__crop-container {\\n\\t\\toverflow: hidden;\\n\\t\\twidth: 128px;\\n\\t\\theight: 128px;\\n\\t\\tborder-radius: 128px;\\n\\t\\tposition: relative;\\n\\t\\tbackground: var(--color-background-darker);\\n\\t\\t--photos-face-width: 128px;\\n\\n\\t\\t@media only screen and (max-width: 1020px) {\\n\\t\\t\\twidth: 95px;\\n\\t\\t\\theight: 95px;\\n\\t\\t\\t--photos-face-width: 95px;\\n\\t\\t}\\n\\t}\\n\\n\\t&:hover, &:focus {\\n\\t\\tbackground: var(--color-background-hover);\\n\\t}\\n\\n\\t&__details {\\n\\t\\tdisplay: flex;\\n\\t\\tflex-direction: column;\\n\\t\\twidth: 128px;\\n\\t\\tmargin-top: 4px;\\n\\t\\ttext-align: center;\\n\\n\\t\\t@media only screen and (max-width: 1020px) {\\n\\t\\t\\twidth: 95px;\\n\\t\\t}\\n\\n\\t\\t&__first-line {\\n\\t\\t\\tdisplay: flex;\\n\\t\\t\\theight: 2em;\\n\\t\\t\\toverflow: hidden;\\n\\t\\t\\ttext-overflow: ellipsis;\\n\\t\\t}\\n\\n\\t\\t&__second-line {\\n\\t\\t\\tmargin-top: 6px;\\n\\t\\t\\tcolor: var(--color-text-maxcontrast);\\n\\t\\t}\\n\\n\\t\\t&__name {\\n\\t\\t\\tflex-grow: 1;\\n\\t\\t\\tmargin: 0;\\n\\t\\t}\\n\\t}\\n}\\n\\n.face-cover--small {\\n\\t* {\\n\\t\\tfont-size: 15px !important;\\n\\t}\\n\\t.face-cover__details {\\n\\t\\twidth: 60px !important;\\n\\t}\\n\\t.face-cover__crop-container {\\n\\t\\twidth: 60px !important;\\n\\t\\theight: 60px !important;\\n\\t\\t--photos-face-width: 60px !important;\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\n\n","import mod from \"-!../vue-loader/lib/index.js??vue-loader-options!./AccountBoxMultipleOutline.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../vue-loader/lib/index.js??vue-loader-options!./AccountBoxMultipleOutline.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./AccountBoxMultipleOutline.vue?vue&type=template&id=6bcc1fce&\"\nimport script from \"./AccountBoxMultipleOutline.vue?vue&type=script&lang=js&\"\nexport * from \"./AccountBoxMultipleOutline.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('span',_vm._b({staticClass:\"material-design-icon account-box-multiple-outline-icon\",attrs:{\"aria-hidden\":!_vm.title,\"aria-label\":_vm.title,\"role\":\"img\"},on:{\"click\":function($event){return _vm.$emit('click', $event)}}},'span',_vm.$attrs,false),[_c('svg',{staticClass:\"material-design-icon__svg\",attrs:{\"fill\":_vm.fillColor,\"width\":_vm.size,\"height\":_vm.size,\"viewBox\":\"0 0 24 24\"}},[_c('path',{attrs:{\"d\":\"M4 6H2V20C2 21.11 2.9 22 4 22H18V20H4V6M18.5 14.25C18.5 12.75 15.5 12 14 12S9.5 12.75 9.5 14.25V15H18.5M14 10.25C15.24 10.25 16.25 9.24 16.25 8S15.24 5.75 14 5.75 11.75 6.76 11.75 8 12.76 10.25 14 10.25M20 2H8C6.9 2 6 2.9 6 4V16C6 17.11 6.9 18 8 18H20C21.11 18 22 17.11 22 16V4C22 2.89 21.1 2 20 2M20 16H8V4H20V16Z\"}},[(_vm.title)?_c('title',[_vm._v(_vm._s(_vm.title))]):_vm._e()])])])\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{class:['face-cover', _vm.small && 'face-cover--small'],on:{\"click\":function($event){return _vm.$emit('click')}}},[_c('div',{staticClass:\"face-cover__crop-container\"},[_c('img',{ref:\"image\",staticClass:\"face-cover__image\",style:(_vm.coverDimensions),attrs:{\"src\":_vm.coverUrl}})]),_vm._v(\" \"),_c('div',{staticClass:\"face-cover__details\"},[(!_vm.baseName.match(/^[0-9]+$/))?_c('div',{staticClass:\"face-cover__details__first-line\"},[_c('h2',{staticClass:\"face-cover__details__name\"},[_vm._v(\"\\n\\t\\t\\t\\t\"+_vm._s(_vm.baseName)+\"\\n\\t\\t\\t\")])]):_vm._e(),_vm._v(\" \"),(_vm.facesFiles[_vm.baseName] && !_vm.small)?_c('div',{staticClass:\"face-cover__details__second-line\"},[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.n('photos', '%n photos', '%n photos', _vm.facesFiles[_vm.baseName].length,))+\"\\n\\t\\t\")]):_vm._e()])])\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n\n\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceCover.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceCover.vue?vue&type=script&lang=js&\"","\n import API from \"!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceCover.vue?vue&type=style&index=0&id=53f3a852&prod&lang=scss&scoped=true&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceCover.vue?vue&type=style&index=0&id=53f3a852&prod&lang=scss&scoped=true&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./FaceCover.vue?vue&type=template&id=53f3a852&scoped=true&\"\nimport script from \"./FaceCover.vue?vue&type=script&lang=js&\"\nexport * from \"./FaceCover.vue?vue&type=script&lang=js&\"\nimport style0 from \"./FaceCover.vue?vue&type=style&index=0&id=53f3a852&prod&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"53f3a852\",\n null\n \n)\n\nexport default component.exports"],"names":["name","computed","mapGetters","methods","getFaceCover","faceName","scoreFacePosition","faceDetection","Math","max","x","width","y","height","this","facesFiles","slice","map","fileId","files","sort","a","b","faceDetections","find","d","title","length","getCoverStyle","cover","detection","zoom","horizontalCenterOfFace","verticalCenterOfFace","transform","transformOrigin","data","errorFetchingFaces","loadingFaces","errorFetchingFiles","loadingFiles","mixins","AbortControllerMixin","beforeMount","fetchFaces","mapActions","Object","keys","faces","client","getCurrentUser","uid","DavRequest","details","signal","abortController","$store","dispatch","logger","response","status","t","error","showError","fetchFaceContent","force","fetchedFiles","file","genFileInfo","filename","he","realpath","replace","JSON","parse","fileIds","fileid","appendFiles","commit","fileIdsToAdd","___CSS_LOADER_EXPORT___","push","module","id","emits","props","type","String","fillColor","default","size","Number","_vm","_c","_self","_b","staticClass","attrs","on","$event","$emit","$attrs","_v","_s","_e","i","FetchFacesMixin","FaceCoverMixin","baseName","required","small","observer","face","coverUrl","coverDimensions","mounted","beforeDestroy","fetchFiles","waitForVisible","entries","listener","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","class","ref","style","match","n"],"sourceRoot":""}