diff --git a/.gitignore b/.gitignore index dbf004d..3935b3f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -.* node_modules build/ *.log notes.txt +output \ No newline at end of file diff --git a/index.js b/index.js index 5a5433d..fd6e676 100644 --- a/index.js +++ b/index.js @@ -1,29 +1,14 @@ -require = require("esm")(module); -import express from 'express'; +const { generateRocketeer } = require("./nft-media/rocketeer"); (async () => { try { - // Web application framework - const app = express(); - app.disable('x-powered-by'); - app.use(express.urlencoded({ extended: true })); - app.use(express.json()); - - // Error handler - app.use(function(err, req, res, next) { - res.locals.message = err.message; - // Also log it to the console - console.log(`${err.status || 500} - ${err.message} - ${req.originalUrl} - ${req.method} - ${req.ip}`); - // Render the error page - res.status(err.status || 500); - res.render('error'); - }); - - // Start listening on the defined port - app.listen(4243, "0.0.0.0", function () { - console.log(`Listening on port 4243`); - }); + for (var id = 1; id <= 3475; id++) { + console.log("Generating Cpn Chad " + id); + console.log(await generateRocketeer(id)); + } + process.exit(0); } catch (err) { - console.log(err); + console.error(err); + process.exit(1); } -})(); \ No newline at end of file +})(); diff --git a/modules/helpers.js b/modules/helpers.js index d969539..a46f0bc 100644 --- a/modules/helpers.js +++ b/modules/helpers.js @@ -1,119 +1,139 @@ // /////////////////////////////// // Helper functions // /////////////////////////////// -exports.dev = !!process.env.development -const log = ( ...messages ) => { - if( process.env.development ) console.log( ...messages ) -} -exports.log = log +exports.dev = !!process.env.development; +const log = (...messages) => { + if (process.env.development) console.log(...messages); +}; +exports.log = log; // Wait in async -const wait = timeInMs => new Promise( resolve => setTimeout( resolve ), timeInMs ) -exports.wait = wait +const wait = (timeInMs) => + new Promise((resolve) => setTimeout(resolve), timeInMs); +exports.wait = wait; // Pick random item from an array -const pickRandomArrayEntry = array => array[ Math.floor( Math.random() * array.length ) ] -exports.pickRandomArrayEntry = pickRandomArrayEntry +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 ) +exports.randomNumberBetween = (min, max) => + Math.floor(Math.random() * (max - min + 1) + min); // Random attribute picker -exports.pickRandomAttributes = ( attributes ) => { +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; - // 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; - // 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 ) => { + // 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; + }, []), + })); - const { probability, value } = val + // 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), + })); +}; - // 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 nameColor = require('color-namer') -const Color = require('color') -exports.getColorName = ( rgb ) => { - try { - return nameColor( rgb ).basic[0].name - } catch( e ) { - return rgb - } -} -exports.getRgbArrayFromColorName = name => { - - const { hex } = nameColor( name ).basic[0] - const color = Color( hex ) - return color.rgb().array() - -} +const nameColor = require("color-namer"); +const Color = require("color"); +exports.getColorName = (rgb) => { + try { + return nameColor(rgb).basic[0].name; + } catch (e) { + return rgb; + } +}; +exports.getRgbArrayFromColorName = (name) => { + const { hex } = nameColor(name).basic[0]; + const color = Color(hex); + return color.rgb().array(); +}; // /////////////////////////////// // 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: .05 }, - { value: 2, probability: .10 }, - { value: 3, probability: .10 }, - { value: 4, probability: .75 } - ] } - - -] -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.' + { + trait_type: "helmet", + values: [ + { value: "classic", probability: 0.2 }, + { value: "racer", probability: 0.1 }, + { value: "punk", probability: 0.1 }, + { value: "knight", probability: 0.2 }, + { value: "geek", probability: 0.2 }, + ], + }, + { + trait_type: "patch", + values: [ + { value: "nimbus", probability: 0.1 }, + { value: "teku", probability: 0.1 }, + { value: "lighthouse", probability: 0.1 }, + { value: "prysm", probability: 0.2 }, + { value: "rocketpool", probability: 0.5 }, + ], + }, + { + trait_type: "backpack", + values: [ + { value: "yes", probability: 0.9 }, + { value: "no", probability: 0.1 }, + ], + }, + { + trait_type: "panel", + values: [ + { value: "yes", probability: 0.9 }, + { value: "no", probability: 0.1 }, + ], + }, + { + trait_type: "background", + values: [ + { value: "planets", probability: 0.2 }, + { value: "system", probability: 0.2 }, + { value: "playful", probability: 0.1 }, + { value: "moon", probability: 0.05 }, + { value: "galaxy", probability: 0.2 }, + { value: "chip", probability: 0.05 }, + ], + }, + { + trait_type: "background complexity", + values: [ + { value: 1, probability: 0.05 }, + { value: 2, probability: 0.1 }, + { value: 3, probability: 0.1 }, + { value: 4, probability: 0.75 }, + ], + }, +]; +exports.heavenlyBodies = [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Saturn", + "Uranus", + "Neptune", + "Pluto", + "the Moon", + "the Sun", +]; diff --git a/nft-media/rocketeer.js b/nft-media/rocketeer.js index b580d69..dff3740 100644 --- a/nft-media/rocketeer.js +++ b/nft-media/rocketeer.js @@ -1,78 +1,100 @@ -const name = require( 'random-name' ) -const { pickRandomArrayEntry, pickRandomAttributes, randomNumberBetween, globalAttributes, heavenlyBodies, web2domain, getColorName } = require( '../modules/helpers' ) -const svgFromAttributes = require( './svg-generator' ) +const name = require("random-name"); +const { + pickRandomArrayEntry, + pickRandomAttributes, + randomNumberBetween, + globalAttributes, + heavenlyBodies, + getColorName, +} = require("../modules/helpers"); +const svgFromAttributes = require("./svg-generator"); // /////////////////////////////// // Rocketeer generator // /////////////////////////////// -async function generateRocketeer( id, network='mainnet' ) { +async function generateRocketeer(id) { - // The base object of a new Rocketeer - const rocketeer = { - name: `${ name.first() } ${ name.middle() } ${ name.last() } of ${ id % 42 == 0 ? 'the Towel' : pickRandomArrayEntry( heavenlyBodies ) }`, - description: '', - image: ``, - external_url: `https://viewer.rocketeer.fans/?rocketeer=${ id }` + ( network == 'mainnet' ? '' : '&testnet=true' ), - attributes: [] - } + // The base object of a new Rocketeer + const rocketeer = { + name: `${name.first()} ${name.middle()} ${name.last()} of ${ + id % 42 == 0 ? "the Towel" : pickRandomArrayEntry(heavenlyBodies) + }`, + description: "", + image: ``, + attributes: [], + }; - // Generate randomized attributes - rocketeer.attributes = pickRandomAttributes( globalAttributes ) + // Generate randomized attributes + rocketeer.attributes = pickRandomAttributes(globalAttributes); - // Set birthday - rocketeer.attributes.push( { - "display_type": "date", - "trait_type": "birthday", - "value": Math.floor( Date.now() / 1000 ) - } ) + // Set birthday + rocketeer.attributes.push({ + display_type: "date", + trait_type: "birthday", + value: Math.floor(Date.now() / 1000), + }); - // Special editions - const edition = { "trait_type": "edition", value: "regular" } - if( id <= 50 ) edition.value = 'genesis' - if( id >= ( 3475 - 166 ) ) edition.value = 'straggler' - if( id % 42 === 0 ) edition.value = 'hitchhiker' - if( ( id - 1 ) % 42 == 0 ) edition.value = 'generous' - rocketeer.attributes.push( edition ) + // Special editions + const edition = { trait_type: "edition", value: "regular" }; + if (id <= 50) edition.value = "genesis"; + if (id >= 3475 - 166) edition.value = "straggler"; + if (id % 42 === 0) edition.value = "hitchhiker"; + if ((id - 1) % 42 == 0) edition.value = "generous"; + rocketeer.attributes.push(edition); - // Create description - rocketeer.description = `${ rocketeer.name } is a proud member of the ${ rocketeer.attributes.find( ( { trait_type } ) => trait_type == 'patch' ).value } guild.` + // Create description + rocketeer.description = `${rocketeer.name} is a proud member of the ${ + rocketeer.attributes.find(({ trait_type }) => trait_type == "patch").value + } guild.`; - // 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 ) } )` - } ) + // 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)} )`, + }); - // Generate, compile and upload image - rocketeer.image = await svgFromAttributes( rocketeer.attributes, `${ network }Rocketeers/${id}` ) + // Generate, compile and upload image + rocketeer.image = await svgFromAttributes( + rocketeer.attributes, + `./output/${id}` + ); - // Namify the attributes - rocketeer.attributes = rocketeer.attributes.map( attribute => { + // Namify the attributes + rocketeer.attributes = rocketeer.attributes.map((attribute) => { + if (!attribute.trait_type.includes("color")) return attribute; + return { + ...attribute, + value: getColorName(attribute.value), + }; + }); - if( !attribute.trait_type.includes( 'color' ) ) return attribute - return { - ...attribute, - value: getColorName( attribute.value ) - } - - } ) - - return rocketeer; + return rocketeer.image; } module.exports = { - web2domain, - generateRocketeer -} \ No newline at end of file + generateRocketeer, +}; diff --git a/nft-media/svg-generator.js b/nft-media/svg-generator.js index 94e43ac..0d1e060 100644 --- a/nft-media/svg-generator.js +++ b/nft-media/svg-generator.js @@ -1,162 +1,167 @@ -const masterPath = `${ __dirname }/../assets/master.svg` -const jsdom = require("jsdom") -const { JSDOM } = jsdom -const { promises: fs } = require( 'fs' ) -const { getStorage } = require( 'firebase-admin/storage' ) +const masterPath = `${__dirname}/../assets/master.svg`; +const jsdom = require("jsdom"); +const { JSDOM } = jsdom; +const fs = require("fs").promises; -// SVG to JPEG -const { convert } = require("convert-svg-to-jpeg") +module.exports = async function svgFromAttributes(attributes = [], path = "") { + // Validations + if (!path.length) throw new Error("svgFromAttributes missing path"); + if (!attributes.length) + throw new Error("svgFromAttributes missing attributes"); -// Existing file checker -const failIfFilesExist = async ( svg, jpeg, path ) => { + console.log("Checking attributes"); - const [ [ svgExists ], [ jpegExists ] ] = await Promise.all( [ svg.exists(), jpeg.exists() ] ) - if( svgExists || jpegExists ) throw new Error( `${ svgExists ? 'SVG' : '' } ${ jpegExists ? ' and JPEG' : '' } already present at ${ path }. This should never happen!` ) + // Get properties + 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" + ); + + console.log("Reading master file"); + + // Generate DOM to work with + const svgString = await fs.readFile(masterPath, { encoding: "utf8" }); + const { + window: { document }, + } = new JSDOM(svgString); + + // /////////////////////////////// + // Attribute selection + // /////////////////////////////// + console.log("Removing unused attributes from master"); + + // 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; + for (let i = 1; i <= toRemove; 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 + // /////////////////////////////// + console.log("Substituting colours from master"); + const defaultPrimary = /rgb\( ?252 ?, ?186 ?, ?157 ?\)/gi; + const defaultVisor = /rgb\( ?71 ?, ?22 ?, ?127 ?\)/gi; + const defaultAccent = /rgb\( ?243 ?, ?99 ?, ?113 ?\)/gi; + const defaultBackpack = /rgb\( ?195 ?, ?178 ?, ?249 ?\)/gi; + + // 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); + + console.log("Baking SVG now..."); + const bakedSvg = [ + ``, + ``, + document.querySelector("svg").outerHTML, + ].join(""); + + console.log("Writing to `" + path + ".svg`..."); + await fs.writeFile(`${path}.svg`, bakedSvg); -} - -module.exports = async function svgFromAttributes( attributes=[], path='' ) { - - // Validations - if( !path.length ) throw new Error( 'svgFromAttributes missing path' ) - if( !attributes.length ) throw new Error( 'svgFromAttributes missing attributes' ) - - // Create file references and check whether they already exist - const storage = getStorage() - const bucket = storage.bucket() - const svgFile = bucket.file( `${path}.svg` ) - const rasterFile = bucket.file( `${path}.jpg` ) - await failIfFilesExist( svgFile, rasterFile, path ) - - // Get properties - 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 - for ( let i = 1; i <= toRemove; 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 = [ - ``, - ``, - document.querySelector( 'svg' ).outerHTML - ].join( '' ) - - const bakedRaster = await convert( bakedSvg, { - quality: 80, - // height: 500, - // width: 500 - } ) - - // Double check that files do not yet exist (in case of weird race condition) - await failIfFilesExist( svgFile, rasterFile, path ) - - // Save files - await svgFile.save( bakedSvg ) - await rasterFile.save( bakedRaster ) - - // Make file public - await svgFile.makePublic( ) - await rasterFile.makePublic( ) - - // Return public url - return rasterFile.publicUrl() - - -} \ No newline at end of file + // Return public url + return "Paths: '" + `${path}.svg` + "'"; +}; diff --git a/package-lock.json b/package-lock.json index 8d4b60d..26ca813 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,9 @@ "express": "^4.18.1", "jsdom": "^18.1.1", "random-name": "^0.1.2" + }, + "devDependencies": { + "nodemon": "^2.0.20" } }, "node_modules/@tootallnate/once": { @@ -30,6 +33,12 @@ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -137,6 +146,19 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -157,6 +179,15 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/body-parser": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", @@ -189,6 +220,18 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -240,6 +283,33 @@ "node": ">=4" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/chroma-js": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-1.4.1.tgz", @@ -743,6 +813,18 @@ "node": ">=4" } }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -794,6 +876,20 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -839,6 +935,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -973,6 +1081,12 @@ "node": ">=0.10.0" } }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1000,6 +1114,48 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/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", @@ -1173,6 +1329,73 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, + "node_modules/nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/nwsapi": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", @@ -1260,6 +1483,18 @@ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pollock": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/pollock/-/pollock-0.2.1.tgz", @@ -1308,6 +1543,12 @@ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -1461,6 +1702,18 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -1512,6 +1765,15 @@ "node": ">=10" } }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -1591,6 +1853,27 @@ "is-arrayish": "^0.3.1" } }, + "node_modules/simple-update-notifier": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", + "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1648,6 +1931,18 @@ "node": ">=0.6.0" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1656,6 +1951,18 @@ "node": ">=0.6" } }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, "node_modules/tough-cookie": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", @@ -1714,6 +2021,12 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -1896,6 +2209,12 @@ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -1977,6 +2296,16 @@ } } }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -1997,6 +2326,12 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, "body-parser": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", @@ -2025,6 +2360,15 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -2064,6 +2408,22 @@ "supports-color": "^5.3.0" } }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "chroma-js": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-1.4.1.tgz", @@ -2474,6 +2834,15 @@ "resolved": "https://registry.npmjs.org/file-url/-/file-url-2.0.2.tgz", "integrity": "sha512-x3989K8a1jM6vulMigE8VngH7C5nci0Ks5d9kVjUXmNF28gmiZUNujk5HjwaS8dAzN2QmUfX56riJKgN00dNRw==" }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -2513,6 +2882,13 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -2546,6 +2922,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -2641,6 +3026,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2665,6 +3056,36 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "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", @@ -2797,6 +3218,56 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, + "nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "nwsapi": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", @@ -2866,6 +3337,12 @@ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, "pollock": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/pollock/-/pollock-0.2.1.tgz", @@ -2905,6 +3382,12 @@ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -3030,6 +3513,15 @@ } } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -3061,6 +3553,12 @@ "xmlchars": "^2.2.0" } }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -3127,6 +3625,23 @@ "is-arrayish": "^0.3.1" } }, + "simple-update-notifier": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", + "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "dev": true, + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3174,11 +3689,29 @@ "os-tmpdir": "~1.0.2" } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, "tough-cookie": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", @@ -3225,6 +3758,12 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", diff --git a/package.json b/package.json index b0f3710..d960697 100644 --- a/package.json +++ b/package.json @@ -14,10 +14,12 @@ "dependencies": { "color": "^4.2.3", "color-namer": "^1.4.0", - "convert-svg-to-jpeg": "^0.5.0", "esm": "^3.2.25", "express": "^4.18.1", "jsdom": "^18.1.1", "random-name": "^0.1.2" + }, + "devDependencies": { + "nodemon": "^2.0.20" } }