From 3c2836781be9bc96355aa459792817ab8db950e3 Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Fri, 14 Apr 2023 19:17:48 +0200
Subject: [PATCH 01/15] refactor: update/simplify fxparam handling in snippet
API
- update fxparam deserializers & utils as per postspectacular/fxlens@7d0a50b
---
project/public/index.html | 253 +++++++++++++++-----------------------
1 file changed, 102 insertions(+), 151 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index 392ca18..b97f9b7 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -40,177 +40,128 @@
let fxparams = search.get('fxparams')
fxparams = fxparams ? fxparams.replace("0x", "") : fxparams
+ function* asBytes(hex, n) {
+ n *= 2
+ for (let i = 0; i < n; i += 2)
+ yield parseInt(hex.substring(i, i + 2), 16)
+ }
+
+ function minmax($min, $max, minDef = Number.MIN_SAFE_INTEGER, maxDef = Number.MAX_SAFE_INTEGER) {
+ return {
+ min:
+ $min !== undefined
+ ? Math.max(Number($min), minDef)
+ : minDef,
+ max:
+ $max !== undefined
+ ? Math.min(Number($max), maxDef)
+ : maxDef,
+ }
+ }
+
// the parameter processor, used to parse fxparams
const processors = {
number: {
- deserialize: (input) => {
- const view = new DataView(new ArrayBuffer(8))
- for (let i = 0; i < 8; i++) {
- view.setUint8(i, parseInt(input.substring(i * 2, i * 2 + 2), 16))
- }
- return view.getFloat64(0)
- },
bytesLength: () => 8,
- constrain: (value, definition) => {
- let min = Number.MIN_SAFE_INTEGER
- if (typeof definition.options?.min !== "undefined")
- min = Number(definition.options.min)
- let max = Number.MAX_SAFE_INTEGER
- if (typeof definition.options?.max !== "undefined")
- max = Number(definition.options.max)
- max = Math.min(max, Number.MAX_SAFE_INTEGER)
- min = Math.max(min, Number.MIN_SAFE_INTEGER)
- const v = Math.min(Math.max(value, min), max)
- return v;
- },
- random: (definition) => {
- let min = Number.MIN_SAFE_INTEGER
- if (typeof definition.options?.min !== "undefined")
- min = Number(definition.options.min)
- let max = Number.MAX_SAFE_INTEGER
- if (typeof definition.options?.max !== "undefined")
- max = Number(definition.options.max)
- max = Math.min(max, Number.MAX_SAFE_INTEGER)
- min = Math.max(min, Number.MIN_SAFE_INTEGER)
- const v = Math.random() * (max - min) + min
- if (definition?.options?.step) {
- const t = 1.0 / definition?.options?.step
- return Math.round(v * t) / t
- }
- return v;
- },
+ deserialize: (input) => new Float64Array(new BigUint64Array([BigInt(`0x${input}`)]).buffer)[0],
+ constrain: (value, { options }) => {
+ const { min, max } = minmax(options?.min, options?.max)
+ return Math.min(Math.max(value, min), max)
+ },
+ random: ({ options }) => {
+ const { min, max } = minmax(options?.min, options?.max)
+ const v = Math.random() * (max - min) + min
+ if (options?.step) {
+ const t = 1.0 / options.step
+ return Math.round(v * t) / t
+ }
+ return v
+ },
},
bigint: {
- deserialize: (input) => {
- const view = new DataView(new ArrayBuffer(8))
- for (let i = 0; i < 8; i++) {
- view.setUint8(i, parseInt(input.substring(i * 2, i * 2 + 2), 16))
- }
- return view.getBigInt64(0)
- },
bytesLength: () => 8,
- random: (definition) => {
- const MIN_SAFE_INT64 = -9223372036854775808n
- const MAX_SAFE_INT64 = 9223372036854775807n
- let min = MIN_SAFE_INT64
- let max = MAX_SAFE_INT64
- if (typeof definition.options?.min !== "undefined")
- min = BigInt(definition.options.min)
- if (typeof definition.options?.max !== "undefined")
- max = BigInt(definition.options.max)
- const range = max - min
- const bits = range.toString(2).length
- let random
- do {
- random = BigInt(
- "0b" +
- Array.from(
- crypto.getRandomValues(new Uint8Array(Math.ceil(bits / 8)))
- )
- .map((b) => b.toString(2).padStart(8, "0"))
- .join("")
- )
- } while (random > range)
- return random + min
- },
+ deserialize: (input) => BigInt.asIntN(64, BigInt("0x" + input)),
+ random: ({ options }) => {
+ const MIN_SAFE_INT64 = -9223372036854775808n
+ const MAX_SAFE_INT64 = 9223372036854775807n
+ if (options?.min !== undefined) {
+ min = BigInt(options.min)
+ if (min < MIN_SAFE_INT64) min = MIN_SAFE_INT64
+ }
+ if (options?.max !== undefined) {
+ max = BigInt(options.max)
+ if (max > MAX_SAFE_INT64) max = MAX_SAFE_INT64
+ }
+ const range = max - min
+ const bits = range.toString(2).length
+ let random
+ do {
+ random = BigInt(
+ "0x" +
+ Array.from(crypto.getRandomValues(new Uint8Array(Math.ceil(bits / 8))))
+ .map((x) => x < 10 ? "0" + x : x.toString(16))
+ .join("")
+ )
+ } while (random > range)
+ return random + min
+ },
},
boolean: {
- // if value is "00" -> 0 -> false, otherwise we consider it's 1
- deserialize: (input) => {
- return input === "00" ? false : true
- },
bytesLength: () => 1,
+ deserialize: (input) => input !== "00",
random: () => Math.random() < 0.5,
},
color: {
- deserialize: (input) => input,
bytesLength: () => 4,
+ deserialize: (input) => input,
transform: (input) => {
- const r = parseInt(input.slice(0,2), 16)
- const g = parseInt(input.slice(2,4), 16)
- const b = parseInt(input.slice(4,6), 16)
- const a = parseInt(input.slice(6,8), 16)
- return {
- hex: {
- rgb: '#' + input.slice(0,6),
- rgba: '#' + input,
- },
- obj: {
- rgb: { r, g, b},
- rgba: { r, g, b, a},
- },
- arr: {
- rgb: [r,g,b],
- rgba: [r,g,b,a],
- }
- }
- },
- constrain: (value, definition) => {
- const hex = value.replace("#", "")
- return hex.slice(0, 8).padEnd(8, "f")
- },
- random: () =>
- `${[...Array(8)]
- .map(() => Math.floor(Math.random() * 16).toString(16))
- .join("")}`,
- },
+ const [r, g, b, a] = asBytes(input, 4)
+ return {
+ hex: {
+ rgb: "#" + input.slice(0, 6),
+ rgba: "#" + input,
+ },
+ obj: {
+ rgb: { r, g, b },
+ rgba: { r, g, b, a },
+ },
+ arr: {
+ rgb: [r, g, b],
+ rgba: [r, g, b, a],
+ },
+ }
+ },
+ constrain: (value) => value.replace("#", "").slice(0, 8).padEnd(8, "f"),
+ random: () => ((Math.random() * 0x100000000) >>> 0).toString(16).padStart(8, "0"),
+ },
string: {
+ bytesLength: () => 64,
deserialize: (input) => {
- const hx = input.match(/.{1,4}/g) || []
- let rtn = ""
- for (let i = 0; i < hx.length; i++) {
- const int = parseInt(hx[i], 16)
- if (int === 0) break
- rtn += String.fromCharCode(int)
- }
- return rtn
- },
- bytesLength: () => 64 * 2,
- constrain: (value, definition) => {
- let min = 0
- if (typeof definition.options?.minLength !== "undefined")
- min = definition.options.minLength
- let max = 64
- if (typeof definition.options?.maxLength !== "undefined")
- max = definition.options.maxLength
- max = Math.min(max, 64)
- let v = value.slice(0, max);
- if (v.length < min) {
- return v.padEnd(min)
- }
- return v;
- },
- random: (definition) => {
- let min = 0
- if (typeof definition.options?.minLength !== "undefined")
- min = definition.options.minLength
- let max = 64
- if (typeof definition.options?.maxLength !== "undefined")
- max = definition.options.maxLength
- max = Math.min(max, 64)
- const length = Math.round(Math.random() * (max - min) + min)
- return [...Array(length)]
- .map((i) => (~~(Math.random() * 36)).toString(36))
- .join("")
- },
+ const buf = new Uint8Array(asBytes(input, 64))
+ const idx = buf.indexOf(0)
+ return new TextDecoder().decode(idx !== -1 ? buf.slice(0, idx) : buf)
+ },
+ constrain: (value, { options }) => {
+ const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64)
+ return value.length > max
+ ? value.slice(0, max)
+ : value.length < min
+ ? value.padEnd(min)
+ : value
+ },
+ random: ({ options }) => {
+ const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64)
+ const length = Math.round(Math.random() * (max - min) + min)
+ return [...Array(length)].map(() => (~~(Math.random() * 36)).toString(36)).join("")
+ },
},
select: {
- deserialize: (input, definition) => {
- return definition.options.options[parseInt(input, 16)] || definition.default
- },
bytesLength: () => 1,
- constrain: (value, definition) => {
- if(definition.options.options.includes(value)) {
- return value;
- }
- return definition.options.options[0]
- },
- random: (definition) => {
- const index = Math.round(
- Math.random() * (definition?.options?.options?.length - 1) + 0
- )
- return definition?.options?.options[index]
- },
+ deserialize: (input, def) => def.options.options[parseInt(input, 16)] || def.default,
+ constrain: (value, { options }) => options.options.includes(value)
+ ? value
+ : options.options[0],
+ random: ({ options }) => options.options[~~(Math.random() * options.options.length)],
}
}
From 42eb37b15d605a551340351bfa2f6de97bec9254 Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Fri, 14 Apr 2023 19:20:22 +0200
Subject: [PATCH 02/15] style: uniform code style
- replace remaining single quote occurrences w/ double quotes
- remove remaining semicolons
---
project/public/index.html | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index b97f9b7..21ee608 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -7,10 +7,10 @@
//---- do not edit the following code (you can indent as you wish)
let search = new URLSearchParams(window.location.search)
let alphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
- var fxhash = search.get('fxhash') || "oo" + Array(49).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join('')
+ var fxhash = search.get("fxhash") || "oo" + Array(49).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join("")
let b58dec = str=>[...str].reduce((p,c)=>p*alphabet.length+alphabet.indexOf(c)|0, 0)
let fxhashTrunc = fxhash.slice(2)
- let regex = new RegExp(".{" + ((fxhash.length/4)|0) + "}", 'g')
+ let regex = new RegExp(".{" + ((fxhash.length/4)|0) + "}", "g")
let hashes = fxhashTrunc.match(regex).map(h => b58dec(h))
let sfc32 = (a, b, c, d) => {
return () => {
@@ -27,7 +27,7 @@
var fxrand = sfc32(...hashes)
// true if preview mode active, false otherwise
// you can append preview=1 to the URL to simulate preview active
- var isFxpreview = search.get('preview') === "1"
+ var isFxpreview = search.get("preview") === "1"
// call this method to trigger the preview
function fxpreview() {
window.dispatchEvent(new Event("fxhash-preview"))
@@ -37,7 +37,7 @@
// NEW: v2 of the fxhash SDK lol
//
// get the byte params from the URL
- let fxparams = search.get('fxparams')
+ let fxparams = search.get("fxparams")
fxparams = fxparams ? fxparams.replace("0x", "") : fxparams
function* asBytes(hex, n) {
@@ -177,7 +177,7 @@
let v
if (typeof def.default === "undefined") v = processor.random(def)
else v = def.default
- params[def.id] = processor.constrain?.(v, def) || v;
+ params[def.id] = processor.constrain?.(v, def) || v
continue
}
// extract the length from the bytes & shift the initial bytes string
@@ -185,7 +185,7 @@
bytes = bytes.substring(processor.bytesLength() * 2)
// deserialize the bytes into the params
const value = processor.deserialize(valueBytes, def)
- params[def.id] = processor.constrain?.(value, def) || value;
+ params[def.id] = processor.constrain?.(value, def) || value
}
return params
}
@@ -196,9 +196,9 @@
const processor = processors[def.type]
const value = values[def.id]
// deserialize the bytes into the params
- paramValues[def.id] = processor.transform ? processor.transform(value) : value;
+ paramValues[def.id] = processor.transform ? processor.transform(value) : value
}
- return paramValues;
+ return paramValues
}
window.$fx = {
From 2a08ff2e8cad68720b45b21a3b190e1a309bb8cf Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Fri, 14 Apr 2023 19:24:30 +0200
Subject: [PATCH 03/15] refactor: update default handling in
deserializeParams()
---
project/public/index.html | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index 21ee608..c3e2835 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -167,16 +167,14 @@
// takes the parameters as bytes and outputs an object with the
// deserialized parameters, identified by their id in an object
- const deserializeParams = (bytes, definition) => {
+ const deserializeParams = (bytes, definitions) => {
const params = {}
- for (const def of definition) {
+ for (const def of definitions) {
const processor = processors[def.type]
// if we don't have any parameters defined in the URL, set the
// default value and move on
if (!bytes) {
- let v
- if (typeof def.default === "undefined") v = processor.random(def)
- else v = def.default
+ const v = def.default === undefined ? processor.random(def) : def.default
params[def.id] = processor.constrain?.(v, def) || v
continue
}
From 222f3c3b646032adffb23c0285859ae81b8cb5a0 Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Fri, 14 Apr 2023 19:26:15 +0200
Subject: [PATCH 04/15] refactor: update "this"-object handling in $fx
---
project/public/index.html | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index c3e2835..e035292 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -211,38 +211,39 @@
rand: fxrand,
preview: fxpreview,
isPreview: isFxpreview,
- params: function(definition) {
+
+ params(definition) {
// todo: maybe do some validation on the dev side ?
// or maybe not ?
this._params = definition
this._rawValues = deserializeParams(fxparams, definition)
this._paramValues = transformParamValues(this._rawValues, definition)
},
- features: function(features) {
+ features(features) {
this._features = features
},
- getFeature: function(id) {
+ getFeature(id) {
return this._features[id]
},
- getFeatures: function() {
+ getFeatures() {
return this._features
},
- getParam: function(id) {
+ getParam(id) {
return this._paramValues[id]
},
- getParams: function() {
+ getParams() {
return this._paramValues
},
- getRawParam: function(id) {
+ getRawParam(id) {
return this._rawValues[id]
},
- getRawParams: function() {
+ getRawParams() {
return this._rawValues
},
- getDefinitions: function() {
- return this._params;
+ getDefinitions() {
+ return this._params
},
- stringifyParams: function(params) {
+ stringifyParams(params) {
return JSON.stringify(
params,
(key, value) => {
From a12283cb21f41c487146245a491149bcbae5a120 Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Fri, 14 Apr 2023 19:26:29 +0200
Subject: [PATCH 05/15] refactor: minor update event handlers
---
project/public/index.html | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index e035292..ca6d4c6 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -253,24 +253,19 @@
2,
)
}
-
}
- window.addEventListener("message", (event) => {
- if (event.data === "fxhash_getHash") {
+ window.addEventListener("message", ({data}) => {
+ if (data === "fxhash_getHash") {
parent.postMessage({
id: "fxhash_getHash",
data: window.$fx.hash
}, "*")
- }
-
- if (event.data === "fxhash_getFeatures") {
+ } else if (data === "fxhash_getFeatures") {
parent.postMessage({
id: "fxhash_getFeatures",
data: window.$fx.getFeatures()
}, "*")
- }
-
- if (event.data === "fxhash_getParams") {
+ } else if (data === "fxhash_getParams") {
parent.postMessage({
id: "fxhash_getParams",
data: {
From 5ad57a64d23bbafe87b8677f83ef1667bb759db5 Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Fri, 14 Apr 2023 22:36:29 +0200
Subject: [PATCH 06/15] fix: update string maxLength handling
---
project/public/index.html | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index 9fd0746..46e1717 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -52,15 +52,15 @@
yield parseInt(hex.substring(i, i + 2), 16)
}
- function minmax($min, $max, minDef = Number.MIN_SAFE_INTEGER, maxDef = Number.MAX_SAFE_INTEGER) {
+ function minmax($min, $max, minDef = Number.MIN_SAFE_INTEGER, maxDef = Number.MAX_SAFE_INTEGER, clamp = true) {
return {
min:
$min !== undefined
- ? Math.max(Number($min), minDef)
+ ? clamp ? Math.max(Number($min), minDef) : Number($min)
: minDef,
max:
$max !== undefined
- ? Math.min(Number($max), maxDef)
+ ? clamp ? Math.min(Number($max), maxDef) : Number($max)
: maxDef,
}
}
@@ -69,7 +69,7 @@
const processors = {
number: {
bytesLength: () => 8,
- deserialize: (input) => new Float64Array(new BigUint64Array([BigInt(`0x${input}`)]).buffer)[0],
+ deserialize: (input) => new Float64Array(new BigUint64Array([BigInt("0x" + input)]).buffer)[0],
constrain: (value, { options }) => {
const { min, max } = minmax(options?.min, options?.max)
return Math.min(Math.max(value, min), max)
@@ -142,13 +142,13 @@
},
string: {
bytesLength: (options) => options?.maxLength !== undefined ? Number(options.maxLength) : 64,
- deserialize: (input) => {
- const buf = new Uint8Array(asBytes(input, 64))
+ deserialize: (input, { options }) => {
+ const buf = new Uint8Array(asBytes(input, processors.string.bytesLength(options)))
const idx = buf.indexOf(0)
- return new TextDecoder().decode(idx !== -1 ? buf.slice(0, idx) : buf)
+ return new TextDecoder().decode(idx !== -1 ? buf.subarray(0, idx) : buf)
},
constrain: (value, { options }) => {
- const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64)
+ const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64, false)
return value.length > max
? value.slice(0, max)
: value.length < min
@@ -156,7 +156,7 @@
: value
},
random: ({ options }) => {
- const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64)
+ const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64, false)
const length = Math.round(Math.random() * (max - min) + min)
return [...Array(length)].map(() => (~~(Math.random() * 36)).toString(36)).join("")
},
From c925e9611dbe21c29fdda152d9faad46857bae1f Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Fri, 14 Apr 2023 22:39:56 +0200
Subject: [PATCH 07/15] refactor: minor regexp updates
---
project/public/index.html | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index 46e1717..cd7766e 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -11,8 +11,8 @@
// make fxrand from hash
var fxhash = search.get("fxhash") || "oo" + Array(49).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join("")
let fxhashTrunc = fxhash.slice(2)
- let regex = new RegExp(".{" + ((fxhash.length/4)|0) + "}", "g")
- let hashes = fxhashTrunc.match(regex).map(h => b58dec(h))
+ let regex = new RegExp(".{" + (fxhash.length >> 2) + "}", "g")
+ let hashes = fxhashTrunc.match(regex).map(b58dec)
let sfc32 = (a, b, c, d) => {
return () => {
a |= 0; b |= 0; c |= 0; d |= 0
@@ -29,7 +29,7 @@
// make fxrandminter from minter address
var fxminter = search.get("fxminter") || "tz1" + Array(33).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join("")
let fxminterTrunc = fxminter.slice(3)
- regex = new RegExp(".{" + ((fxminterTrunc.length/4)|0) + "}", "g")
+ regex = new RegExp(".{" + (fxminterTrunc.length >> 2) + "}", "g")
hashes = fxminterTrunc.match(regex).map(h => b58dec(h))
var fxrandminter = sfc32(...hashes)
From c4b6a51021b41173eb8dc7e711acb5335cd75804 Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Sat, 15 Apr 2023 10:32:08 +0200
Subject: [PATCH 08/15] style: fix indentation (2 spaces)
---
project/public/index.html | 140 +++++++++++++++++++-------------------
1 file changed, 70 insertions(+), 70 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index cd7766e..1c35088 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -47,12 +47,12 @@
fxparams = fxparams ? fxparams.replace("0x", "") : fxparams
function* asBytes(hex, n) {
- n *= 2
- for (let i = 0; i < n; i += 2)
- yield parseInt(hex.substring(i, i + 2), 16)
- }
+ n *= 2
+ for (let i = 0; i < n; i += 2)
+ yield parseInt(hex.substring(i, i + 2), 16)
+ }
- function minmax($min, $max, minDef = Number.MIN_SAFE_INTEGER, maxDef = Number.MAX_SAFE_INTEGER, clamp = true) {
+ function minmax($min, $max, minDef = Number.MIN_SAFE_INTEGER, maxDef = Number.MAX_SAFE_INTEGER, clamp = true) {
return {
min:
$min !== undefined
@@ -71,46 +71,46 @@
bytesLength: () => 8,
deserialize: (input) => new Float64Array(new BigUint64Array([BigInt("0x" + input)]).buffer)[0],
constrain: (value, { options }) => {
- const { min, max } = minmax(options?.min, options?.max)
- return Math.min(Math.max(value, min), max)
- },
+ const { min, max } = minmax(options?.min, options?.max)
+ return Math.min(Math.max(value, min), max)
+ },
random: ({ options }) => {
- const { min, max } = minmax(options?.min, options?.max)
- const v = Math.random() * (max - min) + min
- if (options?.step) {
- const t = 1.0 / options.step
- return Math.round(v * t) / t
- }
- return v
- },
+ const { min, max } = minmax(options?.min, options?.max)
+ const v = Math.random() * (max - min) + min
+ if (options?.step) {
+ const t = 1.0 / options.step
+ return Math.round(v * t) / t
+ }
+ return v
+ },
},
bigint: {
bytesLength: () => 8,
deserialize: (input) => BigInt.asIntN(64, BigInt("0x" + input)),
random: ({ options }) => {
- const MIN_SAFE_INT64 = -9223372036854775808n
- const MAX_SAFE_INT64 = 9223372036854775807n
- if (options?.min !== undefined) {
- min = BigInt(options.min)
- if (min < MIN_SAFE_INT64) min = MIN_SAFE_INT64
- }
- if (options?.max !== undefined) {
- max = BigInt(options.max)
- if (max > MAX_SAFE_INT64) max = MAX_SAFE_INT64
- }
- const range = max - min
- const bits = range.toString(2).length
- let random
- do {
- random = BigInt(
- "0x" +
- Array.from(crypto.getRandomValues(new Uint8Array(Math.ceil(bits / 8))))
- .map((x) => x < 10 ? "0" + x : x.toString(16))
- .join("")
- )
- } while (random > range)
- return random + min
- },
+ const MIN_SAFE_INT64 = -9223372036854775808n
+ const MAX_SAFE_INT64 = 9223372036854775807n
+ if (options?.min !== undefined) {
+ min = BigInt(options.min)
+ if (min < MIN_SAFE_INT64) min = MIN_SAFE_INT64
+ }
+ if (options?.max !== undefined) {
+ max = BigInt(options.max)
+ if (max > MAX_SAFE_INT64) max = MAX_SAFE_INT64
+ }
+ const range = max - min
+ const bits = range.toString(2).length
+ let random
+ do {
+ random = BigInt(
+ "0x" +
+ Array.from(crypto.getRandomValues(new Uint8Array(Math.ceil(bits / 8))))
+ .map((x) => x < 10 ? "0" + x : x.toString(16))
+ .join("")
+ )
+ } while (random > range)
+ return random + min
+ },
},
boolean: {
bytesLength: () => 1,
@@ -121,45 +121,45 @@
bytesLength: () => 4,
deserialize: (input) => input,
transform: (input) => {
- const [r, g, b, a] = asBytes(input, 4)
- return {
- hex: {
- rgb: "#" + input.slice(0, 6),
- rgba: "#" + input,
- },
- obj: {
- rgb: { r, g, b },
- rgba: { r, g, b, a },
- },
- arr: {
- rgb: [r, g, b],
- rgba: [r, g, b, a],
- },
- }
- },
+ const [r, g, b, a] = asBytes(input, 4)
+ return {
+ hex: {
+ rgb: "#" + input.slice(0, 6),
+ rgba: "#" + input,
+ },
+ obj: {
+ rgb: { r, g, b },
+ rgba: { r, g, b, a },
+ },
+ arr: {
+ rgb: [r, g, b],
+ rgba: [r, g, b, a],
+ },
+ }
+ },
constrain: (value) => value.replace("#", "").slice(0, 8).padEnd(8, "f"),
random: () => ((Math.random() * 0x100000000) >>> 0).toString(16).padStart(8, "0"),
},
string: {
bytesLength: (options) => options?.maxLength !== undefined ? Number(options.maxLength) : 64,
deserialize: (input, { options }) => {
- const buf = new Uint8Array(asBytes(input, processors.string.bytesLength(options)))
- const idx = buf.indexOf(0)
- return new TextDecoder().decode(idx !== -1 ? buf.subarray(0, idx) : buf)
- },
+ const buf = new Uint8Array(asBytes(input, processors.string.bytesLength(options)))
+ const idx = buf.indexOf(0)
+ return new TextDecoder().decode(idx !== -1 ? buf.subarray(0, idx) : buf)
+ },
constrain: (value, { options }) => {
- const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64, false)
- return value.length > max
- ? value.slice(0, max)
- : value.length < min
- ? value.padEnd(min)
- : value
- },
+ const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64, false)
+ return value.length > max
+ ? value.slice(0, max)
+ : value.length < min
+ ? value.padEnd(min)
+ : value
+ },
random: ({ options }) => {
- const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64, false)
- const length = Math.round(Math.random() * (max - min) + min)
- return [...Array(length)].map(() => (~~(Math.random() * 36)).toString(36)).join("")
- },
+ const { min, max } = minmax(options?.minLength, options?.maxLength, 0, 64, false)
+ const length = Math.round(Math.random() * (max - min) + min)
+ return [...Array(length)].map(() => (~~(Math.random() * 36)).toString(36)).join("")
+ },
},
select: {
bytesLength: () => 1,
From a0f58e0614d3a62fe0c8417329a91dfb20d96cbf Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Sat, 15 Apr 2023 11:05:25 +0200
Subject: [PATCH 09/15] refactor: simplify hash/PRNG initialization
- add rndHash() & matcher() helpers
- improve internal re-use for fxhash & fxminter init
---
project/public/index.html | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index 1c35088..80001d7 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -8,11 +8,6 @@
let search = new URLSearchParams(window.location.search)
let alphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
let b58dec = str=>[...str].reduce((p,c)=>p*alphabet.length+alphabet.indexOf(c)|0, 0)
- // make fxrand from hash
- var fxhash = search.get("fxhash") || "oo" + Array(49).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join("")
- let fxhashTrunc = fxhash.slice(2)
- let regex = new RegExp(".{" + (fxhash.length >> 2) + "}", "g")
- let hashes = fxhashTrunc.match(regex).map(b58dec)
let sfc32 = (a, b, c, d) => {
return () => {
a |= 0; b |= 0; c |= 0; d |= 0
@@ -25,13 +20,14 @@
return (t >>> 0) / 4294967296
}
}
- var fxrand = sfc32(...hashes)
+ let rndHash = (n) => Array(n).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join("")
+ let matcher = (str, start) => str.slice(start).match(new RegExp(".{"+((str.length-start)>>2)+"}","g")).map(b58dec)
+ // make fxrand from hash
+ var fxhash = search.get("fxhash") || "oo" + rndHash(49)
+ var fxrand = sfc32(...matcher(fxhash, 2))
// make fxrandminter from minter address
- var fxminter = search.get("fxminter") || "tz1" + Array(33).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join("")
- let fxminterTrunc = fxminter.slice(3)
- regex = new RegExp(".{" + (fxminterTrunc.length >> 2) + "}", "g")
- hashes = fxminterTrunc.match(regex).map(h => b58dec(h))
- var fxrandminter = sfc32(...hashes)
+ var fxminter = search.get("fxminter") || "tz1" + rndHash(33)
+ var fxrandminter = sfc32(...matcher(fxminter, 3))
// true if preview mode active, false otherwise
// you can append preview=1 to the URL to simulate preview active
From a393769ec7d6405f863e4cc94c0787c80b86c614 Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Sat, 15 Apr 2023 11:05:55 +0200
Subject: [PATCH 10/15] style: update formatting
---
project/public/index.html | 51 +++++++++------------------------------
1 file changed, 11 insertions(+), 40 deletions(-)
diff --git a/project/public/index.html b/project/public/index.html
index 80001d7..a8b398a 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -50,14 +50,8 @@
function minmax($min, $max, minDef = Number.MIN_SAFE_INTEGER, maxDef = Number.MAX_SAFE_INTEGER, clamp = true) {
return {
- min:
- $min !== undefined
- ? clamp ? Math.max(Number($min), minDef) : Number($min)
- : minDef,
- max:
- $max !== undefined
- ? clamp ? Math.min(Number($max), maxDef) : Number($max)
- : maxDef,
+ min: $min !== undefined ? clamp ? Math.max(Number($min), minDef) : Number($min) : minDef,
+ max: $max !== undefined ? clamp ? Math.min(Number($max), maxDef) : Number($max) : maxDef,
}
}
@@ -227,39 +221,16 @@
this._rawValues = deserializeParams(fxparams, definition)
this._paramValues = transformParamValues(this._rawValues, definition)
},
- features(features) {
- this._features = features
- },
- getFeature(id) {
- return this._features[id]
- },
- getFeatures() {
- return this._features
- },
- getParam(id) {
- return this._paramValues[id]
- },
- getParams() {
- return this._paramValues
- },
- getRawParam(id) {
- return this._rawValues[id]
- },
- getRawParams() {
- return this._rawValues
- },
- getDefinitions() {
- return this._params
- },
+ features(features) { this._features = features },
+ getFeature(id) { return this._features[id] },
+ getFeatures() { return this._features },
+ getParam(id) { return this._paramValues[id] },
+ getParams() { return this._paramValues },
+ getRawParam(id) { return this._rawValues[id] },
+ getRawParams() { return this._rawValues },
+ getDefinitions() { return this._params },
stringifyParams(params) {
- return JSON.stringify(
- params,
- (key, value) => {
- if (typeof value === "bigint") return value.toString()
- return value
- },
- 2,
- )
+ return JSON.stringify(params, (_, v) => typeof v === "bigint" ? v.toString() : v, 2)
}
}
From ee3020bbb712ee9d817991facda6e1fc6b3d6b6c Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Sat, 15 Apr 2023 11:07:12 +0200
Subject: [PATCH 11/15] feat: add fxminter output to project scaffolding
---
project/src/index.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/project/src/index.js b/project/src/index.js
index dfaaed3..0bb2de0 100644
--- a/project/src/index.js
+++ b/project/src/index.js
@@ -105,6 +105,9 @@ url: ${window.location.href}
hash: ${$fx.hash}
+hash: ${$fx.minter}
+
+
params:
From efa34e6d49dc47d90833e0c1ef87a07e9737542f Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Sat, 15 Apr 2023 11:09:08 +0200
Subject: [PATCH 12/15] minor: fix typo
---
project/src/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/project/src/index.js b/project/src/index.js
index 0bb2de0..3ab7b76 100644
--- a/project/src/index.js
+++ b/project/src/index.js
@@ -105,7 +105,7 @@ url: ${window.location.href}
hash: ${$fx.hash}
-hash: ${$fx.minter}
+minter: ${$fx.minter}
params:
From 98f585ac85aef6b227de34ac6f5560e54c1a915d Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Sat, 15 Apr 2023 13:27:03 +0200
Subject: [PATCH 13/15] fix: typo in hex conversion
---
project/public/index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/project/public/index.html b/project/public/index.html
index a8b398a..23de2df 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -95,7 +95,7 @@
random = BigInt(
"0x" +
Array.from(crypto.getRandomValues(new Uint8Array(Math.ceil(bits / 8))))
- .map((x) => x < 10 ? "0" + x : x.toString(16))
+ .map((x) => x < 16 ? "0" + x : x.toString(16))
.join("")
)
} while (random > range)
From 059f38e7b962417ffff374145820e84d4bf344c8 Mon Sep 17 00:00:00 2001
From: Karsten Schmidt
Date: Sat, 15 Apr 2023 13:37:32 +0200
Subject: [PATCH 14/15] fix: update hex conversion
- undoing previous megabrain blooper
---
project/public/index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/project/public/index.html b/project/public/index.html
index 23de2df..76ee38b 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -95,7 +95,7 @@
random = BigInt(
"0x" +
Array.from(crypto.getRandomValues(new Uint8Array(Math.ceil(bits / 8))))
- .map((x) => x < 16 ? "0" + x : x.toString(16))
+ .map((x) => x.toString(16).padStart(2,"0"))
.join("")
)
} while (random > range)
From 8dca39508126a956e387c2925348ce639cabf3b7 Mon Sep 17 00:00:00 2001
From: maerzhase
Date: Fri, 16 Jun 2023 15:36:34 +0200
Subject: [PATCH 15/15] run prettier
---
.prettierrc.json | 6 +
project/public/index.html | 977 ++++++++++++++++++++------------------
2 files changed, 529 insertions(+), 454 deletions(-)
create mode 100644 .prettierrc.json
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..0a379d5
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,6 @@
+{
+ "trailingComma": "es5",
+ "tabWidth": 2,
+ "semi": false,
+ "singleQuote": false
+}
\ No newline at end of file
diff --git a/project/public/index.html b/project/public/index.html
index 01563fd..418e0aa 100644
--- a/project/public/index.html
+++ b/project/public/index.html
@@ -4,488 +4,557 @@
FXHASH project