1 |
- {"version":3,"file":"settings-vue-settings-personal-webauthn.mjs","sources":["../node_modules/lodash/_baseMap.js","../node_modules/lodash/_baseSortBy.js","../node_modules/lodash/_compareAscending.js","../node_modules/lodash/_compareMultiple.js","../node_modules/lodash/_baseOrderBy.js","../node_modules/lodash/sortBy.js","../node_modules/lodash/fp/sortBy.js","../apps/settings/src/service/WebAuthnRegistrationSerice.ts","../apps/settings/src/components/WebAuthn/AddDevice.vue","../apps/settings/src/components/WebAuthn/Device.vue","../apps/settings/src/components/WebAuthn/Section.vue","../apps/settings/src/main-personal-webauth.js"],"sourcesContent":["var baseEach = require('./_baseEach'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * The base implementation of `_.map` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction baseMap(collection, iteratee) {\n var index = -1,\n result = isArrayLike(collection) ? Array(collection.length) : [];\n\n baseEach(collection, function(value, key, collection) {\n result[++index] = iteratee(value, key, collection);\n });\n return result;\n}\n\nmodule.exports = baseMap;\n","/**\n * The base implementation of `_.sortBy` which uses `comparer` to define the\n * sort order of `array` and replaces criteria objects with their corresponding\n * values.\n *\n * @private\n * @param {Array} array The array to sort.\n * @param {Function} comparer The function to define sort order.\n * @returns {Array} Returns `array`.\n */\nfunction baseSortBy(array, comparer) {\n var length = array.length;\n\n array.sort(comparer);\n while (length--) {\n array[length] = array[length].value;\n }\n return array;\n}\n\nmodule.exports = baseSortBy;\n","var isSymbol = require('./isSymbol');\n\n/**\n * Compares values to sort them in ascending order.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {number} Returns the sort order indicator for `value`.\n */\nfunction compareAscending(value, other) {\n if (value !== other) {\n var valIsDefined = value !== undefined,\n valIsNull = value === null,\n valIsReflexive = value === value,\n valIsSymbol = isSymbol(value);\n\n var othIsDefined = other !== undefined,\n othIsNull = other === null,\n othIsReflexive = other === other,\n othIsSymbol = isSymbol(other);\n\n if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n (valIsNull && othIsDefined && othIsReflexive) ||\n (!valIsDefined && othIsReflexive) ||\n !valIsReflexive) {\n return 1;\n }\n if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n (othIsNull && valIsDefined && valIsReflexive) ||\n (!othIsDefined && valIsReflexive) ||\n !othIsReflexive) {\n return -1;\n }\n }\n return 0;\n}\n\nmodule.exports = compareAscending;\n","var compareAscending = require('./_compareAscending');\n\n/**\n * Used by `_.orderBy` to compare multiple properties of a value to another\n * and stable sort them.\n *\n * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,\n * specify an order of \"desc\" for descending or \"asc\" for ascending sort order\n * of corresponding values.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {boolean[]|string[]} orders The order to sort by for each property.\n * @returns {number} Returns the sort order indicator for `object`.\n */\nfunction compareMultiple(object, other, orders) {\n var index = -1,\n objCriteria = object.criteria,\n othCriteria = other.criteria,\n length = objCriteria.length,\n ordersLength = orders.length;\n\n while (++index < length) {\n var result = compareAscending(objCriteria[index], othCriteria[index]);\n if (result) {\n if (index >= ordersLength) {\n return result;\n }\n var order = orders[index];\n return result * (order == 'desc' ? -1 : 1);\n }\n }\n // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications\n // that causes it, under certain circumstances, to provide the same value for\n // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247\n // for more details.\n //\n // This also ensures a stable sort in V8 and other engines.\n // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n return object.index - other.index;\n}\n\nmodule.exports = compareMultiple;\n","var arrayMap = require('./_arrayMap'),\n baseGet = require('./_baseGet'),\n baseIteratee = require('./_baseIteratee'),\n baseMap = require('./_baseMap'),\n baseSortBy = require('./_baseSortBy'),\n baseUnary = require('./_baseUnary'),\n compareMultiple = require('./_compareMultiple'),\n identity = require('./identity'),\n isArray = require('./isArray');\n\n/**\n * The base implementation of `_.orderBy` without param guards.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n * @param {string[]} orders The sort orders of `iteratees`.\n * @returns {Array} Returns the new sorted array.\n */\nfunction baseOrderBy(collection, iteratees, orders) {\n if (iteratees.length) {\n iteratees = arrayMap(iteratees, function(iteratee) {\n if (isArray(iteratee)) {\n return function(value) {\n return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);\n }\n }\n return iteratee;\n });\n } else {\n iteratees = [identity];\n }\n\n var index = -1;\n iteratees = arrayMap(iteratees, baseUnary(baseIteratee));\n\n var result = baseMap(collection, function(value, key, collection) {\n var criteria = arrayMap(iteratees, function(iteratee) {\n return iteratee(value);\n });\n return { 'criteria': criteria, 'index': ++index, 'value': value };\n });\n\n return baseSortBy(result, function(object, other) {\n return compareMultiple(object, other, orders);\n });\n}\n\nmodule.exports = baseOrderBy;\n","var baseFlatten = require('./_baseFlatten'),\n baseOrderBy = require('./_baseOrderBy'),\n baseRest = require('./_baseRest'),\n isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Creates an array of elements, sorted in ascending order by the results of\n * running each element in a collection thru each iteratee. This method\n * performs a stable sort, that is, it preserves the original sort order of\n * equal elements. The iteratees are invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {...(Function|Function[])} [iteratees=[_.identity]]\n * The iteratees to sort by.\n * @returns {Array} Returns the new sorted array.\n * @example\n *\n * var users = [\n * { 'user': 'fred', 'age': 48 },\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 30 },\n * { 'user': 'barney', 'age': 34 }\n * ];\n *\n * _.sortBy(users, [function(o) { return o.user; }]);\n * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]\n *\n * _.sortBy(users, ['user', 'age']);\n * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]\n */\nvar sortBy = baseRest(function(collection, iteratees) {\n if (collection == null) {\n return [];\n }\n var length = iteratees.length;\n if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {\n iteratees = [];\n } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {\n iteratees = [iteratees[0]];\n }\n return baseOrderBy(collection, baseFlatten(iteratees, 1), []);\n});\n\nmodule.exports = sortBy;\n","var convert = require('./convert'),\n func = convert('sortBy', require('../sortBy'));\n\nfunc.placeholder = require('./placeholder');\nmodule.exports = func;\n","/**\n * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { RegistrationResponseJSON } from '@simplewebauthn/types'\n\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { startRegistration as registerWebAuthn } from '@simplewebauthn/browser'\n\nimport Axios from 'axios'\nimport axios from '@nextcloud/axios'\nimport logger from '../logger'\n\n/**\n * Start registering a new device\n * @return The device attributes\n */\nexport async function startRegistration() {\n\tconst url = generateUrl('/settings/api/personal/webauthn/registration')\n\n\ttry {\n\t\tlogger.debug('Fetching webauthn registration data')\n\t\tconst { data } = await axios.get(url)\n\t\tlogger.debug('Start webauthn registration')\n\t\tconst attrs = await registerWebAuthn(data)\n\t\treturn attrs\n\t} catch (e) {\n\t\tlogger.error(e as Error)\n\t\tif (Axios.isAxiosError(e)) {\n\t\t\tthrow new Error(t('settings', 'Could not register device: Network error'))\n\t\t} else if ((e as Error).name === 'InvalidStateError') {\n\t\t\tthrow new Error(t('settings', 'Could not register device: Probably already registered'))\n\t\t}\n\t\tthrow new Error(t('settings', 'Could not register device'))\n\t}\n}\n\n/**\n * @param name Name of the device\n * @param data Device attributes\n */\nexport async function finishRegistration(name: string, data: RegistrationResponseJSON) {\n\tconst url = generateUrl('/settings/api/personal/webauthn/registration')\n\n\tconst resp = await axios.post(url, { name, data: JSON.stringify(data) })\n\treturn resp.data\n}\n\n/**\n * @param id Remove registered device with that id\n */\nexport async function removeRegistration(id: string | number) {\n\tconst url = generateUrl(`/settings/api/personal/webauthn/registration/${id}`)\n\n\tawait axios.delete(url)\n}\n","<!--\n - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n\n<template>\n\t<div v-if=\"!isHttps && !isLocalhost\">\n\t\t{{ t('settings', 'Passwordless authentication requires a secure connection.') }}\n\t</div>\n\t<div v-else>\n\t\t<NcButton v-if=\"step === RegistrationSteps.READY\"\n\t\t\ttype=\"primary\"\n\t\t\t@click=\"start\">\n\t\t\t{{ t('settings', 'Add WebAuthn device') }}\n\t\t</NcButton>\n\n\t\t<div v-else-if=\"step === RegistrationSteps.REGISTRATION\"\n\t\t\tclass=\"new-webauthn-device\">\n\t\t\t<span class=\"icon-loading-small webauthn-loading\" />\n\t\t\t{{ t('settings', 'Please authorize your WebAuthn device.') }}\n\t\t</div>\n\n\t\t<div v-else-if=\"step === RegistrationSteps.NAMING\"\n\t\t\tclass=\"new-webauthn-device\">\n\t\t\t<span class=\"icon-loading-small webauthn-loading\" />\n\t\t\t<form @submit.prevent=\"submit\">\n\t\t\t\t<NcTextField ref=\"nameInput\"\n\t\t\t\t\tclass=\"new-webauthn-device__name\"\n\t\t\t\t\t:label=\"t('settings', 'Device name')\"\n\t\t\t\t\t:value.sync=\"name\"\n\t\t\t\t\tshow-trailing-button\n\t\t\t\t\t:trailing-button-label=\"t('settings', 'Add')\"\n\t\t\t\t\ttrailing-button-icon=\"arrowRight\"\n\t\t\t\t\t@trailing-button-click=\"submit\" />\n\t\t\t</form>\n\t\t</div>\n\n\t\t<div v-else-if=\"step === RegistrationSteps.PERSIST\"\n\t\t\tclass=\"new-webauthn-device\">\n\t\t\t<span class=\"icon-loading-small webauthn-loading\" />\n\t\t\t{{ t('settings', 'Adding your device …') }}\n\t\t</div>\n\n\t\t<div v-else>\n\t\t\tInvalid registration step. This should not have happened.\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport { showError } from '@nextcloud/dialogs'\nimport { confirmPassword } from '@nextcloud/password-confirmation'\nimport NcButton from '@nextcloud/vue/dist/Components/NcButton.js'\nimport NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'\n\nimport logger from '../../logger.ts'\nimport {\n\tstartRegistration,\n\tfinishRegistration,\n} from '../../service/WebAuthnRegistrationSerice.ts'\n\nconst logAndPass = (text) => (data) => {\n\tlogger.debug(text)\n\treturn data\n}\n\nconst RegistrationSteps = Object.freeze({\n\tREADY: 1,\n\tREGISTRATION: 2,\n\tNAMING: 3,\n\tPERSIST: 4,\n})\n\nexport default {\n\tname: 'AddDevice',\n\n\tcomponents: {\n\t\tNcButton,\n\t\tNcTextField,\n\t},\n\n\tprops: {\n\t\thttpWarning: Boolean,\n\t\tisHttps: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\tisLocalhost: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tsetup() {\n\t\t// non reactive props\n\t\treturn {\n\t\t\tRegistrationSteps,\n\t\t}\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tname: '',\n\t\t\tcredential: {},\n\t\t\tstep: RegistrationSteps.READY,\n\t\t}\n\t},\n\n\twatch: {\n\t\t/**\n\t\t * Auto focus the name input when naming a device\n\t\t */\n\t\tstep() {\n\t\t\tif (this.step === RegistrationSteps.NAMING) {\n\t\t\t\tthis.$nextTick(() => this.$refs.nameInput?.focus())\n\t\t\t}\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Start the registration process by loading the authenticator parameters\n\t\t * The next step is the naming of the device\n\t\t */\n\t\tasync start() {\n\t\t\tthis.step = RegistrationSteps.REGISTRATION\n\t\t\tconsole.debug('Starting WebAuthn registration')\n\n\t\t\ttry {\n\t\t\t\tawait confirmPassword()\n\t\t\t\tthis.credential = await startRegistration()\n\t\t\t\tthis.step = RegistrationSteps.NAMING\n\t\t\t} catch (err) {\n\t\t\t\tshowError(err)\n\t\t\t\tthis.step = RegistrationSteps.READY\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Save the new device with the given name on the server\n\t\t */\n\t\tsubmit() {\n\t\t\tthis.step = RegistrationSteps.PERSIST\n\n\t\t\treturn confirmPassword()\n\t\t\t\t.then(logAndPass('confirmed password'))\n\t\t\t\t.then(this.saveRegistrationData)\n\t\t\t\t.then(logAndPass('registration data saved'))\n\t\t\t\t.then(() => this.reset())\n\t\t\t\t.then(logAndPass('app reset'))\n\t\t\t\t.catch(console.error)\n\t\t},\n\n\t\tasync saveRegistrationData() {\n\t\t\ttry {\n\t\t\t\tconst device = await finishRegistration(this.name, this.credential)\n\n\t\t\t\tlogger.info('new device added', { device })\n\n\t\t\t\tthis.$emit('added', device)\n\t\t\t} catch (err) {\n\t\t\t\tlogger.error('Error persisting webauthn registration', { error: err })\n\t\t\t\tthrow new Error(t('settings', 'Server error while trying to complete WebAuthn device registration'))\n\t\t\t}\n\t\t},\n\n\t\treset() {\n\t\t\tthis.name = ''\n\t\t\tthis.registrationData = {}\n\t\t\tthis.step = RegistrationSteps.READY\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.webauthn-loading {\n\tdisplay: inline-block;\n\tvertical-align: sub;\n\tmargin-left: 2px;\n\tmargin-right: 2px;\n}\n\n.new-webauthn-device {\n\tdisplay: flex;\n\tgap: 22px;\n\talign-items: center;\n\n\t&__name {\n\t\tmax-width: min(100vw, 400px);\n\t}\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n\n<template>\n\t<li class=\"webauthn-device\">\n\t\t<span class=\"icon-webauthn-device\" />\n\t\t{{ name || t('settings', 'Unnamed device') }}\n\t\t<NcActions :force-menu=\"true\">\n\t\t\t<NcActionButton icon=\"icon-delete\" @click=\"$emit('delete')\">\n\t\t\t\t{{ t('settings', 'Delete') }}\n\t\t\t</NcActionButton>\n\t\t</NcActions>\n\t</li>\n</template>\n\n<script>\nimport NcActions from '@nextcloud/vue/dist/Components/NcActions.js'\nimport NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'\n\nexport default {\n\tname: 'Device',\n\tcomponents: {\n\t\tNcActionButton,\n\t\tNcActions,\n\t},\n\tprops: {\n\t\tname: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n\t.webauthn-device {\n\t\tline-height: 300%;\n\t\tdisplay: flex;\n\t}\n\n\t.icon-webauthn-device {\n\t\tdisplay: inline-block;\n\t\tbackground-size: 100%;\n\t\tpadding: 3px;\n\t\tmargin: 3px;\n\t}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n\n<template>\n\t<div id=\"security-webauthn\" class=\"section\">\n\t\t<h2>{{ t('settings', 'Passwordless Authentication') }}</h2>\n\t\t<p class=\"settings-hint hidden-when-empty\">\n\t\t\t{{ t('settings', 'Set up your account for passwordless authentication following the FIDO2 standard.') }}\n\t\t</p>\n\t\t<NcNoteCard v-if=\"devices.length === 0\" type=\"info\">\n\t\t\t{{ t('settings', 'No devices configured.') }}\n\t\t</NcNoteCard>\n\n\t\t<h3 v-else id=\"security-webauthn__active-devices\">\n\t\t\t{{ t('settings', 'The following devices are configured for your account:') }}\n\t\t</h3>\n\t\t<ul aria-labelledby=\"security-webauthn__active-devices\" class=\"security-webauthn__device-list\">\n\t\t\t<Device v-for=\"device in sortedDevices\"\n\t\t\t\t:key=\"device.id\"\n\t\t\t\t:name=\"device.name\"\n\t\t\t\t@delete=\"deleteDevice(device.id)\" />\n\t\t</ul>\n\n\t\t<NcNoteCard v-if=\"!supportsWebauthn\" type=\"warning\">\n\t\t\t{{ t('settings', 'Your browser does not support WebAuthn.') }}\n\t\t</NcNoteCard>\n\n\t\t<AddDevice v-if=\"supportsWebauthn\"\n\t\t\t:is-https=\"isHttps\"\n\t\t\t:is-localhost=\"isLocalhost\"\n\t\t\t@added=\"deviceAdded\" />\n\t</div>\n</template>\n\n<script>\nimport { browserSupportsWebAuthn } from '@simplewebauthn/browser'\nimport { confirmPassword } from '@nextcloud/password-confirmation'\nimport NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'\nimport sortBy from 'lodash/fp/sortBy.js'\n\nimport AddDevice from './AddDevice.vue'\nimport Device from './Device.vue'\nimport logger from '../../logger.ts'\nimport { removeRegistration } from '../../service/WebAuthnRegistrationSerice.ts'\n\nconst sortByName = sortBy('name')\n\nexport default {\n\tcomponents: {\n\t\tAddDevice,\n\t\tDevice,\n\t\tNcNoteCard,\n\t},\n\tprops: {\n\t\tinitialDevices: {\n\t\t\ttype: Array,\n\t\t\trequired: true,\n\t\t},\n\t\tisHttps: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\tisLocalhost: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tsetup() {\n\t\t// Non reactive properties\n\t\treturn {\n\t\t\tsupportsWebauthn: browserSupportsWebAuthn(),\n\t\t}\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tdevices: this.initialDevices,\n\t\t}\n\t},\n\tcomputed: {\n\t\tsortedDevices() {\n\t\t\treturn sortByName(this.devices)\n\t\t},\n\t},\n\tmethods: {\n\t\tdeviceAdded(device) {\n\t\t\tlogger.debug(`adding new device to the list ${device.id}`)\n\n\t\t\tthis.devices.push(device)\n\t\t},\n\t\tasync deleteDevice(id) {\n\t\t\tlogger.info(`deleting webauthn device ${id}`)\n\n\t\t\tawait confirmPassword()\n\t\t\tawait removeRegistration(id)\n\n\t\t\tthis.devices = this.devices.filter(d => d.id !== id)\n\n\t\t\tlogger.info(`webauthn device ${id} removed successfully`)\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.security-webauthn__device-list {\n\tmargin-block: 12px 18px;\n}\n</style>\n","/**\n * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport Vue from 'vue'\nimport { loadState } from '@nextcloud/initial-state'\n\nimport WebAuthnSection from './components/WebAuthn/Section.vue'\n\nVue.prototype.t = t\n\nconst View = Vue.extend(WebAuthnSection)\nconst devices = loadState('settings', 'webauthn-devices')\nnew View({\n\tpropsData: {\n\t\tinitialDevices: devices,\n\t\tisHttps: window.location.protocol === 'https:',\n\t\tisLocalhost: window.location.hostname === 'localhost',\n\t},\n}).$mount('#security-webauthn')\n"],"names":["baseEach","require$$0","isArrayLike","require$$1","baseMap","collection","iteratee","index","result","value","key","_baseMap","baseSortBy","array","comparer","length","_baseSortBy","isSymbol","compareAscending","other","valIsDefined","valIsNull","valIsReflexive","valIsSymbol","othIsDefined","othIsNull","othIsReflexive","othIsSymbol","_compareAscending","compareMultiple","object","orders","objCriteria","othCriteria","ordersLength","order","_compareMultiple","arrayMap","baseGet","baseIteratee","require$$2","require$$3","require$$4","baseUnary","require$$5","require$$6","identity","require$$7","isArray","require$$8","baseOrderBy","iteratees","criteria","_baseOrderBy","baseFlatten","baseRest","isIterateeCall","sortBy","sortBy_1","convert","func","startRegistration","url","generateUrl","logger","data","axios","registerWebAuthn","e","Axios","t","finishRegistration","name","removeRegistration","id","logAndPass","text","RegistrationSteps","_sfc_main","NcButton","NcTextField","_a","confirmPassword","err","showError","device","NcActionButton","NcActions","sortByName","AddDevice","Device","NcNoteCard","browserSupportsWebAuthn","d","Vue","View","WebAuthnSection","devices","loadState"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6]}
|