feat: admin api keys

parent 6625267b
......@@ -29,7 +29,7 @@ exports.up = async knex => {
table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
table.string('name').notNullable()
table.text('key').notNullable()
table.string('expiration').notNullable()
table.timestamp('expiration').notNullable().defaultTo(knex.fn.now())
table.boolean('isRevoked').notNullable().defaultTo(false)
table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
......
......@@ -12,6 +12,7 @@ module.exports = {
*/
async apiKeys (obj, args, context) {
const keys = await WIKI.models.apiKeys.query().orderBy(['isRevoked', 'name'])
console.info(keys)
return keys.map(k => ({
id: k.id,
name: k.name,
......@@ -78,9 +79,10 @@ module.exports = {
WIKI.events.outbound.emit('reloadApiKeys')
return {
key,
responseResult: graphHelper.generateSuccess('API Key created successfully')
operation: graphHelper.generateSuccess('API Key created successfully')
}
} catch (err) {
WIKI.logger.warn(err)
return graphHelper.generateError(err)
}
},
......@@ -165,7 +167,7 @@ module.exports = {
WIKI.config.api.isEnabled = args.enabled
await WIKI.configSvc.saveToDb(['api'])
return {
responseResult: graphHelper.generateSuccess('API State changed successfully')
operation: graphHelper.generateSuccess('API State changed successfully')
}
} catch (err) {
return graphHelper.generateError(err)
......@@ -182,7 +184,7 @@ module.exports = {
await WIKI.auth.reloadApiKeys()
WIKI.events.outbound.emit('reloadApiKeys')
return {
responseResult: graphHelper.generateSuccess('API Key revoked successfully')
operation: graphHelper.generateSuccess('API Key revoked successfully')
}
} catch (err) {
return graphHelper.generateError(err)
......
......@@ -21,8 +21,7 @@ extend type Mutation {
createApiKey(
name: String!
expiration: String!
fullAccess: Boolean!
group: Int
groups: [UUID]!
): AuthenticationCreateApiKeyResponse
login(
......@@ -53,7 +52,7 @@ extend type Mutation {
): AuthenticationRegisterResponse
revokeApiKey(
id: Int!
id: UUID!
): DefaultResponse
setApiState(
......@@ -135,13 +134,13 @@ input AuthenticationStrategyInput {
}
type AuthenticationApiKey {
id: Int!
name: String!
keyShort: String!
expiration: Date!
createdAt: Date!
updatedAt: Date!
isRevoked: Boolean!
id: UUID
name: String
keyShort: String
expiration: Date
createdAt: Date
updatedAt: Date
isRevoked: Boolean
}
type AuthenticationCreateApiKeyResponse {
......
/* global WIKI */
const Model = require('objection').Model
const moment = require('moment')
const { DateTime } = require('luxon')
const ms = require('ms')
const jwt = require('jsonwebtoken')
......@@ -17,7 +17,7 @@ module.exports = class ApiKey extends Model {
required: ['name', 'key'],
properties: {
id: {type: 'integer'},
id: {type: 'string'},
name: {type: 'string'},
key: {type: 'string'},
expiration: {type: 'string'},
......@@ -31,29 +31,33 @@ module.exports = class ApiKey extends Model {
async $beforeUpdate(opt, context) {
await super.$beforeUpdate(opt, context)
this.updatedAt = moment.utc().toISOString()
this.updatedAt = new Date().toISOString()
}
async $beforeInsert(context) {
await super.$beforeInsert(context)
this.createdAt = moment.utc().toISOString()
this.updatedAt = moment.utc().toISOString()
this.createdAt = new Date().toISOString()
this.updatedAt = new Date().toISOString()
}
static async createNewKey ({ name, expiration, fullAccess, group }) {
static async createNewKey ({ name, expiration, groups }) {
console.info(DateTime.utc().plus(ms(expiration)).toISO())
const entry = await WIKI.models.apiKeys.query().insert({
name,
key: 'pending',
expiration: moment.utc().add(ms(expiration), 'ms').toISOString(),
expiration: DateTime.utc().plus(ms(expiration)).toISO(),
isRevoked: true
})
console.info(entry)
const key = jwt.sign({
api: entry.id,
grp: fullAccess ? 1 : group
grp: groups
}, {
key: WIKI.config.certs.private,
passphrase: WIKI.config.sessionSecret
key: WIKI.config.auth.certs.private,
passphrase: WIKI.config.auth.secret
}, {
algorithm: 'RS256',
expiresIn: expiration,
......
......@@ -35,7 +35,7 @@ module.exports = class Authentication extends Model {
}
static async getStrategies() {
const strategies = await WIKI.models.authentication.query().orderBy('order')
const strategies = await WIKI.models.authentication.query()
return strategies.map(str => ({
...str,
domainWhitelist: _.get(str.domainWhitelist, 'v', []),
......
......@@ -32,7 +32,7 @@
"@codemirror/tooltip": "0.19.16",
"@codemirror/view": "6.0.2",
"@lezer/common": "1.0.0",
"@quasar/extras": "1.14.2",
"@quasar/extras": "1.15.0",
"@tiptap/core": "2.0.0-beta.176",
"@tiptap/extension-code-block": "2.0.0-beta.37",
"@tiptap/extension-code-block-lowlight": "2.0.0-beta.68",
......@@ -57,9 +57,8 @@
"@tiptap/extension-typography": "2.0.0-beta.20",
"@tiptap/starter-kit": "2.0.0-beta.185",
"@tiptap/vue-3": "2.0.0-beta.91",
"@vue/apollo-option": "4.0.0-alpha.17",
"apollo-upload-client": "17.0.0",
"browser-fs-access": "0.30.2",
"browser-fs-access": "0.31.0",
"clipboard": "2.0.11",
"codemirror": "6.0.1",
"filesize": "9.0.11",
......@@ -69,31 +68,31 @@
"js-cookie": "3.0.1",
"jwt-decode": "3.1.2",
"lodash-es": "4.17.21",
"luxon": "2.5.0",
"pinia": "2.0.14",
"luxon": "3.0.1",
"pinia": "2.0.17",
"pug": "3.0.2",
"quasar": "2.7.5",
"tippy.js": "6.3.7",
"uuid": "8.3.2",
"v-network-graph": "0.6.3",
"v-network-graph": "0.6.5",
"vue": "3.2.37",
"vue-codemirror": "6.0.0",
"vue-codemirror": "6.0.2",
"vue-i18n": "9.1.10",
"vue-router": "4.1.1",
"vue-router": "4.1.3",
"vuedraggable": "4.1.0",
"zxcvbn": "4.4.2"
},
"devDependencies": {
"@intlify/vite-plugin-vue-i18n": "3.4.0",
"@intlify/vite-plugin-vue-i18n": "5.0.1",
"@quasar/app-vite": "1.0.5",
"@types/lodash": "4.14.182",
"browserlist": "latest",
"eslint": "8.19.0",
"eslint": "8.20.0",
"eslint-config-standard": "17.0.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-n": "15.2.4",
"eslint-plugin-promise": "6.0.0",
"eslint-plugin-vue": "9.2.0"
"eslint-plugin-vue": "9.3.0"
},
"engines": {
"node": "^18 || ^16",
......
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="96px" height="96px"><linearGradient id="Gx4Hql1L2mKhvP9291EBWa" x1="19.53" x2="28.032" y1="12.426" y2="32.179" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#Gx4Hql1L2mKhvP9291EBWa)" d="M31.19,22H27v-8c0-0.552-0.448-1-1-1h-4c-0.552,0-1,0.448-1,1v8h-4.19 c-0.72,0-1.08,0.87-0.571,1.379l6.701,6.701c0.586,0.586,1.536,0.586,2.121,0l6.701-6.701C32.271,22.87,31.91,22,31.19,22z"/><linearGradient id="Gx4Hql1L2mKhvP9291EBWb" x1="39.761" x2="43.605" y1="31.57" y2="42.462" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#Gx4Hql1L2mKhvP9291EBWb)" d="M39,33v10l4.828-4.828c0.75-0.75,1.172-1.768,1.172-2.828V33c0-0.552-0.448-1-1-1h-4 C39.448,32,39,32.448,39,33z"/><linearGradient id="Gx4Hql1L2mKhvP9291EBWc" x1="9" x2="39" y1="40" y2="40" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0362b0"/><stop offset=".112" stop-color="#036abd"/><stop offset=".258" stop-color="#036fc5"/><stop offset=".5" stop-color="#0370c8"/><stop offset=".742" stop-color="#036fc5"/><stop offset=".888" stop-color="#036abd"/><stop offset="1" stop-color="#0362b0"/></linearGradient><rect width="30" height="6" x="9" y="37" fill="url(#Gx4Hql1L2mKhvP9291EBWc)"/><linearGradient id="Gx4Hql1L2mKhvP9291EBWd" x1="332.761" x2="336.605" y1="31.57" y2="42.462" gradientTransform="matrix(-1 0 0 1 341 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#Gx4Hql1L2mKhvP9291EBWd)" d="M9,33v10l-4.828-4.828C3.421,37.421,3,36.404,3,35.343V33c0-0.552,0.448-1,1-1h4 C8.552,32,9,32.448,9,33z"/><linearGradient id="Gx4Hql1L2mKhvP9291EBWe" x1="23.174" x2="24.956" y1="4.081" y2="8.222" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#Gx4Hql1L2mKhvP9291EBWe)" d="M26,7h-4c-0.552,0-1-0.448-1-1v0c0-0.552,0.448-1,1-1h4c0.552,0,1,0.448,1,1v0 C27,6.552,26.552,7,26,7z"/><linearGradient id="Gx4Hql1L2mKhvP9291EBWf" x1="23.174" x2="24.956" y1="8.081" y2="12.222" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#32bdef"/><stop offset="1" stop-color="#1ea2e4"/></linearGradient><path fill="url(#Gx4Hql1L2mKhvP9291EBWf)" d="M26,11h-4c-0.552,0-1-0.448-1-1v0c0-0.552,0.448-1,1-1h4c0.552,0,1,0.448,1,1v0 C27,10.552,26.552,11,26,11z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="96px" height="96px"><linearGradient id="XED_QU6xiox5XDw0HU_eba" x1="20.958" x2="5.741" y1="26.758" y2="42.622" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#e5a505"/><stop offset=".01" stop-color="#e9a804"/><stop offset=".06" stop-color="#f4b102"/><stop offset=".129" stop-color="#fbb600"/><stop offset=".323" stop-color="#fdb700"/></linearGradient><path fill="url(#XED_QU6xiox5XDw0HU_eba)" d="M12,41.5c0-1.381,1.119-2.5,2.5-2.5c0.156,0,0.307,0.019,0.454,0.046l1.186-1.186 C16.058,37.586,16,37.301,16,37c0-1.657,1.343-3,3-3c0.301,0,0.586,0.058,0.86,0.14L24,30l-6-6L4.586,37.414 C4.211,37.789,4,38.298,4,38.828v1.343c0,0.53,0.211,1.039,0.586,1.414l1.828,1.828C6.789,43.789,7.298,44,7.828,44h1.343 c0.53,0,1.039-0.211,1.414-0.586l1.46-1.46C12.019,41.807,12,41.656,12,41.5z"/><linearGradient id="XED_QU6xiox5XDw0HU_ebb" x1="21.64" x2="36.971" y1="7.073" y2="29.362" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fede00"/><stop offset="1" stop-color="#ffd000"/></linearGradient><path fill="url(#XED_QU6xiox5XDw0HU_ebb)" d="M29.5,5C22.044,5,16,11.044,16,18.5S22.044,32,29.5,32S43,25.956,43,18.5S36.956,5,29.5,5z M33,19c-2.209,0-4-1.791-4-4s1.791-4,4-4s4,1.791,4,4S35.209,19,33,19z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="96px" height="96px"><linearGradient id="GCWVriy4rQhfclYQVzRmda" x1="9.812" x2="38.361" y1="9.812" y2="38.361" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f44f5a"/><stop offset=".443" stop-color="#ee3d4a"/><stop offset="1" stop-color="#e52030"/></linearGradient><path fill="url(#GCWVriy4rQhfclYQVzRmda)" d="M24,4C12.955,4,4,12.955,4,24s8.955,20,20,20s20-8.955,20-20C44,12.955,35.045,4,24,4z M24,38 c-7.732,0-14-6.268-14-14s6.268-14,14-14s14,6.268,14,14S31.732,38,24,38z"/><linearGradient id="GCWVriy4rQhfclYQVzRmdb" x1="6.821" x2="41.08" y1="6.321" y2="40.58" gradientTransform="translate(-.146 .354)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f44f5a"/><stop offset=".443" stop-color="#ee3d4a"/><stop offset="1" stop-color="#e52030"/></linearGradient><polygon fill="url(#GCWVriy4rQhfclYQVzRmdb)" points="13.371,38.871 9.129,34.629 34.629,9.129 38.871,13.371"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="80px" height="80px"><path fill="#fff" d="M6.5 37.5L6.5 2.5 24.793 2.5 33.5 11.207 33.5 37.5z"/><path fill="#4788c7" d="M24.586,3L33,11.414V37H7V3H24.586 M25,2H6v36h28V11L25,2L25,2z"/><path fill="#dff0fe" d="M24.5 11.5L24.5 2.5 24.793 2.5 33.5 11.207 33.5 11.5z"/><path fill="#4788c7" d="M25,3.414L32.586,11H25V3.414 M25,2h-1v10h10v-1L25,2L25,2z"/><path fill="none" stroke="#4788c7" stroke-miterlimit="10" d="M13.5 18.5L14.5 18.5 14.5 23M19.5 22.5L19.5 22.5c-.552 0-1-.448-1-1v-2c0-.552.448-1 1-1h0c.552 0 1 .448 1 1v2C20.5 22.052 20.052 22.5 19.5 22.5zM25.5 22.5L25.5 22.5c-.552 0-1-.448-1-1v-2c0-.552.448-1 1-1h0c.552 0 1 .448 1 1v2C26.5 22.052 26.052 22.5 25.5 22.5zM25.5 25.5L26.5 25.5 26.5 30M20.5 29.5L20.5 29.5c-.552 0-1-.448-1-1v-2c0-.552.448-1 1-1h0c.552 0 1 .448 1 1v2C21.5 29.052 21.052 29.5 20.5 29.5zM14.5 29.5L14.5 29.5c-.552 0-1-.448-1-1v-2c0-.552.448-1 1-1h0c.552 0 1 .448 1 1v2C15.5 29.052 15.052 29.5 14.5 29.5z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="80px" height="80px"><path fill="#fff" d="M2.5,37.5V8.985C2.5,5.409,5.409,2.5,8.985,2.5H37.5v35H2.5z"/><path fill="#4788c7" d="M37,3v34H3V8.985C3,5.685,5.685,3,8.985,3H37 M38,2H8.985C5.127,2,2,5.127,2,8.985V38h36V2L38,2z"/><path fill="#b6dcfe" d="M2.522,7.5c0.253-2.8,2.613-5,5.478-5h29.5v5H2.522z"/><path fill="#4788c7" d="M37,3v4H3.1C3.565,4.721,5.585,3,8,3H37 M38,2H8C4.686,2,2,4.686,2,8h36V2L38,2z"/><path fill="#b6dcfe" d="M13 14H15V16H13zM21 14H23V16H21zM25 14H27V16H25zM29 14H31V16H29zM9 18H11V20H9zM13 18H15V20H13zM21 18H23V20H21zM25 18H27V20H25zM29 18H31V20H29zM9 26H11V28H9zM13 26H15V28H13zM21 26H23V28H21zM17 14H19V16H17zM17 18H19V20H17zM9 22H11V24H9zM13 22H15V24H13zM21 22H23V24H21zM25 22H27V24H25zM29 22H31V24H29zM17 22H19V24H17zM17 26H19V28H17zM25 26H27V28H25zM3 34H37V37H3z"/><path fill="#98ccfd" d="M12,23.5C5.659,23.5,0.5,18.341,0.5,12S5.659,0.5,12,0.5S23.5,5.659,23.5,12S18.341,23.5,12,23.5z"/><path fill="#4788c7" d="M12,1c6.065,0,11,4.935,11,11s-4.935,11-11,11S1,18.065,1,12S5.935,1,12,1 M12,0 C5.373,0,0,5.373,0,12s5.373,12,12,12s12-5.373,12-12S18.627,0,12,0L12,0z"/><g><path fill="#fff" d="M12 3A9 9 0 1 0 12 21A9 9 0 1 0 12 3Z"/></g><path fill="none" stroke="#4788c7" stroke-linecap="round" stroke-miterlimit="10" d="M14.5 5.5L12 12 15.5 15.5"/><g><path fill="#4788c7" d="M12 10.667A1.333 1.333 0 1 0 12 13.333A1.333 1.333 0 1 0 12 10.667Z"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" width="667.44532" height="589.48587" viewBox="0 0 667.44532 589.48587" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M783.23262,532.89214a7.72132,7.72132,0,0,1,4.04472-11.12741l-.39756-27.43609,12.016,7.67645L797.4311,526.882a7.76317,7.76317,0,0,1-14.19848,6.01015Z" transform="translate(-266.27734 -155.25706)" fill="#a0616a"/><path d="M768.75126,383.9362A15.63963,15.63963,0,0,0,755.837,398.99425c-.174,8.02961,2.50557,11.02363,6.29215,12.10551,7,2,18.14816,42.44832,18.14816,42.44832s1.18325,37.72571,3.09163,35.86286-.25137,2.4842.3285,3.81067-2.74888,3.313.4155,4.81973,1.16437,13.50674,1.16437,13.50674l14-1s-2.32454-9.77573.83773-10.38786,1.72534-3.39426.44381-5.5032,2.26732-5.11484.49289-6.11189,3.22557-39.997,3.22557-39.997L784.7285,391.02842a15.64187,15.64187,0,0,0-15.97722-7.09223Z" transform="translate(-266.27734 -155.25706)" fill="#1976d2"/><polygon points="460 230.943 470.071 213.291 483.677 213.291 493.882 231.943 460 230.943" fill="#1976d2"/><path d="M699.18878,227.46306c-8.04694-26.95441-30.7807-44.551-58.25122-48.41126-.30219-.0426-.589.01367-.8899-.00574a8.68011,8.68011,0,0,0-1.18756-.27349c-37.778-4.88251-79.0177,3.86193-111.84076,24.3988-31.46228,19.68549-67.61309,30.793-104.72552,30.5462q-1.72879-.01145-3.47113.075c-28.56079,1.42511-53.76636,22.21533-61.48755,49.5606-1.01331,3.58777.75244,6.79352,3.59186,8.82673,4.98932,3.57348,8.3974,6.078,14.53607,7.37841q16.43014,3.48075,32.9726,6.40137V262.03075a15.70447,15.70447,0,0,1,15.68627-15.68628H639.59106a15.70448,15.70448,0,0,1,15.68628,15.68628V316.738a64.51829,64.51829,0,0,0,8.63245-3.39789,66.83714,66.83714,0,0,0,25.76849-22.487C702.15289,272.75279,705.44769,248.42662,699.18878,227.46306Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M608.4671,484.54808H417.99a16.59835,16.59835,0,0,1-16.57911-16.5791V394.05852a172.96506,172.96506,0,0,0-71.7163-6.286,8.68011,8.68011,0,0,0-1.18756.27349c-.30085.01941-.58771-.03686-.8899.00574-27.47052,3.86029-50.20428,21.45685-58.25122,48.41126-6.25891,20.96356-2.96411,45.28973,9.5105,63.39a66.83714,66.83714,0,0,0,25.76849,22.487c14.28736,6.88226,29.32532,7.39972,44.91919,7.88568a1018.27653,1018.27653,0,0,0,140.261-5.30163q34.38208-3.68766,68.47858-9.63837,17.4516-3.0541,34.788-6.72742c6.13867-1.30041,9.54675-3.80493,14.53607-7.37841,2.83942-2.03321,4.60517-5.239,3.59186-8.82673A65.80907,65.80907,0,0,0,608.4671,484.54808Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M625.32431,462.62108H438.38871a13.62481,13.62481,0,0,1-13.609-13.609V275.28913a13.62481,13.62481,0,0,1,13.609-13.609h186.9356a13.6248,13.6248,0,0,1,13.609,13.609V449.01205A13.6248,13.6248,0,0,1,625.32431,462.62108Z" transform="translate(-266.27734 -155.25706)" fill="#e6e6e6"/><path d="M585.97983,453.4416H447.57038a13.62481,13.62481,0,0,1-13.609-13.609V284.47592a13.62481,13.62481,0,0,1,13.609-13.609H616.14483a13.62481,13.62481,0,0,1,13.609,13.609V409.66757A43.82338,43.82338,0,0,1,585.97983,453.4416Z" transform="translate(-266.27734 -155.25706)" fill="#fff"/><circle cx="265.58027" cy="206.89718" r="61" fill="#1976d2"/><path d="M557.5542,359.08519l-20.356-24.75391a6.00075,6.00075,0,0,0-9.14014-.15136l-21.76855,24.7539a6.00029,6.00029,0,0,0,9.01172,7.92481L526.564,354.05119v32.115a6,6,0,0,0,12,0V354.8853l9.72168,11.822a6,6,0,0,0,9.26856-7.62207Z" transform="translate(-266.27734 -155.25706)" fill="#fff"/><polygon points="528.453 578.324 519.404 578.323 515.099 543.416 528.456 543.417 528.453 578.324" fill="#a0616a"/><path d="M795.04973,743.0215l-27.82942-.001v-.35195a10.83258,10.83258,0,0,1,10.832-10.83181h.00067l5.0834-3.85654,9.4845,3.85712,2.42932.00009Z" transform="translate(-266.27734 -155.25706)" fill="#2f2e41"/><polygon points="460.453 578.324 451.404 578.323 447.099 543.416 460.456 543.417 460.453 578.324" fill="#a0616a"/><path d="M727.04973,743.0215l-27.82942-.001v-.35195a10.83258,10.83258,0,0,1,10.832-10.83181h.00067l5.0834-3.85654,9.4845,3.85712,2.42932.00009Z" transform="translate(-266.27734 -155.25706)" fill="#2f2e41"/><path d="M797.61645,704.6906c3.30164-2.1576,1.38892-2.01752,1.38892-2.01752s-7.383-59.85993-13-78l-6.49994-88.33655s-.41266,1.76215,0-2.52069,3.41266-1.28284.41266-4.28284-5-4.52868-3-6.76434,7.51721-6.75861,4.2586-9.49713-9.67126-20.59845-9.67126-20.59845l-62.50006.5,2.5-.5s-7.80182-2.89459-4.228.875-2,13-4,22c-1.65643,7.454-6.57379,9.43207,0,11,6.57379,1.56787.62476,6.01092.62476,6.01092s-9.89673,47.11408-2.39673,78.11408c0,0,5.17413,76.67175,7.79339,83.26587,2.61933,6.59405,3.61933,2.59405,2.61933,6.59405s-3-3-1,4a92.51269,92.51269,0,0,1,2.58728,11.14008l13.56231-1s3.1496-9.92743,0-12.53375-.97491,5,2.43775-.80316-.58734-3.80317-1.58734-11.80317,8.17468-45.2677,1.58734-68.13385l12.17328-64.16278,19.32666,66.43671s10.25128,81.14014,13.582,84.00006c3.33069,2.85986,1.9856-4.08209,3.33069,2.85986,1.35925,7.01508,4.44653,5.15515,4.35925,6.01508-.93127,9.17242,15.33911.125,15.33911.125a51.36513,51.36513,0,0,1,0-6.99994C797.91809,707.533,794.31482,706.84813,797.61645,704.6906Z" transform="translate(-266.27734 -155.25706)" fill="#2f2e41"/><path d="M715.27734,513.54808c-4,0-15-5.41732-13-7.70866s2-9.89764,2-12.09449,9-83.19685,9-83.19685l-.68388-19.83247a8.86212,8.86212,0,0,1,8.85686-9.16753l8.827-3,25-1,12.46645,4A7.22686,7.22686,0,0,1,774.181,392.0598l0,0a65.07422,65.07422,0,0,1,9.55278,35.95453c-.28682,9.47129-5.08528,21.038-6.24161,31.73814-.1015.93921-.17494,1.87174-.2148,2.79559-.01112.25761-2.05815,1.54144-.02907.77072s-1.08747,1.94967-.0292,3.58947,3.10929.635.08378,2.63741,3.63258,21.34431,2.97449,22.0024c-2,2-6,3-3,6s6,1,2,5-15.98425,11-15.98425,11Z" transform="translate(-266.27734 -155.25706)" fill="#3f3d56"/><circle cx="475.73406" cy="189.15557" r="21.52319" fill="#a0616a"/><path d="M610.92115,411.192a7.72133,7.72133,0,0,1,10.62241,5.2291l27.317,2.584-8.93584,11.11135L615.354,425.9591a7.76317,7.76317,0,0,1-4.43284-14.76715Z" transform="translate(-266.27734 -155.25706)" fill="#a0616a"/><path d="M740.44091,395.17016a15.63965,15.63965,0,0,0-15.058-12.91423c-8.02961-.174-11.02364,2.50557-12.10552,6.29215-2,7-34.19685,31.60617-34.19685,31.60617l-27.65117-2.99243c-1.66278-.54016-.87427-2.05438-7.12586-.77115-3.07953-2.01669-5.07055-1.675-6.785-.73428l-10.24109-1.10831,1,16s10.96343-2.608,13,2,1.57046,5.26992,6,2,4,0,4,0l32,8,50.07135-31.40068a15.64187,15.64187,0,0,0,7.09222-15.97722Z" transform="translate(-266.27734 -155.25706)" fill="#1976d2"/><path d="M750.36737,363.628l1.41.45c-4.41.37-12.27,2.83-11.5,1.47s-2.14-6.49-.72-7.14a9.03069,9.03069,0,0,0,3.82-2.59c.9-1.26.88-3.34-.47-4.11-1.31-.76-2.93.06-4.23.83-1.31.76-3.73-10.42-3.11-13.91-3.65-2-8.07,1.83-12.17,1.08-2.51-.46-4.32-2.52-5.46-4.86a15.246,15.246,0,0,0,4.03-6.42,19.90965,19.90965,0,0,1-5.52,1.83,12.97091,12.97091,0,0,1,.14-5.48,8.94283,8.94283,0,0,1,5.57-6.34,6.48235,6.48235,0,0,1,7.6,2.82,6.44436,6.44436,0,0,0-4.08-6.4,6.77636,6.77636,0,0,1,9.75,4.61,20.93429,20.93429,0,0,1,14.59-1.56c4.84,1.27,11.26,6.64,11.26,6.64C772.19732,326.95805,771.67736,368.47807,750.36737,363.628Z" transform="translate(-266.27734 -155.25706)" fill="#2f2e41"/><path d="M864.39375,734.43979a1.2164,1.2164,0,0,0,.88157-2.10832l-.08335-.33136.03312-.07954a3.26656,3.26656,0,0,1,6.02555.02239c.98551,2.37356,2.24023,4.75117,2.54918,7.26082a9.66393,9.66393,0,0,1-.16964,3.32354,38.74392,38.74392,0,0,0,3.52438-16.09157,37.39746,37.39746,0,0,0-.232-4.17178q-.19217-1.70334-.53318-3.38243a39.19285,39.19285,0,0,0-7.77228-16.61089A10.43034,10.43034,0,0,1,864.2792,697.77a7.95618,7.95618,0,0,1-.72357-2.17417,9.819,9.819,0,0,0,.637-3.3859c.2943-.44659.82105-.66859,1.14248-1.10437,1.59857-2.16733,3.801-1.78891,4.95074,1.15632,2.45615,1.23962,2.47993,3.29545.97284,5.27269-.95881,1.25793-1.09055,2.96-1.93184,4.30676.08657.1108.17659.21813.26313.32893a39.4457,39.4457,0,0,1,4.11715,6.52255,16.39818,16.39818,0,0,1,.979-7.61655c.93706-2.26054,2.69343-4.16438,4.24012-6.11862a3.36576,3.36576,0,0,1,5.9948,1.65271l.00927.0864q-.3446.1944-.67464.41269a1.65,1.65,0,0,0,.66523,3.00262l.03364.00518a16.41807,16.41807,0,0,1-.43274,2.45462c1.98421,7.67347-2.29957,10.46831-8.41623,10.59386-.135.06923-.2666.13847-.40163.20427a40.262,40.262,0,0,1,2.16725,10.19917,38.18677,38.18677,0,0,1-.0277,6.1659l.0104-.07269a10.09082,10.09082,0,0,1,3.44475-5.82663c2.65092-2.17763,6.39617-2.97954,9.256-4.72993a1.89376,1.89376,0,0,1,2.90049,1.84233l-.01169.07644a11.08173,11.08173,0,0,0-1.24287.5989q-.3446.19445-.67465.41269a1.65,1.65,0,0,0,.66524,3.00265l.03367.00517.0692.01042a16.43116,16.43116,0,0,1-3.02234,4.73259c-1.24068,6.69864-6.56941,7.3342-12.2695,5.38348h-.00347a40.251,40.251,0,0,1-2.70387,7.89347h-9.65909c-.03464-.10732-.06579-.21812-.097-.32545a10.97506,10.97506,0,0,0,2.67273-.15921c-.71666-.87938-1.43329-1.76569-2.14994-2.645a.60206.60206,0,0,1-.045-.05194c-.36351-.45-.73049-.89666-1.094-1.34671l-.0002-.00055a16.07543,16.07543,0,0,1,.471-4.09507Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M542.80633,744.4356l389.72565.30734a1.19068,1.19068,0,0,0,0-2.38137l-389.72565-.30733a1.19068,1.19068,0,0,0,0,2.38136Z" transform="translate(-266.27734 -155.25706)" fill="#cacaca"/><path d="M522.8955,577.54808A14.14551,14.14551,0,1,1,537.041,563.40257,14.16159,14.16159,0,0,1,522.8955,577.54808Zm0-26.291A12.14551,12.14551,0,1,0,535.041,563.40257,12.159,12.159,0,0,0,522.8955,551.25706Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M528.43314,562.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,1,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M683.8955,368.54808A14.14551,14.14551,0,1,1,698.041,354.40257,14.16159,14.16159,0,0,1,683.8955,368.54808Zm0-26.291A12.14551,12.14551,0,1,0,696.041,354.40257,12.159,12.159,0,0,0,683.8955,342.25706Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M689.43314,353.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,1,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M364.8955,356.54808A14.14551,14.14551,0,1,1,379.041,342.40257,14.16159,14.16159,0,0,1,364.8955,356.54808Zm0-26.291A12.14551,12.14551,0,1,0,377.041,342.40257,12.159,12.159,0,0,0,364.8955,330.25706Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M370.43314,341.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,0,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M477.8955,183.54808A14.14551,14.14551,0,1,1,492.041,169.40257,14.16159,14.16159,0,0,1,477.8955,183.54808Zm0-26.291A12.14551,12.14551,0,1,0,490.041,169.40257,12.159,12.159,0,0,0,477.8955,157.25706Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M483.43314,168.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,0,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z" transform="translate(-266.27734 -155.25706)" fill="#f2f2f2"/><path d="M326.8955,461.54808A14.14575,14.14575,0,1,1,341.041,447.40257,14.16159,14.16159,0,0,1,326.8955,461.54808Zm0-26.2915a12.14575,12.14575,0,1,0,12.14551,12.146A12.15941,12.15941,0,0,0,326.8955,435.25658Z" transform="translate(-266.27734 -155.25706)" fill="#fff"/><path d="M332.43314,446.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,0,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z" transform="translate(-266.27734 -155.25706)" fill="#fff"/><path d="M632.8955,224.54808A14.14575,14.14575,0,1,1,647.041,210.40257,14.16159,14.16159,0,0,1,632.8955,224.54808Zm0-26.2915a12.14575,12.14575,0,1,0,12.14551,12.146A12.15941,12.15941,0,0,0,632.8955,198.25658Z" transform="translate(-266.27734 -155.25706)" fill="#fff"/><path d="M638.43314,209.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,1,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z" transform="translate(-266.27734 -155.25706)" fill="#fff"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="445.34356" height="581.89215" viewBox="0 0 445.34356 581.89215" xmlns:xlink="http://www.w3.org/1999/xlink"><g><g><polygon points="128.92467 552.93374 138.51901 555.79104 154.10605 520.14411 139.9457 515.927 128.92467 552.93374" fill="#a0616a"/><path d="M140.8288,550.50975l-.00948-.0032-10.43597-2.44529-.00948-.0032-2.41704-.56239-8.30729,21.23876-.44694,1.13674,6.81666,2.03656,.56063-1.09837,2.56737-4.98059,.97997,6.0405,.21014,1.31629,18.06517,5.38934c1.074,.32018,2.18446,.18836,3.11913-.29834,1.0011-.49591,1.80138-1.39733,2.14092-2.55981,1.8212-3.33262-10.90289-15.51054-12.20874-18.11479l1.94052-6.50076-2.56557-.59145Z" fill="#2f2e41"/></g><path d="M190.38148,436.50921l-1.11692,2.88136-3.2501,8.36326-34.86355,89.0697-24.50891-6.02604c4.61286-33.65321,7.87162-54.49264,19.51731-72.39887,3.22505-4.96212,7.10411-9.70346,11.8281-14.43122,0,0-18.60782-.05679-40.46153-.50324-1.91794-.04031-3.86751-.07977-5.83331-.1347-18.09197-.42404-37.43081-1.12036-49.85358-2.27547-7.55893-.70184-12.77747-4.31265-16.19828-9.39219-9.79061-14.46282-5.12804-40.86067,.92335-45.88758l40.90617-16.26706,16.4964,29.65811,1.72604,3.09769,61.44197,4.30703c8.96469,.62842,16.58175,6.79079,19.06825,15.42664l4.17858,14.51258Z" fill="#2f2e41"/><path d="M27.34356,0l-3,491,421-73V0H27.34356ZM96.67706,416H29.34356v-67.33301H96.67706v67.33301Zm0-69.33301H29.34356v-67.33398H96.67706v67.33398Zm0-69.33398H29.34356v-67.33301H96.67706v67.33301Zm0-69.33301H29.34356v-67.3335H96.67706v67.3335Zm0-69.3335H29.34356V71.3335H96.67706v67.33301Zm0-69.33301H29.34356v-.00007C29.34356,32.1462,59.48977,2,96.67699,2h.00007V69.3335Zm69.33301,346.6665H98.67706v-67.33301h67.33301v67.33301Zm0-69.33301H98.67706v-67.33398h67.33301v67.33398Zm0-69.33398H98.67706v-67.33301h67.33301v67.33301Zm0-69.33301H98.67706v-67.3335h67.33301v67.3335Zm0-69.3335H98.67706v-.00007c0-37.18696,30.14598-67.33294,67.33294-67.33294h.00007v67.33301Zm0-69.33301H98.67706V2h67.33301V69.3335Zm69.3335,346.6665h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.33398h67.3335v67.33398Zm0-69.33398h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.3335h67.3335v67.3335Zm0-69.3335h-67.3335V71.3335h67.3335v67.33301Zm0-69.33301h-67.3335V2h67.3335V69.3335Zm69.3335,346.6665h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.33398h67.3335v67.33398Zm0-69.33398h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.3335h67.3335v67.3335Zm0-69.3335h-67.3335V71.3335h67.3335v67.33301Zm0-69.33301h-67.3335V2h67.3335V69.3335Zm69.33301,346.6665h-.00007c-37.18696,0-67.33294-30.14598-67.33294-67.33294v-.00007h67.33301v67.33301Zm0-69.33301h-67.33301v-67.33398h67.33301v67.33398Zm0-69.33398h-67.33301v-67.33301h67.33301v67.33301Zm0-69.33301h-67.33301v-67.3335h67.33301v67.3335Zm0-69.3335h-67.33301V71.3335h67.33301v67.33301Zm0-69.33301h-67.33301V2h67.33301V69.3335Zm2.00056,346.6665h-.00056v-67.33301h67.3335v.00007c0,37.18696-30.14598,67.33294-67.33294,67.33294Zm67.33294-69.33301h-67.3335v-67.33398h67.3335v67.33398Zm0-69.33398h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.3335h67.3335v67.3335Zm0-69.3335h-67.3335v-.00007c0-37.18696,30.14598-67.33294,67.33294-67.33294h.00056v67.33301Zm0-69.33301h-67.3335V2h67.3335V69.3335Z" fill="#f2f2f2"/><g><path d="M143.7444,210.76081l-8.21832,22.88252-13.72683-2.87098,9.54972-23.88366c-.26444-.73975-.42738-1.52969-.46665-2.35514-.21357-4.48952,3.25279-8.30215,7.74231-8.51572,4.48952-.21357,8.30215,3.25279,8.51572,7.74231,.1362,2.86317-1.22794,5.44608-3.39596,7.00067Z" fill="#a0616a"/><path d="M145.10987,216.968l-18.60773,50.03919-2.68918,7.22055c-2.42809,6.53008-9.11185,10.43936-16.00056,9.36736l-43.2153-6.75236-3.19397-19.81033,46.61723,4.10299,7.79503-20.44702,10.34248-27.14067,2.35996,.42301,13.21703,2.38503,3.375,.61223Z" fill="#1976d2"/></g><g><polygon points="64.23966 550.32766 72.28542 556.28428 99.08998 528.08542 87.21519 519.29401 64.23966 550.32766" fill="#a0616a"/><path d="M74.42615,558.9911l4.03844-5.4543-2.21077-1.43683-8.98752-5.86479-2.08328-1.35297-15.04861,17.1392-.80671,.9189,5.71269,4.22975,.9037-.83655,4.10272-3.80625-1.13075,6.00673-.2508,1.31996,15.14552,11.21394c.90448,.66969,1.98926,.92533,3.02758,.78863,1.11791-.13048,2.17554-.70563,2.89561-1.67815,2.84985-2.51225-4.96672-18.29191-5.30781-21.18729Z" fill="#2f2e41"/></g><path d="M237.34356,348c-76.09326,0-138-61.90625-138-138S161.2503,72,237.34356,72s138,61.90674,138,138-61.90674,138-138,138Zm0-274c-74.99072,0-100,58.00928-100,133s25.00928,139,100,139,136-61.00977,136-136-61.00928-136-136-136Z" fill="#3f3d56"/><path d="M302.72351,204.42767l-61.15649-61.15649c-.17749-.23376-.36621-.46167-.57953-.67499-1.28137-1.28137-2.96454-1.91388-4.64392-1.90161-1.67938-.01227-3.36255,.62024-4.64392,1.90161-.21332,.21332-.40204,.44122-.57953,.67499l-61.15649,61.15649c-2.53839,2.53839-2.53839,6.65393,0,9.19238,2.53839,2.53839,6.65399,2.53839,9.19238,0l50.68756-50.68756v107.5675c0,3.58984,2.91016,6.5,6.5,6.5s6.5-2.91016,6.5-6.5v-107.5675l50.68756,50.68756c2.53839,2.53839,6.65399,2.53839,9.19238,0,2.53839-2.53845,2.53839-6.65399,0-9.19238Z" fill="#1976d2"/><polygon points="78.34356 342 88.20183 374.1502 43.34356 379 59.34356 338 78.34356 342" fill="#a0616a"/><path d="M162.34356,466l-2.03003,2.32996-5.89996,6.76001-63.07001,71.91003-21-14c15.78003-30.08002,25.92999-48.57001,42.96997-61.45001,4.72003-3.57001,9.98004-6.71002,16.03003-9.54999,0,0-17.47998-6.38-37.88-14.23004-1.78998-.69-3.60999-1.38995-5.44-2.10999-16.87-6.54999-34.82001-13.77997-46.10999-19.08997-6.87-3.23004-10.54999-8.40002-12.03998-14.34003-4.29004-16.92999,9.06995-40.16998,16.46997-42.83997l44-1.39001,5.42999,33.5,.57001,3.5s16.12,7.78998,33.03998,15.57996c2.54004,1.16003,5.09003,2.33002,7.61005,3.47003,4,1.79999,7.89996,3.53998,11.51996,5.10999,.0827,.0359,.16553,.07177,.24848,.1076,10.49055,4.53143,17.02074,15.14447,16.2606,26.54657l-.67906,10.18587Z" fill="#2f2e41"/><path d="M89.32354,317.12c-1.07001,7.64001-1.32001,14.85999,.02002,18.88,.35629,1.06887,5.69178,8.88274,6,10,2.75418,9.98352-9,12-9,12l-45.09302,14.9706c-2.5966,.86206-4.78235-2.14578-3.12334-4.32137,3.69858-4.85026,7.07707-11.85798,6.83635-21.13922-.37512-14.46322-6.77592-37.46541-10.31388-49.1613-1.4559-4.81296-1.10486-9.98511,.98004-14.56086l5.03386-11.04787,7.32001-16.04999,2.35999-11.69,21,1,2.59003,9.51001,19.53998,29.82996c.78998,1.21002,1.31,2.56,1.53998,3.95001,.31,1.73999,.16003,3.56-.45001,5.27002-2.02997,5.69-4.09998,14.35999-5.23999,22.56Z" fill="#1976d2"/><g><path d="M211.82763,280.34608l-23.93249,4.28793-4.35699-13.32985,25.46422-3.63317c.50933-.59812,1.11277-1.13329,1.80867-1.57897,3.78491-2.42402,8.81827-1.32079,11.24229,2.46412,2.42402,3.78491,1.32079,8.81827-2.46412,11.24229-2.4138,1.5459-5.33291,1.65158-7.76158,.54765Z" fill="#a0616a"/><path d="M51.52867,280.18309l3.03433,3.25994c7.35817,7.90527,17.443,12.72244,28.21635,13.47794l40.24253,2.82209,74.74517-14.05192-4.55133-17.86856-70.65911,12.17742-71.02793,.18309Z" fill="#1976d2"/></g></g><g><path d="M.00957,228.79794c-.2166,9.32008,3.26648,18.34462,8.27021,26.27122,1.4867-4.62743,4.15943-8.83902,6.94682-12.85381-1.45518,8.60015,.13811,17.65509,4.2583,25.34008,.15437,.10796,.29947,.20475,.45585,.29233,4.07857,2.4534,9.24943,3.44712,13.66155,1.67514-9.11615-9.82665-10.2763-26.10791-2.6334-37.13004,2.16385-3.12756,4.96233-5.89365,6.30257-9.45289,2.11609-5.67895,.08194-11.93163-1.20127-17.85254-1.19989-5.51058-1.40992-12.06821,2.28708-16.10676-.7592-1.08524-2.20101-1.8355-3.56069-1.63943-2.27941,.32199-3.93858,2.30324-4.99531,4.34381-1.05672,2.04051-1.75366,4.30209-3.22635,6.06458-2.72722,3.29889-7.37161,4.07886-11.28556,5.81745C5.81066,207.78906,.23679,218.42727,.00957,228.79794Z" fill="#2f2e41"/><path d="M79.79675,223.46911c-.54166-1.89581,3.19176,9.69287,1.39023,9.90208-8.20531,.94132-19.46907,5.84176-25.184,8.12793-.25738-.02991-.51476-.05978-.76452-.09713-.61312-.06726-1.21114-.16439-1.80153-.27643-13.30712-2.51777-18.42436-22.95907-18.42436-23.14584,0-.91893,2.2055-26.15831,5.67986-26.53186,.90077-.09713,1.81669-.14943,2.74772-.14943h8.62162c1.8318-.38851,3.64848-.65746,5.41213-.78446h.01515c17.35676-1.3224,31.04235,9.2567,29.76311,22.12948-.00758,.01491-.02273,.02987-.03026,.04482-.37094,.55286-.69642,1.07584-.98407,1.5764-.28007,.47068-.51472,.91893-.71906,1.34479-1.58204,3.28732,2.48454,7.42377-.21196,8.19585-3.58634,1.02687,9.43221,34.7781-4.76294,34.7781,6.90484,1.96318,.74711-29.88452-.74711-35.11431Z" fill="#2f2e41"/><circle cx="64.30255" cy="222.86019" r="20.41274" fill="#a0616a"/><path d="M87.25214,213.75664c-.34063,.1793-.67369,.34364-1.01433,.50803-.35574,.17182-.71153,.34369-1.06727,.50055-6.83524,3.10054-12.39877,3.44418-15.77477-1.00858-.09083-2.33099-.61312-4.64707-1.55173-6.79876,.17413,2.38329-.47688,4.81141-1.80153,6.79876h-6.79736c-7.00175,4.64702-10.59724,5.13266-5.73766,20.3887,1.35496,4.25107,6.74242,28.98798,4.62298,32.65633-.61312-.06726-7.13605-27.16184-7.72644-27.27388-13.30712-2.51777-21.76218-24.44131-20.67975-25.68149,0-3.64592,.84778-7.0901,2.36924-10.1682,1.96804-3.99708,5.06397-7.35909,8.88653-9.66764,2.25568-1.09828,4.6325-1.98735,7.10015-2.6672,.06057-.01496,.11356-.02991,.17408-.04482,.74937-.20174,1.51389-.38851,2.27841-.54542,1.56688-.32873,3.15645-.57525,4.7839-.72468,.11356-.00748,.22707-.01496,.33306-.01496,.66612,0,1.28682,.18678,1.82422,.5006,.00758,0,.00758,.00743,.01515,.00743,.39363,.2316,.74179,.53795,1.01433,.90402,.4693,.59768,.74179,1.34479,.74179,2.15917h7.56946c.28007,0,.56013,.00748,.8402,.02239,10.54425,.41838,19.02205,8.71136,19.56707,19.0813,.02268,.3586,.03026,.70972,.03026,1.06837Z" fill="#2f2e41"/><path d="M56.06882,193.78318c0,7.42714-6.02089,13.44803-13.44803,13.44803-7.42714,0-13.44803-6.02089-13.44803-13.44803s6.02089-13.44803,13.44803-13.44803c7.42714,0,13.44803,6.02089,13.44803,13.44803Z" fill="#2f2e41"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" width="753" height="480.95111" viewBox="0 0 753 480.95111" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M372.67989,690.09163l-2-.03906a463.83342,463.83342,0,0,1,7.09961-66.28711c8.64844-46.88086,23.02929-77.66992,42.74316-91.51172l1.14844,1.63672C375.61934,566.22444,372.70333,688.85628,372.67989,690.09163Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><path d="M397.67989,689.61311l-2-.03906c.043-2.21484,1.293-54.41406,21.84277-68.8418l1.14844,1.63672C398.9504,636.21468,397.68965,689.08089,397.67989,689.61311Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><circle cx="209.54903" cy="314.54765" r="10.00001" fill="#1976d2"/><circle cx="204.59688" cy="400.54767" r="10" fill="#1976d2"/><path d="M393.01866,540.06667c1.87935,12.004-3.0189,22.7406-3.0189,22.7406s-7.9453-8.72583-9.82465-20.72986,3.01891-22.7406,3.01891-22.7406S391.1393,528.06264,393.01866,540.06667Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><path d="M425.70583,569.22047c-11.493,3.9422-22.91878.98963-22.91878.98963s7.20793-9.34412,18.70088-13.28632,22.9188-.98962,22.9188-.98962S437.19878,565.27828,425.70583,569.22047Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><path d="M426.07508,645.38161a31.13456,31.13456,0,0,1-16.06421.69366,28.37369,28.37369,0,0,1,29.172-10.00628A31.13431,31.13431,0,0,1,426.07508,645.38161Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><polygon points="606.671 467.453 593.531 467.453 587.28 416.768 606.674 416.769 606.671 467.453" fill="#9e616a"/><path d="M833.52257,689.71536l-42.3702-.00157v-.53592a16.49256,16.49256,0,0,1,16.49166-16.4914h.001l25.87827.001Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><polygon points="525.57 467.453 512.429 467.453 506.178 416.768 525.572 416.769 525.57 467.453" fill="#9e616a"/><path d="M752.421,689.71536l-42.3702-.00157v-.53592a16.49256,16.49256,0,0,1,16.49166-16.4914h.00105l25.87827.001Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><path d="M716.28867,393.14081l-18.19929-2.81212-5.87957,9.464-63.27234,16.12848.1713.87221a11.90415,11.90415,0,1,0,2.58765,12.30932L708.321,413.12185Z" transform="translate(-223.5 -209.52444)" fill="#9e616a"/><path d="M898.0541,381.87169a11.85506,11.85506,0,0,0-4.37548.841l.36312-.63329-80.44329-41.58032L802.631,358.229l83.63476,37.12523a11.89949,11.89949,0,1,0,11.78838-13.48252Z" transform="translate(-223.5 -209.52444)" fill="#9e616a"/><circle cx="736.07056" cy="267.73324" r="35.53801" transform="translate(130.38899 741.8887) rotate(-80.78252)" fill="#2f2e41"/><circle cx="512.26421" cy="70.76964" r="22.6708" fill="#a0616a"/><ellipse cx="512.57057" cy="48.4052" rx="24.50896" ry="14.70538" fill="#2f2e41"/><circle cx="515.02148" cy="22.67078" r="14.70537" fill="#2f2e41"/><path d="M718.91431,224.22982A14.70692,14.70692,0,0,1,732.08789,209.604a14.86918,14.86918,0,0,0-1.53183-.07951,14.70539,14.70539,0,0,0,0,29.41076,14.86917,14.86917,0,0,0,1.53183-.0795A14.70693,14.70693,0,0,1,718.91431,224.22982Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><path d="M723.97781,336.57587l1.82839-17.57652s24.80562-16.34735,33.23625-6.68558l50.38786,86.21281s31.323,11.13572,30.21575,53.658l-1.498,205.5398L802.631,661.61826,781.063,501.3681l-19.48674,166.026-41.35039-1.29476,3.72025-109.37556,19.71737-106.02732-.1889-35.18233-8.68389-14.19874s-15.90728-6.39038-16.35213-24.44983l-.34823-25.38571Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><path d="M749.98787,317.13922l.48927-8.23917s75.032,19.772,69.07954,33.90894-17.11318,18.60128-17.11318,18.60128l-43.155-17.11318Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><path d="M730.38083,337.64127l-5.64584-6.02061s-45.03187,63.189-31.41423,70.24916,25.0524,3.35351,25.0524,3.35351l22.22821-40.75684Z" transform="translate(-223.5 -209.52444)" fill="#2f2e41"/><path d="M640.24484,543.397,922.80569,486.993l-23.614-118.29636L616.63089,425.1006Z" transform="translate(-223.5 -209.52444)" fill="#fff"/><path d="M925.11811,488.5359,638.702,545.70941,614.31843,423.5577l286.41613-57.1735ZM641.78762,541.08463l278.70571-55.63437L897.64892,371.009,618.94321,426.64335Z" transform="translate(-223.5 -209.52444)" fill="#e4e4e4"/><rect x="649.55431" y="429.35966" width="233.18398" height="6.07982" transform="translate(-293.32159 -51.18186) rotate(-11.28883)" fill="#e4e4e4"/><rect x="654.1884" y="452.57456" width="233.18398" height="6.07982" transform="translate(-297.77636 -49.82557) rotate(-11.28883)" fill="#e4e4e4"/><rect x="658.84925" y="475.92356" width="233.18398" height="6.07982" transform="translate(-302.25687 -48.46145) rotate(-11.28883)" fill="#e4e4e4"/><path d="M770.62873,443.64449,762.631,445.241a2.24918,2.24918,0,0,1-2.643-1.76342L756.20675,424.535a2.24917,2.24917,0,0,1,1.76341-2.643l7.99772-1.59648a2.24918,2.24918,0,0,1,2.643,1.76342l3.78125,18.94256A2.24917,2.24917,0,0,1,770.62873,443.64449Z" transform="translate(-223.5 -209.52444)" fill="#1976d2"/><path d="M861.72707,449.59966l-7.99771,1.59648a2.24916,2.24916,0,0,1-2.643-1.76342l-3.78126-18.94255a2.24917,2.24917,0,0,1,1.76342-2.643l7.99772-1.59648a2.24917,2.24917,0,0,1,2.643,1.76342l3.78125,18.94255A2.24916,2.24916,0,0,1,861.72707,449.59966Z" transform="translate(-223.5 -209.52444)" fill="#1976d2"/><path d="M812.39337,483.72688l-7.99771,1.59648a2.24916,2.24916,0,0,1-2.643-1.76342l-3.78126-18.94255a2.24917,2.24917,0,0,1,1.76342-2.643l7.99772-1.59648a2.24917,2.24917,0,0,1,2.643,1.76342l3.78125,18.94256A2.24915,2.24915,0,0,1,812.39337,483.72688Z" transform="translate(-223.5 -209.52444)" fill="#1976d2"/><path d="M975.5,690.47556h-751a1,1,0,0,1,0-2h751a1,1,0,0,1,0,2Z" transform="translate(-223.5 -209.52444)" fill="#cacaca"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" width="825.20213" height="591.41898" viewBox="0 0 825.20213 591.41898" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M855.22391,530.60767a3.61324,3.61324,0,0,0,2.90706-6.13407c-.07417-.366-.12737-.62878-.20154-.99475q.05434-.11581.10925-.23144a9.7031,9.7031,0,0,1,17.876.89878c2.59635,7.179,5.991,14.40726,6.561,21.8966a28.70516,28.70516,0,0,1-.96247,9.83823,115.08607,115.08607,0,0,0,12.68043-47.26037,111.08146,111.08146,0,0,0-.112-12.41061q-.33489-5.08075-1.11483-10.11009a116.41936,116.41936,0,0,0-20.7675-50.36176,30.98251,30.98251,0,0,1-12.24992-13.95369,23.63369,23.63369,0,0,1-1.84668-6.55118c.62279.11137,1.25731.19237,1.882.2626.19474.01931.39969.03918.59443.05857l.07346.00673a3.5799,3.5799,0,0,0,3.20814-5.68922q-.38259-.51834-.7657-1.03621c-.387-.5328-.78478-1.05577-1.17173-1.58848a1.78375,1.78375,0,0,1-.12638-.16038c-.44535-.60755-.891-1.2048-1.33637-1.81235a10.3517,10.3517,0,0,1,3.54254-3.11908c4.86483-2.55314,11.30882-.328,14.53022,4.11493,3.23163,4.44334,3.599,10.48308,2.15829,15.77961a41.485,41.485,0,0,1-6.32713,12.51228c.24157.34072.49384.67161.73533,1.01232a117.17152,117.17152,0,0,1,11.3155,19.92258,48.70927,48.70927,0,0,1,3.957-22.46476c3.09271-6.57809,8.56723-11.98458,13.42656-17.56958,5.83684-6.70843,16.99941-3.14247,17.55956,5.73205q.00813.12888.0156.25766-1.04937.52926-2.05883,1.13134a4.9011,4.9011,0,0,0,1.55911,9.00132l.09912.02006a48.76709,48.76709,0,0,1-1.62312,7.22358,50.20985,50.20985,0,0,1-26.43617,30.27174c-.41021.18678-.8102.374-1.21994.5506a119.59729,119.59729,0,0,1,5.02184,30.56259,113.43466,113.43466,0,0,1-.93392,18.29177l.04087-.2143a29.97406,29.97406,0,0,1,11.02621-16.813c8.16666-6.09535,19.39042-7.95739,28.11808-12.75615a5.62528,5.62528,0,0,1,8.3519,5.86726q-.02235.11259-.04527.22517a32.92431,32.92431,0,0,0-3.77057,1.60542q-1.04937.52938-2.05883,1.13133a4.90116,4.90116,0,0,0,1.55911,9.00141l.0992.02c.0714.01365.13259.02683.20391.04048a48.808,48.808,0,0,1-9.6217,13.62515,50.25442,50.25442,0,0,1-37.14994,14.27914l-.01031-.00048a119.56225,119.56225,0,0,1-9.11335,23.04815l-28.66063-1.33426c-.088-.32324-.16508-.65631-.24275-.97907a32.59881,32.59881,0,0,0,7.95257-.10325c-2.005-2.70831-4.009-5.43714-6.014-8.14536a1.78114,1.78114,0,0,1-.12638-.16029c-1.01644-1.38562-2.04367-2.7615-3.06011-4.14712l-.0005-.00167a47.75014,47.75014,0,0,1,1.96332-12.08589Z" transform="translate(-187.39893 -154.29051)" fill="#f2f2f2"/><path d="M277.74278,282.7727a3.61324,3.61324,0,0,1-3.28049-5.94275c.05141-.36985.08827-.63544.13969-1.00529q-.0614-.11225-.12334-.22425a9.70311,9.70311,0,0,0-17.78635,2.00152c-2.14784,7.32572-5.08937,14.74988-5.19559,22.26013a28.70519,28.70519,0,0,0,1.56847,9.76A115.08612,115.08612,0,0,1,237.489,263.2354a111.08,111.08,0,0,1-.655-12.39382q.02032-5.09173.488-10.15965a116.41941,116.41941,0,0,1,17.61625-51.54865,30.9826,30.9826,0,0,0,11.36441-14.68388,23.63353,23.63353,0,0,0,1.43838-6.65276c-.61471.14962-1.243.26968-1.86218.37837-.19317.0313-.3965.0638-.58967.09518l-.0729.01126a3.5799,3.5799,0,0,1-3.55352-5.48014q.34985-.541.70021-1.08154c.35338-.55569.71805-1.10224,1.07136-1.65784a1.783,1.783,0,0,0,.11622-.16788c.407-.63391.81488-1.25754,1.22185-1.89145a10.35181,10.35181,0,0,0-3.72849-2.89425c-5.01327-2.24769-11.30748.37131-14.24822,5.0048-2.95093,4.63452-2.94443,10.68542-1.17923,15.88282a41.485,41.485,0,0,0,7.0881,12.09746c-.22006.355-.4514.70083-.67138,1.05582a117.17159,117.17159,0,0,0-10.063,20.58363,48.70935,48.70935,0,0,0-5.33737-22.17736c-3.49323-6.37444-9.29133-11.43236-14.48644-16.70646-6.24017-6.335-17.16108-2.08617-17.17187,6.806q-.00015.12915.00035.25814,1.08007.46341,2.12481,1.002a4.9011,4.9011,0,0,1-1,9.08046l-.09769.02615a48.76726,48.76726,0,0,0,2.06632,7.10949,50.20987,50.20987,0,0,0,28.256,28.58057c.421.16108.83176.32327,1.25162.47418a119.5973,119.5973,0,0,0-3.124,30.81447,113.4334,113.4334,0,0,0,2.06228,18.19912l-.054-.21137a29.974,29.974,0,0,0-12.04392-16.09966c-8.52766-5.57913-19.845-6.74416-28.85249-10.99452a5.62528,5.62528,0,0,0-7.97344,6.37206q.02925.111.05909.22194a32.92391,32.92391,0,0,1,3.86256,1.3694q1.08007.46353,2.1248,1.002a4.90116,4.90116,0,0,1-1,9.08054l-.09777.02608c-.07043.018-.13068.035-.201.053a48.80794,48.80794,0,0,0,10.44514,13.00466,50.25449,50.25449,0,0,0,37.9612,11.95658l.01025-.00112a119.563,119.563,0,0,0,10.51995,22.44105l28.52344-3.10249c.06784-.32806.12422-.66525.1818-.99219a32.5995,32.5995,0,0,1-7.94375.38829c1.83384-2.827,3.66537-5.67444,5.49922-8.50137a1.7786,1.7786,0,0,0,.11623-.1678c.9289-1.44577,1.86915-2.88248,2.798-4.32825l.0004-.00171a47.75009,47.75009,0,0,0-2.70629-11.94149Z" transform="translate(-187.39893 -154.29051)" fill="#f2f2f2"/><path d="M671.818,272.20237a10.016,10.016,0,0,1,6.38343,13.969l15.30646,17.01743-8.07279,11.82394L664.157,290.67726a10.07034,10.07034,0,0,1,7.661-18.47489Z" transform="translate(-187.39893 -154.29051)" fill="#a0616a"/><path d="M815.11419,313.98886l0,0a20.02625,20.02625,0,0,0-27.60778-6.54222l-50.33925,31.17727-54.30081-46.15769L669.3562,305.04493l59.987,77.82961,77.96532-40.64446C805.489,343.17862,817.31273,317.56739,815.11419,313.98886Z" transform="translate(-187.39893 -154.29051)" fill="#ccc"/><path d="M715.39088,417.65494a189.27007,189.27007,0,0,1-189.308,189.308c-104.55063,0-189.308-84.75749-189.308-189.308a189.24483,189.24483,0,0,1,9.65476-59.84238A189.50618,189.50618,0,0,1,526.08289,228.347,189.24453,189.24453,0,0,1,693.0211,328.33307a186.77361,186.77361,0,0,1,10.46447,23.10619c.41,1.10421.80984,2.20843,1.19884,3.32331v.01053q2.60321,7.35132,4.58557,14.97635A189.32006,189.32006,0,0,1,715.39088,417.65494Z" transform="translate(-187.39893 -154.29051)" fill="#3f3d56"/><path d="M505.371,289.93115a63.51666,63.51666,0,0,0-55.7615-2.28136c-7.79648,3.393-16.00583,9.47972-18.6067,20.47116,10.519-6.20795,24.13568,3.60058,26.8425,19.33555l-.63186.17419c-1.42965,10.89863,1.76186,22.76429,7.94073,29.52228.81123-7.01955,5.42678-11.797,9.96657-14.78135,4.53979-2.9843,9.562-5.15219,13.02707-10.28189,4.10787-6.08133,5.151-14.96914,6.7829-23.077C496.56263,300.90483,499.65869,292.1904,505.371,289.93115Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M446.48934,382.675c-2.91326,4.375-6.80454,7.12011-10.29617,10.53817-3.48109,3.42859-6.79414,8.056-7.48817,13.99821-.44177,3.80718.24187,7.67741.14712,11.52684-.09449,3.84917-1.37767,8.18221-3.99642,9.1393-4.13328,1.49335-7.28842-6.18406-11.53724-6.72045-3.37608-.42071-6.41541,4.89049-5.43739,9.497.97814,4.6065,5.57412,6.64675,8.21392,3.63888,2.38741,4.007.70457,11.27444-2.88168,12.50486-.37873,2.52413-.7572,5.03773-1.1254,7.56174-9.06574-6.34185-18.22611-12.78872-25.9351-22.07541a67.00679,67.00679,0,0,1-15.27087-36.09467c-.99907-10.67489.48375-22.88524-4.41713-31.099-3.923-6.57319-10.654-8.02468-16.71184-7.61437-1.10421.07356-2.219.19976-3.32331.33649a187.23535,187.23535,0,0,1,13.55644-31.02548,13.2821,13.2821,0,0,0,3.397-2.11395c5.63728-4.78521,8.14036-14.47155,12.71528-21.171q.44177-.64686.915-1.262c4.68019-6.1105,10.94835-9.25511,17.00622-12.1789,13.40931-6.51,27.20763-13.10427,41.36375-12.19982l-4.028.38913q-7.05168,19.75116-14.114,39.50233-1.07283,3.0288-2.16646,6.06839c-2.67138,7.48805-5.42686,15.4601-5.01668,23.84221.24187,4.964,1.96657,10.26471,5.248,11.96848,3.06039,1.57756,6.40488-.35755,9.36012-2.27173,1.25161-.79932,2.49268-1.59863,3.74416-2.40846,4.49082-2.89221,9.4654-5.858,14.20862-3.92287,4.34358,1.76694,7.55122,7.667,8.16129,14.02992A28.04928,28.04928,0,0,1,446.48934,382.675Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M473.19842,472.57227q-19.67374-12.11336-39.34763-24.22672l.22263-.57342c-8.15482,3.106-11.54047,17.60169-10.19276,29.456,1.34764,11.85442,5.91745,22.45144,8.226,34.00207a90.25226,90.25226,0,0,1-3.40267,47.35761,387.843,387.843,0,0,0,45.56027-62.78054,33.58822,33.58822,0,0,0,4.12118-9.13813c.83321-3.44179.70508-7.57955-.96357-10.33953A11.5109,11.5109,0,0,0,473.19842,472.57227Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M421.43456,325.65321c-1.3927,3.13139-1.92854,7.30684-.66468,10.5469,1.29075,3.309,4.01943,4.80443,6.53166,6.04952l7.24713,3.59224c2.411,1.19506,5.00969,2.40208,7.46752,1.41883,2.96442-1.18591,5.01982-5.83337,4.48812-10.14785-.56592-4.59118-3.45988-7.7493-6.13638-10.43868q-5.61837-5.64531-11.23667-11.29061l-2.11089,2.58543A28.19193,28.19193,0,0,0,421.43456,325.65321Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M676.54061,374.73455q4.89062,1.15159,9.781,2.30319c-.568,11.01151-6.02628,21.20266-13.34615,24.894-3.05,1.53558-6.447,2.10342-8.97113,4.9747-2.28213,2.60822-3.43911,6.66768-4.50135,10.54856q-2.79233,10.15963-5.58465,20.319c-1.99815,7.29894-4.56426,15.40772-9.75978,18.037-4.45924,2.26108-9.56-.50493-12.9886-5.143-3.42859-4.638-5.52149-10.87466-7.55135-16.95345.1262,6.6257-2.95524,13.12534-7.31986,15.42852-4.37516,2.30319-9.69688.22082-12.62054-4.92193-2.10342-3.69152-2.97629-8.56108-5.03773-12.3051-2.06132-3.744-6.38383-5.88956-8.63451-2.37688-1.48295,2.3349-1.29371,5.91061-2.02986,8.87651-1.14633,4.60637-4.6169,7.49858-8.056,7.7511-3.42859.25241-6.77309-1.72482-9.64424-4.40673-5.92114-5.55307-10.28577-14.36628-11.979-24.15777-.74667-4.36463-.957-9.11826.33662-13.20956,1.29359-4.091,4.41714-7.24617,7.51964-6.46792,2.04038-4.31211-1.98763-10.03336-5.61611-9.52856-3.639.5048-6.4891,4.40661-9.47592,7.40409-2.9763,2.99735-7.141,5.17433-10.13851,2.198.02105,2.766-2.22963,4.596-4.17526,4.36462-1.93525-.22082-3.65994-1.77733-5.43727-2.88168-6.8677-4.28053-15.58643-1.44083-20.46638,6.65729,3.05-12.97808,7.51976-27.87034,16.89041-30.92033,3.82837-1.25148,8.00363-.22082,11.62146-2.38741,6.405-3.83864,7.69859-18.34178,2.16658-24.326.70457,5.65808.568,12.26286-2.419,16.13321-2.98683,3.87036-9.25511,1.34609-8.87638-4.37515-.86248,3.94391-5.15341,4.54346-7.13063,1.5144-1.98775-3.0288-1.81944-7.98232-.41019-11.60028s3.80719-6.21564,6.13143-8.70819c4.99563-5.35318,10.06495-10.76951,15.84936-14.13507,5.79494-3.36542,12.48381-4.50122,18.28914-1.15673,3.06065,1.76681,5.753,4.71165,8.87651,6.26816,3.12368,1.567,7.08852,1.36728,9.16049-2.29279,2.32424-4.08064,1.23042-10.13851,2.0929-15.23928,1.546-9.01311,10.55909-13.23048,15.55472-7.27789-3.7335-.957-7.59333,3.46018-8.05615,8.81348-.47322,5.35317,2.22975,10.759,5.84758,12.37866,6.07892,2.69231,12.03151-4.08078,16.62761-10.34893q7.19361-9.844,14.40839-19.67748a23.78177,23.78177,0,0,1,2.57664-3.13407,8.291,8.291,0,0,1,11.327-.23135c4.8589,3.96484,7.14116,12.09468,11.12719,17.68972,5.78441,8.12971,14.44,10.10693,22.496,11.6845q9.00784,1.75107,18.02648,3.52321a186.77361,186.77361,0,0,1,10.46447,23.10619C693.305,355.76164,683.91311,363.84937,676.54061,374.73455Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M695.95528,501.2765a188.54566,188.54566,0,0,1-15.67052,26.21909c-3.78613-1.61968-7.85625,1.27253-11.40051,3.986-3.702,2.83957-8.15076,5.60558-11.94742,3.01841-3.88076-2.65033-5.13236-10.06482-3.90181-15.944,1.23042-5.8685,4.30133-10.53816,7.27776-14.97635,3.15513-4.71165,6.53108-9.60213,10.91676-11.4321,4.39621-1.83,10.04377.7572,11.327,7.00443l3.113-.10527c-1.74588-2.3978-.83077-7.362,1.51453-8.23485,2.70284-1.02013,5.04826,2.69231,6.64676,5.97377C694.546,498.26849,695.27164,499.762,695.95528,501.2765Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M576.72735,456.85307c-6.69134.4208-11.99157-7.81664-15.51364-15.92031-3.52206-8.10375-6.73574-17.37094-12.77336-21.49573-3.44981-2.35695-7.3829-2.68032-11.12485-3.82245-3.742-1.142-7.65866-3.50524-9.44741-8.31792l-4.2446-1.71473c-5.60569,3.152-11.28535,6.36156-16.11556,11.4909a36.01807,36.01807,0,0,0-9.60269,20.99346c-.81084,8.4961,2.18328,17.96965,7.77788,21.16122,4.42058,2.52189,9.56739.93232,14.04519,3.24105,5.59453,2.88442,8.916,11.2636,10.17332,19.53684s.93866,16.87112,1.83819,25.23825,3.37871,17.07349,8.50933,21.36133c6.42036,5.36571,15.8412.907,18.72178-8.86044,1.413-4.79111,1.36427-10.19733,2.42106-15.1707,1.861-8.75838,6.88293-15.25634,10.866-22.44083C576.24114,474.94861,579.37645,465.19075,576.72735,456.85307Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M510.60693,370.79a17.86027,17.86027,0,0,1,1.74249,1.84977,6.0774,6.0774,0,0,1-.107,6.27583,5.83861,5.83861,0,0,0,4.18126-2.12511,26.87915,26.87915,0,0,0,3.20585-4.51587c.68252-1.11285,1.40836-2.61751.94522-3.93927-.3161-.90214-1.06361-1.287-1.58767-1.96542-.83059-1.07533-1.03646-2.78336-1.46641-4.25929-.92846-3.18785-3.15264-5.53192-5.56707-5.86707l.33533.06416c-1.00855.34549-1.7128,1.94712-1.48986,3.38824.20313,1.31242,1.04646,2.402.96255,3.74051-.12061,1.92473-2.04418,2.828-2.163,4.753A3.67445,3.67445,0,0,0,510.60693,370.79Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M499.14247,338.08151c.00994-.00271.01994-.00326.02988-.0058a5.35694,5.35694,0,0,0,.57089-.60813Z" transform="translate(-187.39893 -154.29051)" fill="#e6e6e6"/><path d="M501.14925,347.11614c1.47948-.95135,2.30574-3.58245,1.81653-5.7846-.48608-2.18856-2.20646-3.66-3.79343-3.25583a3.86646,3.86646,0,0,1-3.59495,1.05839c-.98109-.25259-2.0582-.90305-2.90906-.16386a4.40412,4.40412,0,0,0-.9909,1.93479q-.47242,1.45027-.9449,2.90028a1.83,1.83,0,0,0-.11163,1.09908.93106.93106,0,0,0,.714.56762q2.83452.83566,5.669,1.67123C498.38094,347.54918,499.86781,347.94034,501.14925,347.11614Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M643.80516,471.848q-1.31031-2.14511-2.62049-4.29038a14.334,14.334,0,0,0-3.45325-4.33578,3.05981,3.05981,0,0,0-4.356.43639l.1064.81686c1.991,2.498,4.09755,5.2729,4.60255,8.98025.19918,1.46151.12986,2.97414.3045,4.442s.671,2.9901,1.61837,3.623c1.37543.91891,2.99049-.43593,3.96942-2.08913a7.19317,7.19317,0,0,0,1.11451-4.57885A8.02966,8.02966,0,0,0,643.80516,471.848Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M682.68046,417.23054q.37892-2.48492.758-4.96988a14.334,14.334,0,0,0,.15018-5.54088,3.05981,3.05981,0,0,0-3.61357-2.47124l-.44463.69346c-.0854,3.1932-.26073,6.67273-2.26178,9.83426-.78878,1.2464-1.8159,2.359-2.62754,3.59445s-1.41218,2.71968-1.09493,3.814c.46053,1.58874,2.56861,1.59226,4.38215.95787a7.19314,7.19314,0,0,0,3.80128-2.78536A8.02963,8.02963,0,0,0,682.68046,417.23054Z" transform="translate(-187.39893 -154.29051)" fill="#e6e6e6"/><path d="M657.50794,473.70914c.42709-1.2275-.18949-2.63572-.31972-3.99283a8.76489,8.76489,0,0,1,1.33382-4.96911,16.1539,16.1539,0,0,0,2.07833-4.55638,3.81152,3.81152,0,0,0-.09971-2.23133c-.28914-.64955-.9895-.94582-1.39116-.43149l.85964.55366a7.82867,7.82867,0,0,0-3.48867.16894,4.3178,4.3178,0,0,0-2.64407,2.98058,18.44055,18.44055,0,0,1-.69335,3.09241c-.51278,1.054-1.50541,1.4046-2.12918,2.32976a5.57021,5.57021,0,0,0,.08774,5.29184,6.1768,6.1768,0,0,0,3.4939,2.74757C655.64528,475.06942,657.02766,475.08927,657.50794,473.70914Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M681.91,481.07154a12.00485,12.00485,0,0,0,1.512,2.77512c1.16822,1.17675,2.75595.4536,4.17324.16757a7.21546,7.21546,0,0,1,6.86407,2.75319A17.47133,17.47133,0,0,0,684.41091,474.231c-3.341-1.362-6.85973-1.49359-10.33414-1.616l-.60013.1538C675.00587,477.22036,679.808,477.12076,681.91,481.07154Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M578.55783,490.17659l.00879.01939q.08736-.168.17459-.33624Z" transform="translate(-187.39893 -154.29051)" fill="#e6e6e6"/><path d="M574.8559,497.342a32.88905,32.88905,0,0,0-2.07687,4.56227,39.71126,39.71126,0,0,0-1.50522,7.80631c-.188,1.50447-.246,3.42594.69654,4.15905a1.337,1.337,0,0,0,1.74906-.23754,6.91827,6.91827,0,0,0,1.26793-1.88467,43.41661,43.41661,0,0,0,4.28028-10.15882c.90215-3.74378.89368-8.15134-.701-11.39266Q576.71136,493.76906,574.8559,497.342Z" transform="translate(-187.39893 -154.29051)" fill="#fff"/><path d="M539.14331,306.43983a4.21456,4.21456,0,0,0,4.54215.88647,14.99873,14.99873,0,0,0,4.27371-2.823,10.0548,10.0548,0,0,0,2.59074-2.82624,5.73178,5.73178,0,0,0,.53-4.36641c-.58529-1.71175-2.07037-2.28553-3.38049-2.67406q-3.14617-.933-6.29241-1.86591l1.51726-1.36753c-1.561-.83779-3.288.71707-4.26378,2.64207a14.22382,14.22382,0,0,0-1.29432,3.98431C536.84394,301.051,537.35456,304.64906,539.14331,306.43983Z" transform="translate(-187.39893 -154.29051)" fill="#e6e6e6"/><path d="M576.17373,294.00836a3.46486,3.46486,0,0,0,4.72246.38419,5.27918,5.27918,0,0,0,2.08866-3.76209c.14845-1.64984-.66729-3.48358-1.8324-3.626l.26665-1.54471c-2.24437-.4053-5.00619-.48651-6.20894,2.239A6.399,6.399,0,0,0,576.17373,294.00836Z" transform="translate(-187.39893 -154.29051)" fill="#e6e6e6"/><path d="M571.22709,211.86454a49.9257,49.9257,0,0,0-55.20724,44.0149c-3.09067,27.39943,11.34417,86.89808,37.66188,111.52805,12.39171-47.189,55.81463-75.17882,61.56026-100.33572C621.38138,240.19076,598.62652,214.95522,571.22709,211.86454Z" transform="translate(-187.39893 -154.29051)" fill="#1976d2"/><circle id="a2705e7e-530b-43fb-b0c6-4087ca2c8018" data-name="b262ea8c-1946-46c9-a449-3a1996c39394" cx="374.72809" cy="102.20342" r="16.28242" fill="#fff"/><circle id="bb575e01-1284-49d3-8651-037e5b7ffa75" data-name="bcc29a3a-8123-4529-80aa-6f70df2823cf" cx="357.60783" cy="225.9293" r="10.66463" fill="#1976d2"/><path d="M575.59911,244.82842A16.28211,16.28211,0,0,1,558.82662,272.741a16.28,16.28,0,0,0,11.9092-29.8527A16.28211,16.28211,0,0,1,575.59911,244.82842Z" transform="translate(-187.39893 -154.29051)" fill="#231f20" opacity="0.2" style="isolation:isolate"/><path d="M615.30574,267.12439c-5.74562,25.15687-49.16855,53.14674-61.56025,100.33571a69.06074,69.06074,0,0,1-6.87746-7.53474c13.92474-44.35631,54.64494-71.30876,60.19629-95.61482,4.96849-21.75442-8.98817-42.429-29.01462-51.16258C602.29173,219.24193,620.93191,242.49051,615.30574,267.12439Z" transform="translate(-187.39893 -154.29051)" fill="#231f20" opacity="0.2" style="isolation:isolate"/><path d="M418.64434,275.39608a37.4925,37.4925,0,0,0-41.45875,33.05369c-2.321,20.576,8.51909,65.25748,28.28279,83.75375,9.30575-35.43731,41.91488-56.45672,46.22965-75.34869C456.3085,296.6681,439.22038,277.71708,418.64434,275.39608Z" transform="translate(-187.39893 -154.29051)" fill="#1976d2"/><circle id="b2d5ab8a-e71c-4a1a-aadf-98f8ab95825b" data-name="b262ea8c-1946-46c9-a449-3a1996c39394" cx="224.41157" cy="154.62072" r="12.22754" fill="#fff"/><circle id="bac33ac8-32b5-423c-9bc5-6c03ceb8d8dc" data-name="bcc29a3a-8123-4529-80aa-6f70df2823cf" cx="211.55484" cy="247.53462" r="8.00877" fill="#1976d2"/><path d="M421.92757,300.15083A12.2273,12.2273,0,1,1,409.332,321.11221a12.22574,12.22574,0,0,0,8.9434-22.41835A12.22721,12.22721,0,0,1,421.92757,300.15083Z" transform="translate(-187.39893 -154.29051)" fill="#231f20" opacity="0.2" style="isolation:isolate"/><path d="M451.7459,316.89434c-4.31476,18.892-36.9239,39.91138-46.22964,75.34869a51.86155,51.86155,0,0,1-5.16474-5.65834c10.457-33.31006,41.03648-53.55043,45.20536-71.80345,3.73116-16.33682-6.74982-31.8627-21.789-38.42135C441.97282,280.93625,455.971,298.39514,451.7459,316.89434Z" transform="translate(-187.39893 -154.29051)" fill="#231f20" opacity="0.2" style="isolation:isolate"/><polygon points="614.063 564.054 600.638 564.054 594.251 512.27 614.066 512.271 614.063 564.054" fill="#a0616a"/><path d="M808.68441,743.83618H799.158l-1.70042-8.99408-4.355,8.99408H767.83616a5.67965,5.67965,0,0,1-3.22736-10.35347l20.177-13.93494v-9.0927l21.22264,1.2667Z" transform="translate(-187.39893 -154.29051)" fill="#2f2e41"/><polygon points="562.063 564.054 548.638 564.054 542.251 512.27 562.066 512.271 562.063 564.054" fill="#a0616a"/><path d="M756.68441,743.83618H747.158l-1.70042-8.99408-4.355,8.99408H715.83616a5.67965,5.67965,0,0,1-3.22736-10.35347l20.177-13.93494v-9.0927l21.22264,1.2667Z" transform="translate(-187.39893 -154.29051)" fill="#2f2e41"/><path d="M698.45785,581.62352C701.027,585.47728,728.97669,691.417,728.97669,691.417l24.78267,2.8261-2.94167-26.65516-4.49613-47.1699-6.96244-31.48522s24.58692-55.95658,26.1413-60.41406l1.10473-3.19861L774.287,595.0346a19.577,19.577,0,0,1,1.16894,7.78459c-.23122,4.35477,4.1364,69.86859,4.1364,69.86859l2.09977,23.49506,21.23324,2.94958L811.54,658.48018c7.19365-13.20558,3.07-60.13148.12843-64.49911s-1.77275-34.78661-1.77275-34.78661c3.75647-1.32184,26.15662-77.70611,14.95252-77.25506.71936-4.07209,1.28453-7.70751,1.28453-7.70751L806.6841,458.54706l-48.67284-12.65291-12.27964-5.89628s-21.93185,40.55432-21.71349,42.57113a11.21429,11.21429,0,0,1-1.65709,7.3093l-22.14331,74.10779S695.863,577.73126,698.45785,581.62352Z" transform="translate(-187.39893 -154.29051)" fill="#2f2e41"/><path d="M820.74021,316.438,812.997,299.99787l-26.35436,1.01288-8.59627,17.10337s-24.56687,29.34271-25.362,38.88375c-1,12,7.31164,70.81225-1,67,0,0-19.59459,23-8,23s64.04242,32.924,67.48383,36.62652,18.80446,6.10321,17.51617-1.62652-7.9442-49.53382-7.9442-49.53382l18.01876-65.733c5.18564-14.19171,6.79951-30.11048-4.923-39.64345Z" transform="translate(-187.39893 -154.29051)" fill="#ccc"/><path d="M723.12108,268.05031A28.8805,28.8805,0,0,0,685.62273,284.238c-5.88478,14.825-6.86,50.22813,4.09122,67.97179,14.08087-24.45936,42.56848-33.49094,49.59479-46.6611C746.8166,291.47589,737.94606,273.9351,723.12108,268.05031Z" transform="translate(-187.39893 -154.29051)" fill="#1976d2"/><circle id="f50692ea-d13f-4759-b5e2-05248e17533e" data-name="b262ea8c-1946-46c9-a449-3a1996c39394" cx="523.86724" cy="137.29013" r="9.41888" fill="#fff"/><circle id="aec6a1c4-a00c-42b6-a49d-0158b63ca54a" data-name="bcc29a3a-8123-4529-80aa-6f70df2823cf" cx="495.52762" cy="203.75403" r="6.16917" fill="#1976d2"/><path d="M720.55717,287.11426a9.41871,9.41871,0,0,1-13.59978,13.03434A9.4175,9.4175,0,0,0,718.13705,285.293,9.41862,9.41862,0,0,1,720.55717,287.11426Z" transform="translate(-187.39893 -154.29051)" fill="#231f20" opacity="0.2" style="isolation:isolate"/><path d="M739.33634,305.58771c-7.0263,13.17015-35.51393,22.20174-49.59479,46.6611a39.949,39.949,0,0,1-2.69508-5.24993c14.50656-22.64545,41.328-31.50828,48.11674-44.233,6.076-11.3889,1.42413-25.0481-8.42863-32.96342C739.34118,276.88434,746.21658,292.69137,739.33634,305.58771Z" transform="translate(-187.39893 -154.29051)" fill="#231f20" opacity="0.2" style="isolation:isolate"/><path d="M680.14627,355.92032a10.01609,10.01609,0,0,1,12.03458,9.542l21.36828,8.20224-1.81735,14.20115-30.01347-12.007a10.07034,10.07034,0,0,1-1.572-19.93845Z" transform="translate(-187.39893 -154.29051)" fill="#a0616a"/><path d="M829.45215,326.65553l0,0a20.02625,20.02625,0,0,0-27.56523,6.71925l-30.67136,50.64907L701.8692,367.58613l-6.31772,17.34458,88.80518,42.06574,44.97713-71.63724C836.06781,345.896,839.36537,332.70754,829.45215,326.65553Z" transform="translate(-187.39893 -154.29051)" fill="#ccc"/><path d="M830.59748,264.58346a29.82287,29.82287,0,1,1-51.29533-20.68525l.14314-.143c.2386-.25061.4772-.50108.72773-.73975a.01167.01167,0,0,0,.01187-.01194c.31017-.28629.62034-.57258.94245-.84692a29.815,29.815,0,0,1,49.47014,22.42685Z" transform="translate(-187.39893 -154.29051)" fill="#2f2e41"/><circle cx="606.02821" cy="117.1931" r="25.00775" fill="#9e616a"/><path d="M819.98324,278.61537l-4.14356-.73193a11.55433,11.55433,0,0,1-9.30469-9.31739l-4.043,6.77588-.17675.0586c-9.63282,3.19824-19.65528,2.2417-30.63379-2.92041a85.46475,85.46475,0,0,1-9.11817-5.02735l-.21679-.13525-.01758-.2544c-.55957-8.13525,1.26562-14.93164,5.1416-19.1372a15.41707,15.41707,0,0,1,11.63379-4.84961.95727.95727,0,0,0,.41309-.228c.05566-.041.11132-.08154.167-.12012v-.042l.28711-.13525c.61718-.29,1.24609-.56787,1.875-.82178a28.19911,28.19911,0,0,1,29.44824,5.708c7.70312,7.354,11.23633,19.69531,8.792,30.71093Z" transform="translate(-187.39893 -154.29051)" fill="#2f2e41"/><path d="M872.72977,299.9221c-8.51007-4.39247,2.43483-20.33442.23554-29.65523-2.19937-9.32081-18.037-12.31871-19.04593-21.84222s-3.38245-19.346-9.6668-26.57249c-4.01568-4.61774-9.93278-8.02669-16.02492-7.44829a14.40868,14.40868,0,0,0-12.62826,17.79207c-1.73455-2.45776-6.22341-1.92509-7.33449.87052-.98788,2.48528,1.19437,5.49568,3.76252,5.71556,3.36046,4.15,7.2086,8.55427,12.47325,9.39144a5.68063,5.68063,0,0,0,4.84076-1.11734c1.23856-1.18942,1.33489-3.56739-.13434-4.45625,6.61615,2.62814,10.49509,9.78155,11.47678,16.83259.98162,7.051-.3765,14.18523-1.27148,21.24778s-1.28057,14.492,1.4886,21.05045c3.27178,7.74885,10.80453,13.30263,19.02518,15.0837s16.97552.04034,24.4166-3.88148c7.44108-3.92212,13.64622-9.90941,18.71523-16.62188C894.3263,302.51121,882.24593,304.834,872.72977,299.9221Z" transform="translate(-187.39893 -154.29051)" fill="#2f2e41"/><path d="M818.91887,277.92016s-7.408-27.65168-39.16341-34.03389c-.03575-.01179-.15508-.05955-.31017-.131-.09538-.05971-.21472-.11941-.334-.179.35786-.20285.70378-.38167,1.06171-.56078a.01167.01167,0,0,0,.01187-.01194c.31017-.28629.62034-.57258.94245-.84692l.90663.03582S813.89667,237.14642,818.91887,277.92016Z" transform="translate(-187.39893 -154.29051)" fill="#fd6584"/><polygon points="614.934 212.357 596.999 233.136 567.364 224.385 599.671 239.273 614.934 212.357" opacity="0.2"/><path d="M909.9846,745.40215l-275.75.30734a1.19069,1.19069,0,0,1,0-2.38137l275.75-.30733a1.19068,1.19068,0,1,1,0,2.38136Z" transform="translate(-187.39893 -154.29051)" fill="#cacaca"/><path d="M922.0884,560.36242q-19.36816,0-42.45654-1.46387c-79.61377-5.05566-182.73779-22.63281-290.376-49.49218C481.61813,482.547,382.32565,449.61242,309.67037,416.672c-35.39257-16.04687-62.55615-31.23633-80.73535-45.14746-19.24707-14.727-27.666-27.564-25.02392-38.15283,5.148-20.62891,50.731-25.14209,88.064-25.29541l.0127,3c-51.26807.21045-81.51367,8.38672-85.16553,23.022-4.65185,18.64014,33.28662,47.74072,104.08691,79.84131,72.49561,32.86813,171.60547,65.73923,279.07322,92.55661,107.46728,26.81641,210.40136,44.36328,289.83984,49.4082,77.57861,4.92774,124.74316-2.9375,129.39453-21.57812,3.86182-15.47657-21.59814-38.27539-71.68945-64.19825l1.3789-2.66406c36.397,18.83594,78.64551,45.85156,73.22168,67.58887-2.64251,10.58887-16.1054,17.96484-40.01507,21.92285C958.48342,559.23156,941.7427,560.36242,922.0884,560.36242Z" transform="translate(-187.39893 -154.29051)" fill="#1976d2"/></svg>
\ No newline at end of file
import { boot } from 'quasar/wrappers'
import { createApolloProvider } from '@vue/apollo-option'
import { ApolloClient, InMemoryCache } from '@apollo/client/core'
import { setContext } from '@apollo/client/link/context'
import { createUploadLink } from 'apollo-upload-client'
......@@ -41,16 +40,9 @@ export default boot(({ app }) => {
ssrForceFetchDelay: 100
})
// Init Vue Apollo
const apolloProvider = createApolloProvider({
defaultClient: client
})
if (import.meta.env.SSR) {
global.APOLLO_CLIENT = client
} else {
window.APOLLO_CLIENT = client
}
app.use(apolloProvider)
})
<template lang="pug">
q-dialog(ref='dialogRef', @hide='onDialogHide', persistent)
q-card(style='min-width: 600px;')
q-card-section.card-header
q-icon(name='img:/_assets/icons/fluent-key-2.svg', left, size='sm')
span {{t(`admin.api.copyKeyTitle`)}}
q-card-section.card-negative
i18n-t(tag='span', keypath='admin.api.newKeyCopyWarn')
template(#bold)
strong {{t('admin.api.newKeyCopyWarnBold')}}
q-form.q-py-sm
q-item
blueprint-icon.self-start(icon='binary-file')
q-item-section
q-input(
type='textarea'
outlined
v-model='props.keyValue'
dense
hide-bottom-space
:label='t(`admin.api.key`)'
:aria-label='t(`admin.api.key`)'
autofocus
)
q-card-actions.card-actions
q-space
q-btn(
unelevated
:label='t(`common.actions.close`)'
color='primary'
padding='xs md'
@click='onDialogOK'
)
</template>
<script setup>
import { useI18n } from 'vue-i18n'
import { useDialogPluginComponent, useQuasar } from 'quasar'
// PROPS
const props = defineProps({
keyValue: {
type: String,
required: true
}
})
// EMITS
defineEmits([
...useDialogPluginComponent.emits
])
// QUASAR
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent()
const $q = useQuasar()
// I18N
const { t } = useI18n()
</script>
<template lang="pug">
q-dialog(ref='dialogRef', @hide='onDialogHide')
q-card(style='min-width: 650px;')
q-card-section.card-header
q-icon(name='img:/_assets/icons/fluent-plus-plus.svg', left, size='sm')
span {{t(`admin.api.newKeyTitle`)}}
q-form.q-py-sm(ref='createKeyForm', @submit='create')
q-item
blueprint-icon.self-start(icon='grand-master-key')
q-item-section
q-input(
outlined
v-model='state.keyName'
dense
:rules='keyNameValidation'
hide-bottom-space
:label='t(`admin.api.newKeyName`)'
:aria-label='t(`admin.api.newKeyName`)'
:hint='t(`admin.api.newKeyNameHint`)'
lazy-rules='ondemand'
autofocus
ref='iptName'
)
q-item
blueprint-icon.self-start(icon='schedule')
q-item-section
q-select(
outlined
:options='expirations'
v-model='state.keyExpiration'
multiple
map-options
option-value='value'
option-label='text'
emit-value
options-dense
dense
hide-bottom-space
:label='t(`admin.api.newKeyExpiration`)'
:aria-label='t(`admin.api.newKeyExpiration`)'
:hint='t(`admin.api.newKeyExpirationHint`)'
)
q-item
blueprint-icon.self-start(icon='access')
q-item-section
q-select(
outlined
:options='state.groups'
v-model='state.keyGroups'
multiple
map-options
emit-value
option-value='id'
option-label='name'
options-dense
dense
:rules='keyGroupsValidation'
hide-bottom-space
:label='t(`admin.api.permissionGroups`)'
:aria-label='t(`admin.api.permissionGroups`)'
:hint='t(`admin.api.newKeyGroupHint`)'
lazy-rules='ondemand'
:loading='state.loadingGroups'
)
template(v-slot:selected)
.text-caption(v-if='state.keyGroups.length > 1')
i18n-t(keypath='admin.api.groupsSelected')
template(#count)
strong {{ state.keyGroups.length }}
.text-caption(v-else-if='state.keyGroups.length === 1')
i18n-t(keypath='admin.api.groupSelected')
template(#group)
strong {{ selectedGroupName }}
span(v-else)
template(v-slot:option='{ itemProps, opt, selected, toggleOption }')
q-item(
v-bind='itemProps'
)
q-item-section(side)
q-checkbox(
size='sm'
:model-value='selected'
@update:model-value='toggleOption(opt)'
)
q-item-section
q-item-label {{opt.name}}
q-card-actions.card-actions
q-space
q-btn.acrylic-btn(
flat
:label='t(`common.actions.cancel`)'
color='grey'
padding='xs md'
@click='onDialogCancel'
)
q-btn(
unelevated
:label='t(`common.actions.create`)'
color='primary'
padding='xs md'
@click='create'
:loading='state.loading > 0'
)
</template>
<script setup>
import gql from 'graphql-tag'
import { cloneDeep, sampleSize } from 'lodash-es'
import { useI18n } from 'vue-i18n'
import { useDialogPluginComponent, useQuasar } from 'quasar'
import { computed, onMounted, reactive, ref } from 'vue'
import ApiKeyCopyDialog from './ApiKeyCopyDialog.vue'
// EMITS
defineEmits([
...useDialogPluginComponent.emits
])
// QUASAR
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const $q = useQuasar()
// I18N
const { t } = useI18n()
// DATA
const state = reactive({
keyName: '',
keyExpiration: '90d',
keyGroups: [],
groups: [],
loadingGroups: false,
loading: false
})
const expirations = [
{ value: '30d', text: t('admin.api.expiration30d') },
{ value: '90d', text: t('admin.api.expiration90d') },
{ value: '180d', text: t('admin.api.expiration180d') },
{ value: '1y', text: t('admin.api.expiration1y') },
{ value: '3y', text: t('admin.api.expiration3y') }
]
// REFS
const createKeyForm = ref(null)
const iptName = ref(null)
// COMPUTED
const selectedGroupName = computed(() => {
return state.groups.filter(g => g.id === state.keyGroups[0])[0]?.name
})
// VALIDATION RULES
const keyNameValidation = [
val => val.length > 0 || t('admin.api.nameMissing'),
val => /^[^<>"]+$/.test(val) || t('admin.api.nameInvalidChars')
]
const keyGroupsValidation = [
val => val.length > 0 || t('admin.api.groupsMissing')
]
// METHODS
async function loadGroups () {
state.loading++
state.loadingGroups = true
const resp = await APOLLO_CLIENT.query({
query: gql`
query getGroupsForCreateApiKey {
groups {
id
name
}
}
`,
fetchPolicy: 'network-only'
})
state.groups = cloneDeep(resp?.data?.groups?.filter(g => g.id !== '10000000-0000-4000-8000-000000000001') ?? [])
state.loadingGroups = false
state.loading--
}
async function create () {
state.loading++
try {
const isFormValid = await createKeyForm.value.validate(true)
if (!isFormValid) {
throw new Error(t('admin.api.createInvalidData'))
}
const resp = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation createApiKey (
$name: String!
$expiration: String!
$groups: [UUID]!
) {
createApiKey (
name: $name
expiration: $expiration
groups: $groups
) {
operation {
succeeded
message
}
key
}
}
`,
variables: {
name: state.keyName,
expiration: state.keyExpiration,
groups: state.keyGroups
}
})
if (resp?.data?.createApiKey?.operation?.succeeded) {
$q.notify({
type: 'positive',
message: t('admin.api.createSuccess')
})
$q.dialog({
component: ApiKeyCopyDialog,
componentProps: {
keyValue: resp?.data?.createApiKey?.key || 'ERROR'
}
}).onDismiss(() => {
onDialogOK()
})
} else {
throw new Error(resp?.data?.createApiKey?.operation?.message || 'An unexpected error occured.')
}
} catch (err) {
$q.notify({
type: 'negative',
message: err.message
})
}
state.loading--
}
// MOUNTED
onMounted(loadGroups)
</script>
<template lang="pug">
q-dialog(ref='dialogRef', @hide='onDialogHide')
q-card(style='min-width: 350px; max-width: 450px;')
q-card-section.card-header
q-icon(name='img:/_assets/icons/fluent-unavailable.svg', left, size='sm')
span {{t(`admin.api.revokeConfirm`)}}
q-card-section
.text-body2
i18n-t(keypath='admin.api.revokeConfirmText')
template(#name)
strong {{apiKey.name}}
q-card-actions.card-actions
q-space
q-btn.acrylic-btn(
flat
:label='t(`common.actions.cancel`)'
color='grey'
padding='xs md'
@click='onDialogCancel'
)
q-btn(
unelevated
:label='t(`admin.api.revoke`)'
color='negative'
padding='xs md'
@click='confirm'
:loading='state.isLoading'
)
</template>
<script setup>
import gql from 'graphql-tag'
import { useI18n } from 'vue-i18n'
import { useDialogPluginComponent, useQuasar } from 'quasar'
import { reactive } from 'vue'
// PROPS
const props = defineProps({
apiKey: {
type: Object,
required: true
}
})
// EMITS
defineEmits([
...useDialogPluginComponent.emits
])
// QUASAR
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const $q = useQuasar()
// I18N
const { t } = useI18n()
// DATA
const state = reactive({
isLoading: false
})
// METHODS
async function confirm () {
state.isLoading = true
try {
const resp = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation revokeApiKey ($id: UUID!) {
revokeApiKey (id: $id) {
operation {
succeeded
message
}
}
}
`,
variables: {
id: props.apiKey.id
}
})
if (resp?.data?.revokeApiKey?.operation?.succeeded) {
$q.notify({
type: 'positive',
message: t('admin.api.revokeSuccess')
})
onDialogOK()
} else {
throw new Error(resp?.data?.revokeApiKey?.operation?.message || 'An unexpected error occured.')
}
} catch (err) {
$q.notify({
type: 'negative',
message: err.message
})
}
state.isLoading = false
}
</script>
<template lang="pug">
q-dialog(ref='dialogRef', @hide='onDialogHide')
q-card(style='min-width: 350px; max-width: 450px;')
q-card-section.card-header
q-icon(name='img:/_assets/icons/fluent-downloading-updates.svg', left, size='sm')
span {{t(`admin.system.checkingForUpdates`)}}
q-card-section
.q-pa-md.text-center
img(src='/_assets/illustrations/undraw_going_up.svg', style='width: 150px;')
q-linear-progress(
indeterminate
size='lg'
rounded
)
.q-mt-sm.text-center.text-caption Fetching latest version info...
q-card-actions.card-actions
q-space
q-btn.acrylic-btn(
flat
:label='t(`common.actions.cancel`)'
color='grey'
padding='xs md'
@click='onDialogCancel'
)
q-btn(
v-if='state.canUpgrade'
unelevated
:label='t(`admin.system.upgrade`)'
color='primary'
padding='xs md'
@click='upgrade'
:loading='state.isLoading'
)
</template>
<script setup>
import gql from 'graphql-tag'
import { useI18n } from 'vue-i18n'
import { useDialogPluginComponent, useQuasar } from 'quasar'
import { reactive } from 'vue'
// EMITS
defineEmits([
...useDialogPluginComponent.emits
])
// QUASAR
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const $q = useQuasar()
// I18N
const { t } = useI18n()
// DATA
const state = reactive({
isLoading: false,
canUpgrade: false
})
// METHODS
async function upgrade () {
state.isLoading = true
try {
const resp = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation deleteHook ($id: UUID!) {
deleteHook(id: $id) {
operation {
succeeded
message
}
}
}
`,
variables: {
id: 0
}
})
if (resp?.data?.deleteHook?.operation?.succeeded) {
$q.notify({
type: 'positive',
message: t('admin.webhooks.deleteSuccess')
})
onDialogOK()
} else {
throw new Error(resp?.data?.deleteHook?.operation?.message || 'An unexpected error occured.')
}
} catch (err) {
$q.notify({
type: 'negative',
message: err.message
})
}
state.isLoading = false
}
</script>
......@@ -152,6 +152,27 @@ body::-webkit-scrollbar-thumb {
}
}
.card-negative {
display: flex;
align-items: center;
font-size: .9rem;
@at-root .body--light & {
background-color: $red-1;
background-image: radial-gradient(at bottom center, lighten($red-1, 2%), lighten($red-2, 2%));
border-bottom: 1px solid $red-3;
text-shadow: 0 0 4px #FFF;
color: $red-9;
}
@at-root .body--dark & {
background-color: $red-9;
background-image: radial-gradient(at bottom center, $red-7, $red-9);
border-bottom: 1px solid $red-7;
text-shadow: 0 0 4px darken($red-9, 10%);
color: #FFF;
}
}
.card-actions {
@at-root .body--light & {
background-color: #FAFAFA;
......
......@@ -24,7 +24,7 @@
"admin.api.headerRevoke": "Revoke",
"admin.api.newKeyButton": "New API Key",
"admin.api.newKeyCopyWarn": "Copy the key shown below as {bold}",
"admin.api.newKeyCopyWarnBold": "it will NOT be shown again",
"admin.api.newKeyCopyWarnBold": "it will NOT be shown again.",
"admin.api.newKeyExpiration": "Expiration",
"admin.api.newKeyExpirationHint": "You can still revoke a key anytime regardless of the expiration.",
"admin.api.newKeyFullAccess": "Full Access",
......@@ -1449,5 +1449,22 @@
"admin.auth.enabledHint": "Should this strategy be available to sites for login.",
"admin.auth.vendor": "Vendor",
"admin.auth.vendorWebsite": "Website",
"admin.auth.status": "Status"
"admin.auth.status": "Status",
"admin.system.checkingForUpdates": "Checking for Updates...",
"admin.system.upgrade": "Upgrade",
"admin.system.checkForUpdates": "Check",
"admin.system.checkUpdate": "Check / Upgrade",
"admin.api.none": "There are no API keys yet.",
"admin.api.groupsMissing": "You must select at least 1 group for this key.",
"admin.api.nameInvalidChars": "Key name has invalid characters.",
"admin.api.nameMissing": "Key name is missing.",
"admin.api.permissionGroups": "Group Permissions",
"admin.api.groupSelected": "Use {group} group permissions",
"admin.api.groupsSelected": "Use permissions from {count} groups",
"admin.api.createInvalidData": "Some fields are missing or have invalid data.",
"admin.api.copyKeyTitle": "Copy API Key",
"admin.api.key": "API Key",
"admin.api.createSuccess": "API Key created successfully.",
"admin.api.revoked": "Revoked",
"admin.api.revokedHint": "This key has been revoked and can no longer be used."
}
......@@ -9,7 +9,7 @@ q-page.admin-api
.col
.flex.items-center
template(v-if='state.enabled')
q-spinner-rings.q-mr-sm(color='green')
q-spinner-rings.q-mr-sm(color='green', size='md')
.text-caption.text-green {{t('admin.api.enabled')}}
template(v-else)
q-spinner-rings.q-mr-sm(color='red', size='md')
......@@ -28,7 +28,7 @@ q-page.admin-api
flat
color='secondary'
:loading='state.loading > 0'
@click='load'
@click='refresh'
)
q-btn.q-mr-sm(
unelevated
......@@ -36,6 +36,7 @@ q-page.admin-api
:label='!state.enabled ? t(`admin.api.enableButton`) : t(`admin.api.disableButton`)'
:color='!state.enabled ? `positive` : `negative`'
@click='globalSwitch'
:loading='state.isToggleLoading'
:disabled='state.loading > 0'
)
q-btn(
......@@ -48,70 +49,47 @@ q-page.admin-api
)
q-separator(inset)
.row.q-pa-md.q-col-gutter-md
.col-12.col-lg-7
q-card.shadow-1
//- v-container(fluid, grid-list-lg)
//- v-layout(row, wrap)
//- v-flex(xs12)
//- .admin-header
//- img.animated.fadeInUp(src='/_assets/svg/icon-rest-api.svg', alt='API', style='width: 80px;')
//- .admin-header-title
//- .headline.primary--text.animated.fadeInLeft {{$t('admin.api.title')}}
//- .subtitle-1.grey--text.animated.fadeInLeft {{$t('admin.api.subtitle')}}
//- v-spacer
//- template(v-if='enabled')
//- status-indicator.mr-3(positive, pulse)
//- .caption.green--text.animated.fadeInLeft {{$t('admin.api.enabled')}}
//- template(v-else)
//- status-indicator.mr-3(negative, pulse)
//- .caption.red--text.animated.fadeInLeft {{$t('admin.api.disabled')}}
//- v-spacer
//- v-btn.mr-3.animated.fadeInDown.wait-p2s(outlined, color='grey', icon, @click='refresh')
//- v-icon mdi-refresh
//- v-btn.mr-3.animated.fadeInDown.wait-p1s(:color='enabled ? `red` : `green`', depressed, @click='globalSwitch', dark, :loading='isToggleLoading')
//- v-icon(left) mdi-power
//- span(v-if='!enabled') {{$t('admin.api.enableButton')}}
//- span(v-else) {{$t('admin.api.disableButton')}}
//- v-btn.animated.fadeInDown(color='primary', depressed, large, @click='newKey', dark)
//- v-icon(left) mdi-plus
//- span {{$t('admin.api.newKeyButton')}}
//- v-card.mt-3.animated.fadeInUp
//- v-simple-table(v-if='keys && keys.length > 0')
//- template(v-slot:default)
//- thead
//- tr.grey(:class='$vuetify.theme.dark ? `darken-4-d5` : `lighten-5`')
//- th {{$t('admin.api.headerName')}}
//- th {{$t('admin.api.headerKeyEnding')}}
//- th {{$t('admin.api.headerExpiration')}}
//- th {{$t('admin.api.headerCreated')}}
//- th {{$t('admin.api.headerLastUpdated')}}
//- th(width='100') {{$t('admin.api.headerRevoke')}}
//- tbody
//- tr(v-for='key of keys', :key='`key-` + key.id')
//- td
//- strong(:class='key.isRevoked ? `red--text` : ``') {{ key.name }}
//- em.caption.ml-1.red--text(v-if='key.isRevoked') (revoked)
//- td.caption {{ key.keyShort }}
//- td(:style='key.isRevoked ? `text-decoration: line-through;` : ``') {{ key.expiration | moment('LL') }}
//- td {{ key.createdAt | moment('calendar') }}
//- td {{ key.updatedAt | moment('calendar') }}
//- td: v-btn(icon, @click='revoke(key)', :disabled='key.isRevoked'): v-icon(color='error') mdi-cancel
//- v-card-text(v-else)
//- v-alert.mb-0(icon='mdi-information', :value='true', outlined, color='info') {{$t('admin.api.noKeyInfo')}}
//- create-api-key(v-model='isCreateDialogShown', @refresh='refresh(false)')
//- v-dialog(v-model='isRevokeConfirmDialogShown', max-width='500', persistent)
//- v-card
//- .dialog-header.is-red {{$t('admin.api.revokeConfirm')}}
//- v-card-text.pa-4
//- i18next(tag='span', path='admin.api.revokeConfirmText')
//- strong(place='name') {{ current.name }}
//- v-card-actions
//- v-spacer
//- v-btn(text, @click='isRevokeConfirmDialogShown = false', :disabled='revokeLoading') {{$t('common.actions.cancel')}}
//- v-btn(color='red', dark, @click='revokeConfirm', :loading='revokeLoading') {{$t('admin.api.revoke')}}
.col-12(v-if='state.keys.length < 1')
q-card.rounded-borders(
flat
:class='$q.dark.isActive ? `bg-dark-5 text-white` : `bg-grey-3 text-dark`'
)
q-card-section.items-center(horizontal)
q-card-section.col-auto.q-pr-none
q-icon(name='las la-info-circle', size='sm')
q-card-section.text-caption {{ t('admin.api.none') }}
.col-12(v-else)
q-card
q-list(separator)
q-item(v-for='key of state.keys', :key='key.id')
q-item-section(side)
q-icon(name='las la-key', :color='key.isRevoked ? `negative` : `positive`')
q-item-section
q-item-label {{key.name}}
q-item-label(caption) Ending in {{key.keyShort}}
q-item-label(caption) Created On: #[strong {{DateTime.fromISO(key.createdAt).toFormat('fff')}}]
q-item-label(caption) Expiration: #[strong(:style='key.isRevoked ? `text-decoration: line-through;` : ``') {{DateTime.fromISO(key.expiration).toFormat('fff')}}]
q-item-section(
v-if='key.isRevoked'
side
style='flex-direction: row; align-items: center;'
)
q-icon.q-mr-sm(
color='negative'
size='xs'
name='las la-exclamation-triangle'
)
.text-caption.text-negative {{t('admin.api.revoked')}}
q-tooltip(anchor='center left', self='center right') {{t('admin.api.revokedHint')}}
q-separator.q-ml-md(vertical)
q-item-section(side, style='flex-direction: row; align-items: center;')
q-btn.acrylic-btn(
:color='key.isRevoked ? `gray` : `red`'
icon='las la-ban'
flat
@click='revoke(key)'
:disable='key.isRevoked'
)
</template>
<script setup>
......@@ -120,6 +98,10 @@ import { cloneDeep } from 'lodash-es'
import { useI18n } from 'vue-i18n'
import { useMeta, useQuasar } from 'quasar'
import { computed, onMounted, reactive, watch } from 'vue'
import { DateTime } from 'luxon'
import ApiKeyCreateDialog from '../components/ApiKeyCreateDialog.vue'
import ApiKeyRevokeDialog from '../components/ApiKeyRevokeDialog.vue'
// QUASAR
......@@ -140,6 +122,7 @@ useMeta({
const state = reactive({
enabled: false,
loading: 0,
isToggleLoading: false,
keys: [],
isCreateDialogShown: false,
isRevokeConfirmDialogShown: false,
......@@ -154,7 +137,7 @@ async function load () {
$q.loading.show()
const resp = await APOLLO_CLIENT.query({
query: gql`
query getHooks {
query getApiKeys {
apiKeys {
id
name
......@@ -175,23 +158,27 @@ async function load () {
state.loading--
}
async function refresh () {
await load()
$q.notify({
type: 'positive',
message: t('admin.api.refreshSuccess')
})
}
async function globalSwitch () {
state.isToggleLoading = true
try {
const resp = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation ($enabled: Boolean!) {
authentication {
setApiState (enabled: $enabled) {
responseResult {
operation {
succeeded
errorCode
slug
message
}
}
}
}
`,
variables: {
enabled: !state.enabled
......@@ -204,7 +191,7 @@ async function globalSwitch () {
})
await load()
} else {
throw new Error(resp?.data?.setApiState?.operation.message || 'An unexpected error occurred.')
throw new Error(resp?.data?.setApiState?.operation?.message || 'An unexpected error occurred.')
}
} catch (err) {
$q.notify({
......@@ -217,62 +204,27 @@ async function globalSwitch () {
}
async function newKey () {
state.isCreateDialogShown = true
$q.dialog({
component: ApiKeyCreateDialog
}).onOk(() => {
load()
})
}
function revoke (key) {
state.current = key
state.isRevokeConfirmDialogShown = true
}
async function revokeConfirm () {
state.revokeLoading = true
try {
const resp = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation ($id: Int!) {
authentication {
revokeApiKey (id: $id) {
responseResult {
succeeded
errorCode
slug
message
}
}
}
}
`,
variables: {
id: state.current.id
$q.dialog({
component: ApiKeyRevokeDialog,
componentProps: {
apiKey: key
}
}).onOk(() => {
load()
})
// if (_get(resp, 'data.authentication.revokeApiKey.responseResult.succeeded', false)) {
// this.$store.commit('showNotification', {
// style: 'success',
// message: this.$t('admin.api.revokeSuccess'),
// icon: 'check'
// })
// this.load()
// } else {
// this.$store.commit('showNotification', {
// style: 'red',
// message: _get(resp, 'data.authentication.revokeApiKey.responseResult.message', 'An unexpected error occurred.'),
// icon: 'alert'
// })
// }
} catch (err) {
// this.$store.commit('pushGraphError', err)
}
state.isRevokeConfirmDialogShown = false
state.revokeLoading = false
}
// MOUNTED
onMounted(() => {
load()
})
onMounted(load)
</script>
......
<template lang="pug">
div
v-dialog(v-model='isShown', max-width='650', persistent)
v-card
.dialog-header.is-short
v-icon.mr-3(color='white') mdi-plus
span {{$t('admin.api.newKeyTitle')}}
v-card-text.pt-5
v-text-field(
outlined
prepend-icon='mdi-format-title'
v-model='name'
:label='$t(`admin.api.newKeyName`)'
persistent-hint
ref='keyNameInput'
:hint='$t(`admin.api.newKeyNameHint`)'
counter='255'
)
v-select.mt-3(
:items='expirations'
outlined
prepend-icon='mdi-clock'
v-model='expiration'
:label='$t(`admin.api.newKeyExpiration`)'
:hint='$t(`admin.api.newKeyExpirationHint`)'
persistent-hint
)
v-divider.mt-4
v-subheader.pl-2: strong.indigo--text {{$t('admin.api.newKeyPermissionScopes')}}
v-list.pl-8(nav)
v-list-item-group(v-model='fullAccess')
v-list-item(
:value='true'
active-class='indigo--text'
)
template(v-slot:default='{ active, toggle }')
v-list-item-action
v-checkbox(
:input-value='active'
:true-value='true'
color='indigo'
@click='toggle'
)
v-list-item-content
v-list-item-title {{$t('admin.api.newKeyFullAccess')}}
v-divider.mt-3
v-subheader.caption.indigo--text {{$t('admin.api.newKeyGroupPermissions')}}
v-list-item
v-select(
:disabled='fullAccess'
:items='groups'
item-text='name'
item-value='id'
outlined
color='indigo'
v-model='group'
:label='$t(`admin.api.newKeyGroup`)'
:hint='$t(`admin.api.newKeyGroupHint`)'
persistent-hint
)
v-card-chin
v-spacer
v-btn(text, @click='isShown = false', :disabled='loading') {{$t('common.actions.cancel')}}
v-btn.px-3(depressed, color='primary', @click='generate', :loading='loading')
v-icon(left) mdi-chevron-right
span {{$t('common.actions.generate')}}
v-dialog(
v-model='isCopyKeyDialogShown'
max-width='750'
persistent
overlay-color='blue darken-5'
overlay-opacity='.9'
)
v-card
v-toolbar(dense, flat, color='primary', dark) {{$t('admin.api.newKeyTitle')}}
v-card-text.pt-5
.body-2.text-center
i18next(tag='span', path='admin.api.newKeyCopyWarn')
strong(place='bold') {{$t('admin.api.newKeyCopyWarnBold')}}
v-textarea.mt-3(
ref='keyContentsIpt'
filled
no-resize
readonly
v-model='key'
:rows='10'
hide-details
)
v-card-chin
v-spacer
v-btn.px-3(depressed, dark, color='primary', @click='isCopyKeyDialogShown = false') {{$t('common.actions.close')}}
</template>
<script>
import _ from 'lodash'
import gql from 'graphql-tag'
import groupsQuery from 'gql/admin/users/users-query-groups.gql'
export default {
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
loading: false,
name: '',
expiration: '1y',
fullAccess: true,
groups: [],
group: null,
isCopyKeyDialogShown: false,
key: ''
}
},
computed: {
isShown: {
get() { return this.value },
set(val) { this.$emit('input', val) }
},
expirations() {
return [
{ value: '30d', text: this.$t('admin.api.expiration30d') },
{ value: '90d', text: this.$t('admin.api.expiration90d') },
{ value: '180d', text: this.$t('admin.api.expiration180d') },
{ value: '1y', text: this.$t('admin.api.expiration1y') },
{ value: '3y', text: this.$t('admin.api.expiration3y') }
]
}
},
watch: {
value (newValue, oldValue) {
if (newValue) {
setTimeout(() => {
this.$refs.keyNameInput.focus()
}, 400)
}
}
},
methods: {
async generate () {
try {
if (_.trim(this.name).length < 2 || this.name.length > 255) {
throw new Error(this.$t('admin.api.newKeyNameError'))
} else if (!this.fullAccess && !this.group) {
throw new Error(this.$t('admin.api.newKeyGroupError'))
} else if (!this.fullAccess && this.group === 2) {
throw new Error(this.$t('admin.api.newKeyGuestGroupError'))
}
} catch (err) {
return this.$store.commit('showNotification', {
style: 'red',
message: err,
icon: 'alert'
})
}
this.loading = true
try {
const resp = await this.$apollo.mutate({
mutation: gql`
mutation ($name: String!, $expiration: String!, $fullAccess: Boolean!, $group: Int) {
authentication {
createApiKey (name: $name, expiration: $expiration, fullAccess: $fullAccess, group: $group) {
key
responseResult {
succeeded
errorCode
slug
message
}
}
}
}
`,
variables: {
name: this.name,
expiration: this.expiration,
fullAccess: (this.fullAccess === true),
group: this.group
},
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-api-create')
}
})
if (_.get(resp, 'data.authentication.createApiKey.responseResult.succeeded', false)) {
this.$store.commit('showNotification', {
style: 'success',
message: this.$t('admin.api.newKeySuccess'),
icon: 'check'
})
this.name = ''
this.expiration = '1y'
this.fullAccess = true
this.group = null
this.isShown = false
this.$emit('refresh')
this.key = _.get(resp, 'data.authentication.createApiKey.key', '???')
this.isCopyKeyDialogShown = true
setTimeout(() => {
this.$refs.keyContentsIpt.$refs.input.select()
}, 400)
} else {
this.$store.commit('showNotification', {
style: 'red',
message: _.get(resp, 'data.authentication.createApiKey.responseResult.message', 'An unexpected error occurred.'),
icon: 'alert'
})
}
} catch (err) {
this.$store.commit('pushGraphError', err)
}
this.loading = false
}
},
apollo: {
groups: {
query: groupsQuery,
fetchPolicy: 'network-only',
update: (data) => data.groups.list,
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-api-groups-refresh')
}
}
}
}
</script>
......@@ -162,8 +162,9 @@ q-page.admin-mail
.text-subtitle1 {{state.strategy.strategy.title}}
q-img.q-mt-sm.rounded-borders(
:src='state.strategy.strategy.logo'
fit='cover'
fit='contain'
no-spinner
style='height: 100px;'
)
.text-body2.q-mt-md {{state.strategy.strategy.description}}
q-separator.q-mb-sm(inset)
......
......@@ -97,12 +97,13 @@ q-page.admin-dashboard
template(#action)
q-btn(
flat
label='Check'
:label='t(`admin.system.checkForUpdates`)'
@click='checkForUpdates'
)
q-separator.q-mx-sm(vertical, dark)
q-btn(
flat
label='System Info'
:label='t(`admin.system.title`)'
to='/_admin/system'
)
.col-12
......@@ -224,6 +225,7 @@ import { useAdminStore } from '../stores/admin'
// COMPONENTS
import CheckUpdateDialog from '../components/CheckUpdateDialog.vue'
import SiteCreateDialog from '../components/SiteCreateDialog.vue'
import UserCreateDialog from '../components/UserCreateDialog.vue'
......@@ -265,6 +267,11 @@ function newUser () {
router.push('/_admin/users')
})
}
function checkForUpdates () {
$q.dialog({
component: CheckUpdateDialog
})
}
</script>
......
......@@ -77,6 +77,10 @@ q-page.admin-flags
unchecked-icon='las la-times'
:aria-label='t(`admin.flags.hidedonatebtn.label`)'
)
.col-12.col-lg-5.gt-md
.q-pa-md.text-center
img(src='/_assets/illustrations/undraw_settings.svg', style='width: 80%;')
</template>
<script setup>
......
......@@ -117,6 +117,9 @@ q-page.admin-locale
:aria-label='lc.name'
)
.q-pa-md.text-center.gt-md(v-else)
img(src='/_assets/illustrations/undraw_world.svg', style='width: 80%;')
//- q-separator.q-my-sm(inset)
//- q-item
//- blueprint-icon(icon='test-passed')
......
......@@ -54,7 +54,16 @@ q-page.admin-system
q-item-label {{ t('admin.system.latestVersion') }}
q-item-label(caption) {{t('admin.system.latestVersionHint')}}
q-item-section
q-item-label.dark-value(caption) {{ state.info.latestVersion }}
.row.q-col-gutter-sm
.col
.dark-value(caption) {{ state.info.latestVersion }}
.col-auto
q-btn.acrylic-btn(
flat
color='purple'
@click='checkForUpdates'
:label='t(`admin.system.checkUpdate`)'
)
//- -----------------------
//- CLIENT
......@@ -234,6 +243,8 @@ import { useMeta, useQuasar } from 'quasar'
import { computed, onMounted, reactive, ref, watch } from 'vue'
import ClipboardJS from 'clipboard'
import CheckUpdateDialog from '../components/CheckUpdateDialog.vue'
// QUASAR
const $q = useQuasar()
......@@ -340,6 +351,12 @@ async function load () {
state.loading--
}
function checkForUpdates () {
$q.dialog({
component: CheckUpdateDialog
})
}
// async function performUpgrade () {
// state.isUpgrading = true
// state.isUpgradingStarted = false
......
This diff was suppressed by a .gitattributes entry.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment