visionary-image 1.0.2 → 1.0.3
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 +33 -23
- package/dist/visionary-image.es.js +210 -208
- package/dist/visionary-image.umd.js +2 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,18 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
React image component with built-in Blurhash placeholders for better UX and Core Web Vitals.
|
|
4
4
|
|
|
5
|
-
 
|
|
5
|
+
 [](https://github.com/visionary-ux/visionary-image/actions/workflows/ci-cd-workflow.yml?query=branch%3Amaster) [](https://bundlephobia.com/package/visionary-image) [](https://visionary-ux.github.io/visionary-image/)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Features
|
|
8
8
|
|
|
9
|
-
- Blurhash
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
9
|
+
- **Easy Blurhash:** Get started with Blurhash in 60 seconds.
|
|
10
|
+
- **Layout stability**: Eliminates Cumulative Layout Shift (CLS) with true-to-size, responsive placeholders.
|
|
11
|
+
- **Automatic lazy loading**: Off-screen images are deferred, reducing initial pageload size and optimizing Interaction to Next Paint (INP).
|
|
12
|
+
- **Lighning-fast previews**: Renders placeholders early (by initial DOM layout) using URL-embedded Blurhash data, powered by [`visionary-url`](https://github.com/visionary-ux/visionary-url).
|
|
13
|
+
- **Framework tested**: Compatible with Remix, Next.js, and Vite and supports both client and server-side rendering (SSR, SSG).
|
|
14
|
+
- **Additional features**: Prevent image dragging; prevent user selecting image
|
|
15
|
+
- **Developer friendly**: Written in Typescript and [unit tested](./src/components/Image/__test__/).
|
|
16
|
+
- Check out the [interactive Storybook sandbox](https://visionary-ux.github.io/visionary-image/)
|
|
17
|
+
- **Search performance**: Enhance search ranking potential by improving Core Web Vitals scores.
|
|
18
|
+
> "We highly recommend site owners achieve good Core Web Vitals for success with Search" — [Google Search Central](https://developers.google.com/search/docs/appearance/core-web-vitals)
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
### Lighthouse Performance
|
|
21
|
+
|
|
22
|
+
Lighthouse report filmstrip showing three-layer image loading process
|
|
23
|
+

|
|
17
24
|
|
|
18
25
|
## Installation
|
|
19
26
|
|
|
@@ -25,7 +32,7 @@ npm install --save visionary-image
|
|
|
25
32
|
|
|
26
33
|
## Usage
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
Begin by creating a Visionary image URL. This is then passed to the `src` prop of the Image component.
|
|
29
36
|
|
|
30
37
|
### Creating a Visionary Image URL
|
|
31
38
|
|
|
@@ -40,14 +47,7 @@ There are several ways to create a Visionary URL.
|
|
|
40
47
|
```tsx
|
|
41
48
|
import { Image } from "visionary-image";
|
|
42
49
|
|
|
43
|
-
const
|
|
44
|
-
const altText = "Nighttime stroll in Tokyo, neon-lit with a purple glow";
|
|
45
|
-
|
|
46
|
-
const App = () => {
|
|
47
|
-
<div>
|
|
48
|
-
<Image alt={altText} src={imageUrl} />
|
|
49
|
-
</div>;
|
|
50
|
-
};
|
|
50
|
+
const ImageDetails = () => <Image alt="..." src="<Visionary URL>" />;
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
## Component Props
|
|
@@ -60,8 +60,9 @@ const App = () => {
|
|
|
60
60
|
| `debug` <br/> boolean | Prints handy debug info to the console (Visionary URL data, render times). |
|
|
61
61
|
| `disableBlurLayer` <br/> boolean | Disables rendering of the blur (canvas) layer. |
|
|
62
62
|
| `disableImageLayer` <br/> boolean | Disables rendering of the image layer. |
|
|
63
|
+
| `height` <br/>number, string | If set, will override internally computed image height. By default, Visionary renders optimally sized images, using the aspect-ratio and max-width placeholder data. |
|
|
63
64
|
| `hideImageLayer` <br/> boolean | Hides the image layer, revealing the blur layer underneath. |
|
|
64
|
-
| `lazy` <br/> boolean | Should image lazily
|
|
65
|
+
| `lazy` <br/> boolean | Should image load lazily. <br/> Default: `true` |
|
|
65
66
|
| `onClick` <br/> function | Callback function to invoke when the image is clicked. function. |
|
|
66
67
|
| `onError` <br/> function | Error callback function. |
|
|
67
68
|
| `onLoad` <br/> function | Image loaded callback function. |
|
|
@@ -69,9 +70,18 @@ const App = () => {
|
|
|
69
70
|
| `preventSelection` <br/>boolean | Prevents user from highlighting the image element. |
|
|
70
71
|
| `punch` <br/>number | Blurhash punch parameter.<br /> Default: `1` |
|
|
71
72
|
| `src` <br/>string | Visionary URL, Visionary Code, or ordinary image URL.<br/> If `src` contains Visionary data, placeholders will be rendered, otherwise falls back to an `img` element. <br/> **required** |
|
|
73
|
+
| `width` <br/>number, string | If set, will override internally computed image width. By default, Visionary renders optimally sized images, using the aspect-ratio and max-width placeholder data. |
|
|
74
|
+
|
|
75
|
+
## Relevant Questions
|
|
76
|
+
|
|
77
|
+
### Do image placeholders render server-side?
|
|
78
|
+
|
|
79
|
+
Yes, Visionary Image supports server-side rendering (SSR) and static site generation (SSG), as well as client-side rendering. In server-rendered scenarios, the first layer (background color) renders immediately, followed by the Blurhash and image layers once the page loads in the client's browser.
|
|
80
|
+
|
|
81
|
+
### How long does the Blurhash canvas take to load?
|
|
82
|
+
|
|
83
|
+
Canvas operations are highly efficient in modern browsers. Rendering the 24x24 pixel Blurhash placeholder typically takes around 1ms.
|
|
72
84
|
|
|
73
|
-
###
|
|
85
|
+
### What is Blurhash and where can I learn more?
|
|
74
86
|
|
|
75
|
-
|
|
76
|
-
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
77
|
-
| `height`, `width` | If set, will override internally computed image dimensions. By default, Visionary renders optimally sized images, using the aspect-ratio and max-width placeholder data. |
|
|
87
|
+
Blurhash uses Discrete Cosine Transforms to represent a color-accurate image placeholder as a compact string (in 20-30 characters). Check out the official [Blurhash docs](https://github.com/woltapp/blurhash) for more info.
|
|
@@ -1,10 +1,10 @@
|
|
|
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
|
|
3
|
-
import { useRef as Y, useCallback as q, useState as
|
|
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";
|
|
4
4
|
function xt(t) {
|
|
5
5
|
return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
|
|
6
6
|
}
|
|
7
|
-
var
|
|
7
|
+
var et = { exports: {} };
|
|
8
8
|
/*!
|
|
9
9
|
Copyright (c) 2018 Jed Watson.
|
|
10
10
|
Licensed under the MIT License (MIT), see
|
|
@@ -39,43 +39,45 @@ var nt = { exports: {} };
|
|
|
39
39
|
}
|
|
40
40
|
t.exports ? (e.default = e, t.exports = e) : window.classNames = e;
|
|
41
41
|
})();
|
|
42
|
-
})(
|
|
43
|
-
var
|
|
44
|
-
const
|
|
42
|
+
})(et);
|
|
43
|
+
var Ut = et.exports;
|
|
44
|
+
const Nt = /* @__PURE__ */ xt(Ut), 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
|
-
},
|
|
50
|
-
const [a, p] =
|
|
49
|
+
}, Tt = ({ root: t, rootMargin: n, threshold: e, unobserveOnEnter: o, target: i, onEnter: r, onLeave: s, defaultInView: u } = {}, c = []) => {
|
|
50
|
+
const [a, p] = It({
|
|
51
51
|
inView: u || !1,
|
|
52
52
|
entry: null,
|
|
53
53
|
observer: null
|
|
54
|
-
}), l = q(([h],
|
|
55
|
-
const b =
|
|
54
|
+
}), l = q(([h], d) => {
|
|
55
|
+
const b = d.thresholds.some((g) => h.intersectionRatio >= g) && h.isIntersecting;
|
|
56
56
|
p({
|
|
57
57
|
inView: b,
|
|
58
58
|
entry: h,
|
|
59
|
-
observer:
|
|
60
|
-
}), b && o && (
|
|
61
|
-
}, [r, s, o]), m =
|
|
62
|
-
return
|
|
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
63
|
i != null && i.current && m(i.current);
|
|
64
64
|
}, [i, m]), [m, a.inView, a.entry, a.observer];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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;
|
|
69
71
|
const Z = {
|
|
70
|
-
[
|
|
71
|
-
[
|
|
72
|
-
[
|
|
73
|
-
[
|
|
74
|
-
[
|
|
75
|
-
[
|
|
76
|
-
[
|
|
77
|
-
[
|
|
78
|
-
[
|
|
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
|
|
79
81
|
};
|
|
80
82
|
Object.keys(Z).reduce(
|
|
81
83
|
(t, n) => {
|
|
@@ -84,118 +86,118 @@ Object.keys(Z).reduce(
|
|
|
84
86
|
},
|
|
85
87
|
{}
|
|
86
88
|
);
|
|
87
|
-
const
|
|
88
|
-
var
|
|
89
|
-
Object.defineProperty(
|
|
90
|
-
function
|
|
89
|
+
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) {
|
|
91
93
|
return String.fromCharCode(parseInt(t.slice(1), 16));
|
|
92
94
|
}
|
|
93
|
-
function
|
|
94
|
-
return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g,
|
|
95
|
+
function $t(t) {
|
|
96
|
+
return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g, Vt));
|
|
95
97
|
}
|
|
96
|
-
|
|
97
|
-
function
|
|
98
|
+
j.encode = $t;
|
|
99
|
+
function jt(t) {
|
|
98
100
|
return `%${`00${t.charCodeAt(0).toString(16)}`.slice(-2)}`;
|
|
99
101
|
}
|
|
100
|
-
function
|
|
101
|
-
return decodeURIComponent(Array.from(atob(t),
|
|
102
|
+
function kt(t) {
|
|
103
|
+
return decodeURIComponent(Array.from(atob(t), jt).join(""));
|
|
102
104
|
}
|
|
103
|
-
|
|
105
|
+
j.decode = kt;
|
|
104
106
|
Object.defineProperty(J, "__esModule", { value: !0 });
|
|
105
|
-
const
|
|
106
|
-
function
|
|
107
|
-
return
|
|
107
|
+
const ot = j;
|
|
108
|
+
function zt(t) {
|
|
109
|
+
return ot.decode(t.replace(/\-/g, "+").replace(/_/g, "/"));
|
|
108
110
|
}
|
|
109
|
-
var
|
|
110
|
-
function
|
|
111
|
-
return
|
|
111
|
+
var Bt = J.decode = zt;
|
|
112
|
+
function Mt(t) {
|
|
113
|
+
return ot.encode(t).replace(/\//g, "_").replace(/\+/g, "-").replace(/=+$/, "");
|
|
112
114
|
}
|
|
113
|
-
var
|
|
114
|
-
const
|
|
115
|
+
var Wt = J.encode = Mt;
|
|
116
|
+
const Gt = (t) => t.filter(Boolean), Q = (t) => {
|
|
115
117
|
try {
|
|
116
118
|
return new URL(t);
|
|
117
119
|
} catch {
|
|
118
120
|
return null;
|
|
119
121
|
}
|
|
120
|
-
},
|
|
122
|
+
}, k = (t = "") => /^[A-Za-z0-9_-]*$/.test(t), Ft = (t) => {
|
|
121
123
|
const { altText: n, bcc: e, blurhash: o, blurhashX: i, blurhashY: r, sourceHeight: s, sourceWidth: u, url: c } = t;
|
|
122
124
|
if (!c || !u || !s)
|
|
123
125
|
return new Error("Cannot construct visionary code: missing required url/width/height");
|
|
124
126
|
const a = [c, u, s];
|
|
125
|
-
return !e || (a.push(e), !o || !i || !r) || (a.push(o, i, r), n && n.length && a.push(n)),
|
|
126
|
-
},
|
|
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) => {
|
|
127
129
|
if (typeof t != "string")
|
|
128
130
|
return null;
|
|
129
131
|
const n = t.trim();
|
|
130
|
-
if (!n.length || !
|
|
132
|
+
if (!n.length || !k(n))
|
|
131
133
|
return null;
|
|
132
|
-
const e =
|
|
134
|
+
const e = Bt(n);
|
|
133
135
|
if (!e)
|
|
134
136
|
return null;
|
|
135
|
-
const o = e.split(
|
|
137
|
+
const o = e.split(rt);
|
|
136
138
|
if (o.length < 3)
|
|
137
139
|
return null;
|
|
138
140
|
const [i, r, s, u, c, a, p, l] = o, m = i.trim();
|
|
139
141
|
if (!m.length)
|
|
140
142
|
return console.error("Cannot parse code, empty file id"), null;
|
|
141
|
-
const h = Number(r.trim()),
|
|
142
|
-
if (isNaN(h) || isNaN(
|
|
143
|
+
const h = Number(r.trim()), d = Number(s.trim());
|
|
144
|
+
if (isNaN(h) || isNaN(d) || !h || !d)
|
|
143
145
|
return console.error("Cannot parse Visionary Code: invalid image dimensions", r, s), null;
|
|
144
|
-
const
|
|
145
|
-
return
|
|
146
|
+
const v = Number(a) ?? 0, b = Number(p) ?? 0;
|
|
147
|
+
return v < 1 || b < 1 ? (console.error(
|
|
146
148
|
"Cannot parse Visionary Code: invalid blurhash x, y component dimensions",
|
|
147
|
-
|
|
149
|
+
v,
|
|
148
150
|
b
|
|
149
151
|
), null) : {
|
|
150
152
|
altText: l,
|
|
151
153
|
bcc: u,
|
|
152
154
|
blurhash: c,
|
|
153
|
-
blurhashX:
|
|
155
|
+
blurhashX: v,
|
|
154
156
|
blurhashY: b,
|
|
155
|
-
sourceHeight:
|
|
157
|
+
sourceHeight: d,
|
|
156
158
|
sourceWidth: h,
|
|
157
159
|
url: m
|
|
158
160
|
};
|
|
159
161
|
};
|
|
160
|
-
class
|
|
162
|
+
class Xt extends Error {
|
|
161
163
|
constructor() {
|
|
162
|
-
super(...arguments),
|
|
164
|
+
super(...arguments), Lt(this, "message", "invalid endpoint URL (does it contain http/https?)");
|
|
163
165
|
}
|
|
164
166
|
}
|
|
165
|
-
const
|
|
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 = []) => {
|
|
166
168
|
const n = {};
|
|
167
169
|
for (const e of t)
|
|
168
|
-
|
|
170
|
+
ct(e) ? n.size = w[e] : Yt(e) ? n.debug = !0 : Zt(e) ? n.download = !0 : qt(e) && (n.format = e);
|
|
169
171
|
return n;
|
|
170
|
-
},
|
|
172
|
+
}, Kt = (t) => {
|
|
171
173
|
if (!t || typeof t != "object")
|
|
172
174
|
return null;
|
|
173
175
|
const n = [];
|
|
174
|
-
return t.debug && n.push(
|
|
175
|
-
},
|
|
176
|
-
if (
|
|
177
|
-
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
|
+
const n = st(t);
|
|
178
180
|
if (n)
|
|
179
181
|
return {
|
|
180
182
|
fields: n,
|
|
181
183
|
options: {}
|
|
182
184
|
};
|
|
183
185
|
}
|
|
184
|
-
return
|
|
185
|
-
},
|
|
186
|
+
return tn(t);
|
|
187
|
+
}, tn = (t) => {
|
|
186
188
|
if (!t)
|
|
187
189
|
return null;
|
|
188
190
|
const n = t.trim();
|
|
189
191
|
if (!n)
|
|
190
192
|
return null;
|
|
191
193
|
try {
|
|
192
|
-
const e =
|
|
194
|
+
const e = en(n);
|
|
193
195
|
if (!e)
|
|
194
196
|
return null;
|
|
195
|
-
const { code: o, optionTokens: i } = e, r =
|
|
197
|
+
const { code: o, optionTokens: i } = e, r = st(o);
|
|
196
198
|
if (!r)
|
|
197
199
|
return null;
|
|
198
|
-
const s =
|
|
200
|
+
const s = Jt(i);
|
|
199
201
|
return {
|
|
200
202
|
fields: r,
|
|
201
203
|
options: s
|
|
@@ -204,25 +206,25 @@ const Ft = (t) => t === T.DEBUG, Ht = (t) => t === T.DOWNLOAD, Xt = (t) => Objec
|
|
|
204
206
|
e instanceof Error ? console.error(`Error parsing URL: ${e.message}`, e) : console.error("uncaught error", e);
|
|
205
207
|
}
|
|
206
208
|
return null;
|
|
207
|
-
},
|
|
208
|
-
const e =
|
|
209
|
+
}, nn = (t, n) => {
|
|
210
|
+
const e = Ft(t);
|
|
209
211
|
if (e instanceof Error)
|
|
210
212
|
return null;
|
|
211
213
|
let o = null;
|
|
212
|
-
if (n != null && n.endpoint && (o =
|
|
213
|
-
throw new
|
|
214
|
+
if (n != null && n.endpoint && (o = Q(n == null ? void 0 : n.endpoint), !o))
|
|
215
|
+
throw new Xt(
|
|
214
216
|
"Cannot construct URL: bad endpoint. Ensure endpoint starts with http:// or https://"
|
|
215
217
|
);
|
|
216
|
-
o || (o =
|
|
217
|
-
const i = [o.origin, "image", e], r = n ?
|
|
218
|
+
o || (o = Q(Pt));
|
|
219
|
+
const i = [o.origin, "image", e], r = n ? Kt(n) : null;
|
|
218
220
|
return r && i.push(r), n != null && n.filename ? i.push(n.filename) : i.push("image.jpg"), i.join("/");
|
|
219
|
-
},
|
|
221
|
+
}, en = (t) => {
|
|
220
222
|
try {
|
|
221
|
-
const n = new URL(t), e =
|
|
223
|
+
const n = new URL(t), e = Gt(n.pathname.split("/"));
|
|
222
224
|
if (e[0] !== "image" || ![3, 4].includes(e.length))
|
|
223
225
|
throw new Error("Unrecognized URL");
|
|
224
226
|
const o = e[1].trim();
|
|
225
|
-
if (!o.length || !
|
|
227
|
+
if (!o.length || !k(o))
|
|
226
228
|
throw new Error("URL is not formatted as base64url");
|
|
227
229
|
if (e.length === 4) {
|
|
228
230
|
const i = e[2].split(",");
|
|
@@ -240,152 +242,152 @@ const Ft = (t) => t === T.DEBUG, Ht = (t) => t === T.DOWNLOAD, Xt = (t) => Objec
|
|
|
240
242
|
return null;
|
|
241
243
|
}
|
|
242
244
|
return null;
|
|
243
|
-
},
|
|
244
|
-
} :
|
|
245
|
-
!console || typeof console.log != "function" || console.log(`${
|
|
246
|
-
},
|
|
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
|
+
}, dt = new Uint8Array(128);
|
|
247
249
|
for (let t = 0; t < 83; t++)
|
|
248
|
-
|
|
250
|
+
dt["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(
|
|
249
251
|
t
|
|
250
252
|
)] = t;
|
|
251
|
-
const
|
|
253
|
+
const L = (t, n, e) => {
|
|
252
254
|
let o = 0;
|
|
253
255
|
for (; n < e; )
|
|
254
|
-
o *= 83, o +=
|
|
256
|
+
o *= 83, o += dt[t.charCodeAt(n++)];
|
|
255
257
|
return o;
|
|
256
|
-
}, ft = Math.pow,
|
|
257
|
-
for (t +=
|
|
258
|
-
t -=
|
|
259
|
-
const n = 1.27323954 * t - 0.405284735 *
|
|
260
|
-
return 0.225 * (
|
|
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;
|
|
261
|
+
const n = 1.27323954 * t - 0.405284735 * C(t);
|
|
262
|
+
return 0.225 * (C(n) - n) + n;
|
|
261
263
|
};
|
|
262
|
-
function
|
|
263
|
-
const n =
|
|
264
|
+
function dn(t) {
|
|
265
|
+
const n = L(t, 2, 6);
|
|
264
266
|
return [n >> 16, n >> 8 & 255, n & 255];
|
|
265
267
|
}
|
|
266
|
-
function
|
|
267
|
-
const i =
|
|
268
|
-
let c = 0, a = 0, p = 0, l = 0, m = 0, h = 0,
|
|
269
|
-
const
|
|
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);
|
|
270
272
|
for (c = 0; c < 3; c++)
|
|
271
|
-
I[c] =
|
|
273
|
+
I[c] = un(z[c]);
|
|
272
274
|
for (c = 1; c < u; c++)
|
|
273
|
-
E =
|
|
274
|
-
const
|
|
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);
|
|
275
277
|
for (a = 0; a < s; a++)
|
|
276
278
|
for (l = 0; l < e; l++)
|
|
277
|
-
|
|
279
|
+
S[a * e + l] = tt(P * l * a / e);
|
|
278
280
|
for (c = 0; c < r; c++)
|
|
279
281
|
for (p = 0; p < n; p++)
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
+
_[c * n + p] = tt(P * p * c / n);
|
|
283
|
+
const N = n * 4, R = new Uint8ClampedArray(N * e);
|
|
282
284
|
for (l = 0; l < e; l++)
|
|
283
285
|
for (p = 0; p < n; p++) {
|
|
284
|
-
for (m = h =
|
|
285
|
-
for (b =
|
|
286
|
-
|
|
287
|
-
|
|
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;
|
|
288
290
|
}
|
|
289
|
-
return
|
|
291
|
+
return R;
|
|
290
292
|
}
|
|
291
|
-
const
|
|
293
|
+
const V = (t) => {
|
|
292
294
|
try {
|
|
293
295
|
return new URL(t);
|
|
294
296
|
} catch {
|
|
295
297
|
return null;
|
|
296
298
|
}
|
|
297
|
-
},
|
|
299
|
+
}, pn = (t, n) => `rgba(${t.r},${t.g},${t.b},${n})`, F = (t) => on || sn ? {
|
|
298
300
|
"data-testid": t
|
|
299
|
-
} : {},
|
|
301
|
+
} : {}, hn = (t, n) => n ? {
|
|
300
302
|
"data-fileid": t
|
|
301
|
-
} : {},
|
|
303
|
+
} : {}, nt = (t, n) => Math.min(t, n), mn = (t) => {
|
|
302
304
|
let n = t.replace(/^#/, "");
|
|
303
305
|
if (n.length !== 3 && n.length !== 6)
|
|
304
306
|
return null;
|
|
305
307
|
n.length === 3 && (n = `${n[0]}${n[0]}${n[1]}${n[1]}${n[2]}${n[2]}`);
|
|
306
308
|
const e = parseInt(n.slice(0, 2), 16), o = parseInt(n.slice(2, 4), 16);
|
|
307
309
|
return { b: parseInt(n.slice(4, 6), 16), g: o, r: e };
|
|
308
|
-
},
|
|
310
|
+
}, A = (t, n = 0) => {
|
|
309
311
|
const e = Math.pow(10, n);
|
|
310
312
|
return Math.round(t * e) / e;
|
|
311
|
-
},
|
|
312
|
-
const e =
|
|
313
|
+
}, gn = (t, n) => {
|
|
314
|
+
const e = V(t), o = V(n);
|
|
313
315
|
return !e || !o ? t : (o.pathname = e.pathname, o.search = e.search, o.toString());
|
|
314
|
-
},
|
|
316
|
+
}, bn = (t, n = {}, e = it, o = at) => {
|
|
315
317
|
if (!t)
|
|
316
318
|
return null;
|
|
317
319
|
try {
|
|
318
|
-
n.debug &&
|
|
319
|
-
const i =
|
|
320
|
-
if (n.debug &&
|
|
320
|
+
n.debug && x("input imageSrc:", t);
|
|
321
|
+
const i = Qt(t);
|
|
322
|
+
if (n.debug && x("Visionary URL data: ", i), !i)
|
|
321
323
|
throw new Error("Could not parse Visionary URL");
|
|
322
324
|
const { fields: r, options: s } = i;
|
|
323
325
|
if (r.sourceWidth < 1 || r.sourceHeight < 1)
|
|
324
326
|
throw new Error("Invalid image dimensions");
|
|
325
|
-
const u = r.sourceWidth / r.sourceHeight, c = (n == null ? void 0 : n.size) ?? s.size ??
|
|
327
|
+
const u = r.sourceWidth / r.sourceHeight, c = (n == null ? void 0 : n.size) ?? s.size ?? rn, a = Z[c];
|
|
326
328
|
let p = 0, l = 0, m = 0;
|
|
327
329
|
if (u >= 1) {
|
|
328
|
-
l = p =
|
|
329
|
-
const g =
|
|
330
|
-
m =
|
|
330
|
+
l = p = nt(a, r.sourceWidth);
|
|
331
|
+
const g = A(l / u);
|
|
332
|
+
m = A(l / g, 6);
|
|
331
333
|
} else
|
|
332
|
-
p =
|
|
333
|
-
const h =
|
|
334
|
+
p = nt(a, r.sourceHeight), l = A(p * u), m = A(l / p, 6);
|
|
335
|
+
const h = A(100 / m, 6), d = {
|
|
334
336
|
...r,
|
|
335
337
|
arPaddingTop: `${h}%`,
|
|
336
338
|
aspectRatio: m,
|
|
337
339
|
maxWidth: l,
|
|
338
340
|
src: t
|
|
339
|
-
},
|
|
340
|
-
if (
|
|
341
|
-
|
|
342
|
-
else if (!
|
|
343
|
-
const g =
|
|
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, {
|
|
344
346
|
endpoint: n.endpoint,
|
|
345
347
|
size: c
|
|
346
348
|
});
|
|
347
|
-
g && (
|
|
349
|
+
g && (d.src = g);
|
|
348
350
|
}
|
|
349
|
-
n.endpoint && (
|
|
350
|
-
const b = r.bcc ?
|
|
351
|
-
if (b && (
|
|
352
|
-
const g = performance.now(),
|
|
353
|
-
n.debug &&
|
|
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);
|
|
354
356
|
}
|
|
355
|
-
return n.debug &&
|
|
357
|
+
return n.debug && x("Visionary Image state: ", d), d;
|
|
356
358
|
} catch {
|
|
357
359
|
return null;
|
|
358
360
|
}
|
|
359
|
-
},
|
|
361
|
+
}, mt = {
|
|
360
362
|
bottom: 0,
|
|
361
363
|
left: 0,
|
|
362
364
|
position: "absolute",
|
|
363
365
|
right: 0,
|
|
364
366
|
top: 0
|
|
365
|
-
},
|
|
366
|
-
...
|
|
367
|
+
}, vn = {
|
|
368
|
+
...mt,
|
|
367
369
|
maxHeight: "100%",
|
|
368
370
|
maxWidth: "100%"
|
|
369
|
-
},
|
|
370
|
-
...
|
|
371
|
+
}, yn = {
|
|
372
|
+
...mt,
|
|
371
373
|
height: "100%",
|
|
372
374
|
width: "100%"
|
|
373
|
-
},
|
|
375
|
+
}, wn = (t) => {
|
|
374
376
|
const n = {
|
|
375
|
-
...
|
|
377
|
+
...vn
|
|
376
378
|
};
|
|
377
379
|
return t && (n.display = "none"), n;
|
|
378
380
|
}, H = {
|
|
379
381
|
CANVAS: "canvas",
|
|
380
382
|
CONTAINER: "container",
|
|
381
383
|
IMAGE: "image"
|
|
382
|
-
},
|
|
383
|
-
container:
|
|
384
|
-
preventDrag:
|
|
385
|
-
preventSelection:
|
|
386
|
-
},
|
|
384
|
+
}, In = "v7y_7587", En = "v7y_b8c0", Rn = "v7y_e0dd", X = {
|
|
385
|
+
container: In,
|
|
386
|
+
preventDrag: En,
|
|
387
|
+
preventSelection: Rn
|
|
388
|
+
}, On = ({
|
|
387
389
|
alt: t,
|
|
388
|
-
bgColorAlpha: n =
|
|
390
|
+
bgColorAlpha: n = it,
|
|
389
391
|
className: e,
|
|
390
392
|
debug: o = !1,
|
|
391
393
|
disableBlurLayer: i = !1,
|
|
@@ -398,121 +400,121 @@ const L = (t) => {
|
|
|
398
400
|
onError: l,
|
|
399
401
|
onLoad: m,
|
|
400
402
|
preventDrag: h = !1,
|
|
401
|
-
preventSelection:
|
|
402
|
-
punch:
|
|
403
|
+
preventSelection: d = !1,
|
|
404
|
+
punch: v = at,
|
|
403
405
|
size: b,
|
|
404
406
|
src: g,
|
|
405
|
-
style:
|
|
407
|
+
style: y,
|
|
406
408
|
width: E
|
|
407
409
|
}) => {
|
|
408
|
-
const
|
|
410
|
+
const f = At(() => bn(g, {
|
|
409
411
|
debug: o,
|
|
410
412
|
disableBlurLayer: i,
|
|
411
413
|
endpoint: s,
|
|
412
414
|
size: b
|
|
413
|
-
}, n,
|
|
414
|
-
|
|
415
|
+
}, n, v), [n, o, i, s, v, b, g]), I = Y(null), [z, S] = Tt();
|
|
416
|
+
cn(
|
|
415
417
|
function() {
|
|
416
|
-
if (!I.current || !(
|
|
418
|
+
if (!I.current || !(f != null && f.blurhash))
|
|
417
419
|
return;
|
|
418
|
-
if (!
|
|
420
|
+
if (!f.pixels) {
|
|
419
421
|
console.warn("No pixel data passed in, skipping");
|
|
420
422
|
return;
|
|
421
423
|
}
|
|
422
|
-
const
|
|
423
|
-
if (!
|
|
424
|
+
const vt = performance.now(), M = I.current.getContext("2d");
|
|
425
|
+
if (!M) {
|
|
424
426
|
console.warn("Cannot access canvasRenderingContext, skipping");
|
|
425
427
|
return;
|
|
426
428
|
}
|
|
427
|
-
const
|
|
428
|
-
if (!
|
|
429
|
+
const W = M.createImageData(U, U);
|
|
430
|
+
if (!W) {
|
|
429
431
|
console.warn("Could not create ImageData on CanvasRenderingContext");
|
|
430
432
|
return;
|
|
431
433
|
}
|
|
432
|
-
if (
|
|
433
|
-
const yt = performance.now() -
|
|
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
437
|
}
|
|
436
438
|
},
|
|
437
|
-
[
|
|
439
|
+
[f == null ? void 0 : f.blurhash, f == null ? void 0 : f.pixels, o]
|
|
438
440
|
);
|
|
439
|
-
const
|
|
440
|
-
(
|
|
441
|
-
o &&
|
|
441
|
+
const _ = q(
|
|
442
|
+
(O) => {
|
|
443
|
+
o && x("Image load error ", O), l && l();
|
|
442
444
|
},
|
|
443
445
|
[o, l]
|
|
444
|
-
),
|
|
446
|
+
), N = {
|
|
445
447
|
alt: t,
|
|
446
|
-
loading: !a ||
|
|
448
|
+
loading: !a || S ? "eager" : "lazy",
|
|
447
449
|
onLoad: m
|
|
448
450
|
};
|
|
449
|
-
if (!
|
|
450
|
-
o &&
|
|
451
|
-
const
|
|
452
|
-
...
|
|
451
|
+
if (!f) {
|
|
452
|
+
o && x("Not a Visionary URL, rendering fallback <img />");
|
|
453
|
+
const O = {
|
|
454
|
+
...N,
|
|
453
455
|
className: e,
|
|
454
456
|
height: u,
|
|
455
457
|
onClick: p,
|
|
456
458
|
onError: l,
|
|
457
459
|
src: g,
|
|
458
|
-
style:
|
|
460
|
+
style: y,
|
|
459
461
|
width: E
|
|
460
462
|
};
|
|
461
|
-
return /* @__PURE__ */
|
|
463
|
+
return /* @__PURE__ */ T("img", { ...O });
|
|
462
464
|
}
|
|
463
|
-
const
|
|
465
|
+
const R = Nt(X.container, e, {
|
|
464
466
|
[X.preventDrag]: !!h,
|
|
465
|
-
[X.preventSelection]: !!
|
|
466
|
-
}),
|
|
467
|
+
[X.preventSelection]: !!d
|
|
468
|
+
}), B = {
|
|
467
469
|
...{
|
|
468
|
-
"--v-ar":
|
|
470
|
+
"--v-ar": f.arPaddingTop
|
|
469
471
|
},
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
472
|
+
...y,
|
|
473
|
+
aspectRatio: f.aspectRatio,
|
|
474
|
+
backgroundColor: (f == null ? void 0 : f.backgroundColor) ?? void 0,
|
|
475
|
+
maxWidth: f.maxWidth,
|
|
473
476
|
position: "relative",
|
|
474
|
-
width: "100%"
|
|
475
|
-
...w
|
|
477
|
+
width: "100%"
|
|
476
478
|
};
|
|
477
|
-
E && (
|
|
478
|
-
const
|
|
479
|
+
E && (B.width = E), u && (B.height = u);
|
|
480
|
+
const gt = {
|
|
479
481
|
onClick: p
|
|
480
|
-
},
|
|
481
|
-
return /* @__PURE__ */ vt(
|
|
482
|
+
}, bt = wn(c), K = /* @__PURE__ */ wt(
|
|
482
483
|
"div",
|
|
483
484
|
{
|
|
484
|
-
className:
|
|
485
|
-
ref:
|
|
486
|
-
style:
|
|
487
|
-
...
|
|
485
|
+
className: R,
|
|
486
|
+
ref: z,
|
|
487
|
+
style: B,
|
|
488
|
+
...hn(f.url, o),
|
|
488
489
|
...F(H.CONTAINER),
|
|
489
|
-
...
|
|
490
|
+
...gt,
|
|
490
491
|
children: [
|
|
491
|
-
!i && /* @__PURE__ */
|
|
492
|
+
!i && /* @__PURE__ */ T(
|
|
492
493
|
"canvas",
|
|
493
494
|
{
|
|
494
|
-
height:
|
|
495
|
+
height: U,
|
|
495
496
|
ref: I,
|
|
496
|
-
style:
|
|
497
|
-
width:
|
|
497
|
+
style: yn,
|
|
498
|
+
width: U,
|
|
498
499
|
...F(H.CANVAS)
|
|
499
500
|
}
|
|
500
501
|
),
|
|
501
502
|
!r && // eslint-disable-next-line jsx-a11y/alt-text -- `sharedImgProps` includes alt tag
|
|
502
|
-
/* @__PURE__ */
|
|
503
|
+
/* @__PURE__ */ T(
|
|
503
504
|
"img",
|
|
504
505
|
{
|
|
505
|
-
...
|
|
506
|
+
...N,
|
|
506
507
|
...F(H.IMAGE),
|
|
507
|
-
onError:
|
|
508
|
-
src:
|
|
509
|
-
style:
|
|
508
|
+
onError: _,
|
|
509
|
+
src: f.src,
|
|
510
|
+
style: bt
|
|
510
511
|
}
|
|
511
512
|
)
|
|
512
513
|
]
|
|
513
514
|
}
|
|
514
515
|
);
|
|
516
|
+
return y != null && y.aspectRatio ? /* @__PURE__ */ T(Dt, { aspectRatio: y.aspectRatio, children: K }) : K;
|
|
515
517
|
};
|
|
516
518
|
export {
|
|
517
|
-
|
|
519
|
+
On as Image
|
|
518
520
|
};
|
|
@@ -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(
|
|
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:{}};/*!
|
|
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(e){(function(){var t={}.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)t.call(r,u)&&r[u]&&(s=i(s,u));return s}function i(r,s){return s?r?r+" "+s:r+s:r}e.exports?(n.default=n,e.exports=n):window.classNames=n})()})(K);var ge=K.exports;const be=me(ge),ye=(e,{root:t,rootMargin:n,threshold:o}={},i=[])=>{const r=x.useRef(null),s=x.useRef(null);return x.useCallback(c=>{r.current&&s.current&&(s.current.unobserve(r.current),s.current.disconnect(),s.current=null),c&&(s.current=new IntersectionObserver(e,{root:t,rootMargin:n,threshold:o}),s.current.observe(c),r.current=c)},[r,t,n,JSON.stringify(o),...i])},ve=({root:e,rootMargin:t,threshold:n,unobserveOnEnter:o,target:i,onEnter:r,onLeave:s,defaultInView:u}={},c=[])=>{const[a,p]=x.useState({inView:u||!1,entry:null,observer:null}),l=x.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=ye(l,{root:e,rootMargin:t,threshold:n},[o,...c]);return x.useEffect(()=>{i!=null&&i.current&&m(i.current)},[i,m]),[m,a.inView,a.entry,a.observer]};var j=(e=>(e.AUTO="auto",e.AVIF="avif",e.JPEG="jpeg",e.WEBP="webp",e))(j||{}),v=(e=>(e.xs="xs",e.sm="sm",e.md="md",e.lg="lg",e.xl="xl",e.xxl="xxl",e["4k"]="4k",e["5k"]="5k",e.full="full",e))(v||{}),O=(e=>(e.DEBUG="debug",e.DOWNLOAD="download",e))(O||{});const we="https://link.visionary.cloud";j.AUTO,v.lg;const M={[v.xs]:160,[v.sm]:320,[v.md]:640,[v.lg]:1280,[v.xl]:1920,[v.xxl]:2560,[v["4k"]]:3840,[v["5k"]]:5120,[v.full]:0};Object.keys(M).reduce((e,t)=>{const n=t,o=M[n];return o&&(e[o]=n),e},{});const Q="!";var Ie=Object.defineProperty,xe=(e,t,n)=>t in e?Ie(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Ee=(e,t,n)=>xe(e,typeof t!="symbol"?t+"":t,n),G={},V={};Object.defineProperty(V,"__esModule",{value:!0});function Ae(e){return String.fromCharCode(parseInt(e.slice(1),16))}function Re(e){return btoa(encodeURIComponent(e).replace(/%[0-9A-F]{2}/g,Ae))}V.encode=Re;function Se(e){return`%${`00${e.charCodeAt(0).toString(16)}`.slice(-2)}`}function Te(e){return decodeURIComponent(Array.from(atob(e),Se).join(""))}V.decode=Te,Object.defineProperty(G,"__esModule",{value:!0});const ee=V;function Ue(e){return ee.decode(e.replace(/\-/g,"+").replace(/_/g,"/"))}var Ne=G.decode=Ue;function Oe(e){return ee.encode(e).replace(/\//g,"_").replace(/\+/g,"-").replace(/=+$/,"")}var Ce=G.encode=Oe;const De=e=>e.filter(Boolean),te=e=>{try{return new URL(e)}catch{return null}},L=(e="")=>/^[A-Za-z0-9_-]*$/.test(e),Pe=e=>{const{altText:t,bcc:n,blurhash:o,blurhashX:i,blurhashY:r,sourceHeight:s,sourceWidth:u,url:c}=e;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),t&&t.length&&a.push(t)),_e(a)},_e=e=>Ce(e.join(Q)),ne=e=>{if(typeof e!="string")return null;const t=e.trim();if(!t.length||!L(t))return null;const n=Ne(t);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 y=Number(a)??0,b=Number(p)??0;return y<1||b<1?(console.error("Cannot parse Visionary Code: invalid blurhash x, y component dimensions",y,b),null):{altText:l,bcc:u,blurhash:c,blurhashX:y,blurhashY:b,sourceHeight:f,sourceWidth:h,url:m}};class je extends Error{constructor(){super(...arguments),Ee(this,"message","invalid endpoint URL (does it contain http/https?)")}}const Ve=e=>e===O.DEBUG,Le=e=>e===O.DOWNLOAD,$e=e=>Object.values(j).includes(e),re=e=>Object.values(v).includes(e),ke=(e=[])=>{const t={};for(const n of e)re(n)?t.size=v[n]:Ve(n)?t.debug=!0:Le(n)?t.download=!0:$e(n)&&(t.format=n);return t},ze=e=>{if(!e||typeof e!="object")return null;const t=[];return e.debug&&t.push(O.DEBUG),e.download&&t.push(O.DOWNLOAD),e.format&&e.format!==j.AUTO&&t.push(e.format),e.size&&re(e.size)&&t.push(e.size),t.length?t.sort().join(","):null},Be=e=>{if(L(e)){const t=ne(e);if(t)return{fields:t,options:{}}}return Me(e)},Me=e=>{if(!e)return null;const t=e.trim();if(!t)return null;try{const n=We(t);if(!n)return null;const{code:o,optionTokens:i}=n,r=ne(o);if(!r)return null;const s=ke(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},Ge=(e,t)=>{const n=Pe(e);if(n instanceof Error)return null;let o=null;if(t!=null&&t.endpoint&&(o=te(t==null?void 0:t.endpoint),!o))throw new je("Cannot construct URL: bad endpoint. Ensure endpoint starts with http:// or https://");o||(o=te(we));const i=[o.origin,"image",n],r=t?ze(t):null;return r&&i.push(r),t!=null&&t.filename?i.push(t.filename):i.push("image.jpg"),i.join("/")},We=e=>{try{const t=new URL(e),n=De(t.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},oe=.7,se=1,N=24,Fe=v.lg,ce=process.env.NODE_ENV,He=ce==="development",ie=typeof document>"u",Xe=ce==="test",Ye=ie?()=>{}:x.useLayoutEffect,qe="<visionary>",S=(e,...t)=>{!console||typeof console.log!="function"||console.log(`${qe} ${e}`,...t)},ae=new Uint8Array(128);for(let e=0;e<83;e++)ae["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(e)]=e;const $=(e,t,n)=>{let o=0;for(;t<n;)o*=83,o+=ae[e.charCodeAt(t++)];return o},le=Math.pow,C=Math.PI,Ze=C*2,ue=3294.6,fe=269.025,Je=e=>e>10.31475?le(e/fe+.052132,2.4):e/ue,W=e=>~~(e>1227e-8?fe*le(e,.416666)-13.025:e*ue+1),D=e=>(e<0?-1:1)*e*e,de=e=>{for(e+=C/2;e>C;)e-=Ze;const t=1.27323954*e-.405284735*D(e);return .225*(D(t)-t)+t};function Ke(e){const t=$(e,2,6);return[t>>16,t>>8&255,t&255]}function Qe(e,t,n,o){const i=$(e,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,y=0,b=0,g=0,w=0,E=0;const d=($(e,1,2)+1)/13446*(o|1),I=new Float64Array(u*3),Y=Ke(e);for(c=0;c<3;c++)I[c]=Je(Y[c]);for(c=1;c<u;c++)E=$(e,4+c*2,6+c*2),I[c*3]=D(~~(E/361)-9)*d,I[c*3+1]=D(~~(E/19)%19-9)*d,I[c*3+2]=D(E%19-9)*d;const z=new Float64Array(s*n),B=new Float64Array(r*t);for(a=0;a<s;a++)for(l=0;l<n;l++)z[a*n+l]=de(C*l*a/n);for(c=0;c<r;c++)for(p=0;p<t;p++)B[c*t+p]=de(C*p*c/t);const P=t*4,U=new Uint8ClampedArray(P*n);for(l=0;l<n;l++)for(p=0;p<t;p++){for(m=h=f=0,a=0;a<s;a++)for(b=z[a*n+l],c=0;c<r;c++)y=B[c*t+p]*b,g=(c+a*r)*3,m+=I[g]*y,h+=I[g+1]*y,f+=I[g+2]*y;w=4*p+l*P,U[w]=W(m),U[w+1]=W(h),U[w+2]=W(f),U[w+3]=255}return U}const k=e=>{try{return new URL(e)}catch{return null}},et=(e,t)=>`rgba(${e.r},${e.g},${e.b},${t})`,F=e=>He||Xe?{"data-testid":e}:{},tt=(e,t)=>t?{"data-fileid":e}:{},pe=(e,t)=>Math.min(e,t),nt=e=>{let t=e.replace(/^#/,"");if(t.length!==3&&t.length!==6)return null;t.length===3&&(t=`${t[0]}${t[0]}${t[1]}${t[1]}${t[2]}${t[2]}`);const n=parseInt(t.slice(0,2),16),o=parseInt(t.slice(2,4),16);return{b:parseInt(t.slice(4,6),16),g:o,r:n}},T=(e,t=0)=>{const n=Math.pow(10,t);return Math.round(e*n)/n},rt=(e,t)=>{const n=k(e),o=k(t);return!n||!o?e:(o.pathname=n.pathname,o.search=n.search,o.toString())},ot=(e,t={},n=oe,o=se)=>{if(!e)return null;try{t.debug&&S("input imageSrc:",e);const i=Be(e);if(t.debug&&S("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=(t==null?void 0:t.size)??s.size??Fe,a=M[c];let p=0,l=0,m=0;if(u>=1){l=p=pe(a,r.sourceWidth);const g=T(l/u);m=T(l/g,6)}else p=pe(a,r.sourceHeight),l=T(p*u),m=T(l/p,6);const h=T(100/m,6),f={...r,arPaddingTop:`${h}%`,aspectRatio:m,maxWidth:l,src:e},y=k(r.url);if(y)f.src=y.toString();else if(!k(e)&&L(r.url)){const g=Ge(r,{endpoint:t.endpoint,size:c});g&&(f.src=g)}t.endpoint&&(f.src=rt(f.src,t.endpoint));const b=r.bcc?nt(r.bcc):null;if(b&&(f.backgroundColor=et(b,n)),!ie&&r.blurhash&&!t.disableBlurLayer){const g=performance.now(),w=Qe(r.blurhash,N,N,o),E=performance.now()-g;t.debug&&S(`Blurhash decode time: ${T(E,1)} ms`),w&&(f.pixels=w)}return t.debug&&S("Visionary Image state: ",f),f}catch{return null}},he={bottom:0,left:0,position:"absolute",right:0,top:0},st={...he,maxHeight:"100%",maxWidth:"100%"},ct={...he,height:"100%",width:"100%"},it=e=>{const t={...st};return e&&(t.display="none"),t},H={CANVAS:"canvas",CONTAINER:"container",IMAGE:"image"},X={container:"v7y_7587",preventDrag:"v7y_b8c0",preventSelection:"v7y_e0dd"},at=({alt:e,bgColorAlpha:t=oe,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:y=se,size:b,src:g,style:w,width:E})=>{const d=x.useMemo(()=>ot(g,{debug:o,disableBlurLayer:i,endpoint:s,size:b},t,y),[t,o,i,s,y,b,g]),I=x.useRef(null),[Y,z]=ve();Ye(function(){if(!I.current||!(d!=null&&d.blurhash))return;if(!d.pixels){console.warn("No pixel data passed in, skipping");return}const ft=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 dt=performance.now()-ft;S(`Canvas render time: ${T(dt,1)} ms`)}},[d==null?void 0:d.blurhash,d==null?void 0:d.pixels,o]);const B=x.useCallback(_=>{o&&S("Image load error ",_),l&&l()},[o,l]),P={alt:e,loading:!a||z?"eager":"lazy",onLoad:m};if(!d){o&&S("Not a Visionary URL, rendering fallback <img />");const _={...P,className:n,height:u,onClick:p,onError:l,src:g,style:w,width:E};return R.jsx("img",{..._})}const U=be(X.container,n,{[X.preventDrag]:!!h,[X.preventSelection]:!!f}),q={...{"--v-ar":d.arPaddingTop},aspectRatio:d.aspectRatio,backgroundColor:(d==null?void 0:d.backgroundColor)??void 0,maxWidth:d.maxWidth,position:"relative",width:"100%",...w};E&&(q.width=E),u&&(q.height=u);const lt={onClick:p},ut=it(c);return R.jsxs("div",{className:U,ref:Y,style:q,...tt(d.url,o),...F(H.CONTAINER),...lt,children:[!i&&R.jsx("canvas",{height:N,ref:I,style:ct,width:N,...F(H.CANVAS)}),!r&&R.jsx("img",{...P,...F(H.IMAGE),onError:B,src:d.src,style:ut})]})};A.Image=at,Object.defineProperty(A,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=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"})});
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
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.
|
|
4
|
+
"version": "1.0.3",
|
|
5
|
+
"homepage": "https://visionary.cloud",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"main": "./dist/visionary-image.umd.js",
|
|
7
8
|
"module": "./dist/visionary-image.es.js",
|