primitiveprimer
Version:
Bluntly extend String, Array, Number, Object prototypes with useful methods, or use them as standalone utilities while leaving prototypes untouched
1,347 lines (1,337 loc) • 34.9 kB
JavaScript
;
var PrimitivePrimer = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/iife.ts
var iife_exports = {};
__export(iife_exports, {
default: () => iife_default
});
// src/array.ts
var assertIsObjectArray = (arr) => {
if (Array.isArray(arr) && arr.every((item) => typeof item === "object" && item !== null)) {
return void 0;
}
throw new Error("not an array of objects");
};
var assertIsArrayOfStrings = (arr) => {
if (arr.every((x) => typeof x === "string")) {
return void 0;
}
throw new Error("not an array of strings");
};
var assertIsArrayOfNumbers = (arr) => {
if (arr.every((x) => typeof x === "number")) {
return void 0;
}
throw new Error("not an array of numbers");
};
var arrayMethodsTS = [
[
"filterGuard",
function(pred) {
return this.filter((x) => pred(x));
}
],
[
"findGuard",
function(pred) {
for (const x of this) if (pred(x)) return x;
return void 0;
}
],
[
"assertIsStringArray",
function() {
assertIsArrayOfStrings(this);
}
],
[
"assertIsNumberArray",
function() {
assertIsArrayOfNumbers(this);
}
],
[
"asStrings",
function() {
try {
assertIsArrayOfStrings(this);
return this;
} catch {
return this;
}
}
],
[
"asNumbers",
function() {
try {
assertIsArrayOfNumbers(this);
return this;
} catch {
return this;
}
}
],
[
"tryAsStrings",
function() {
try {
assertIsArrayOfStrings(this);
return this;
} catch {
return null;
}
}
],
[
"tryAsNumbers",
function() {
try {
assertIsArrayOfNumbers(this);
return this;
} catch {
return null;
}
}
]
];
var arrayMethods = [
[
"first",
function(n = 1) {
return n === 1 ? this[0] : this.slice(0, n);
}
],
[
"last",
function(n = 1) {
return n === 1 ? this[this.length - 1] : this.slice(-n);
}
],
[
"findByKey",
function(key, value) {
assertIsObjectArray(this);
for (const item of this) if (item[key] === value) return item;
return null;
}
],
[
"groupBy",
function(fn) {
return this.reduce((acc, item) => {
const key = typeof fn === "function" ? fn(item) : item[fn];
(acc[key] ||= []).push(item);
return acc;
}, {});
}
],
[
"sumByKey",
function(key) {
assertIsObjectArray(this);
return this.reduce((acc, item) => acc + (typeof item[key] === "number" ? item[key] : 0), 0);
}
],
[
"autoParseKeys",
function() {
assertIsObjectArray(this);
return this.map((obj) => {
if (obj && typeof obj === "object") {
for (const key in obj) {
if (typeof obj[key] === "string") {
try {
obj[key] = JSON.parse(obj[key]);
} catch {
}
}
}
}
return obj;
});
}
],
[
"unique",
function() {
return [...new Set(this)];
}
],
[
"shuffle",
function() {
const arr = [...this];
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
],
[
"highestByKey",
function(key) {
try {
assertIsObjectArray(this);
assertIsArrayOfNumbers(this.map((item) => item[key]));
this.length;
return this.reduce((max, item) => typeof item[key] === "number" && item[key] > (max?.[key] ?? -Infinity) ? item : max);
} catch (e) {
console.error("not an numberarray in object", e);
return -1;
}
}
],
[
"lowestByKey",
function(key) {
try {
assertIsObjectArray(this);
assertIsArrayOfNumbers(this.map((item) => item[key]));
return this.reduce((min, item) => typeof item[key] === "number" && item[key] < (min?.[key] ?? Infinity) ? item : min);
} catch (e) {
console.error("not an objectArray", e);
return -1;
}
}
],
[
"sortByKey",
function(key, ascending = true) {
try {
assertIsObjectArray(this);
return [...this].sort((a, b) => {
const aVal = a[key] ?? 0;
const bVal = b[key] ?? 0;
return ascending ? aVal - bVal : bVal - aVal;
});
} catch (e) {
console.error("not an objectArray", e);
return [];
}
}
],
[
"sortByKeyName",
function(key, ascending = true) {
try {
assertIsObjectArray(this);
return [...this].sort((a, b) => {
const aVal = String(a[key] ?? "");
const bVal = String(b[key] ?? "");
return ascending ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
});
} catch (e) {
console.error("not an objectArray", e);
return [];
}
}
],
[
"mapByKey",
function(key) {
assertIsObjectArray(this);
return this.map((item) => item && typeof item === "object" ? item[key] : void 0);
}
],
[
"sumKey",
function(key) {
try {
assertIsObjectArray(this);
assertIsArrayOfNumbers(this.map((item) => item[key]));
return this.reduce((acc, cur) => acc + (parseFloat(String(cur[key])) || 0), 0);
} catch (e) {
console.error("not an numberarray in object", e);
return 0;
}
}
],
[
"averageKey",
function(key) {
try {
assertIsObjectArray(this);
assertIsArrayOfNumbers(this.map((item) => item[key]));
let total = 0, count = 0;
for (const cur of this) {
const v = parseFloat(String(cur[key]));
if (!Number.isNaN(v)) {
total += v;
count++;
}
}
return count ? total / count : 0;
} catch (e) {
console.error("not an numberarray in object", e);
return 0;
}
}
],
[
"filterKey",
function(key, pred) {
try {
assertIsObjectArray(this);
return this.filter((item) => pred(item[key]));
} catch (e) {
console.error("not an objectArray", e);
return [];
}
}
],
[
"distinct",
function(keyOrFn) {
try {
assertIsObjectArray(this);
const seen = /* @__PURE__ */ new Set();
const getKey = typeof keyOrFn === "function" ? keyOrFn : (x) => x[keyOrFn];
const out = [];
for (const item of this) {
const k = getKey(item);
if (!seen.has(k)) {
seen.add(k);
out.push(item);
}
}
return out;
} catch (e) {
console.error("not an objectArray", e);
return [];
}
}
],
[
"aggregate",
function(keyOrFn, reducer, init) {
try {
assertIsObjectArray(this);
const getKey = typeof keyOrFn === "function" ? keyOrFn : (x) => x[keyOrFn];
const groups = /* @__PURE__ */ new Map();
for (const item of this) {
const k = getKey(item);
const acc = groups.has(k) ? groups.get(k) : init;
groups.set(k, reducer(acc, item));
}
const out = {};
for (const [k, v] of groups.entries()) out[k] = v;
return out;
} catch (e) {
console.error("not an objectArray", e);
return {};
}
}
],
[
"toTable",
function() {
try {
assertIsObjectArray(this);
const out = {};
for (const item of this) {
for (const [k, v] of Object.entries(item)) {
(out[k] ??= []).push(v);
}
}
return out;
} catch (e) {
console.error("not an objectArray", e);
return {};
}
}
],
[
"sumBy",
function(key) {
try {
assertIsObjectArray(this);
assertIsArrayOfNumbers(this.map((item) => item[key]));
return this.reduce((acc, cur) => {
const v = parseFloat(String(cur[key]));
return acc + (Number.isNaN(v) ? 0 : v);
}, 0);
} catch (e) {
console.error("not an objectArray", e);
return 0;
}
}
],
[
"averageBy",
function(key) {
try {
assertIsObjectArray(this);
assertIsArrayOfNumbers(this.map((item) => item[key]));
let total = 0, count = 0;
for (const cur of this) {
const v = parseFloat(String(cur[key]));
if (!Number.isNaN(v)) {
total += v;
count++;
}
}
return count ? total / count : 0;
} catch (e) {
console.error("not an objectArray", e);
return 0;
}
}
],
[
"seededShuffle",
function(seed) {
const thisClone = [...this];
const total = this.length;
const res = Array.from({ length: total }, (_, i) => i);
const rand = () => (seed = 1103515245 * seed + 12345 >>> 0) / 4294967295;
for (let i = total - 1; i > 0; i--) {
const j = Math.floor(rand() * (i + 1));
[res[i], res[j]] = [res[j], res[i]];
}
const shuffled = res.map((i) => thisClone[i]);
return shuffled;
}
],
[
"intersect",
function(other) {
const set = new Set(other);
return this.filter((x) => set.has(x));
}
],
[
"difference",
function(other) {
const set = new Set(other);
return this.filter((x) => !set.has(x));
}
],
[
"sum",
function() {
try {
assertIsArrayOfNumbers(this);
let total = 0;
for (const v of this) {
const n = typeof v === "number" ? v : parseFloat(String(v));
if (!Number.isNaN(n)) total += n;
else if (v) total += 1;
}
return total;
} catch (e) {
console.error("not an array of numbers", e);
return 0;
}
}
],
[
"average",
function() {
try {
assertIsArrayOfNumbers(this);
let total = 0;
let count = 0;
for (const v of this) {
const n = typeof v === "number" ? v : parseFloat(String(v));
if (!Number.isNaN(n)) {
total += n;
count++;
} else if (v) {
total += 1;
count++;
}
}
return count === 0 ? 0 : total / count;
} catch (e) {
console.error("not an array of numbers", e);
return 0;
}
}
],
[
"validateEach",
function(validatorFn) {
return this.map((item) => item != null && validatorFn(item) ? item : null);
}
],
[
"clearNil",
function() {
return this.filter((x) => x != null);
}
],
[
"indexOfHighestNumber",
function() {
try {
assertIsArrayOfNumbers(this);
if (this.length === 0) return -1;
let highestIndex = 0;
for (let i = 1; i < this.length; i++) {
if (this[i] > this[highestIndex]) {
highestIndex = i;
}
}
return highestIndex;
} catch (e) {
console.error("not an array of numbers", e);
return -1;
}
}
],
[
"indexOfLowestNumber",
function() {
try {
assertIsArrayOfNumbers(this);
if (this.length === 0) return -1;
let lowestIndex = 0;
for (let i = 1; i < this.length; i++) {
if (this[i] < this[lowestIndex]) {
lowestIndex = i;
}
}
return lowestIndex;
} catch (e) {
console.error("not an array of numbers", e);
return -1;
}
}
]
];
function extendArray() {
for (const method of arrayMethods) {
Object.defineProperty(Array.prototype, method[0], {
value: method[1],
writable: true,
configurable: true,
enumerable: false
});
}
for (const method of arrayMethodsTS) {
Object.defineProperty(Array.prototype, method[0], {
value: method[1],
writable: true,
configurable: true,
enumerable: false
});
}
}
// src/number.ts
var numberMethods = [
[
"percentage",
function(percent) {
return this * percent / 100;
}
],
[
"isEven",
function() {
return this % 2 === 0;
}
],
[
"isOdd",
function() {
return this % 2 !== 0;
}
],
[
"toFixedNumber",
function(decimals = 2) {
return parseFloat(this.toFixed(decimals));
}
],
[
"between",
function(min, max) {
return this >= min && this <= max;
}
],
[
"assertNrBetween",
function(min = 0, max = Infinity) {
return this >= min && this <= max;
}
],
[
"clamp",
function(min, max) {
return Math.min(Math.max(this, min), max);
}
],
[
"times",
function(fn) {
for (let i = 0; i < this; i++) fn(i);
}
],
[
"toStringWithLeadingZeros",
function(length) {
return String(this).padStart(length, "0");
}
],
[
"toTimeCode",
function() {
const totalSeconds = Math.floor(this);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor(totalSeconds % 3600 / 60);
const seconds = totalSeconds % 60;
return `${hours}:${minutes.toStringWithLeadingZeros(2)}:${seconds.toStringWithLeadingZeros(2)}`;
}
],
[
"percentOf",
function(total) {
return total === 0 ? 0 : this / total * 100;
}
],
[
"ratioOf",
function(total) {
return total === 0 ? 0 : this / total;
}
],
[
"isInteger",
function() {
return Number.isInteger(this);
}
],
[
"isFinite",
function() {
return Number.isFinite(this);
}
],
[
"isSafeInteger",
function() {
return Number.isSafeInteger(this);
}
],
[
"isPositive",
function() {
return this > 0;
}
],
[
"isNegative",
function() {
return this < 0;
}
],
[
"isNonNegative",
function() {
return this >= 0;
}
],
[
"assertIsInteger",
function() {
if (!Number.isInteger(this)) throw new Error("Not an integer");
}
],
[
"assertIsFinite",
function() {
if (!Number.isFinite(this)) throw new Error("Not finite (NaN or Infinity)");
}
]
];
function extendNumber() {
for (const method of numberMethods) {
Object.defineProperty(Number.prototype, method[0], {
value: method[1],
writable: true,
configurable: true
});
}
}
// src/object.ts
var objectMethods = [
[
"sortKeys",
function(sorterFn = null) {
return Object.fromEntries(Object.entries(this).sort(([keyA], [keyB]) => sorterFn ? sorterFn(keyA, keyB) : keyA.localeCompare(keyB)));
}
],
[
"fill",
function(source) {
for (const [key, value] of Object.entries(source)) {
if (!(key in this)) {
this[key] = value;
}
}
return this;
}
],
[
"parseKeys",
function(...keys) {
const obj = this.valueOf();
const result = {};
for (const key of keys) {
try {
result[key] = JSON.parse(obj[key]);
} catch {
result[key] = obj[key];
}
}
return obj;
}
],
[
"valuesMap",
function(fn) {
return Object.fromEntries(Object.entries(this).map(([k, v]) => [k, fn(v, k)]));
}
],
[
"entriesMap",
function(fn) {
return Object.fromEntries(Object.entries(this).map(fn));
}
],
[
"keysMap",
function(fn) {
return Object.fromEntries(Object.entries(this).map(([k, v]) => fn(k, v)));
}
],
[
"equals",
function(other) {
const keysA = Object.keys(this);
const keysB = Object.keys(other);
if (keysA.length !== keysB.length) return false;
return keysA.every((k) => keysB.includes(k) && typeof this[k] === typeof other[k]);
}
],
[
"omit",
function(...keys) {
const out = {};
for (const k of Object.keys(this)) if (!keys.includes(k)) out[k] = this[k];
return out;
}
],
[
"pick",
function(...keys) {
const out = {};
for (const k of keys) if (k in this) out[k] = this[k];
return out;
}
],
[
"complement",
function(src) {
const out = { ...this };
for (const k of Object.keys(src)) if (!(k in out)) out[k] = src[k];
return out;
}
],
[
"clean",
function() {
const out = {};
for (const [k, v] of Object.entries(this)) {
if (v === "" || v == null) continue;
out[k] = v;
}
return out;
}
],
[
"ensureSchema",
function(schema, opts = {}) {
const out = {};
for (const [k, def] of Object.entries(schema)) {
let v = this[k];
if (v == null) v = def;
if (opts.coerce) {
const type = typeof def;
if (type === "number") v = Number(v);
else if (type === "boolean") v = Boolean(v);
else if (type === "string") v = String(v);
}
out[k] = v;
}
return out;
}
],
[
"filterEntries",
function(predicate) {
const out = {};
for (const [k, v] of Object.entries(this)) if (predicate(k, v)) out[k] = v;
return out;
}
],
[
"merge",
function(other, opts = {}) {
const out = { ...this };
for (const [k, v] of Object.entries(other)) {
const cur = out[k];
if (Array.isArray(cur) && Array.isArray(v)) {
const strat = opts.arrayStrategy ?? "concat";
if (strat === "replace") out[k] = v;
else if (strat === "unique") out[k] = Array.from(/* @__PURE__ */ new Set([...cur, ...v]));
else out[k] = [...cur, ...v];
} else if (cur && typeof cur === "object" && v && typeof v === "object") {
out[k] = { ...cur, ...v };
} else {
out[k] = v;
}
}
return out;
}
],
[
"fromTable",
function() {
const keys = Object.keys(this);
const len = Math.max(0, ...keys.map((k) => this[k]?.length ?? 0));
const out = Array.from({ length: len }, () => ({}));
for (const k of keys) {
const col = this[k] || [];
for (let i = 0; i < len; i++) out[i][k] = col[i];
}
return out;
}
]
];
function extendObject() {
for (const method of objectMethods) {
Object.defineProperty(Object.prototype, method[0], {
value: method[1],
writable: true,
configurable: true,
enumerable: false
});
}
}
// src/string.ts
function assertIs(value, guard, message = "Type assertion failed") {
if (!guard(value)) {
throw new Error(message);
}
}
var stringMethods = [
[
"assertNonEmptyString",
function() {
try {
assertIs(this, (v) => typeof v === "string");
return this;
} catch {
return false;
}
}
],
[
"isNonEmty",
function() {
return typeof this === "string" && this.trim().length > 0;
}
],
[
"changeExtension",
function(ext) {
return this.replace(/\.[0-9a-z]{1,5}$/i, "." + ext.replace(/\W/, "").substring(0, 5));
}
],
[
"reverse",
function() {
return this.split("").reverse().join("");
}
],
[
"toTitleCase",
function() {
return this.replace(/\w\S*/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase());
}
],
[
"words",
function() {
return this.match(/\b\w+\b/g) || [];
}
],
[
"slashreverse",
function(str) {
return str.replace(/[\\/]/g, (ch) => ch === "\\" ? "/" : "\\");
}
],
[
"slashwin",
function() {
return this.replace(/[\\/]/g, "\\");
}
],
[
"slashlinux",
function() {
return this.replace(/[\\/]/g, "/");
}
],
[
"strip",
function() {
return this.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/\s+/g, "").trim();
}
],
[
"containsAny",
function(...arr) {
return arr.some((sub) => this.includes(sub));
}
],
[
"toSlug",
function() {
return this.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/\s+/g, "-").replace(/[^\w-]/g, "").replace(/--+/g, "-").replace(/^-+|-+$/g, "");
}
],
[
"stripCompare",
function(other) {
const normalize2 = (str) => str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[\s_]/g, "").trim();
return normalize2(this).includes(normalize2(other));
}
],
[
"toWordCapitalized",
function() {
return this ? this.charAt(0).toUpperCase() + this.slice(1).toLowerCase() : "";
}
],
[
"truncate",
function(length, suffix = "\u2026") {
return this.length > length ? this.slice(0, length) + suffix : this.toString();
}
],
[
"isJson",
function() {
try {
JSON.parse(this);
return true;
} catch {
return false;
}
}
],
[
"toCamelCase",
function() {
return this.replace(/([-_][a-z])/gi, ($1) => $1.toUpperCase().replace("-", "").replace("_", ""));
}
],
[
"safeParseJson",
function() {
try {
return JSON.parse(this);
} catch {
return this.valueOf();
}
}
],
[
"nullParseJson",
function() {
if (!this.trim()) return null;
try {
return JSON.parse(this);
} catch {
return null;
}
}
],
[
"filenameCompare",
function(otherPath) {
const normalize2 = (p) => p.replace(/\\/g, "/").split("/").pop()?.toLowerCase() ?? "";
return normalize2(this) === normalize2(otherPath);
}
],
[
"substringFrom",
function(startStr, stopStr) {
const s = String(this);
if (!startStr) return s;
const i = s.indexOf(startStr);
if (i === -1) return "";
const from = i + startStr.length;
if (!stopStr) return s.slice(from);
const j = s.indexOf(stopStr, from);
return j === -1 ? s.slice(from) : s.slice(from, j);
}
],
[
"escapeHTML",
function() {
return this.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\"/g, """).replace(/'/g, "'");
}
],
[
"unescapeHTML",
function() {
return this.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&");
}
],
[
"humanize",
function() {
const s = this.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[\-_]+/g, " ").replace(/\s{2,}/g, " ").trim();
return s.replace(/(^\w|[.!?]\s+\w)/g, (m) => m.toUpperCase());
}
],
[
"underscore",
function() {
return this.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s\-]+/g, "_").toLowerCase();
}
],
[
"countOccurrence",
function(str2, caseSens = true) {
const src = caseSens ? this : this.toLowerCase();
const needle = caseSens ? str2 : str2.toLowerCase();
if (!needle) return 0;
let i = 0, pos = 0;
while ((pos = src.indexOf(needle, pos)) !== -1) {
i++;
pos += needle.length;
}
return i;
}
],
[
"isNumber",
function() {
return /^\s*[+-]?(?:\d+\.?\d*|\.\d+)\s*$/.test(this);
}
],
[
"isFloat",
function() {
return /^\s*[+-]?\d*\.\d+\s*$/.test(this) && !Number.isNaN(parseFloat(this));
}
],
[
"isAlphaNumeric",
function() {
return /^[a-z0-9]+$/i.test(this);
}
],
[
"isLower",
function() {
return this === this.toLowerCase() && /[a-z]/.test(this);
}
],
[
"isUpper",
function() {
return this === this.toUpperCase() && /[A-Z]/.test(this);
}
],
[
"hashed",
function(truncate) {
let h = 5381;
for (let i = 0; i < this.length; i++) h = (h << 5) + h + this.charCodeAt(i);
let out = (h >>> 0).toString(16);
return typeof truncate === "number" ? out.slice(0, Math.max(0, truncate)) : out;
}
],
[
"replaceLast",
function(search, replacement) {
const s = String(this);
if (search instanceof RegExp) {
const m = s.match(search);
if (!m) return s;
const last = m[m.length - 1];
const idx = s.lastIndexOf(last);
return idx === -1 ? s : s.slice(0, idx) + replacement + s.slice(idx + last.length);
} else {
const idx = s.lastIndexOf(search);
return idx === -1 ? s : s.slice(0, idx) + replacement + s.slice(idx + search.length);
}
}
],
[
"latinise",
function() {
return this.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
}
],
[
"ellipsis",
function(total) {
if (total <= 3) return this.slice(0, total);
return this.length > total ? this.slice(0, total - 3) + "..." : this;
}
],
[
"toNumber",
function() {
const cleaned = this.replace(/[^0-9+\-\.eE]/g, " ");
const match = cleaned.match(/[+\-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+\-]?\d+)?/);
return match ? Number(match[0]) : NaN;
}
],
[
"toBoolean",
function() {
const s = this.trim().toLowerCase();
if (["1", "true", "yes", "on", "y"].includes(s)) return true;
if (["0", "false", "no", "off", "n"].includes(s)) return false;
return Boolean(s);
}
]
];
function extendString() {
for (const method of stringMethods) {
Object.defineProperty(String.prototype, method[0], {
value: method[1],
writable: true,
configurable: true
});
}
}
// src/math.ts
var mathUtilsObj = {
randomRangeFloat(min, max) {
return Math.random() * (max - min) + min;
},
randomRangeInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
lerp(min, max, t) {
return min + (max - min) * t;
},
clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
},
degToRad(deg) {
return deg * (Math.PI / 180);
},
radToDeg(rad) {
return rad * (180 / Math.PI);
},
distance(x1, y1, x2, y2) {
return Math.hypot(x2 - x1, y2 - y1);
},
roundTo(value, decimals = 2) {
return Math.round(value * 10 ** decimals) / 10 ** decimals;
},
isPowerOfTwo(value) {
return value > 0 && (value & value - 1) === 0;
},
nextPowerOfTwo(value) {
return 2 ** Math.ceil(Math.log2(value));
},
normalize(value, min, max) {
return (value - min) / (max - min);
},
smoothStep(edge0, edge1, x) {
const t = Math.max(0, Math.min(1, (x - edge0) / (edge1 - edge0)));
return t * t * (3 - 2 * t);
},
mix(x, y, a) {
return x * (1 - a) + y * a;
},
mixColors(hex1, hex2, mixPerc) {
const cleanHex = (h) => h.replace("#", "").padStart(6, "0");
const [h1, h2] = [cleanHex(hex1), cleanHex(hex2)];
const [r1, g1, b1] = [parseInt(h1.slice(0, 2), 16), parseInt(h1.slice(2, 4), 16), parseInt(h1.slice(4, 6), 16)];
const [r2, g2, b2] = [parseInt(h2.slice(0, 2), 16), parseInt(h2.slice(2, 4), 16), parseInt(h2.slice(4, 6), 16)];
const r = Math.round(this.mix(r1, r2, mixPerc));
const g = Math.round(this.mix(g1, g2, mixPerc));
const b = Math.round(this.mix(b1, b2, mixPerc));
const toHex = (n) => n.toString(16).padStart(2, "0");
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
};
function extendMathUtils() {
if (!globalThis.mathUtils) {
globalThis.mathUtils = mathUtilsObj;
}
if (typeof globalThis.window !== "undefined") {
Object.assign(globalThis.window, { mathUtils: mathUtilsObj });
}
}
// src/primitivetools.ts
var pkitImpl = (value) => {
if (typeof value === "string") return createPrimeString(value);
if (typeof value === "number") return createPrimeNumber(value);
if (Array.isArray(value)) return createPrimeArray(value);
if (value && typeof value === "object") return createPrimeObject(value);
if (value === null) return false;
if (typeof value === "undefined") return null;
if (typeof value === "function") return pkitImpl(value());
};
function createPrimeString(value) {
let current = value;
return Object.fromEntries(
stringMethods.map(([name, fn]) => {
return [
name,
function(...args) {
current = fn.apply(current, args);
return current;
}
];
})
);
}
function createPrimeNumber(initial) {
let current = initial;
let result;
return Object.fromEntries(
numberMethods.map(([name, fn]) => {
return [
name,
function(...args) {
result = fn.apply(current, args);
return result;
}
];
})
);
}
function createPrimeArray(initial) {
let current = initial;
let result = null;
return Object.fromEntries(
arrayMethods.map(([name, fn]) => {
return [
name,
function(...args) {
result = fn.apply(current, args);
return result;
}
];
})
);
}
function createPrimeObject(initial) {
let current = initial;
return Object.fromEntries(
objectMethods.map(([name, fn]) => {
return [
name,
function(...args) {
current = fn.apply(current, args);
return current;
}
];
})
);
}
var normalize = (p) => {
return p.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
};
var sep = globalThis.process ? globalThis.process.platform === "win32" ? "\\" : "/" : globalThis.window?.navigator.platform.startsWith("Win") ? "\\" : "/";
var pathkit = {
sep,
normalize,
join: (...parts) => normalize(parts.filter(Boolean).join(sep)),
basename: (p) => normalize(p).split("/").pop() || "",
dirname: (p) => {
const parts = normalize(p).split("/");
parts.pop();
return parts.length ? parts.join("/") : ".";
},
extname: (p) => {
const b = normalize(p).split("/").pop() || "";
const i = b.lastIndexOf(".");
return i > 0 ? b.slice(i) : "";
}
};
var pkit = pkitImpl;
pkit.math = mathUtilsObj;
pkit.path = pathkit;
var primitivetools_default = pkit;
// src/pathShim.ts
function createBrowserPathShim() {
const normalize2 = (p) => {
return p.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
};
const sep2 = "/";
return {
sep: sep2,
normalize: normalize2,
join: (...parts) => normalize2(parts.filter(Boolean).join(sep2)),
basename: (p) => normalize2(p).split("/").pop() || "",
dirname: (p) => {
const parts = normalize2(p).split("/");
parts.pop();
return parts.length ? parts.join("/") : ".";
},
extname: (p) => {
const b = normalize2(p).split("/").pop() || "";
const i = b.lastIndexOf(".");
return i > 0 ? b.slice(i) : "";
}
};
}
function extendPath() {
if (typeof globalThis === "undefined") return;
if (globalThis.path) return;
globalThis.path = createBrowserPathShim();
}
// src/primitives.ts
function applyPrimitives() {
extendString();
extendArray();
extendNumber();
extendObject();
extendPath();
extendMathUtils();
}
// src/iife.ts
var applyPrimitives2 = applyPrimitives;
globalThis.applyPrimitives = applyPrimitives2;
globalThis.pkit = primitivetools_default;
if (typeof globalThis.window !== "undefined") {
Object.assign(globalThis.window, { applyPrimitives: applyPrimitives2, pkit: primitivetools_default });
}
var iife_default = { applyPrimitives: applyPrimitives2, pkit: primitivetools_default };
return __toCommonJS(iife_exports);
})();
//# sourceMappingURL=primitiveprimer.global.js.map