First image generator version done

This commit is contained in:
Mentor Palokaj 2021-10-29 18:06:18 +02:00
parent 872e632cbe
commit 12862f86f7
12 changed files with 16000 additions and 117 deletions

2678
functions/assets/demo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

12683
functions/assets/master.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.3 MiB

Binary file not shown.

View File

@ -1,12 +1,13 @@
// Dependencies
const admin = require( 'firebase-admin' )
const { initializeApp } = require( 'firebase-admin/app' )
const { getFirestore, FieldValue, FieldPath } = require( 'firebase-admin/firestore' )
// Admin api
const app = admin.initializeApp()
const db = app.firestore()
const { FieldValue, FieldPath } = admin.firestore
const app = initializeApp()
const db = getFirestore()
module.exports = {
app: app,
db: db,
FieldValue: FieldValue,
FieldPath: FieldPath

View File

@ -0,0 +1,93 @@
// ///////////////////////////////
// Helper functions
// ///////////////////////////////
// Pick random item from an array
const pickRandomArrayEntry = array => array[ Math.floor( Math.random() * array.length ) ]
exports.pickRandomArrayEntry = pickRandomArrayEntry
// Generate random number between x and y
exports.randomNumberBetween = ( min, max ) => Math.floor( Math.random() * ( max - min + 1 ) + min )
// Random attribute picker
exports.pickRandomAttributes = ( attributes ) => {
// Decimal accuracy, if probabilities have the lowest 0.01 then 100 is enough, for 0.001 1000 is needed
const probabilityDecimals = 3
// Remap the trait so it has a 'lottery ticket box' based on probs
const attributeLottery = attributes.map( ( { values, ...attribute } ) => ( {
// Attribute meta stays the same
...attribute,
// Values are reduced from objects with probabilities to an array with elements
values: values.reduce( ( acc, val ) => {
const { probability, value } = val
// Map probabilities to a flat array of items
const amountToAdd = 10 * probabilityDecimals * probability
for ( let i = 0; i < amountToAdd; i++ ) acc.push( value )
return acc
}, [] )
} ) )
// Pick a random element from the lottery box array items
return attributeLottery.map( ( { values, ...attribute } ) => ( {
// Attribute meta stays the same
...attribute,
// Select random entry from array
value: pickRandomArrayEntry( values )
} ) )
}
// ///////////////////////////////
// Attribute sources
// ///////////////////////////////
exports.globalAttributes = [
{ trait_type: "helmet", values: [
{ value: 'classic', probability: .2 },
{ value: 'racer', probability: .1 },
{ value: 'punk', probability: .1 },
{ value: 'knight', probability: .2 },
{ value: 'geek', probability: .2 }
] },
{ trait_type: "patch", values: [
{ value: 'nimbus', probability: .1 },
{ value: 'teku', probability: .1 },
{ value: 'lighthouse', probability: .1 },
{ value: 'prysm', probability: .2 },
{ value: 'rocketpool', probability: .5 }
] },
{ trait_type: "backpack", values: [
{ value: 'yes', probability: .9 },
{ value: 'no', probability: .1 }
] },
{ trait_type: "panel", values: [
{ value: 'yes', probability: .9 },
{ value: 'no', probability: .1 }
] },
{ trait_type: "background", values: [
{ value: 'planets', probability: .2 },
{ value: 'system', probability: .2 },
{ value: 'playful', probability: .1 },
{ value: 'moon', probability: .05 },
{ value: 'galaxy', probability: .2 },
{ value: 'chip', probability: .05 }
] },
{ trait_type: "background complexity", values: [
{ value: 1, probability: .4 },
{ value: 2, probability: .3 },
{ value: 3, probability: .2 },
{ value: 4, probability: .1 }
] }
]
exports.heavenlyBodies = [ "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "the Moon", "the Sun" ]
exports.web2domain = 'https://rocketeer.fans'
exports.lorem = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'

View File

@ -1,60 +1,8 @@
const name = require( 'random-name' )
const { db } = require( './firebase' )
const { getTotalSupply } = require( './contract' )
// ///////////////////////////////
// Attribute sources
// ///////////////////////////////
const globalAttributes = [
{ trait_type: "Age", display_type: "number", values: [
{ value: 35, probability: .5 },
{ value: 45, probability: .25 },
{ value: 25, probability: .25 }
] }
]
const heavenlyBodies = [ "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "the Moon", "the Sun" ]
const web2domain = 'https://rocketeer.fans'
const lorem = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
// ///////////////////////////////
// Rocketeer helpers
// ///////////////////////////////
// Pick random item from array with equal probability
const pickRandomArrayEntry = array => array[ Math.floor( Math.random() * array.length ) ]
// Pick random attributes based on global attribute array
function pickRandomAttributes( attributes ) {
// Decimal accuracy, if probabilities have the lowest 0.01 then 100 is enough, for 0.001 1000 is needed
const probabilityDecimals = 3
// Remap the trait so it has a 'lottery ticket box' based on probs
const attributeLottery = attributes.map( ( { values, ...attribute } ) => ( {
// Attribute meta stays the same
...attribute,
// Values are reduced from objects with probabilities to an array with elements
values: values.reduce( ( acc, val ) => {
const { probability, value } = val
// Map probabilities to a flat array of items
const amountToAdd = 10 * probabilityDecimals * probability
for ( let i = 0; i < amountToAdd; i++ ) acc.push( value )
return acc
}, [] )
} ) )
// Pick a random element from the lottery box array items
return attributeLottery.map( ( { values, ...attribute } ) => ( {
// Attribute meta stays the same
...attribute,
// Select random entry from array
value: pickRandomArrayEntry( values )
} ) )
}
const { pickRandomArrayEntry, pickRandomAttributes, randomNumberBetween, globalAttributes, heavenlyBodies, web2domain, lorem } = require( './helpers' )
const svgFromAttributes = require( './svg-generator' )
// ///////////////////////////////
// Caching
@ -106,15 +54,36 @@ async function generateRocketeer( id, network='mainnet' ) {
name: `${ name.first() } ${ name.middle() } ${ name.last() } of ${ pickRandomArrayEntry( heavenlyBodies ) }`,
description: lorem,
image: ``,
external_url: `https://viewer.rocketeer.fans/?rocketeer=${ id }` + network == 'mainnet' ? '' : '&testnet=true',
external_url: `https://viewer.rocketeer.fans/?rocketeer=${ id }` + ( network == 'mainnet' ? '' : '&testnet=true' ),
attributes: []
}
// Generate randomized attributes
rocketeer.attributes = pickRandomAttributes( globalAttributes )
// Generate color attributes
rocketeer.attributes.push( {
"trait_type": "outfit color",
value: `rgb( ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) } )`
} )
rocketeer.attributes.push( {
"trait_type": "outfit accent color",
value: `rgb( ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) } )`
} )
rocketeer.attributes.push( {
"trait_type": "backpack color",
value: `rgb( ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) } )`
} )
rocketeer.attributes.push( {
"trait_type": "visor color",
value: `rgb( ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) } )`
} )
// Write to demo file
// TODO: Generate, compile and upload image
rocketeer.image = `${web2domain}/assets/draft-rocketeer.png`
rocketeer.image = await svgFromAttributes( rocketeer.attributes )
// Save new Rocketeer
await db.collection( `${ network }Rocketeers` ).doc( id ).set( rocketeer )
@ -125,13 +94,13 @@ async function generateRocketeer( id, network='mainnet' ) {
async function safelyReturnRocketeer( id, network ) {
// Chech if this is an illegal ID
const invalidId = await isInvalidRocketeerId( id, network )
if( invalidId ) throw invalidId
// // Chech if this is an illegal ID
// const invalidId = await isInvalidRocketeerId( id, network )
// if( invalidId ) throw invalidId
// Get old rocketeer if it exists
const oldRocketeer = await getExistingRocketeer( id, network )
if( oldRocketeer ) return oldRocketeer
// // Get old rocketeer if it exists
// const oldRocketeer = await getExistingRocketeer( id, network )
// if( oldRocketeer ) return oldRocketeer
// If no old rocketeer exists, make a new one and save it
return generateRocketeer( id, network )

View File

@ -0,0 +1,134 @@
const masterPath = `${ __dirname }/../assets/master.svg`
const jsdom = require("jsdom")
const { JSDOM } = jsdom
const { promises: fs } = require( 'fs' )
const { getStorage } = require( 'firebase-admin/storage' )
module.exports = async function svgFromAttributes( attributes=[] ) {
const { value: primary_color } = attributes.find( ( { trait_type } ) => trait_type == "outfit color" )
const { value: accent_color } = attributes.find( ( { trait_type } ) => trait_type == "outfit accent color" )
const { value: backpack_color } = attributes.find( ( { trait_type } ) => trait_type == "backpack color" )
const { value: visor_color } = attributes.find( ( { trait_type } ) => trait_type == "visor color" )
const { value: backpack } = attributes.find( ( { trait_type } ) => trait_type == "backpack" )
const { value: panel } = attributes.find( ( { trait_type } ) => trait_type == "panel" )
const { value: patch } = attributes.find( ( { trait_type } ) => trait_type == "patch" )
const { value: helmet } = attributes.find( ( { trait_type } ) => trait_type == "helmet" )
const { value: background } = attributes.find( ( { trait_type } ) => trait_type == "background" )
const { value: background_complexity } = attributes.find( ( { trait_type } ) => trait_type == "background complexity" )
// Generate DOM to work with
const svgString = await fs.readFile( masterPath, 'utf8' )
const { window: { document } } = new JSDOM( svgString )
// ///////////////////////////////
// Attribute selection
// ///////////////////////////////
// Remove obsolete patches
const obsoletePatches = [ 'nimbus', 'teku', 'lighthouse', 'prysm', 'rocketpool' ].filter( p => p !== patch )
for ( let i = obsoletePatches.length - 1; i >= 0; i-- ) {
const element = document.querySelector( `#${ obsoletePatches[i] }` )
if( element ) element.remove()
else console.log( `Could not find #${ obsoletePatches[i] }` )
}
// Remove obsolete hemets
const obsoleteHelmets = [ 'classic', 'racer', 'punk', 'knight', 'geek' ].filter( p => p !== helmet )
for ( let i = obsoleteHelmets.length - 1; i >= 0; i-- ) {
const element = document.querySelector( `#${ obsoleteHelmets[i] }` )
if( element ) element.remove()
else console.log( `Could not find #${ obsoleteHelmets[i] }` )
}
// Remove panel if need be
if( panel === 'no' ) {
const element = document.querySelector( `#panel` )
if( element ) element.remove()
else console.log( `Could not find #panel` )
}
// Remove backpack if need be
if( backpack === 'no' ) {
const element = document.querySelector( `#backpack` )
if( element ) element.remove()
else console.log( 'Could not find #backpack' )
}
// Remove obsolete backgrounds
const obsoleteBackgrounds = [ 'planets', 'system', 'playful', 'moon', 'galaxy', 'chip' ].filter( p => p !== background )
for ( let i = obsoleteBackgrounds.length - 1; i >= 0; i-- ) {
const element = document.querySelector( `#${ obsoleteBackgrounds[i] }` )
if( element ) element.remove()
else console.log( `Could not find #${ obsoleteBackgrounds[i] }` )
}
// ///////////////////////////////
// Background customisation
// ///////////////////////////////
// In playful, keeping things is basic, removing them is cool
if( background === 'playful' ) {
const toRemove = background_complexity
for ( let i = 1; i <= toRemove; i++ ) {
const element = document.querySelector( `#playful-element-${ 5 - i }` )
if( element ) element.remove()
else console.log( `Could not find #playful-element-${ 5 - i }` )
}
} else {
// In others, keeping is cool, and removing is less cool
// so higher rarity means less looping
const toRemove = 4 - background_complexity
console.log( `Removing ${ toRemove } background props` )
for ( let i = 1; i <= toRemove; i++ ) {
console.log( `Remove #${ background }-element-${ 5 - i }` )
const element = document.querySelector( `#${ background }-element-${ 5 - i }` )
if( element ) element.remove()
else console.log( `Could not find #${ background }-element-${ 5 - i }` )
}
}
// ///////////////////////////////
// Color substitutions
// ///////////////////////////////
const defaultPrimary = /rgb\( ?252 ?, ?186 ?, ?157 ?\)/ig
const defaultVisor = /rgb\( ?71 ?, ?22 ?, ?127 ?\)/ig
const defaultAccent = /rgb\( ?243 ?, ?99 ?, ?113 ?\)/ig
const defaultBackpack = /rgb\( ?195 ?, ?178 ?, ?249 ?\)/ig
// Substitutions
const replace = ( from, to ) => {
const replaced = document.querySelector( 'svg' ).innerHTML.replace( from, to )
document.querySelector( 'svg' ).innerHTML = replaced
}
replace( defaultPrimary, primary_color )
replace( defaultAccent, accent_color )
replace( defaultVisor, visor_color )
replace( defaultBackpack, backpack_color )
const bakedSvg = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">${ document.querySelector( 'svg' ).outerHTML }`
// Store file on firebase
const storage = getStorage()
const bucket = storage.bucket()
// Make file reference
const file = bucket.file( `rocketeers/demo-${ Date.now() }.svg` )
// Save file buffer
await file.save( bakedSvg )
// Make file public
await file.makePublic( )
// Return public url
return file.publicUrl()
}

View File

@ -21,6 +21,7 @@ app.get( '/testnetapi/rocketeer/:id', async ( req, res ) => {
// Log error for debugging
console.error( `Testnet api error for ${ id }: `, Object.keys( e ) )
console.log( e )
// Return error to frontend
return res.json( { error: e.mesage || e.toString() } )

View File

@ -592,9 +592,9 @@
}
},
"@firebase/database": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.1.tgz",
"integrity": "sha512-Ethk0hc476qnkSKNBa+8Yc7iM8AO69HYWsaD+QUC983FZtnuMyNLHtEeSUbLQYvyHo7cOjcc52slop14WmfZeQ==",
"version": "0.12.2",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.2.tgz",
"integrity": "sha512-Y1LZR1LIQM8YKMkeUPpAq3/e53hcfcXO+JEZ6vCzBeD6xRawqmpw6B5/DzePdCNNvjcqheXzSaR7T39eRZo/wA==",
"requires": {
"@firebase/auth-interop-types": "0.1.6",
"@firebase/component": "0.5.7",
@ -605,12 +605,12 @@
}
},
"@firebase/database-compat": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.1.tgz",
"integrity": "sha512-K3DFWiw0YkLZtlfA9TOGPw6zVXKu5dQ1XqIGztUufFVRYW8IizReXVxzSSmJNR4Adr2LiU9j66Wenc6e5UfwaQ==",
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.2.tgz",
"integrity": "sha512-sV32QIRSNIBj/6OYtpmPzA/SfQz1/NBZbhxg9dIhGaSt9e5HaMxXRuz2lImudX0Sd/v8DKdExrxa++K6rKrRtA==",
"requires": {
"@firebase/component": "0.5.7",
"@firebase/database": "0.12.1",
"@firebase/database": "0.12.2",
"@firebase/database-types": "0.9.1",
"@firebase/logger": "0.3.0",
"@firebase/util": "1.4.0",
@ -711,9 +711,9 @@
"optional": true
},
"@google-cloud/storage": {
"version": "5.15.2",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.15.2.tgz",
"integrity": "sha512-41gmpyy9BUiEJIjbL9RvGsCsnBGzuZj5A4lnigyTeGNKXghnnnw89Zf1/I+pVGItk3L8lVMvxXakKWLVZP1Mmg==",
"version": "5.15.3",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.15.3.tgz",
"integrity": "sha512-a2Y+mvfbzznWorQiv6c+qdPDlBpe47tikV8tpQSnvYXz1Ed/rjin41k2nKUQUcAPGHtYeTzGfKnCNKC+lv8qRg==",
"optional": true,
"requires": {
"@google-cloud/common": "^3.7.4",
@ -738,18 +738,19 @@
}
},
"@grpc/grpc-js": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.8.tgz",
"integrity": "sha512-4qJqqn+CU/nBydz9ePJP+oa8dz0U42Ut/GejlbyaQ1xTkynCc+ndNHHnISlNeHawDsv4MOAyP3mV/EnDNUw2zA==",
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.2.tgz",
"integrity": "sha512-aUN6oGk9un8rfYWz73nQgFxPCYJQYd8LpIGguZHBsNduBMyqG6EWANrsVBuTG+nl/l4dKb3x+qi1l9+oxDxqGg==",
"optional": true,
"requires": {
"@grpc/proto-loader": "^0.6.4",
"@types/node": ">=12.12.47"
}
},
"@grpc/proto-loader": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.5.tgz",
"integrity": "sha512-GZdzyVQI1Bln/kCzIYgTKu+rQJ5dno0gVrfmLe4jqQu7T2e7svSwJzpCBqVU5hhBSJP3peuPjOMWsj5GR61YmQ==",
"version": "0.6.6",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz",
"integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==",
"optional": true,
"requires": {
"@types/long": "^4.0.1",
@ -861,8 +862,7 @@
"@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
"optional": true
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="
},
"@types/bn.js": {
"version": "4.11.6",
@ -989,6 +989,11 @@
"@types/node": "*"
}
},
"abab": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
"integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q=="
},
"abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@ -1010,8 +1015,16 @@
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"dev": true
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
},
"acorn-globals": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
"integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
"requires": {
"acorn": "^7.1.1",
"acorn-walk": "^7.1.1"
}
},
"acorn-jsx": {
"version": "5.3.2",
@ -1019,11 +1032,15 @@
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true
},
"acorn-walk": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
"integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA=="
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"optional": true,
"requires": {
"debug": "4"
}
@ -1236,6 +1253,11 @@
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
},
"browser-process-hrtime": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
"integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
},
"browserify-aes": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
@ -1724,6 +1746,26 @@
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"optional": true
},
"cssom": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
"integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="
},
"cssstyle": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
"integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
"requires": {
"cssom": "~0.3.6"
},
"dependencies": {
"cssom": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
}
}
},
"d": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
@ -1741,6 +1783,40 @@
"assert-plus": "^1.0.0"
}
},
"data-urls": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.1.tgz",
"integrity": "sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw==",
"requires": {
"abab": "^2.0.3",
"whatwg-mimetype": "^3.0.0",
"whatwg-url": "^10.0.0"
},
"dependencies": {
"tr46": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
"requires": {
"punycode": "^2.1.1"
}
},
"webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
},
"whatwg-url": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz",
"integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==",
"requires": {
"tr46": "^3.0.0",
"webidl-conversions": "^7.0.0"
}
}
}
},
"date-and-time": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.0.1.tgz",
@ -1755,6 +1831,11 @@
"ms": "2.1.2"
}
},
"decimal.js": {
"version": "10.3.1",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz",
"integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ=="
},
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
@ -1771,8 +1852,7 @@
"deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
},
"defer-to-connect": {
"version": "1.1.3",
@ -1843,6 +1923,21 @@
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
"domexception": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
"integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
"requires": {
"webidl-conversions": "^7.0.0"
},
"dependencies": {
"webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
}
}
},
"dot-prop": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
@ -2026,6 +2121,66 @@
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true
},
"escodegen": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
"integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
"requires": {
"esprima": "^4.0.1",
"estraverse": "^5.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
},
"dependencies": {
"estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
}
},
"optionator": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
"integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
"requires": {
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.6",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"word-wrap": "~1.2.3"
}
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
"prelude-ls": "~1.1.2"
}
}
}
},
"eslint": {
"version": "7.32.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
@ -2146,8 +2301,7 @@
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"esquery": {
"version": "1.4.0",
@ -2192,8 +2346,7 @@
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
"etag": {
"version": "1.8.1",
@ -2422,8 +2575,7 @@
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"fast-text-encoding": {
"version": "1.0.3",
@ -2478,9 +2630,9 @@
}
},
"firebase-admin": {
"version": "9.12.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.12.0.tgz",
"integrity": "sha512-AtA7OH5RbIFGoc0gZOQgaYC6cdjdhZv4w3XgWoupkPKO1HY+0GzixOuXDa75kFeoVyhIyo4PkLg/GAC1dC1P6w==",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-10.0.0.tgz",
"integrity": "sha512-EOAk5ZaqXhBBvx9ZyXd28kw8glMTt3xl0g3BepGRCy0RSSUPGOzfAqjGhc65guSKgFOpT5mAUycYcJbqullKUQ==",
"requires": {
"@firebase/database-compat": "^0.1.1",
"@firebase/database-types": "^0.7.2",
@ -2732,9 +2884,9 @@
}
},
"google-auth-library": {
"version": "7.10.0",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.0.tgz",
"integrity": "sha512-ICsqaU+lxMHVlDUzMrfVIEqnARw2AwBiZ/2KnNM6BcTf9Nott+Af87DTIzmlnW865p3REUP2MVL0xkPC3a61aQ==",
"version": "7.10.1",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz",
"integrity": "sha512-nQxgM1ZopUMcpMnu95kOSzI+9tJl4YDOZJomSTBGlRLpxfBopdwto7WvzoI87HuN0nQqVETgOsHi/C/po1rppA==",
"optional": true,
"requires": {
"arrify": "^2.0.0",
@ -2749,12 +2901,12 @@
}
},
"google-gax": {
"version": "2.27.1",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.27.1.tgz",
"integrity": "sha512-8j8hfY42mGZt52C1L23srr2WTxOsOGUsC3s07Aw/f1UrbofsHdRaGf72Jax4jWEFXe/2x1MVBkwMvZxHMbO1Ag==",
"version": "2.28.0",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.28.0.tgz",
"integrity": "sha512-kuqc8a4+CTCMBcF3tlOL7Sa74JWkTzcZxatAQTCVK35WToXkHnJ0qncFOJuegUv3EbV9IQY4j/+NZdFLv+lbTA==",
"optional": true,
"requires": {
"@grpc/grpc-js": "~1.3.0",
"@grpc/grpc-js": "~1.4.0",
"@grpc/proto-loader": "^0.6.1",
"@types/long": "^4.0.0",
"abort-controller": "^3.0.0",
@ -2916,6 +3068,14 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
"html-encoding-sniffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
"integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
"requires": {
"whatwg-encoding": "^2.0.0"
}
},
"http-cache-semantics": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
@ -2954,7 +3114,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
"integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
"optional": true,
"requires": {
"@tootallnate/once": "2",
"agent-base": "6",
@ -2975,7 +3134,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"optional": true,
"requires": {
"agent-base": "6",
"debug": "4"
@ -3166,6 +3324,11 @@
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
},
"is-potential-custom-element-name": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
},
"is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@ -3292,6 +3455,94 @@
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"jsdom": {
"version": "18.0.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-18.0.0.tgz",
"integrity": "sha512-HVLuBcFmwdWulStv5U+J59b1AyzXhM92KXlM8HQ3ecYtRM2OQEUCPMa4oNuDeCBmtRcC7tJvb0Xz5OeFXMOKTA==",
"requires": {
"abab": "^2.0.5",
"acorn": "^8.5.0",
"acorn-globals": "^6.0.0",
"cssom": "^0.5.0",
"cssstyle": "^2.3.0",
"data-urls": "^3.0.1",
"decimal.js": "^10.3.1",
"domexception": "^4.0.0",
"escodegen": "^2.0.0",
"form-data": "^4.0.0",
"html-encoding-sniffer": "^3.0.0",
"http-proxy-agent": "^5.0.0",
"https-proxy-agent": "^5.0.0",
"is-potential-custom-element-name": "^1.0.1",
"nwsapi": "^2.2.0",
"parse5": "6.0.1",
"saxes": "^5.0.1",
"symbol-tree": "^3.2.4",
"tough-cookie": "^4.0.0",
"w3c-hr-time": "^1.0.2",
"w3c-xmlserializer": "^3.0.0",
"webidl-conversions": "^7.0.0",
"whatwg-encoding": "^2.0.0",
"whatwg-mimetype": "^3.0.0",
"whatwg-url": "^10.0.0",
"ws": "^8.2.3",
"xml-name-validator": "^4.0.0"
},
"dependencies": {
"acorn": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz",
"integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q=="
},
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"tough-cookie": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
"integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
"requires": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
"universalify": "^0.1.2"
}
},
"tr46": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
"requires": {
"punycode": "^2.1.1"
}
},
"webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
},
"whatwg-url": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz",
"integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==",
"requires": {
"tr46": "^3.0.0",
"webidl-conversions": "^7.0.0"
}
},
"ws": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA=="
}
}
},
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@ -3416,9 +3667,9 @@
}
},
"jwks-rsa": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.4.tgz",
"integrity": "sha512-iJqVCECYZZ+3oPmY1qXv3Fq+3ywDtuNEVBvG41pPlaR0zyGxa12nC0beAOBBUhETJmc05puS50mRQN4NkCGhmg==",
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.5.tgz",
"integrity": "sha512-fliHfsiBRzEU0nXzSvwnh0hynzGB0WihF+CinKbSRlaqRxbqqKf2xbBPgwc8mzf18/WgwlG8e5eTpfSTBcU4DQ==",
"requires": {
"@types/express-jwt": "0.0.42",
"debug": "^4.3.2",
@ -3833,6 +4084,11 @@
}
}
},
"nwsapi": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
"integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ=="
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@ -3961,6 +4217,11 @@
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz",
"integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw=="
},
"parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@ -4034,9 +4295,9 @@
"dev": true
},
"proto3-json-serializer": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.4.tgz",
"integrity": "sha512-bFzdsKU/zaTobWrRxRniMZIzzcgKYlmBWL1gAcTXZ2M7TQTGPI0JoYYs6bN7tpWj59ZCfwg7Ii/A2e8BbQGYnQ==",
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.5.tgz",
"integrity": "sha512-G395jcZkgNXNeS+6FGqd09TsXeoCs9wmBWByDiwFy7Yd7HD8pyfyvf6q+rGh7PhT4AshRpG4NowzoKYUtkNjKg==",
"optional": true
},
"protobufjs": {
@ -4310,6 +4571,14 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"saxes": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
"integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
"requires": {
"xmlchars": "^2.2.0"
}
},
"scrypt-js": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
@ -4682,6 +4951,11 @@
}
}
},
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
},
"table": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz",
@ -4984,6 +5258,22 @@
"extsprintf": "^1.2.0"
}
},
"w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
"integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
"requires": {
"browser-process-hrtime": "^1.0.0"
}
},
"w3c-xmlserializer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz",
"integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==",
"requires": {
"xml-name-validator": "^4.0.0"
}
},
"web3": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/web3/-/web3-1.6.0.tgz",
@ -5321,6 +5611,29 @@
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="
},
"whatwg-encoding": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
"integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
"requires": {
"iconv-lite": "0.6.3"
},
"dependencies": {
"iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
}
}
}
},
"whatwg-mimetype": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
"integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
@ -5368,8 +5681,7 @@
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"dev": true
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
},
"wrap-ansi": {
"version": "7.0.0",
@ -5463,6 +5775,16 @@
"cookiejar": "^2.1.1"
}
},
"xml-name-validator": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
"integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw=="
},
"xmlchars": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

View File

@ -16,8 +16,9 @@
"dependencies": {
"cors": "^2.8.5",
"express": "^4.17.1",
"firebase-admin": "^9.12.0",
"firebase-admin": "^10.0.0",
"firebase-functions": "^3.11.0",
"jsdom": "^18.0.0",
"random-name": "^0.1.2",
"web3": "^1.6.0"
},

View File

@ -2,7 +2,8 @@ rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth!=null;
allow write: if request.auth!=null;
allow read: if true;
}
}
}