visionary-image 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  React image component with built-in Blurhash placeholders for better UX and Core Web Vitals.
4
4
 
5
- ![GitHub Release](https://img.shields.io/github/v/release/visionary-ux/visionary-image?color=beige) [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/visionary-ux/visionary-image/.github%2Fworkflows%2Fci-cd-workflow.yml?branch=master&style=flat-square)](https://github.com/visionary-ux/visionary-image/actions/workflows/ci-cd-workflow.yml?query=branch%3Amaster) [![npm package size (minzipped, via Bundlephobia)](https://img.shields.io/bundlephobia/minzip/visionary-image?style=flat-square&color=blue)](https://bundlephobia.com/package/visionary-image) [![Storybook demo](https://img.shields.io/badge/-Storybook-FF4785?style=flat-square&logo=storybook&logoColor=white)](https://visionary-ux.github.io/visionary-image/)
5
+ ![GitHub Release](https://img.shields.io/github/v/release/visionary-ux/visionary-image?color=beige) [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/visionary-ux/visionary-image/.github%2Fworkflows%2Fci-cd-workflow.yml?branch=master)](https://github.com/visionary-ux/visionary-image/actions/workflows/ci-cd-workflow.yml?query=branch%3Amaster) [![npm package size (minzipped, via Bundlephobia)](https://img.shields.io/bundlephobia/minzip/visionary-image?color=blue)](https://bundlephobia.com/package/visionary-image) ![NPM Downloads](https://img.shields.io/npm/d18m/visionary-image?color=lightgray) [![Storybook demo](https://img.shields.io/badge/-Storybook-FF4785?logo=storybook&logoColor=white)](https://visionary-ux.github.io/visionary-image/)
6
6
 
7
7
  ## Features
8
8
 
@@ -1,6 +1,6 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.id="v7y-styles",e.appendChild(document.createTextNode('.v7y_7587:before{content:"";display:block;padding-top:var(--v-ar)}.v7y_b8c0{-webkit-user-drag:none;pointer-events:none}.v7y_e0dd{-webkit-user-select:none;user-select:none}')),document.head.appendChild(e)}}catch(n){console.error("vite-plugin-css-injected-by-js",n)}})();
2
- import { jsx as T, jsxs as wt } from "react/jsx-runtime";
3
- import { useRef as Y, useCallback as q, useState as It, useEffect as Et, useLayoutEffect as Rt, useMemo as At } from "react";
2
+ import { jsx as U, jsxs as yt } from "react/jsx-runtime";
3
+ import { useRef as Y, useCallback as q, useState as Rt, useEffect as At, useLayoutEffect as It, useMemo as Et } from "react";
4
4
  function xt(t) {
5
5
  return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
6
6
  }
@@ -40,44 +40,47 @@ var et = { exports: {} };
40
40
  t.exports ? (e.default = e, t.exports = e) : window.classNames = e;
41
41
  })();
42
42
  })(et);
43
- var Ut = et.exports;
44
- const Nt = /* @__PURE__ */ xt(Ut), Ot = (t, { root: n, rootMargin: e, threshold: o } = {}, i = []) => {
43
+ var Tt = et.exports;
44
+ const Pt = /* @__PURE__ */ xt(Tt), Ot = (t, { root: n, rootMargin: e, threshold: o } = {}, i = []) => {
45
45
  const r = Y(null), s = Y(null);
46
46
  return q((c) => {
47
47
  r.current && s.current && (s.current.unobserve(r.current), s.current.disconnect(), s.current = null), c && (s.current = new IntersectionObserver(t, { root: n, rootMargin: e, threshold: o }), s.current.observe(c), r.current = c);
48
48
  }, [r, n, e, JSON.stringify(o), ...i]);
49
- }, Tt = ({ root: t, rootMargin: n, threshold: e, unobserveOnEnter: o, target: i, onEnter: r, onLeave: s, defaultInView: u } = {}, c = []) => {
50
- const [a, p] = It({
49
+ }, Ut = ({ root: t, rootMargin: n, threshold: e, unobserveOnEnter: o, target: i, onEnter: r, onLeave: s, defaultInView: u } = {}, c = []) => {
50
+ const [a, p] = Rt({
51
51
  inView: u || !1,
52
52
  entry: null,
53
53
  observer: null
54
- }), l = q(([h], d) => {
55
- const b = d.thresholds.some((g) => h.intersectionRatio >= g) && h.isIntersecting;
54
+ }), l = q(([m], d) => {
55
+ const v = d.thresholds.some((b) => m.intersectionRatio >= b) && m.isIntersecting;
56
56
  p({
57
- inView: b,
58
- entry: h,
57
+ inView: v,
58
+ entry: m,
59
59
  observer: d
60
- }), b && o && (d.unobserve(h.target), d.disconnect()), b ? r == null || r(h, d) : s == null || s(h, d);
61
- }, [r, s, o]), m = Ot(l, { root: t, rootMargin: n, threshold: e }, [o, ...c]);
62
- return Et(() => {
63
- i != null && i.current && m(i.current);
64
- }, [i, m]), [m, a.inView, a.entry, a.observer];
65
- }, Ct = {
66
- overflow: "hidden"
67
- }, Dt = ({ aspectRatio: t, children: n }) => /* @__PURE__ */ T("div", { style: { aspectRatio: t, ...Ct }, children: n });
68
- var $ = /* @__PURE__ */ ((t) => (t.AUTO = "auto", t.AVIF = "avif", t.JPEG = "jpeg", t.WEBP = "webp", t))($ || {}), w = /* @__PURE__ */ ((t) => (t.xs = "xs", t.sm = "sm", t.md = "md", t.lg = "lg", t.xl = "xl", t.xxl = "xxl", t["4k"] = "4k", t["5k"] = "5k", t.full = "full", t))(w || {}), D = /* @__PURE__ */ ((t) => (t.DEBUG = "debug", t.DOWNLOAD = "download", t))(D || {});
69
- const Pt = "https://link.visionary.cloud";
70
- $.AUTO, w.lg;
60
+ }), v && o && (d.unobserve(m.target), d.disconnect()), v ? r == null || r(m, d) : s == null || s(m, d);
61
+ }, [r, s, o]), g = Ot(l, { root: t, rootMargin: n, threshold: e }, [o, ...c]);
62
+ return At(() => {
63
+ i != null && i.current && g(i.current);
64
+ }, [i, g]), [g, a.inView, a.entry, a.observer];
65
+ }, V = {
66
+ ASPECT_RATIO_WRAPPER: "aspect-ratio-wrapper",
67
+ CANVAS: "canvas",
68
+ CONTAINER: "container",
69
+ IMAGE: "image"
70
+ };
71
+ var W = /* @__PURE__ */ ((t) => (t.AUTO = "auto", t.AVIF = "avif", t.JPEG = "jpeg", t.WEBP = "webp", t))(W || {}), y = /* @__PURE__ */ ((t) => (t.xs = "xs", t.sm = "sm", t.md = "md", t.lg = "lg", t.xl = "xl", t.xxl = "xxl", t["4k"] = "4k", t["5k"] = "5k", t.full = "full", t))(y || {}), N = /* @__PURE__ */ ((t) => (t.DEBUG = "debug", t.DOWNLOAD = "download", t))(N || {});
72
+ const Ct = "https://link.visionary.cloud";
73
+ W.AUTO, y.lg;
71
74
  const Z = {
72
- [w.xs]: 160,
73
- [w.sm]: 320,
74
- [w.md]: 640,
75
- [w.lg]: 1280,
76
- [w.xl]: 1920,
77
- [w.xxl]: 2560,
78
- [w["4k"]]: 3840,
79
- [w["5k"]]: 5120,
80
- [w.full]: 0
75
+ [y.xs]: 160,
76
+ [y.sm]: 320,
77
+ [y.md]: 640,
78
+ [y.lg]: 1280,
79
+ [y.xl]: 1920,
80
+ [y.xxl]: 2560,
81
+ [y["4k"]]: 3840,
82
+ [y["5k"]]: 5120,
83
+ [y.full]: 0
81
84
  };
82
85
  Object.keys(Z).reduce(
83
86
  (t, n) => {
@@ -87,95 +90,95 @@ Object.keys(Z).reduce(
87
90
  {}
88
91
  );
89
92
  const rt = "!";
90
- var St = Object.defineProperty, _t = (t, n, e) => n in t ? St(t, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[n] = e, Lt = (t, n, e) => _t(t, typeof n != "symbol" ? n + "" : n, e), J = {}, j = {};
91
- Object.defineProperty(j, "__esModule", { value: !0 });
92
- function Vt(t) {
93
+ var Nt = Object.defineProperty, _t = (t, n, e) => n in t ? Nt(t, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[n] = e, Dt = (t, n, e) => _t(t, typeof n != "symbol" ? n + "" : n, e), J = {}, z = {};
94
+ Object.defineProperty(z, "__esModule", { value: !0 });
95
+ function Lt(t) {
93
96
  return String.fromCharCode(parseInt(t.slice(1), 16));
94
97
  }
95
- function $t(t) {
96
- return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g, Vt));
98
+ function St(t) {
99
+ return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g, Lt));
97
100
  }
98
- j.encode = $t;
99
- function jt(t) {
101
+ z.encode = St;
102
+ function Vt(t) {
100
103
  return `%${`00${t.charCodeAt(0).toString(16)}`.slice(-2)}`;
101
104
  }
102
- function kt(t) {
103
- return decodeURIComponent(Array.from(atob(t), jt).join(""));
105
+ function $t(t) {
106
+ return decodeURIComponent(Array.from(atob(t), Vt).join(""));
104
107
  }
105
- j.decode = kt;
108
+ z.decode = $t;
106
109
  Object.defineProperty(J, "__esModule", { value: !0 });
107
- const ot = j;
108
- function zt(t) {
110
+ const ot = z;
111
+ function jt(t) {
109
112
  return ot.decode(t.replace(/\-/g, "+").replace(/_/g, "/"));
110
113
  }
111
- var Bt = J.decode = zt;
112
- function Mt(t) {
114
+ var kt = J.decode = jt;
115
+ function Wt(t) {
113
116
  return ot.encode(t).replace(/\//g, "_").replace(/\+/g, "-").replace(/=+$/, "");
114
117
  }
115
- var Wt = J.encode = Mt;
116
- const Gt = (t) => t.filter(Boolean), Q = (t) => {
118
+ var zt = J.encode = Wt;
119
+ const Bt = (t) => t.filter(Boolean), Q = (t) => {
117
120
  try {
118
121
  return new URL(t);
119
122
  } catch {
120
123
  return null;
121
124
  }
122
- }, k = (t = "") => /^[A-Za-z0-9_-]*$/.test(t), Ft = (t) => {
125
+ }, B = (t = "") => /^[A-Za-z0-9_-]*$/.test(t), Mt = (t) => {
123
126
  const { altText: n, bcc: e, blurhash: o, blurhashX: i, blurhashY: r, sourceHeight: s, sourceWidth: u, url: c } = t;
124
127
  if (!c || !u || !s)
125
128
  return new Error("Cannot construct visionary code: missing required url/width/height");
126
129
  const a = [c, u, s];
127
- return !e || (a.push(e), !o || !i || !r) || (a.push(o, i, r), n && n.length && a.push(n)), Ht(a);
128
- }, Ht = (t) => Wt(t.join(rt)), st = (t) => {
130
+ return !e || (a.push(e), !o || !i || !r) || (a.push(o, i, r), n && n.length && a.push(n)), Gt(a);
131
+ }, Gt = (t) => zt(t.join(rt)), st = (t) => {
129
132
  if (typeof t != "string")
130
133
  return null;
131
134
  const n = t.trim();
132
- if (!n.length || !k(n))
135
+ if (!n.length || !B(n))
133
136
  return null;
134
- const e = Bt(n);
137
+ const e = kt(n);
135
138
  if (!e)
136
139
  return null;
137
140
  const o = e.split(rt);
138
141
  if (o.length < 3)
139
142
  return null;
140
- const [i, r, s, u, c, a, p, l] = o, m = i.trim();
141
- if (!m.length)
143
+ const [i, r, s, u, c, a, p, l] = o, g = i.trim();
144
+ if (!g.length)
142
145
  return console.error("Cannot parse code, empty file id"), null;
143
- const h = Number(r.trim()), d = Number(s.trim());
144
- if (isNaN(h) || isNaN(d) || !h || !d)
146
+ const m = Number(r.trim()), d = Number(s.trim());
147
+ if (isNaN(m) || isNaN(d) || !m || !d)
145
148
  return console.error("Cannot parse Visionary Code: invalid image dimensions", r, s), null;
146
- const v = Number(a) ?? 0, b = Number(p) ?? 0;
147
- return v < 1 || b < 1 ? (console.error(
149
+ const w = Number(a) ?? 0, v = Number(p) ?? 0;
150
+ return w < 1 || v < 1 ? (console.error(
148
151
  "Cannot parse Visionary Code: invalid blurhash x, y component dimensions",
149
- v,
150
- b
152
+ w,
153
+ v
151
154
  ), null) : {
152
155
  altText: l,
153
156
  bcc: u,
154
157
  blurhash: c,
155
- blurhashX: v,
156
- blurhashY: b,
158
+ blurhashX: w,
159
+ blurhashY: v,
157
160
  sourceHeight: d,
158
- sourceWidth: h,
159
- url: m
161
+ sourceWidth: m,
162
+ url: g
160
163
  };
161
164
  };
162
- class Xt extends Error {
165
+ class Ft extends Error {
163
166
  constructor() {
164
- super(...arguments), Lt(this, "message", "invalid endpoint URL (does it contain http/https?)");
167
+ super(...arguments), Dt(this, "message", "invalid endpoint URL (does it contain http/https?)");
165
168
  }
166
169
  }
167
- const Yt = (t) => t === D.DEBUG, Zt = (t) => t === D.DOWNLOAD, qt = (t) => Object.values($).includes(t), ct = (t) => Object.values(w).includes(t), Jt = (t = []) => {
170
+ const Ht = (t) => t === N.DEBUG, Xt = (t) => t === N.DOWNLOAD, Yt = (t) => Object.values(W).includes(t), ct = (t) => Object.values(y).includes(t), Zt = (t = []) => {
168
171
  const n = {};
169
172
  for (const e of t)
170
- ct(e) ? n.size = w[e] : Yt(e) ? n.debug = !0 : Zt(e) ? n.download = !0 : qt(e) && (n.format = e);
173
+ ct(e) ? n.size = y[e] : Ht(e) ? n.debug = !0 : Xt(e) ? n.download = !0 : Yt(e) && (n.format = e);
171
174
  return n;
172
- }, Kt = (t) => {
175
+ }, qt = (t) => {
173
176
  if (!t || typeof t != "object")
174
177
  return null;
175
178
  const n = [];
176
- return t.debug && n.push(D.DEBUG), t.download && n.push(D.DOWNLOAD), t.format && t.format !== $.AUTO && n.push(t.format), t.size && ct(t.size) && n.push(t.size), n.length ? n.sort().join(",") : null;
177
- }, Qt = (t) => {
178
- if (k(t)) {
179
+ return t.debug && n.push(N.DEBUG), t.download && n.push(N.DOWNLOAD), t.format && t.format !== W.AUTO && n.push(t.format), t.size && ct(t.size) && n.push(t.size), n.length ? n.sort().join(",") : null;
180
+ }, Jt = (t) => {
181
+ if (B(t)) {
179
182
  const n = st(t);
180
183
  if (n)
181
184
  return {
@@ -183,21 +186,21 @@ const Yt = (t) => t === D.DEBUG, Zt = (t) => t === D.DOWNLOAD, qt = (t) => Objec
183
186
  options: {}
184
187
  };
185
188
  }
186
- return tn(t);
187
- }, tn = (t) => {
189
+ return Kt(t);
190
+ }, Kt = (t) => {
188
191
  if (!t)
189
192
  return null;
190
193
  const n = t.trim();
191
194
  if (!n)
192
195
  return null;
193
196
  try {
194
- const e = en(n);
197
+ const e = tn(n);
195
198
  if (!e)
196
199
  return null;
197
200
  const { code: o, optionTokens: i } = e, r = st(o);
198
201
  if (!r)
199
202
  return null;
200
- const s = Jt(i);
203
+ const s = Zt(i);
201
204
  return {
202
205
  fields: r,
203
206
  options: s
@@ -206,25 +209,25 @@ const Yt = (t) => t === D.DEBUG, Zt = (t) => t === D.DOWNLOAD, qt = (t) => Objec
206
209
  e instanceof Error ? console.error(`Error parsing URL: ${e.message}`, e) : console.error("uncaught error", e);
207
210
  }
208
211
  return null;
209
- }, nn = (t, n) => {
210
- const e = Ft(t);
212
+ }, Qt = (t, n) => {
213
+ const e = Mt(t);
211
214
  if (e instanceof Error)
212
215
  return null;
213
216
  let o = null;
214
217
  if (n != null && n.endpoint && (o = Q(n == null ? void 0 : n.endpoint), !o))
215
- throw new Xt(
218
+ throw new Ft(
216
219
  "Cannot construct URL: bad endpoint. Ensure endpoint starts with http:// or https://"
217
220
  );
218
- o || (o = Q(Pt));
219
- const i = [o.origin, "image", e], r = n ? Kt(n) : null;
221
+ o || (o = Q(Ct));
222
+ const i = [o.origin, "image", e], r = n ? qt(n) : null;
220
223
  return r && i.push(r), n != null && n.filename ? i.push(n.filename) : i.push("image.jpg"), i.join("/");
221
- }, en = (t) => {
224
+ }, tn = (t) => {
222
225
  try {
223
- const n = new URL(t), e = Gt(n.pathname.split("/"));
226
+ const n = new URL(t), e = Bt(n.pathname.split("/"));
224
227
  if (e[0] !== "image" || ![3, 4].includes(e.length))
225
228
  throw new Error("Unrecognized URL");
226
229
  const o = e[1].trim();
227
- if (!o.length || !k(o))
230
+ if (!o.length || !B(o))
228
231
  throw new Error("URL is not formatted as base64url");
229
232
  if (e.length === 4) {
230
233
  const i = e[2].split(",");
@@ -242,117 +245,119 @@ const Yt = (t) => t === D.DEBUG, Zt = (t) => t === D.DOWNLOAD, qt = (t) => Objec
242
245
  return null;
243
246
  }
244
247
  return null;
245
- }, it = 0.7, at = 1, U = 24, rn = w.lg, lt = process.env.NODE_ENV, on = lt === "development", ut = typeof document > "u", sn = lt === "test", cn = ut ? () => {
246
- } : Rt, an = "<visionary>", x = (t, ...n) => {
247
- !console || typeof console.log != "function" || console.log(`${an} ${t}`, ...n);
248
+ }, it = 0.7, at = 1, T = 24, nn = y.lg, lt = process.env.NODE_ENV, en = lt === "development", ut = typeof document > "u", rn = lt === "test", k = (t) => {
249
+ try {
250
+ return new URL(t);
251
+ } catch {
252
+ return null;
253
+ }
254
+ }, on = (t, n) => `rgba(${t.r},${t.g},${t.b},${n})`, $ = (t) => en || rn ? {
255
+ "data-testid": t
256
+ } : {}, sn = (t, n) => n ? {
257
+ "data-fileid": t
258
+ } : {}, tt = (t, n) => Math.min(t, n), cn = (t) => {
259
+ let n = t.replace(/^#/, "");
260
+ if (n.length !== 3 && n.length !== 6)
261
+ return null;
262
+ n.length === 3 && (n = `${n[0]}${n[0]}${n[1]}${n[1]}${n[2]}${n[2]}`);
263
+ const e = parseInt(n.slice(0, 2), 16), o = parseInt(n.slice(2, 4), 16);
264
+ return { b: parseInt(n.slice(4, 6), 16), g: o, r: e };
265
+ }, E = (t, n = 0) => {
266
+ const e = Math.pow(10, n);
267
+ return Math.round(t * e) / e;
268
+ }, an = (t, n) => {
269
+ const e = k(t), o = k(n);
270
+ return !e || !o ? t : (o.pathname = e.pathname, o.search = e.search, o.toString());
271
+ }, ln = {
272
+ overflow: "hidden"
273
+ }, un = ({ aspectRatio: t, children: n }) => /* @__PURE__ */ U("div", { style: { aspectRatio: t, ...ln }, ...$(V.ASPECT_RATIO_WRAPPER), children: n }), dn = ut ? () => {
274
+ } : It, fn = "<visionary>", x = (t, ...n) => {
275
+ !console || typeof console.log != "function" || console.log(`${fn} ${t}`, ...n);
248
276
  }, dt = new Uint8Array(128);
249
277
  for (let t = 0; t < 83; t++)
250
278
  dt["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(
251
279
  t
252
280
  )] = t;
253
- const L = (t, n, e) => {
281
+ const j = (t, n, e) => {
254
282
  let o = 0;
255
283
  for (; n < e; )
256
284
  o *= 83, o += dt[t.charCodeAt(n++)];
257
285
  return o;
258
- }, ft = Math.pow, P = Math.PI, ln = P * 2, pt = 3294.6, ht = 269.025, un = (t) => t > 10.31475 ? ft(t / ht + 0.052132, 2.4) : t / pt, G = (t) => ~~(t > 1227e-8 ? ht * ft(t, 0.416666) - 13.025 : t * pt + 1), C = (t) => (t < 0 ? -1 : 1) * t * t, tt = (t) => {
259
- for (t += P / 2; t > P; )
260
- t -= ln;
286
+ }, ft = Math.pow, _ = Math.PI, pn = _ * 2, pt = 3294.6, ht = 269.025, hn = (t) => t > 10.31475 ? ft(t / ht + 0.052132, 2.4) : t / pt, H = (t) => ~~(t > 1227e-8 ? ht * ft(t, 0.416666) - 13.025 : t * pt + 1), C = (t) => (t < 0 ? -1 : 1) * t * t, nt = (t) => {
287
+ for (t += _ / 2; t > _; )
288
+ t -= pn;
261
289
  const n = 1.27323954 * t - 0.405284735 * C(t);
262
290
  return 0.225 * (C(n) - n) + n;
263
291
  };
264
- function dn(t) {
265
- const n = L(t, 2, 6);
292
+ function mn(t) {
293
+ const n = j(t, 2, 6);
266
294
  return [n >> 16, n >> 8 & 255, n & 255];
267
295
  }
268
- function fn(t, n, e, o) {
269
- const i = L(t, 0, 1), r = i % 9 + 1, s = ~~(i / 9) + 1, u = r * s;
270
- let c = 0, a = 0, p = 0, l = 0, m = 0, h = 0, d = 0, v = 0, b = 0, g = 0, y = 0, E = 0;
271
- const f = (L(t, 1, 2) + 1) / 13446 * (o | 1), I = new Float64Array(u * 3), z = dn(t);
296
+ function gn(t, n, e, o) {
297
+ const i = j(t, 0, 1), r = i % 9 + 1, s = ~~(i / 9) + 1, u = r * s;
298
+ let c = 0, a = 0, p = 0, l = 0, g = 0, m = 0, d = 0, w = 0, v = 0, b = 0, h = 0, A = 0;
299
+ const f = (j(t, 1, 2) + 1) / 13446 * (o | 1), R = new Float64Array(u * 3), M = mn(t);
272
300
  for (c = 0; c < 3; c++)
273
- I[c] = un(z[c]);
301
+ R[c] = hn(M[c]);
274
302
  for (c = 1; c < u; c++)
275
- E = L(t, 4 + c * 2, 6 + c * 2), I[c * 3] = C(~~(E / 361) - 9) * f, I[c * 3 + 1] = C(~~(E / 19) % 19 - 9) * f, I[c * 3 + 2] = C(E % 19 - 9) * f;
276
- const S = new Float64Array(s * e), _ = new Float64Array(r * n);
303
+ A = j(t, 4 + c * 2, 6 + c * 2), R[c * 3] = C(~~(A / 361) - 9) * f, R[c * 3 + 1] = C(~~(A / 19) % 19 - 9) * f, R[c * 3 + 2] = C(A % 19 - 9) * f;
304
+ const D = new Float64Array(s * e), L = new Float64Array(r * n);
277
305
  for (a = 0; a < s; a++)
278
306
  for (l = 0; l < e; l++)
279
- S[a * e + l] = tt(P * l * a / e);
307
+ D[a * e + l] = nt(_ * l * a / e);
280
308
  for (c = 0; c < r; c++)
281
309
  for (p = 0; p < n; p++)
282
- _[c * n + p] = tt(P * p * c / n);
283
- const N = n * 4, R = new Uint8ClampedArray(N * e);
310
+ L[c * n + p] = nt(_ * p * c / n);
311
+ const P = n * 4, I = new Uint8ClampedArray(P * e);
284
312
  for (l = 0; l < e; l++)
285
313
  for (p = 0; p < n; p++) {
286
- for (m = h = d = 0, a = 0; a < s; a++)
287
- for (b = S[a * e + l], c = 0; c < r; c++)
288
- v = _[c * n + p] * b, g = (c + a * r) * 3, m += I[g] * v, h += I[g + 1] * v, d += I[g + 2] * v;
289
- y = 4 * p + l * N, R[y] = G(m), R[y + 1] = G(h), R[y + 2] = G(d), R[y + 3] = 255;
314
+ for (g = m = d = 0, a = 0; a < s; a++)
315
+ for (v = D[a * e + l], c = 0; c < r; c++)
316
+ w = L[c * n + p] * v, b = (c + a * r) * 3, g += R[b] * w, m += R[b + 1] * w, d += R[b + 2] * w;
317
+ h = 4 * p + l * P, I[h] = H(g), I[h + 1] = H(m), I[h + 2] = H(d), I[h + 3] = 255;
290
318
  }
291
- return R;
319
+ return I;
292
320
  }
293
- const V = (t) => {
294
- try {
295
- return new URL(t);
296
- } catch {
297
- return null;
298
- }
299
- }, pn = (t, n) => `rgba(${t.r},${t.g},${t.b},${n})`, F = (t) => on || sn ? {
300
- "data-testid": t
301
- } : {}, hn = (t, n) => n ? {
302
- "data-fileid": t
303
- } : {}, nt = (t, n) => Math.min(t, n), mn = (t) => {
304
- let n = t.replace(/^#/, "");
305
- if (n.length !== 3 && n.length !== 6)
306
- return null;
307
- n.length === 3 && (n = `${n[0]}${n[0]}${n[1]}${n[1]}${n[2]}${n[2]}`);
308
- const e = parseInt(n.slice(0, 2), 16), o = parseInt(n.slice(2, 4), 16);
309
- return { b: parseInt(n.slice(4, 6), 16), g: o, r: e };
310
- }, A = (t, n = 0) => {
311
- const e = Math.pow(10, n);
312
- return Math.round(t * e) / e;
313
- }, gn = (t, n) => {
314
- const e = V(t), o = V(n);
315
- return !e || !o ? t : (o.pathname = e.pathname, o.search = e.search, o.toString());
316
- }, bn = (t, n = {}, e = it, o = at) => {
321
+ const bn = (t, n = {}, e = it, o = at) => {
317
322
  if (!t)
318
323
  return null;
319
324
  try {
320
325
  n.debug && x("input imageSrc:", t);
321
- const i = Qt(t);
326
+ const i = Jt(t);
322
327
  if (n.debug && x("Visionary URL data: ", i), !i)
323
328
  throw new Error("Could not parse Visionary URL");
324
329
  const { fields: r, options: s } = i;
325
330
  if (r.sourceWidth < 1 || r.sourceHeight < 1)
326
331
  throw new Error("Invalid image dimensions");
327
- const u = r.sourceWidth / r.sourceHeight, c = (n == null ? void 0 : n.size) ?? s.size ?? rn, a = Z[c];
328
- let p = 0, l = 0, m = 0;
332
+ const u = r.sourceWidth / r.sourceHeight, c = (n == null ? void 0 : n.size) ?? s.size ?? nn, a = Z[c];
333
+ let p = 0, l = 0, g = 0;
329
334
  if (u >= 1) {
330
- l = p = nt(a, r.sourceWidth);
331
- const g = A(l / u);
332
- m = A(l / g, 6);
335
+ l = p = tt(a, r.sourceWidth);
336
+ const b = E(l / u);
337
+ g = E(l / b, 6);
333
338
  } else
334
- p = nt(a, r.sourceHeight), l = A(p * u), m = A(l / p, 6);
335
- const h = A(100 / m, 6), d = {
339
+ p = tt(a, r.sourceHeight), l = E(p * u), g = E(l / p, 6);
340
+ const m = E(100 / g, 6), d = {
336
341
  ...r,
337
- arPaddingTop: `${h}%`,
338
- aspectRatio: m,
342
+ arPaddingTop: `${m}%`,
343
+ aspectRatio: g,
339
344
  maxWidth: l,
340
345
  src: t
341
- }, v = V(r.url);
342
- if (v)
343
- d.src = v.toString();
344
- else if (!V(t) && k(r.url)) {
345
- const g = nn(r, {
346
+ }, w = k(r.url);
347
+ if (w)
348
+ d.src = w.toString();
349
+ else if (!k(t) && B(r.url)) {
350
+ const b = Qt(r, {
346
351
  endpoint: n.endpoint,
347
352
  size: c
348
353
  });
349
- g && (d.src = g);
354
+ b && (d.src = b);
350
355
  }
351
- n.endpoint && (d.src = gn(d.src, n.endpoint));
352
- const b = r.bcc ? mn(r.bcc) : null;
353
- if (b && (d.backgroundColor = pn(b, e)), !ut && r.blurhash && !n.disableBlurLayer) {
354
- const g = performance.now(), y = fn(r.blurhash, U, U, o), E = performance.now() - g;
355
- n.debug && x(`Blurhash decode time: ${A(E, 1)} ms`), y && (d.pixels = y);
356
+ n.endpoint && (d.src = an(d.src, n.endpoint));
357
+ const v = r.bcc ? cn(r.bcc) : null;
358
+ if (v && (d.backgroundColor = on(v, e)), !ut && r.blurhash && !n.disableBlurLayer) {
359
+ const b = performance.now(), h = gn(r.blurhash, T, T, o), A = performance.now() - b;
360
+ n.debug && x(`Blurhash decode time: ${E(A, 1)} ms`), h && (d.pixels = h);
356
361
  }
357
362
  return n.debug && x("Visionary Image state: ", d), d;
358
363
  } catch {
@@ -368,23 +373,19 @@ const V = (t) => {
368
373
  ...mt,
369
374
  maxHeight: "100%",
370
375
  maxWidth: "100%"
371
- }, yn = {
376
+ }, wn = {
372
377
  ...mt,
373
378
  height: "100%",
374
379
  width: "100%"
375
- }, wn = (t) => {
380
+ }, yn = (t) => {
376
381
  const n = {
377
382
  ...vn
378
383
  };
379
384
  return t && (n.display = "none"), n;
380
- }, H = {
381
- CANVAS: "canvas",
382
- CONTAINER: "container",
383
- IMAGE: "image"
384
- }, In = "v7y_7587", En = "v7y_b8c0", Rn = "v7y_e0dd", X = {
385
- container: In,
386
- preventDrag: En,
387
- preventSelection: Rn
385
+ }, Rn = "v7y_7587", An = "v7y_b8c0", In = "v7y_e0dd", X = {
386
+ container: Rn,
387
+ preventDrag: An,
388
+ preventSelection: In
388
389
  }, On = ({
389
390
  alt: t,
390
391
  bgColorAlpha: n = it,
@@ -398,114 +399,114 @@ const V = (t) => {
398
399
  lazy: a = !0,
399
400
  onClick: p,
400
401
  onError: l,
401
- onLoad: m,
402
- preventDrag: h = !1,
402
+ onLoad: g,
403
+ preventDrag: m = !1,
403
404
  preventSelection: d = !1,
404
- punch: v = at,
405
- size: b,
406
- src: g,
407
- style: y,
408
- width: E
405
+ punch: w = at,
406
+ size: v,
407
+ src: b,
408
+ style: h,
409
+ width: A
409
410
  }) => {
410
- const f = At(() => bn(g, {
411
+ const f = Et(() => bn(b, {
411
412
  debug: o,
412
413
  disableBlurLayer: i,
413
414
  endpoint: s,
414
- size: b
415
- }, n, v), [n, o, i, s, v, b, g]), I = Y(null), [z, S] = Tt();
416
- cn(
415
+ size: v
416
+ }, n, w), [n, o, i, s, w, v, b]), R = Y(null), [M, D] = Ut();
417
+ dn(
417
418
  function() {
418
- if (!I.current || !(f != null && f.blurhash))
419
+ if (!R.current || !(f != null && f.blurhash))
419
420
  return;
420
421
  if (!f.pixels) {
421
422
  console.warn("No pixel data passed in, skipping");
422
423
  return;
423
424
  }
424
- const vt = performance.now(), M = I.current.getContext("2d");
425
- if (!M) {
425
+ const vt = performance.now(), G = R.current.getContext("2d");
426
+ if (!G) {
426
427
  console.warn("Cannot access canvasRenderingContext, skipping");
427
428
  return;
428
429
  }
429
- const W = M.createImageData(U, U);
430
- if (!W) {
430
+ const F = G.createImageData(T, T);
431
+ if (!F) {
431
432
  console.warn("Could not create ImageData on CanvasRenderingContext");
432
433
  return;
433
434
  }
434
- if (W.data.set(f.pixels), M.putImageData(W, 0, 0), o) {
435
- const yt = performance.now() - vt;
436
- x(`Canvas render time: ${A(yt, 1)} ms`);
435
+ if (F.data.set(f.pixels), G.putImageData(F, 0, 0), o) {
436
+ const wt = performance.now() - vt;
437
+ x(`Canvas render time: ${E(wt, 1)} ms`);
437
438
  }
438
439
  },
439
440
  [f == null ? void 0 : f.blurhash, f == null ? void 0 : f.pixels, o]
440
441
  );
441
- const _ = q(
442
+ const L = q(
442
443
  (O) => {
443
444
  o && x("Image load error ", O), l && l();
444
445
  },
445
446
  [o, l]
446
- ), N = {
447
+ ), P = {
447
448
  alt: t,
448
- loading: !a || S ? "eager" : "lazy",
449
- onLoad: m
449
+ loading: !a || D ? "eager" : "lazy",
450
+ onLoad: g
450
451
  };
451
452
  if (!f) {
452
453
  o && x("Not a Visionary URL, rendering fallback <img />");
453
454
  const O = {
454
- ...N,
455
+ ...P,
455
456
  className: e,
456
457
  height: u,
457
458
  onClick: p,
458
459
  onError: l,
459
- src: g,
460
- style: y,
461
- width: E
460
+ src: b,
461
+ style: h,
462
+ width: A
462
463
  };
463
- return /* @__PURE__ */ T("img", { ...O });
464
+ return /* @__PURE__ */ U("img", { ...O });
464
465
  }
465
- const R = Nt(X.container, e, {
466
- [X.preventDrag]: !!h,
466
+ const I = Pt(X.container, e, {
467
+ [X.preventDrag]: !!m,
467
468
  [X.preventSelection]: !!d
468
- }), B = {
469
+ }), S = {
469
470
  ...{
470
471
  "--v-ar": f.arPaddingTop
471
472
  },
472
- ...y,
473
+ ...h,
473
474
  aspectRatio: f.aspectRatio,
474
475
  backgroundColor: (f == null ? void 0 : f.backgroundColor) ?? void 0,
475
476
  maxWidth: f.maxWidth,
476
477
  position: "relative",
477
478
  width: "100%"
478
479
  };
479
- E && (B.width = E), u && (B.height = u);
480
+ A && (S.width = A), u && (S.height = u), h != null && h.maxWidth && (S.maxWidth = h.maxWidth);
480
481
  const gt = {
481
482
  onClick: p
482
- }, bt = wn(c), K = /* @__PURE__ */ wt(
483
+ }, bt = yn(c), K = /* @__PURE__ */ yt(
483
484
  "div",
484
485
  {
485
- className: R,
486
- ref: z,
487
- style: B,
488
- ...hn(f.url, o),
489
- ...F(H.CONTAINER),
486
+ className: I,
487
+ ref: M,
488
+ style: S,
489
+ ...sn(f.url, o),
490
+ ...$(V.CONTAINER),
490
491
  ...gt,
491
492
  children: [
492
- !i && /* @__PURE__ */ T(
493
+ !i && /* @__PURE__ */ U(
493
494
  "canvas",
494
495
  {
495
- height: U,
496
- ref: I,
497
- style: yn,
498
- width: U,
499
- ...F(H.CANVAS)
496
+ height: T,
497
+ ref: R,
498
+ style: wn,
499
+ width: T,
500
+ ...$(V.CANVAS)
500
501
  }
501
502
  ),
502
503
  !r && // eslint-disable-next-line jsx-a11y/alt-text -- `sharedImgProps` includes alt tag
503
- /* @__PURE__ */ T(
504
+ /* @__PURE__ */ U(
504
505
  "img",
505
506
  {
506
- ...N,
507
- ...F(H.IMAGE),
508
- onError: _,
507
+ ...P,
508
+ ...$(V.IMAGE),
509
+ onError: L,
509
510
  src: f.src,
510
511
  style: bt
511
512
  }
@@ -513,7 +514,7 @@ const V = (t) => {
513
514
  ]
514
515
  }
515
516
  );
516
- return y != null && y.aspectRatio ? /* @__PURE__ */ T(Dt, { aspectRatio: y.aspectRatio, children: K }) : K;
517
+ return h != null && h.aspectRatio ? /* @__PURE__ */ U(un, { aspectRatio: h.aspectRatio, children: K }) : K;
517
518
  };
518
519
  export {
519
520
  On as Image
@@ -1,6 +1,6 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.id="v7y-styles",e.appendChild(document.createTextNode('.v7y_7587:before{content:"";display:block;padding-top:var(--v-ar)}.v7y_b8c0{-webkit-user-drag:none;pointer-events:none}.v7y_e0dd{-webkit-user-select:none;user-select:none}')),document.head.appendChild(e)}}catch(n){console.error("vite-plugin-css-injected-by-js",n)}})();
2
- (function(R,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],x):(R=typeof globalThis<"u"?globalThis:R||self,x(R.VisionaryImage={},R.jsxRuntime,R.React))})(this,function(R,x,E){"use strict";function gt(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var K={exports:{}};/*!
2
+ (function(E,A){typeof exports=="object"&&typeof module<"u"?A(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],A):(E=typeof globalThis<"u"?globalThis:E||self,A(E.VisionaryImage={},E.jsxRuntime,E.React))})(this,function(E,A,R){"use strict";function gt(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var K={exports:{}};/*!
3
3
  Copyright (c) 2018 Jed Watson.
4
4
  Licensed under the MIT License (MIT), see
5
5
  http://jedwatson.github.io/classnames
6
- */(function(t){(function(){var e={}.hasOwnProperty;function n(){for(var r="",s=0;s<arguments.length;s++){var u=arguments[s];u&&(r=i(r,o(u)))}return r}function o(r){if(typeof r=="string"||typeof r=="number")return r;if(typeof r!="object")return"";if(Array.isArray(r))return n.apply(null,r);if(r.toString!==Object.prototype.toString&&!r.toString.toString().includes("[native code]"))return r.toString();var s="";for(var u in r)e.call(r,u)&&r[u]&&(s=i(s,u));return s}function i(r,s){return s?r?r+" "+s:r+s:r}t.exports?(n.default=n,t.exports=n):window.classNames=n})()})(K);var bt=K.exports;const vt=gt(bt),yt=(t,{root:e,rootMargin:n,threshold:o}={},i=[])=>{const r=E.useRef(null),s=E.useRef(null);return E.useCallback(c=>{r.current&&s.current&&(s.current.unobserve(r.current),s.current.disconnect(),s.current=null),c&&(s.current=new IntersectionObserver(t,{root:e,rootMargin:n,threshold:o}),s.current.observe(c),r.current=c)},[r,e,n,JSON.stringify(o),...i])},wt=({root:t,rootMargin:e,threshold:n,unobserveOnEnter:o,target:i,onEnter:r,onLeave:s,defaultInView:u}={},c=[])=>{const[a,p]=E.useState({inView:u||!1,entry:null,observer:null}),l=E.useCallback(([h],f)=>{const b=f.thresholds.some(g=>h.intersectionRatio>=g)&&h.isIntersecting;p({inView:b,entry:h,observer:f}),b&&o&&(f.unobserve(h.target),f.disconnect()),b?r==null||r(h,f):s==null||s(h,f)},[r,s,o]),m=yt(l,{root:t,rootMargin:e,threshold:n},[o,...c]);return E.useEffect(()=>{i!=null&&i.current&&m(i.current)},[i,m]),[m,a.inView,a.entry,a.observer]},It={overflow:"hidden"},xt=({aspectRatio:t,children:e})=>x.jsx("div",{style:{aspectRatio:t,...It},children:e});var j=(t=>(t.AUTO="auto",t.AVIF="avif",t.JPEG="jpeg",t.WEBP="webp",t))(j||{}),w=(t=>(t.xs="xs",t.sm="sm",t.md="md",t.lg="lg",t.xl="xl",t.xxl="xxl",t["4k"]="4k",t["5k"]="5k",t.full="full",t))(w||{}),O=(t=>(t.DEBUG="debug",t.DOWNLOAD="download",t))(O||{});const Et="https://link.visionary.cloud";j.AUTO,w.lg;const M={[w.xs]:160,[w.sm]:320,[w.md]:640,[w.lg]:1280,[w.xl]:1920,[w.xxl]:2560,[w["4k"]]:3840,[w["5k"]]:5120,[w.full]:0};Object.keys(M).reduce((t,e)=>{const n=e,o=M[n];return o&&(t[o]=n),t},{});const Q="!";var At=Object.defineProperty,Rt=(t,e,n)=>e in t?At(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,Tt=(t,e,n)=>Rt(t,typeof e!="symbol"?e+"":e,n),W={},V={};Object.defineProperty(V,"__esModule",{value:!0});function Ut(t){return String.fromCharCode(parseInt(t.slice(1),16))}function Ct(t){return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g,Ut))}V.encode=Ct;function Nt(t){return`%${`00${t.charCodeAt(0).toString(16)}`.slice(-2)}`}function Ot(t){return decodeURIComponent(Array.from(atob(t),Nt).join(""))}V.decode=Ot,Object.defineProperty(W,"__esModule",{value:!0});const tt=V;function St(t){return tt.decode(t.replace(/\-/g,"+").replace(/_/g,"/"))}var Dt=W.decode=St;function Pt(t){return tt.encode(t).replace(/\//g,"_").replace(/\+/g,"-").replace(/=+$/,"")}var _t=W.encode=Pt;const jt=t=>t.filter(Boolean),et=t=>{try{return new URL(t)}catch{return null}},L=(t="")=>/^[A-Za-z0-9_-]*$/.test(t),Vt=t=>{const{altText:e,bcc:n,blurhash:o,blurhashX:i,blurhashY:r,sourceHeight:s,sourceWidth:u,url:c}=t;if(!c||!u||!s)return new Error("Cannot construct visionary code: missing required url/width/height");const a=[c,u,s];return!n||(a.push(n),!o||!i||!r)||(a.push(o,i,r),e&&e.length&&a.push(e)),Lt(a)},Lt=t=>_t(t.join(Q)),nt=t=>{if(typeof t!="string")return null;const e=t.trim();if(!e.length||!L(e))return null;const n=Dt(e);if(!n)return null;const o=n.split(Q);if(o.length<3)return null;const[i,r,s,u,c,a,p,l]=o,m=i.trim();if(!m.length)return console.error("Cannot parse code, empty file id"),null;const h=Number(r.trim()),f=Number(s.trim());if(isNaN(h)||isNaN(f)||!h||!f)return console.error("Cannot parse Visionary Code: invalid image dimensions",r,s),null;const v=Number(a)??0,b=Number(p)??0;return v<1||b<1?(console.error("Cannot parse Visionary Code: invalid blurhash x, y component dimensions",v,b),null):{altText:l,bcc:u,blurhash:c,blurhashX:v,blurhashY:b,sourceHeight:f,sourceWidth:h,url:m}};class $t extends Error{constructor(){super(...arguments),Tt(this,"message","invalid endpoint URL (does it contain http/https?)")}}const kt=t=>t===O.DEBUG,zt=t=>t===O.DOWNLOAD,Bt=t=>Object.values(j).includes(t),rt=t=>Object.values(w).includes(t),Mt=(t=[])=>{const e={};for(const n of t)rt(n)?e.size=w[n]:kt(n)?e.debug=!0:zt(n)?e.download=!0:Bt(n)&&(e.format=n);return e},Wt=t=>{if(!t||typeof t!="object")return null;const e=[];return t.debug&&e.push(O.DEBUG),t.download&&e.push(O.DOWNLOAD),t.format&&t.format!==j.AUTO&&e.push(t.format),t.size&&rt(t.size)&&e.push(t.size),e.length?e.sort().join(","):null},Gt=t=>{if(L(t)){const e=nt(t);if(e)return{fields:e,options:{}}}return Ft(t)},Ft=t=>{if(!t)return null;const e=t.trim();if(!e)return null;try{const n=Xt(e);if(!n)return null;const{code:o,optionTokens:i}=n,r=nt(o);if(!r)return null;const s=Mt(i);return{fields:r,options:s}}catch(n){n instanceof Error?console.error(`Error parsing URL: ${n.message}`,n):console.error("uncaught error",n)}return null},Ht=(t,e)=>{const n=Vt(t);if(n instanceof Error)return null;let o=null;if(e!=null&&e.endpoint&&(o=et(e==null?void 0:e.endpoint),!o))throw new $t("Cannot construct URL: bad endpoint. Ensure endpoint starts with http:// or https://");o||(o=et(Et));const i=[o.origin,"image",n],r=e?Wt(e):null;return r&&i.push(r),e!=null&&e.filename?i.push(e.filename):i.push("image.jpg"),i.join("/")},Xt=t=>{try{const e=new URL(t),n=jt(e.pathname.split("/"));if(n[0]!=="image"||![3,4].includes(n.length))throw new Error("Unrecognized URL");const o=n[1].trim();if(!o.length||!L(o))throw new Error("URL is not formatted as base64url");if(n.length===4){const i=n[2].split(",");return{code:o,optionTokens:i}}if(n.length===3)return{code:o,optionTokens:[]}}catch{return null}return null},ot=.7,st=1,N=24,Yt=w.lg,ct=process.env.NODE_ENV,qt=ct==="development",it=typeof document>"u",Zt=ct==="test",Jt=it?()=>{}:E.useLayoutEffect,Kt="<visionary>",T=(t,...e)=>{!console||typeof console.log!="function"||console.log(`${Kt} ${t}`,...e)},at=new Uint8Array(128);for(let t=0;t<83;t++)at["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(t)]=t;const $=(t,e,n)=>{let o=0;for(;e<n;)o*=83,o+=at[t.charCodeAt(e++)];return o},lt=Math.pow,S=Math.PI,Qt=S*2,ut=3294.6,ft=269.025,te=t=>t>10.31475?lt(t/ft+.052132,2.4):t/ut,G=t=>~~(t>1227e-8?ft*lt(t,.416666)-13.025:t*ut+1),D=t=>(t<0?-1:1)*t*t,dt=t=>{for(t+=S/2;t>S;)t-=Qt;const e=1.27323954*t-.405284735*D(t);return .225*(D(e)-e)+e};function ee(t){const e=$(t,2,6);return[e>>16,e>>8&255,e&255]}function ne(t,e,n,o){const i=$(t,0,1),r=i%9+1,s=~~(i/9)+1,u=r*s;let c=0,a=0,p=0,l=0,m=0,h=0,f=0,v=0,b=0,g=0,y=0,A=0;const d=($(t,1,2)+1)/13446*(o|1),I=new Float64Array(u*3),Y=ee(t);for(c=0;c<3;c++)I[c]=te(Y[c]);for(c=1;c<u;c++)A=$(t,4+c*2,6+c*2),I[c*3]=D(~~(A/361)-9)*d,I[c*3+1]=D(~~(A/19)%19-9)*d,I[c*3+2]=D(A%19-9)*d;const z=new Float64Array(s*n),B=new Float64Array(r*e);for(a=0;a<s;a++)for(l=0;l<n;l++)z[a*n+l]=dt(S*l*a/n);for(c=0;c<r;c++)for(p=0;p<e;p++)B[c*e+p]=dt(S*p*c/e);const P=e*4,C=new Uint8ClampedArray(P*n);for(l=0;l<n;l++)for(p=0;p<e;p++){for(m=h=f=0,a=0;a<s;a++)for(b=z[a*n+l],c=0;c<r;c++)v=B[c*e+p]*b,g=(c+a*r)*3,m+=I[g]*v,h+=I[g+1]*v,f+=I[g+2]*v;y=4*p+l*P,C[y]=G(m),C[y+1]=G(h),C[y+2]=G(f),C[y+3]=255}return C}const k=t=>{try{return new URL(t)}catch{return null}},re=(t,e)=>`rgba(${t.r},${t.g},${t.b},${e})`,F=t=>qt||Zt?{"data-testid":t}:{},oe=(t,e)=>e?{"data-fileid":t}:{},pt=(t,e)=>Math.min(t,e),se=t=>{let e=t.replace(/^#/,"");if(e.length!==3&&e.length!==6)return null;e.length===3&&(e=`${e[0]}${e[0]}${e[1]}${e[1]}${e[2]}${e[2]}`);const n=parseInt(e.slice(0,2),16),o=parseInt(e.slice(2,4),16);return{b:parseInt(e.slice(4,6),16),g:o,r:n}},U=(t,e=0)=>{const n=Math.pow(10,e);return Math.round(t*n)/n},ce=(t,e)=>{const n=k(t),o=k(e);return!n||!o?t:(o.pathname=n.pathname,o.search=n.search,o.toString())},ie=(t,e={},n=ot,o=st)=>{if(!t)return null;try{e.debug&&T("input imageSrc:",t);const i=Gt(t);if(e.debug&&T("Visionary URL data: ",i),!i)throw new Error("Could not parse Visionary URL");const{fields:r,options:s}=i;if(r.sourceWidth<1||r.sourceHeight<1)throw new Error("Invalid image dimensions");const u=r.sourceWidth/r.sourceHeight,c=(e==null?void 0:e.size)??s.size??Yt,a=M[c];let p=0,l=0,m=0;if(u>=1){l=p=pt(a,r.sourceWidth);const g=U(l/u);m=U(l/g,6)}else p=pt(a,r.sourceHeight),l=U(p*u),m=U(l/p,6);const h=U(100/m,6),f={...r,arPaddingTop:`${h}%`,aspectRatio:m,maxWidth:l,src:t},v=k(r.url);if(v)f.src=v.toString();else if(!k(t)&&L(r.url)){const g=Ht(r,{endpoint:e.endpoint,size:c});g&&(f.src=g)}e.endpoint&&(f.src=ce(f.src,e.endpoint));const b=r.bcc?se(r.bcc):null;if(b&&(f.backgroundColor=re(b,n)),!it&&r.blurhash&&!e.disableBlurLayer){const g=performance.now(),y=ne(r.blurhash,N,N,o),A=performance.now()-g;e.debug&&T(`Blurhash decode time: ${U(A,1)} ms`),y&&(f.pixels=y)}return e.debug&&T("Visionary Image state: ",f),f}catch{return null}},ht={bottom:0,left:0,position:"absolute",right:0,top:0},ae={...ht,maxHeight:"100%",maxWidth:"100%"},le={...ht,height:"100%",width:"100%"},ue=t=>{const e={...ae};return t&&(e.display="none"),e},H={CANVAS:"canvas",CONTAINER:"container",IMAGE:"image"},X={container:"v7y_7587",preventDrag:"v7y_b8c0",preventSelection:"v7y_e0dd"},fe=({alt:t,bgColorAlpha:e=ot,className:n,debug:o=!1,disableBlurLayer:i=!1,disableImageLayer:r=!1,endpoint:s,height:u,hideImageLayer:c=!1,lazy:a=!0,onClick:p,onError:l,onLoad:m,preventDrag:h=!1,preventSelection:f=!1,punch:v=st,size:b,src:g,style:y,width:A})=>{const d=E.useMemo(()=>ie(g,{debug:o,disableBlurLayer:i,endpoint:s,size:b},e,v),[e,o,i,s,v,b,g]),I=E.useRef(null),[Y,z]=wt();Jt(function(){if(!I.current||!(d!=null&&d.blurhash))return;if(!d.pixels){console.warn("No pixel data passed in, skipping");return}const he=performance.now(),Z=I.current.getContext("2d");if(!Z){console.warn("Cannot access canvasRenderingContext, skipping");return}const J=Z.createImageData(N,N);if(!J){console.warn("Could not create ImageData on CanvasRenderingContext");return}if(J.data.set(d.pixels),Z.putImageData(J,0,0),o){const me=performance.now()-he;T(`Canvas render time: ${U(me,1)} ms`)}},[d==null?void 0:d.blurhash,d==null?void 0:d.pixels,o]);const B=E.useCallback(_=>{o&&T("Image load error ",_),l&&l()},[o,l]),P={alt:t,loading:!a||z?"eager":"lazy",onLoad:m};if(!d){o&&T("Not a Visionary URL, rendering fallback <img />");const _={...P,className:n,height:u,onClick:p,onError:l,src:g,style:y,width:A};return x.jsx("img",{..._})}const C=vt(X.container,n,{[X.preventDrag]:!!h,[X.preventSelection]:!!f}),q={...{"--v-ar":d.arPaddingTop},...y,aspectRatio:d.aspectRatio,backgroundColor:(d==null?void 0:d.backgroundColor)??void 0,maxWidth:d.maxWidth,position:"relative",width:"100%"};A&&(q.width=A),u&&(q.height=u);const de={onClick:p},pe=ue(c),mt=x.jsxs("div",{className:C,ref:Y,style:q,...oe(d.url,o),...F(H.CONTAINER),...de,children:[!i&&x.jsx("canvas",{height:N,ref:I,style:le,width:N,...F(H.CANVAS)}),!r&&x.jsx("img",{...P,...F(H.IMAGE),onError:B,src:d.src,style:pe})]});return y!=null&&y.aspectRatio?x.jsx(xt,{aspectRatio:y.aspectRatio,children:mt}):mt};R.Image=fe,Object.defineProperty(R,Symbol.toStringTag,{value:"Module"})});
6
+ */(function(t){(function(){var e={}.hasOwnProperty;function n(){for(var r="",s=0;s<arguments.length;s++){var u=arguments[s];u&&(r=c(r,o(u)))}return r}function o(r){if(typeof r=="string"||typeof r=="number")return r;if(typeof r!="object")return"";if(Array.isArray(r))return n.apply(null,r);if(r.toString!==Object.prototype.toString&&!r.toString.toString().includes("[native code]"))return r.toString();var s="";for(var u in r)e.call(r,u)&&r[u]&&(s=c(s,u));return s}function c(r,s){return s?r?r+" "+s:r+s:r}t.exports?(n.default=n,t.exports=n):window.classNames=n})()})(K);var bt=K.exports;const vt=gt(bt),yt=(t,{root:e,rootMargin:n,threshold:o}={},c=[])=>{const r=R.useRef(null),s=R.useRef(null);return R.useCallback(i=>{r.current&&s.current&&(s.current.unobserve(r.current),s.current.disconnect(),s.current=null),i&&(s.current=new IntersectionObserver(t,{root:e,rootMargin:n,threshold:o}),s.current.observe(i),r.current=i)},[r,e,n,JSON.stringify(o),...c])},wt=({root:t,rootMargin:e,threshold:n,unobserveOnEnter:o,target:c,onEnter:r,onLeave:s,defaultInView:u}={},i=[])=>{const[a,p]=R.useState({inView:u||!1,entry:null,observer:null}),l=R.useCallback(([m],d)=>{const v=d.thresholds.some(b=>m.intersectionRatio>=b)&&m.isIntersecting;p({inView:v,entry:m,observer:d}),v&&o&&(d.unobserve(m.target),d.disconnect()),v?r==null||r(m,d):s==null||s(m,d)},[r,s,o]),g=yt(l,{root:t,rootMargin:e,threshold:n},[o,...i]);return R.useEffect(()=>{c!=null&&c.current&&g(c.current)},[c,g]),[g,a.inView,a.entry,a.observer]},j={ASPECT_RATIO_WRAPPER:"aspect-ratio-wrapper",CANVAS:"canvas",CONTAINER:"container",IMAGE:"image"};var V=(t=>(t.AUTO="auto",t.AVIF="avif",t.JPEG="jpeg",t.WEBP="webp",t))(V||{}),w=(t=>(t.xs="xs",t.sm="sm",t.md="md",t.lg="lg",t.xl="xl",t.xxl="xxl",t["4k"]="4k",t["5k"]="5k",t.full="full",t))(w||{}),U=(t=>(t.DEBUG="debug",t.DOWNLOAD="download",t))(U||{});const It="https://link.visionary.cloud";V.AUTO,w.lg;const F={[w.xs]:160,[w.sm]:320,[w.md]:640,[w.lg]:1280,[w.xl]:1920,[w.xxl]:2560,[w["4k"]]:3840,[w["5k"]]:5120,[w.full]:0};Object.keys(F).reduce((t,e)=>{const n=e,o=F[n];return o&&(t[o]=n),t},{});const Q="!";var At=Object.defineProperty,Rt=(t,e,n)=>e in t?At(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,xt=(t,e,n)=>Rt(t,typeof e!="symbol"?e+"":e,n),H={},L={};Object.defineProperty(L,"__esModule",{value:!0});function Et(t){return String.fromCharCode(parseInt(t.slice(1),16))}function Tt(t){return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g,Et))}L.encode=Tt;function Pt(t){return`%${`00${t.charCodeAt(0).toString(16)}`.slice(-2)}`}function Ct(t){return decodeURIComponent(Array.from(atob(t),Pt).join(""))}L.decode=Ct,Object.defineProperty(H,"__esModule",{value:!0});const tt=L;function Ot(t){return tt.decode(t.replace(/\-/g,"+").replace(/_/g,"/"))}var Ut=H.decode=Ot;function Nt(t){return tt.encode(t).replace(/\//g,"_").replace(/\+/g,"-").replace(/=+$/,"")}var _t=H.encode=Nt;const Dt=t=>t.filter(Boolean),et=t=>{try{return new URL(t)}catch{return null}},$=(t="")=>/^[A-Za-z0-9_-]*$/.test(t),St=t=>{const{altText:e,bcc:n,blurhash:o,blurhashX:c,blurhashY:r,sourceHeight:s,sourceWidth:u,url:i}=t;if(!i||!u||!s)return new Error("Cannot construct visionary code: missing required url/width/height");const a=[i,u,s];return!n||(a.push(n),!o||!c||!r)||(a.push(o,c,r),e&&e.length&&a.push(e)),jt(a)},jt=t=>_t(t.join(Q)),nt=t=>{if(typeof t!="string")return null;const e=t.trim();if(!e.length||!$(e))return null;const n=Ut(e);if(!n)return null;const o=n.split(Q);if(o.length<3)return null;const[c,r,s,u,i,a,p,l]=o,g=c.trim();if(!g.length)return console.error("Cannot parse code, empty file id"),null;const m=Number(r.trim()),d=Number(s.trim());if(isNaN(m)||isNaN(d)||!m||!d)return console.error("Cannot parse Visionary Code: invalid image dimensions",r,s),null;const y=Number(a)??0,v=Number(p)??0;return y<1||v<1?(console.error("Cannot parse Visionary Code: invalid blurhash x, y component dimensions",y,v),null):{altText:l,bcc:u,blurhash:i,blurhashX:y,blurhashY:v,sourceHeight:d,sourceWidth:m,url:g}};class Vt extends Error{constructor(){super(...arguments),xt(this,"message","invalid endpoint URL (does it contain http/https?)")}}const Lt=t=>t===U.DEBUG,$t=t=>t===U.DOWNLOAD,kt=t=>Object.values(V).includes(t),rt=t=>Object.values(w).includes(t),Wt=(t=[])=>{const e={};for(const n of t)rt(n)?e.size=w[n]:Lt(n)?e.debug=!0:$t(n)?e.download=!0:kt(n)&&(e.format=n);return e},zt=t=>{if(!t||typeof t!="object")return null;const e=[];return t.debug&&e.push(U.DEBUG),t.download&&e.push(U.DOWNLOAD),t.format&&t.format!==V.AUTO&&e.push(t.format),t.size&&rt(t.size)&&e.push(t.size),e.length?e.sort().join(","):null},Bt=t=>{if($(t)){const e=nt(t);if(e)return{fields:e,options:{}}}return Mt(t)},Mt=t=>{if(!t)return null;const e=t.trim();if(!e)return null;try{const n=Ft(e);if(!n)return null;const{code:o,optionTokens:c}=n,r=nt(o);if(!r)return null;const s=Wt(c);return{fields:r,options:s}}catch(n){n instanceof Error?console.error(`Error parsing URL: ${n.message}`,n):console.error("uncaught error",n)}return null},Gt=(t,e)=>{const n=St(t);if(n instanceof Error)return null;let o=null;if(e!=null&&e.endpoint&&(o=et(e==null?void 0:e.endpoint),!o))throw new Vt("Cannot construct URL: bad endpoint. Ensure endpoint starts with http:// or https://");o||(o=et(It));const c=[o.origin,"image",n],r=e?zt(e):null;return r&&c.push(r),e!=null&&e.filename?c.push(e.filename):c.push("image.jpg"),c.join("/")},Ft=t=>{try{const e=new URL(t),n=Dt(e.pathname.split("/"));if(n[0]!=="image"||![3,4].includes(n.length))throw new Error("Unrecognized URL");const o=n[1].trim();if(!o.length||!$(o))throw new Error("URL is not formatted as base64url");if(n.length===4){const c=n[2].split(",");return{code:o,optionTokens:c}}if(n.length===3)return{code:o,optionTokens:[]}}catch{return null}return null},ot=.7,st=1,O=24,Ht=w.lg,it=process.env.NODE_ENV,Xt=it==="development",ct=typeof document>"u",Yt=it==="test",k=t=>{try{return new URL(t)}catch{return null}},qt=(t,e)=>`rgba(${t.r},${t.g},${t.b},${e})`,W=t=>Xt||Yt?{"data-testid":t}:{},Zt=(t,e)=>e?{"data-fileid":t}:{},at=(t,e)=>Math.min(t,e),Jt=t=>{let e=t.replace(/^#/,"");if(e.length!==3&&e.length!==6)return null;e.length===3&&(e=`${e[0]}${e[0]}${e[1]}${e[1]}${e[2]}${e[2]}`);const n=parseInt(e.slice(0,2),16),o=parseInt(e.slice(2,4),16);return{b:parseInt(e.slice(4,6),16),g:o,r:n}},T=(t,e=0)=>{const n=Math.pow(10,e);return Math.round(t*n)/n},Kt=(t,e)=>{const n=k(t),o=k(e);return!n||!o?t:(o.pathname=n.pathname,o.search=n.search,o.toString())},Qt={overflow:"hidden"},te=({aspectRatio:t,children:e})=>A.jsx("div",{style:{aspectRatio:t,...Qt},...W(j.ASPECT_RATIO_WRAPPER),children:e}),ee=ct?()=>{}:R.useLayoutEffect,ne="<visionary>",P=(t,...e)=>{!console||typeof console.log!="function"||console.log(`${ne} ${t}`,...e)},lt=new Uint8Array(128);for(let t=0;t<83;t++)lt["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(t)]=t;const z=(t,e,n)=>{let o=0;for(;e<n;)o*=83,o+=lt[t.charCodeAt(e++)];return o},ut=Math.pow,N=Math.PI,re=N*2,dt=3294.6,ft=269.025,oe=t=>t>10.31475?ut(t/ft+.052132,2.4):t/dt,X=t=>~~(t>1227e-8?ft*ut(t,.416666)-13.025:t*dt+1),_=t=>(t<0?-1:1)*t*t,pt=t=>{for(t+=N/2;t>N;)t-=re;const e=1.27323954*t-.405284735*_(t);return .225*(_(e)-e)+e};function se(t){const e=z(t,2,6);return[e>>16,e>>8&255,e&255]}function ie(t,e,n,o){const c=z(t,0,1),r=c%9+1,s=~~(c/9)+1,u=r*s;let i=0,a=0,p=0,l=0,g=0,m=0,d=0,y=0,v=0,b=0,h=0,x=0;const f=(z(t,1,2)+1)/13446*(o|1),I=new Float64Array(u*3),q=se(t);for(i=0;i<3;i++)I[i]=oe(q[i]);for(i=1;i<u;i++)x=z(t,4+i*2,6+i*2),I[i*3]=_(~~(x/361)-9)*f,I[i*3+1]=_(~~(x/19)%19-9)*f,I[i*3+2]=_(x%19-9)*f;const B=new Float64Array(s*n),M=new Float64Array(r*e);for(a=0;a<s;a++)for(l=0;l<n;l++)B[a*n+l]=pt(N*l*a/n);for(i=0;i<r;i++)for(p=0;p<e;p++)M[i*e+p]=pt(N*p*i/e);const D=e*4,C=new Uint8ClampedArray(D*n);for(l=0;l<n;l++)for(p=0;p<e;p++){for(g=m=d=0,a=0;a<s;a++)for(v=B[a*n+l],i=0;i<r;i++)y=M[i*e+p]*v,b=(i+a*r)*3,g+=I[b]*y,m+=I[b+1]*y,d+=I[b+2]*y;h=4*p+l*D,C[h]=X(g),C[h+1]=X(m),C[h+2]=X(d),C[h+3]=255}return C}const ce=(t,e={},n=ot,o=st)=>{if(!t)return null;try{e.debug&&P("input imageSrc:",t);const c=Bt(t);if(e.debug&&P("Visionary URL data: ",c),!c)throw new Error("Could not parse Visionary URL");const{fields:r,options:s}=c;if(r.sourceWidth<1||r.sourceHeight<1)throw new Error("Invalid image dimensions");const u=r.sourceWidth/r.sourceHeight,i=(e==null?void 0:e.size)??s.size??Ht,a=F[i];let p=0,l=0,g=0;if(u>=1){l=p=at(a,r.sourceWidth);const b=T(l/u);g=T(l/b,6)}else p=at(a,r.sourceHeight),l=T(p*u),g=T(l/p,6);const m=T(100/g,6),d={...r,arPaddingTop:`${m}%`,aspectRatio:g,maxWidth:l,src:t},y=k(r.url);if(y)d.src=y.toString();else if(!k(t)&&$(r.url)){const b=Gt(r,{endpoint:e.endpoint,size:i});b&&(d.src=b)}e.endpoint&&(d.src=Kt(d.src,e.endpoint));const v=r.bcc?Jt(r.bcc):null;if(v&&(d.backgroundColor=qt(v,n)),!ct&&r.blurhash&&!e.disableBlurLayer){const b=performance.now(),h=ie(r.blurhash,O,O,o),x=performance.now()-b;e.debug&&P(`Blurhash decode time: ${T(x,1)} ms`),h&&(d.pixels=h)}return e.debug&&P("Visionary Image state: ",d),d}catch{return null}},ht={bottom:0,left:0,position:"absolute",right:0,top:0},ae={...ht,maxHeight:"100%",maxWidth:"100%"},le={...ht,height:"100%",width:"100%"},ue=t=>{const e={...ae};return t&&(e.display="none"),e},Y={container:"v7y_7587",preventDrag:"v7y_b8c0",preventSelection:"v7y_e0dd"},de=({alt:t,bgColorAlpha:e=ot,className:n,debug:o=!1,disableBlurLayer:c=!1,disableImageLayer:r=!1,endpoint:s,height:u,hideImageLayer:i=!1,lazy:a=!0,onClick:p,onError:l,onLoad:g,preventDrag:m=!1,preventSelection:d=!1,punch:y=st,size:v,src:b,style:h,width:x})=>{const f=R.useMemo(()=>ce(b,{debug:o,disableBlurLayer:c,endpoint:s,size:v},e,y),[e,o,c,s,y,v,b]),I=R.useRef(null),[q,B]=wt();ee(function(){if(!I.current||!(f!=null&&f.blurhash))return;if(!f.pixels){console.warn("No pixel data passed in, skipping");return}const he=performance.now(),Z=I.current.getContext("2d");if(!Z){console.warn("Cannot access canvasRenderingContext, skipping");return}const J=Z.createImageData(O,O);if(!J){console.warn("Could not create ImageData on CanvasRenderingContext");return}if(J.data.set(f.pixels),Z.putImageData(J,0,0),o){const me=performance.now()-he;P(`Canvas render time: ${T(me,1)} ms`)}},[f==null?void 0:f.blurhash,f==null?void 0:f.pixels,o]);const M=R.useCallback(S=>{o&&P("Image load error ",S),l&&l()},[o,l]),D={alt:t,loading:!a||B?"eager":"lazy",onLoad:g};if(!f){o&&P("Not a Visionary URL, rendering fallback <img />");const S={...D,className:n,height:u,onClick:p,onError:l,src:b,style:h,width:x};return A.jsx("img",{...S})}const C=vt(Y.container,n,{[Y.preventDrag]:!!m,[Y.preventSelection]:!!d}),G={...{"--v-ar":f.arPaddingTop},...h,aspectRatio:f.aspectRatio,backgroundColor:(f==null?void 0:f.backgroundColor)??void 0,maxWidth:f.maxWidth,position:"relative",width:"100%"};x&&(G.width=x),u&&(G.height=u),h!=null&&h.maxWidth&&(G.maxWidth=h.maxWidth);const fe={onClick:p},pe=ue(i),mt=A.jsxs("div",{className:C,ref:q,style:G,...Zt(f.url,o),...W(j.CONTAINER),...fe,children:[!c&&A.jsx("canvas",{height:O,ref:I,style:le,width:O,...W(j.CANVAS)}),!r&&A.jsx("img",{...D,...W(j.IMAGE),onError:M,src:f.src,style:pe})]});return h!=null&&h.aspectRatio?A.jsx(te,{aspectRatio:h.aspectRatio,children:mt}):mt};E.Image=de,Object.defineProperty(E,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "visionary-image",
3
3
  "description": "React image component with built-in Blurhash placeholders for better UX and Core Web Vitals.",
4
- "version": "1.0.3",
4
+ "version": "1.0.4",
5
5
  "homepage": "https://visionary.cloud",
6
6
  "type": "module",
7
7
  "main": "./dist/visionary-image.umd.js",