@behold/widget 0.5.63 → 0.5.65

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1242 @@
1
+ import { B as BaseElement, a as setClasses, h as hasChanges, s as setCssVars, c as createElement, t as throttle, b as getPlaceholderImage, f as forceLayout, i as isEqual, d as preloadMedia } from './index-zGq7k0wG.js';
2
+
3
+ function RGBStringToHSLArray(rgb) {
4
+ if (!rgb)
5
+ return rgb;
6
+ let [r, g, b] = rgb.split(',');
7
+ r /= 255;
8
+ g /= 255;
9
+ b /= 255;
10
+ const l = Math.max(r, g, b);
11
+ const s = l - Math.min(r, g, b);
12
+ const h = s
13
+ ? l === r
14
+ ? (g - b) / s
15
+ : l === g
16
+ ? 2 + (b - r) / s
17
+ : 4 + (r - g) / s
18
+ : 0;
19
+ return [
20
+ 60 * h < 0 ? 60 * h + 360 : 60 * h,
21
+ 100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0),
22
+ (100 * (2 * l - s)) / 2,
23
+ ];
24
+ }
25
+
26
+ /*
27
+ * Get the median HSL value from an array of HSL palettes
28
+ */
29
+ function getMedianHSL(palettes, algo) {
30
+ algo = 'dominant' ;
31
+ const flattenedHSL = flattenByKey(palettes, algo).map((rgb) => RGBStringToHSLArray(rgb).join(','));
32
+ const hAvg = getArrayMedian(getHSLValueArray(flattenedHSL, 0));
33
+ const sAvg = getArrayMedian(getHSLValueArray(flattenedHSL, 1));
34
+ const lAvg = getArrayMedian(getHSLValueArray(flattenedHSL, 2));
35
+ return [hAvg, sAvg, lAvg];
36
+ }
37
+ /*
38
+ * Flatten an array of objects into an array of values for a key
39
+ */
40
+ function flattenByKey(arr, key) {
41
+ return arr.filter((item) => item[key]).map((item) => item[key]);
42
+ }
43
+ /*
44
+ * Get the median value of an array of numbers
45
+ */
46
+ function getArrayMedian(arr) {
47
+ const copy = [...arr];
48
+ copy.sort(function (a, b) {
49
+ return a - b;
50
+ });
51
+ const middle = Math.floor((copy.length - 1) / 2);
52
+ if (copy.length % 2) {
53
+ return copy[middle];
54
+ }
55
+ else {
56
+ return (copy[middle] + copy[middle + 1]) / 2;
57
+ }
58
+ }
59
+ /*
60
+ * Get an array of integers at an index from a string of HSL values
61
+ */
62
+ function getHSLValueArray(palettes, index) {
63
+ return palettes.map((hsl) => parseInt(hsl.split(',')[index]));
64
+ }
65
+
66
+ class BaseWidget extends BaseElement {
67
+ label = 'BaseWidget';
68
+ // Internal
69
+ shadow;
70
+ styleEl;
71
+ contents;
72
+ stylesAdded;
73
+ constructor() {
74
+ super();
75
+ this.shadow = this.attachShadow({ mode: 'open' });
76
+ // Bind handlers
77
+ // NOTE: For some reason mangling these listeners breaks things, so no "_" prefix
78
+ // @todo investigate this bug
79
+ this.handleKeydown = this.handleKeydown.bind(this);
80
+ this.handleFocus = this.handleFocus.bind(this);
81
+ this.handleFocusout = this.handleFocusout.bind(this);
82
+ this.handleShadowFocusout = this.handleShadowFocusout.bind(this);
83
+ // On global state change
84
+ this.onGlobalStateChange(() => {
85
+ setClasses(this, {
86
+ 'keyboard-nav': this.globalState.keyboardNavEnabled,
87
+ });
88
+ });
89
+ // Connected
90
+ this.onConnect(() => {
91
+ this.styleEl = document.createElement('style');
92
+ setClasses(this, {
93
+ 'keyboard-nav': this.globalState.keyboardNavEnabled,
94
+ });
95
+ this.addEventListener('focus', this.handleFocus);
96
+ this.addEventListener('focusout', this.handleFocusout);
97
+ this.shadow.addEventListener('focusout', this.handleShadowFocusout);
98
+ this.addEventListener('keydown', this.handleKeydown);
99
+ });
100
+ }
101
+ /*
102
+ * Focus previous post
103
+ */
104
+ focusPreviousPost() {
105
+ this.dispatchEvent(new CustomEvent('post-focus-previous'));
106
+ }
107
+ /*
108
+ * Focus next post
109
+ */
110
+ focusNextPost() {
111
+ this.dispatchEvent(new CustomEvent('post-focus-next'));
112
+ }
113
+ /*
114
+ * Handle keydown
115
+ */
116
+ handleKeydown(evt) {
117
+ if (evt.key === 'ArrowLeft' && evt.shiftKey) {
118
+ this.focusPreviousPost();
119
+ }
120
+ if (evt.key === 'ArrowRight' && evt.shiftKey) {
121
+ this.focusNextPost();
122
+ }
123
+ if (this.shadow.activeElement) {
124
+ this.classList.remove('has-focus');
125
+ }
126
+ }
127
+ /**
128
+ * Handle focus
129
+ */
130
+ handleFocus(evt) {
131
+ if (!this.shadow.activeElement) {
132
+ this.classList.add('has-focus');
133
+ }
134
+ }
135
+ /**
136
+ * Handle focusout
137
+ */
138
+ handleFocusout() {
139
+ this.classList.remove('has-focus');
140
+ }
141
+ /**
142
+ * Handle shadow focusout
143
+ */
144
+ handleShadowFocusout(evt) {
145
+ if (evt.relatedTarget === this) {
146
+ this.classList.add('has-focus');
147
+ }
148
+ }
149
+ /*
150
+ * Render content
151
+ */
152
+ renderWidget(contents, styles) {
153
+ if (!this.stylesAdded || !this.contents) {
154
+ this.contents = contents;
155
+ this.styleEl.beholdReplaceChildren(...styles.map((style) => style.toString()));
156
+ this.shadow.beholdReplaceChildren(this.contents, this.styleEl);
157
+ this.stylesAdded = true;
158
+ }
159
+ else {
160
+ this.contents.replaceWith(contents);
161
+ }
162
+ }
163
+ }
164
+
165
+ /*
166
+ * Get a loading color, ready to apply as a style
167
+ */
168
+ function getLoadingColorString(loadingColor, colorPalette, loadingColorTone, medianPaletteHSL) {
169
+ let styleString = '';
170
+ switch (loadingColor) {
171
+ case 'dominant':
172
+ case 'vibrant':
173
+ case 'muted':
174
+ case 'vibrantLight':
175
+ case 'mutedLight':
176
+ case 'vibrantDark':
177
+ case 'mutedDark':
178
+ styleString = colorPalette
179
+ ? `rgb(${colorPalette[loadingColor]})`
180
+ : getHSLCSSFromArray(medianPaletteHSL);
181
+ break;
182
+ case 'tone':
183
+ if (loadingColorTone) {
184
+ const hslColor = loadingColorTone.split(',');
185
+ if (colorPalette) {
186
+ const delta = getLogWithSign(1.6, RGBStringToHSLArray(colorPalette.dominant)[2] - medianPaletteHSL[2]);
187
+ const hslString = `hsl(${hslColor[0]},${hslColor[1]}%,${parseInt(hslColor[2]) + delta}%)`;
188
+ styleString = hslString;
189
+ }
190
+ else {
191
+ styleString = `hsl(${hslColor[0]},${hslColor[1]}%,${hslColor[2]}%, ${Math.max(1 * Math.random(), 0.3)})`;
192
+ }
193
+ }
194
+ else {
195
+ styleString = getHSLCSSFromArray(medianPaletteHSL);
196
+ }
197
+ }
198
+ return styleString;
199
+ }
200
+ /*
201
+ * Get logx of y, with positivity maintained
202
+ */
203
+ function getLogWithSign(x, y) {
204
+ return (Math.log(Math.abs(y)) / Math.log(x)) * Math.sign(y);
205
+ }
206
+ /*
207
+ * Get css hsl string
208
+ */
209
+ function getHSLCSSFromArray(arr) {
210
+ if (!arr)
211
+ return '';
212
+ return `hsl(${arr[0]}, ${arr[1]}%, ${arr[2]}%, ${Math.max(1 * Math.random(), 0.3)})`;
213
+ }
214
+
215
+ /**
216
+ * @description
217
+ * Required props: 'post', 'widgetSettings', 'feedMetadata', 'medianPaletteHSL', 'index', 'totalPosts'
218
+ */
219
+ class BasePost extends BaseElement {
220
+ label = 'BasePost';
221
+ // Provided
222
+ post;
223
+ widgetSettings;
224
+ feedMetadata;
225
+ medianPaletteHSL;
226
+ hasRowGap = false;
227
+ isLastRow = false;
228
+ onClick;
229
+ previewLoadingColors = null;
230
+ aspectRatio;
231
+ index;
232
+ totalPosts;
233
+ // Internal
234
+ _innerEl;
235
+ _captionEl;
236
+ constructor() {
237
+ super();
238
+ // Listen to Prop changes
239
+ this.onPropChange(this._baseHandlePropChange, [
240
+ 'post',
241
+ 'widgetSettings',
242
+ 'feedMetadata',
243
+ 'medianPaletteHSL',
244
+ 'hasRowGap',
245
+ 'isLastRow',
246
+ 'previewLoadingColors',
247
+ 'aspectRatio',
248
+ 'index',
249
+ 'totalPosts',
250
+ ], [
251
+ 'post',
252
+ 'widgetSettings',
253
+ 'feedMetadata',
254
+ 'medianPaletteHSL',
255
+ 'index',
256
+ 'totalPosts',
257
+ ]);
258
+ // Bind Event Handlers
259
+ this._handleButtonClick = this._handleButtonClick.bind(this);
260
+ this.hideBackground = this.hideBackground.bind(this);
261
+ this.onConnect(() => {
262
+ this.onResize(this, this, this._handleResize);
263
+ });
264
+ }
265
+ /*
266
+ * Handle prop change
267
+ */
268
+ _baseHandlePropChange({ changedProp, oldValue, newValue }) {
269
+ switch (changedProp) {
270
+ case 'post':
271
+ if (hasChanges(newValue, oldValue, ['colorPalette'])) {
272
+ this._setBackgroundColor();
273
+ }
274
+ break;
275
+ case 'widgetSettings':
276
+ if (hasChanges(newValue, oldValue, ['loadingColor', 'loadingColorTone'])) {
277
+ this._setBackgroundColor();
278
+ }
279
+ if (this._innerEl &&
280
+ hasChanges(newValue, oldValue, ['linkTarget']) &&
281
+ newValue?.onPostClick?.toLowerCase().includes('link')) {
282
+ this._innerEl.setAttribute('target', newValue.linkTarget);
283
+ }
284
+ if (this._innerEl &&
285
+ hasChanges(newValue, oldValue, ['customLinkURL']) &&
286
+ newValue.onPostClick === 'customLink') {
287
+ this._innerEl.setAttribute('href', newValue.customLinkURL);
288
+ }
289
+ if (hasChanges(newValue, oldValue, [
290
+ 'hoverOverlayColor',
291
+ 'hoverOverlayCustomColor',
292
+ 'hoverOverlayOpacity',
293
+ ])) {
294
+ this._setOverlayColor();
295
+ }
296
+ this._setContainerStyles();
297
+ break;
298
+ case 'previewLoadingColors':
299
+ this._setBackgroundColor();
300
+ break;
301
+ case 'hasRowGap':
302
+ case 'isLastRow':
303
+ this._setContainerStyles();
304
+ break;
305
+ }
306
+ }
307
+ /*
308
+ * Set overlay color
309
+ */
310
+ _setOverlayColor() {
311
+ let overlayColor = 'rgba(0, 0, 0, 0.3)';
312
+ let overlayCustomColor = this.widgetSettings.hoverOverlayCustomColor ?? '0,0,0';
313
+ let overlayOpacity = this.widgetSettings.hoverOverlayOpacity ?? 65;
314
+ if (this.widgetSettings.hoverOverlayColor === 'auto') {
315
+ const hslArray = RGBStringToHSLArray(this.post.colorPalette?.dominant || '100,100,100').map((val) => Math.round(val));
316
+ overlayColor = `hsl(${hslArray[0]} ${Math.min(hslArray[1], 50)}% ${Math.min(hslArray[2], 40)}% / ${overlayOpacity / 100})`;
317
+ }
318
+ if (this.widgetSettings.hoverOverlayColor === 'custom') {
319
+ const hslArray = overlayCustomColor.split(',');
320
+ overlayColor = `hsl(${hslArray[0]} ${hslArray[1]}% ${hslArray[2]}% / ${overlayOpacity / 100})`;
321
+ }
322
+ setCssVars(this, { '--overlay-color': overlayColor });
323
+ }
324
+ /*
325
+ * Set post styles
326
+ */
327
+ _setContainerStyles() {
328
+ setClasses(this, {
329
+ post: true,
330
+ 'post--hover-icon': this.widgetSettings.onHover === 'showIcon',
331
+ 'post--hover-caption': this.widgetSettings.onHover === 'showCaption',
332
+ 'post--has-row-gap': this.hasRowGap,
333
+ 'post--last-row': this.isLastRow,
334
+ });
335
+ this._setOverlayColor();
336
+ }
337
+ /*
338
+ * Render contents
339
+ */
340
+ renderPost(contentEl) {
341
+ let elementType = 'div';
342
+ let link = this.post.permalink;
343
+ this._setContainerStyles();
344
+ if (this.widgetSettings.onPostClick === 'linkToProfile' &&
345
+ this.feedMetadata.username) {
346
+ link = `https://instagram.com/${this.feedMetadata.username}`;
347
+ }
348
+ if (this.widgetSettings.onPostClick === 'customLink' &&
349
+ this.widgetSettings.customLinkURL) {
350
+ link = this.widgetSettings?.customLinkURL;
351
+ }
352
+ if (this.widgetSettings.onPostClick.toLowerCase().includes('link')) {
353
+ elementType = 'a';
354
+ }
355
+ if (this.widgetSettings.onPostClick.toLowerCase().includes('popup')) {
356
+ elementType = 'button';
357
+ }
358
+ let _captionEl = null;
359
+ if (this.widgetSettings.onHover === 'showCaption') {
360
+ const innerCaptionEl = createElement({
361
+ contents: this.post.prunedCaption?.length
362
+ ? this.post.prunedCaption
363
+ : this.post.caption,
364
+ classes: `post-caption__inner`,
365
+ });
366
+ _captionEl = createElement({
367
+ contents: innerCaptionEl,
368
+ classes: `post-caption`,
369
+ });
370
+ }
371
+ let mediaType = 'image';
372
+ switch (this.post?.mediaType) {
373
+ case 'VIDEO':
374
+ mediaType = this.post.isReel ? 'reel' : 'video';
375
+ break;
376
+ case 'CAROUSEL_ALBUM':
377
+ mediaType = 'album';
378
+ break;
379
+ case 'IMAGE':
380
+ default:
381
+ mediaType = 'image';
382
+ }
383
+ this._innerEl = createElement({
384
+ type: elementType,
385
+ contents: [contentEl, _captionEl || ''],
386
+ attributes: {
387
+ draggable: 'false',
388
+ 'aria-label': `${mediaType}, post ${this.index + 1} of ${this.totalPosts}`,
389
+ tabindex: -1,
390
+ ...(elementType === 'a'
391
+ ? {
392
+ href: link,
393
+ target: this.widgetSettings.linkTarget,
394
+ }
395
+ : {}),
396
+ },
397
+ listeners: {
398
+ ...(elementType === 'button'
399
+ ? {
400
+ click: this._handleButtonClick,
401
+ }
402
+ : {}),
403
+ },
404
+ });
405
+ this.beholdReplaceChildren(this._innerEl);
406
+ }
407
+ /*
408
+ * Hide background color
409
+ */
410
+ hideBackground() {
411
+ this.style.backgroundColor = 'transparent';
412
+ }
413
+ /*
414
+ * Set background color
415
+ */
416
+ _setBackgroundColor() {
417
+ const color = this.previewLoadingColors ?? this.widgetSettings.loadingColor;
418
+ this.style.backgroundColor = getLoadingColorString(color, this.post.colorPalette, this.widgetSettings.loadingColorTone, this.medianPaletteHSL);
419
+ }
420
+ /*
421
+ * Handle Resize
422
+ */
423
+ _handleResize(entry) {
424
+ const width = entry?.borderBoxSize?.[0]?.inlineSize || entry?.contentRect?.width || 0;
425
+ const height = entry?.borderBoxSize?.[0]?.blockSize || entry?.contentRect?.height || 0;
426
+ setCssVars(this, {
427
+ '--post-width': width + 'px',
428
+ '--post-height': height + 'px',
429
+ });
430
+ let size = 'xlarge';
431
+ if (width < 600)
432
+ size = 'large';
433
+ if (width < 400)
434
+ size = 'medium';
435
+ if (width < 250)
436
+ size = 'small';
437
+ if (width < 175)
438
+ size = 'xsmall';
439
+ const widths = ['xsmall', 'small', 'medium', 'large', 'xlarge'];
440
+ widths.forEach((sizeString) => {
441
+ setClasses(this, {
442
+ [`post--${sizeString}`]: sizeString === size,
443
+ });
444
+ });
445
+ }
446
+ /**
447
+ * Handle button click
448
+ */
449
+ _handleButtonClick() {
450
+ if (this.onClick) {
451
+ this.onClick(this);
452
+ }
453
+ }
454
+ focus() {
455
+ this._innerEl.focus();
456
+ }
457
+ }
458
+
459
+ /**
460
+ * @description
461
+ * Required props: 'sizes', 'mediaUrl'
462
+ */
463
+ class Image extends BaseElement {
464
+ label = 'Image';
465
+ // Provided
466
+ sizes;
467
+ mediaUrl;
468
+ aspectRatio;
469
+ showLoader = false;
470
+ // Internal
471
+ _imageEl;
472
+ _ldrEl;
473
+ _initialLocalState = {
474
+ isLoaded: false,
475
+ isVisible: false,
476
+ didError: false,
477
+ shouldPreload: false,
478
+ loaderIsShowing: false,
479
+ imageSrc: null,
480
+ sizeObj: null,
481
+ };
482
+ _throttledHandleResize;
483
+ constructor() {
484
+ super();
485
+ // Listen to prop changes
486
+ this.onPropChange(this._handlePropChange, ['sizes', 'mediaUrl', 'aspectRatio', 'showLoader'], ['sizes', 'mediaUrl', 'aspectRatio']);
487
+ // Listen to local state changes
488
+ this.onLocalStateChange(this._handleLocalStateChange, this._initialLocalState);
489
+ // Bind event handlers
490
+ this._handleIntersection = this._handleIntersection.bind(this);
491
+ this._handleImageLoad = this._handleImageLoad.bind(this);
492
+ this._handleImageError = this._handleImageError.bind(this);
493
+ this._throttledHandleResize = throttle(this._handleResize, 50, this);
494
+ this.preload = this.preload.bind(this);
495
+ this.onConnect(() => {
496
+ const height = this.aspectRatio ? 300 : this.sizes?.full.height ?? 300;
497
+ const width = this.aspectRatio
498
+ ? 300 * this.aspectRatio
499
+ : this.sizes?.full.width ?? 300;
500
+ this.style.aspectRatio = this.aspectRatio
501
+ ? `${this.aspectRatio}`
502
+ : `${width}/${height}`;
503
+ let src = !this.sizes?.full.height
504
+ ? this.mediaUrl ?? getPlaceholderImage(width, height)
505
+ : getPlaceholderImage(width, height);
506
+ this._imageEl = createElement({
507
+ type: 'img',
508
+ attributes: {
509
+ alt: '',
510
+ role: 'presentation',
511
+ height: height + 'px',
512
+ width: width + 'px',
513
+ tabindex: -1,
514
+ src,
515
+ draggable: 'false',
516
+ },
517
+ listeners: {
518
+ load: this._handleImageLoad,
519
+ error: this._handleImageError,
520
+ },
521
+ });
522
+ if (this.showLoader) {
523
+ this._ldrEl = createElement({ classes: 'ldr' });
524
+ this.beholdReplaceChildren(this._ldrEl, this._imageEl);
525
+ }
526
+ else {
527
+ this.beholdReplaceChildren(this._imageEl);
528
+ }
529
+ forceLayout();
530
+ this.raf(() => {
531
+ this.onResize(this, this, this._throttledHandleResize);
532
+ this.onIntersection(this, this._handleIntersection);
533
+ }, 'connect');
534
+ });
535
+ this.onDisconnect(() => {
536
+ this.updateLocalState({
537
+ isVisible: false,
538
+ isLoaded: false,
539
+ });
540
+ if (this._imageEl) {
541
+ this._imageEl.removeEventListener('load', this._handleImageLoad);
542
+ this._imageEl.removeEventListener('error', this._handleImageError);
543
+ }
544
+ });
545
+ }
546
+ /*
547
+ * Handle prop change
548
+ */
549
+ _handlePropChange({ changedProp, oldValue, newValue }) {
550
+ switch (changedProp) {
551
+ case 'showLoader':
552
+ if (!oldValue && newValue && this._imageEl) {
553
+ this._ldrEl = createElement({ classes: 'ldr' });
554
+ this.beholdReplaceChildren(this._ldrEl, this._imageEl);
555
+ }
556
+ break;
557
+ case 'sizes':
558
+ if (isEqual(oldValue, newValue))
559
+ return;
560
+ // If _imageEl hasn't rendered yet, skip getting closest size
561
+ // since we don't have its size in the DOM
562
+ this.updateLocalState({
563
+ isLoaded: false,
564
+ sizeObj: this._imageEl?.isConnected
565
+ ? this._getClosestSize(this.offsetWidth, this.offsetHeight)
566
+ : null,
567
+ });
568
+ break;
569
+ }
570
+ }
571
+ /**
572
+ * Handle local state change
573
+ */
574
+ _handleLocalStateChange({ changedProps, newState }) {
575
+ if (changedProps.includes('loaderIsShowing')) {
576
+ if (this._ldrEl) {
577
+ setClasses(this._ldrEl, {
578
+ 'ldr--visible': newState.loaderIsShowing && !newState.isLoaded,
579
+ });
580
+ }
581
+ }
582
+ if (changedProps.includes('imageSrc')) {
583
+ if (this._imageEl &&
584
+ (newState.isVisible || newState.shouldPreload) &&
585
+ newState.imageSrc !== this._imageEl.src) {
586
+ this._imageEl.src = newState.imageSrc;
587
+ }
588
+ }
589
+ if (changedProps.includes('sizeObj')) {
590
+ if (!newState.didError) {
591
+ const backupSrc = this.mediaUrl;
592
+ this.updateLocalState({
593
+ imageSrc: newState.sizeObj?.mediaUrl ?? backupSrc,
594
+ });
595
+ }
596
+ }
597
+ }
598
+ /*
599
+ * Handle intersection
600
+ */
601
+ _handleIntersection(entry) {
602
+ if (entry.isIntersecting) {
603
+ this.updateLocalState({ isVisible: true });
604
+ if (!this.localState.isLoaded && this.showLoader) {
605
+ this.to(() => {
606
+ this.updateLocalState({ loaderIsShowing: true });
607
+ }, 50, 'loader');
608
+ }
609
+ if (this.localState.imageSrc &&
610
+ this._imageEl.src !== this.localState.imageSrc) {
611
+ this._imageEl.src = this.localState.imageSrc;
612
+ }
613
+ }
614
+ else {
615
+ this.updateLocalState({ isVisible: false });
616
+ }
617
+ }
618
+ /*
619
+ * Handle Resize
620
+ */
621
+ _handleResize(entry) {
622
+ let currentWidth = entry.borderBoxSize
623
+ ? entry.borderBoxSize[0].inlineSize
624
+ : entry.contentRect.width || 0;
625
+ let currentHeight = entry.borderBoxSize
626
+ ? entry.borderBoxSize[0].blockSize
627
+ : entry.contentRect.height || 0;
628
+ const closestSize = this._getClosestSize(currentWidth, currentHeight);
629
+ if (!this.localState.sizeObj?.width ||
630
+ this.localState.sizeObj?.width < closestSize?.width ||
631
+ this.localState.sizeObj?.height < closestSize?.height) {
632
+ this.updateLocalState({ sizeObj: closestSize });
633
+ }
634
+ }
635
+ /*
636
+ * Handle image load
637
+ */
638
+ _handleImageLoad() {
639
+ if (this._imageEl.src !== this.localState.imageSrc &&
640
+ !this.localState.shouldPreload &&
641
+ this.sizes?.full.height) {
642
+ return;
643
+ }
644
+ this.cancelTo('loader');
645
+ this.updateLocalState({
646
+ isLoaded: true,
647
+ loaderIsShowing: false,
648
+ });
649
+ this.dispatchEvent(new Event('load'));
650
+ this.classList.add('is-loaded');
651
+ }
652
+ /**
653
+ * Handle error
654
+ */
655
+ _handleImageError() {
656
+ if (this.localState.imageSrc !== this.mediaUrl &&
657
+ !this.localState.didError) {
658
+ this.updateLocalState({ didError: true });
659
+ this.updateLocalState({ imageSrc: this.mediaUrl });
660
+ }
661
+ }
662
+ /**
663
+ * Get closest size to current max dimension
664
+ */
665
+ _getClosestSize(targetWidth, targetHeight) {
666
+ if (!this.sizes)
667
+ return;
668
+ return this.sizes
669
+ ? Object.values(this.sizes).reduce(function (acc, curr) {
670
+ // Is curr width closer to the target width than the accumulator size?
671
+ if (Math.abs(curr.width / 2 - targetWidth) <
672
+ Math.abs(acc.width / 2 - targetWidth)) {
673
+ return curr;
674
+ }
675
+ // Is curr height closer to the target height than the accumulator size?
676
+ if (Math.abs(curr.height / 2 - targetHeight) <
677
+ Math.abs(acc.height / 2 - targetHeight)) {
678
+ return curr;
679
+ }
680
+ // Nope, accumulator size is best
681
+ return acc;
682
+ })
683
+ : null;
684
+ }
685
+ /**
686
+ * Preload
687
+ */
688
+ preload() {
689
+ if (!this.localState.isLoaded) {
690
+ if (this.localState.imageSrc &&
691
+ this.localState.sizeObj &&
692
+ this._imageEl.src !== this.localState.imageSrc) {
693
+ this._imageEl.src = this.localState.imageSrc;
694
+ }
695
+ else {
696
+ this.updateLocalState({ shouldPreload: true });
697
+ }
698
+ }
699
+ }
700
+ /*
701
+ * Register
702
+ */
703
+ static register(name = 'behold-image') {
704
+ if (!customElements.get(name)) {
705
+ customElements.define(name, Image);
706
+ }
707
+ return name;
708
+ }
709
+ }
710
+
711
+ /**
712
+ * @description
713
+ * Required props: 'post'
714
+ */
715
+ class ImagePost extends BasePost {
716
+ label = 'ImagePost';
717
+ // Internal
718
+ _imageEl;
719
+ constructor() {
720
+ super();
721
+ // Register child components
722
+ Image.register();
723
+ // Listen to Prop changes
724
+ this.onPropChange(this._handlePropChange, ['post', 'widgetSettings', 'aspectRatio'], null, this._render);
725
+ }
726
+ /*
727
+ * Handle prop change
728
+ */
729
+ _handlePropChange({ changedProp, oldValue, newValue }) {
730
+ switch (changedProp) {
731
+ case 'widgetSettings':
732
+ if (hasChanges(newValue, oldValue, ['onHover', 'onPostClick'])) {
733
+ this._render();
734
+ }
735
+ break;
736
+ case 'post':
737
+ case 'aspectRatio':
738
+ this._render();
739
+ break;
740
+ }
741
+ }
742
+ /**
743
+ * Render
744
+ */
745
+ _render() {
746
+ this.cancelTo('imageLoad');
747
+ const { sizes, mediaUrl } = this.post;
748
+ this._imageEl = createElement({
749
+ type: 'behold-image',
750
+ props: {
751
+ sizes,
752
+ mediaUrl,
753
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
754
+ },
755
+ });
756
+ this._imageEl.addEventListener('load', (evt) => {
757
+ this.to(this.hideBackground, 600, 'imageLoad');
758
+ });
759
+ this.renderPost(this._imageEl);
760
+ }
761
+ /*
762
+ * Register
763
+ */
764
+ static register(name = 'behold-image-post') {
765
+ if (!customElements.get(name)) {
766
+ customElements.define(name, ImagePost);
767
+ }
768
+ return name;
769
+ }
770
+ }
771
+
772
+ /**
773
+ * @description
774
+ * Required props: 'mediaUrl', 'sizes'
775
+ */
776
+ class Video extends BaseElement {
777
+ label = 'Video';
778
+ // Provided
779
+ mediaUrl;
780
+ sizes;
781
+ autoplay;
782
+ aspectRatio;
783
+ renderPlaceholder;
784
+ // Internal
785
+ _isPlaying;
786
+ _isAttemptingToPlay;
787
+ _videoEl;
788
+ _imageEl;
789
+ constructor() {
790
+ super();
791
+ this._isPlaying = this.autoplay || false;
792
+ this._isAttemptingToPlay = false;
793
+ // Bind event handlers
794
+ this._handleIntersection = this._handleIntersection.bind(this);
795
+ this._handleVideoLoad = this._handleVideoLoad.bind(this);
796
+ this._handlePageVisibility = this._handlePageVisibility.bind(this);
797
+ this._handlePlay = this._handlePlay.bind(this);
798
+ this._handlePause = this._handlePause.bind(this);
799
+ this.preload = this.preload.bind(this);
800
+ // Listen to page visibility
801
+ document.addEventListener('visibilitychange', this._handlePageVisibility);
802
+ // On loop
803
+ this.onLoop(async () => {
804
+ if (!this._videoEl || !this.isLoaded)
805
+ return;
806
+ if (!this._isAttemptingToPlay &&
807
+ this._isPlaying &&
808
+ !this._isVideoElPlaying) {
809
+ try {
810
+ this._isAttemptingToPlay = true;
811
+ await this._videoEl.play();
812
+ this._isAttemptingToPlay = false;
813
+ }
814
+ catch (error) {
815
+ this._isAttemptingToPlay = false;
816
+ }
817
+ }
818
+ if (!this._isPlaying && this._isVideoElPlaying) {
819
+ this._videoEl.pause();
820
+ this._isAttemptingToPlay = false;
821
+ }
822
+ }, 15);
823
+ // Listen to prop changes
824
+ this.onPropChange(({ changedProp, newValue }) => {
825
+ if (this.localState.shouldPreload && this.mediaUrl) {
826
+ preloadMedia('video', this.mediaUrl);
827
+ }
828
+ if (changedProp === 'autoplay') {
829
+ if (newValue) {
830
+ this.play();
831
+ }
832
+ else {
833
+ this.pause();
834
+ }
835
+ }
836
+ }, ['mediaUrl', 'sizes', 'autoplay', 'aspectRatio', 'renderPlaceholder'], ['mediaUrl', 'sizes', 'renderPlaceholder']);
837
+ // Listen to local state changes
838
+ this.onLocalStateChange(() => { }, {
839
+ isMuted: true,
840
+ isLoaded: false,
841
+ shouldPreload: false,
842
+ });
843
+ // Connect
844
+ this.onConnect(() => {
845
+ this.onIntersection(this, this._handleIntersection);
846
+ this.render();
847
+ });
848
+ // Cleanup
849
+ this.onDisconnect(() => {
850
+ document.removeEventListener('visibilitychange', this._handlePageVisibility);
851
+ if (this._videoEl) {
852
+ this._videoEl.removeEventListener('play', this._handlePlay);
853
+ this._videoEl.removeEventListener('pause', this._handlePause);
854
+ this._videoEl.removeEventListener('loadeddata', this._handleVideoLoad);
855
+ }
856
+ });
857
+ }
858
+ /**
859
+ * Add isPlaying property
860
+ */
861
+ get isPlaying() {
862
+ return this._isPlaying || false;
863
+ }
864
+ get _isVideoElPlaying() {
865
+ return !!(this._videoEl.currentTime > 0 &&
866
+ !this._videoEl.paused &&
867
+ !this._videoEl.ended &&
868
+ this._videoEl.readyState > 2);
869
+ }
870
+ /**
871
+ * Reflect props from videoEl
872
+ */
873
+ get paused() {
874
+ return this._videoEl?.paused;
875
+ }
876
+ get muted() {
877
+ return this._videoEl?.muted;
878
+ }
879
+ get isLoaded() {
880
+ return this.localState.isLoaded;
881
+ }
882
+ /*
883
+ * Render
884
+ */
885
+ render() {
886
+ this._videoEl = createElement({
887
+ type: 'video',
888
+ attributes: {
889
+ loop: true,
890
+ playsinline: true,
891
+ crossorigin: 'anonymous',
892
+ tabIndex: -1,
893
+ disablePictureInPicture: true,
894
+ disableremoteplayback: true,
895
+ height: this.sizes?.full.height || 100,
896
+ width: this.sizes?.full.width || 100,
897
+ },
898
+ props: {
899
+ muted: this.localState.isMuted,
900
+ autoplay: this.autoplay || false,
901
+ },
902
+ listeners: {
903
+ play: this._handlePlay,
904
+ pause: this._handlePause,
905
+ },
906
+ });
907
+ if (this.renderPlaceholder) {
908
+ this._imageEl = createElement({
909
+ type: 'img',
910
+ attributes: {
911
+ height: this.sizes.full.height,
912
+ width: this.sizes.full.width,
913
+ src: getPlaceholderImage(this.sizes.full.width, this.sizes.full.height),
914
+ },
915
+ });
916
+ this.beholdReplaceChildren(this._imageEl);
917
+ }
918
+ }
919
+ /*
920
+ * Handle intersectionObserver
921
+ */
922
+ _handleIntersection(entry) {
923
+ if (entry.isIntersecting && this._videoEl) {
924
+ if (this._videoEl.src !== this.mediaUrl) {
925
+ this._videoEl.addEventListener('loadeddata', this._handleVideoLoad, {
926
+ once: true,
927
+ });
928
+ this._videoEl.src = this.mediaUrl;
929
+ // Fix for iOS
930
+ this._videoEl.load();
931
+ }
932
+ }
933
+ else if (!this.autoplay) {
934
+ this.pause();
935
+ }
936
+ }
937
+ /*
938
+ * Handle video load
939
+ */
940
+ _handleVideoLoad() {
941
+ this.updateLocalState({ isLoaded: true });
942
+ if (!this.autoplay) {
943
+ this._videoEl.currentTime = 0.25;
944
+ this._videoEl.pause();
945
+ }
946
+ this.dispatchEvent(new Event('load'));
947
+ this.beholdReplaceChildren(this._videoEl);
948
+ forceLayout();
949
+ this.raf(() => {
950
+ this.classList.add('is-loaded');
951
+ }, '_handleVideoLoad');
952
+ }
953
+ /**
954
+ * Handle play
955
+ */
956
+ _handlePlay() {
957
+ this.dispatchEvent(new Event('play'));
958
+ }
959
+ /**
960
+ * Handle pause
961
+ */
962
+ _handlePause() {
963
+ this.dispatchEvent(new Event('pause'));
964
+ }
965
+ /*
966
+ * Play
967
+ */
968
+ play() {
969
+ this._isPlaying = true;
970
+ }
971
+ /*
972
+ * Pause
973
+ */
974
+ pause() {
975
+ this._isPlaying = false;
976
+ }
977
+ /**
978
+ * Mute
979
+ */
980
+ mute() {
981
+ this.updateLocalState({ isMuted: true });
982
+ if (this._videoEl) {
983
+ this._videoEl.muted = true;
984
+ }
985
+ }
986
+ /**
987
+ * Unmute
988
+ */
989
+ unmute() {
990
+ this.updateLocalState({ isMuted: false });
991
+ if (this._videoEl) {
992
+ this._videoEl.muted = false;
993
+ }
994
+ }
995
+ /*
996
+ * Handle page visibility change
997
+ */
998
+ _handlePageVisibility() {
999
+ if (document.hidden) {
1000
+ this.pause();
1001
+ if (this._videoEl) {
1002
+ this._videoEl.pause();
1003
+ }
1004
+ }
1005
+ if (!document.hidden && this.autoplay) {
1006
+ this.play();
1007
+ }
1008
+ }
1009
+ /**
1010
+ * Preload
1011
+ */
1012
+ preload() {
1013
+ if (!this.localState.isLoaded && this.mediaUrl) {
1014
+ preloadMedia('video', this.mediaUrl);
1015
+ }
1016
+ else {
1017
+ this.updateLocalState({ shouldPreload: true });
1018
+ }
1019
+ }
1020
+ /*
1021
+ * Register
1022
+ */
1023
+ static register(name = 'behold-video') {
1024
+ if (!customElements.get(name)) {
1025
+ customElements.define(name, Video);
1026
+ }
1027
+ return name;
1028
+ }
1029
+ }
1030
+
1031
+ /**
1032
+ * @description
1033
+ * Required props: 'post', 'widgetSettings',
1034
+ */
1035
+ class VideoPost extends BasePost {
1036
+ label = 'VideoPost';
1037
+ // Internal
1038
+ _videoEl;
1039
+ _imageEl;
1040
+ constructor() {
1041
+ super();
1042
+ // Listen to Prop changes
1043
+ this.onPropChange(this._handlePropChange, ['post', 'widgetSettings', 'aspectRatio'], null, this._render);
1044
+ // Register child components
1045
+ Video.register();
1046
+ Image.register();
1047
+ // Bind listeners
1048
+ this._handleMouseover = this._handleMouseover.bind(this);
1049
+ this._handleMouseleave = this._handleMouseleave.bind(this);
1050
+ this.onDisconnect(() => {
1051
+ this.removeEventListener('mouseover', this._handleMouseover);
1052
+ this.removeEventListener('mouseleave', this._handleMouseleave);
1053
+ });
1054
+ }
1055
+ /*
1056
+ * Handle prop change
1057
+ */
1058
+ _handlePropChange({ changedProp, oldValue, newValue }) {
1059
+ switch (changedProp) {
1060
+ case 'widgetSettings':
1061
+ if (hasChanges(oldValue, newValue, [
1062
+ 'onHover',
1063
+ 'onPostClick',
1064
+ 'previewVideosOnHover',
1065
+ ])) {
1066
+ this._render();
1067
+ }
1068
+ if (hasChanges(oldValue, newValue, ['autoplayVideos'])) {
1069
+ if (this.widgetSettings.previewVideosOnHover) {
1070
+ this._videoEl.autoplay = newValue.autoplayVideos;
1071
+ }
1072
+ else {
1073
+ this._render();
1074
+ }
1075
+ }
1076
+ break;
1077
+ case 'post':
1078
+ case 'aspectRatio':
1079
+ this._render();
1080
+ break;
1081
+ }
1082
+ }
1083
+ /**
1084
+ * handle mouseover
1085
+ */
1086
+ _handleMouseover() {
1087
+ this._videoEl?.play();
1088
+ }
1089
+ /**
1090
+ * Handle mouseleave
1091
+ */
1092
+ _handleMouseleave() {
1093
+ if (!this.widgetSettings.autoplayVideos) {
1094
+ this._videoEl?.pause();
1095
+ }
1096
+ }
1097
+ /**
1098
+ * Render
1099
+ */
1100
+ _render() {
1101
+ this.cancelTo('mediaLoad');
1102
+ const { sizes, mediaUrl, thumbnailUrl } = this.post;
1103
+ if (((this.widgetSettings.previewVideosOnHover ||
1104
+ this.widgetSettings.autoplayVideos) &&
1105
+ mediaUrl) ||
1106
+ (!sizes.full.mediaUrl && !thumbnailUrl && mediaUrl)) {
1107
+ this._videoEl = createElement({
1108
+ type: 'behold-video',
1109
+ props: {
1110
+ mediaUrl,
1111
+ sizes,
1112
+ autoplay: this.widgetSettings.autoplayVideos,
1113
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
1114
+ renderPlaceholder: false,
1115
+ },
1116
+ listeners: {
1117
+ mouseover: this._handleMouseover,
1118
+ mouseleave: this._handleMouseleave,
1119
+ },
1120
+ });
1121
+ this._videoEl.addEventListener('load', () => {
1122
+ this.to(this.hideBackground, 600, 'mediaLoad');
1123
+ });
1124
+ this.renderPost(this._videoEl);
1125
+ }
1126
+ else {
1127
+ this._imageEl = createElement({
1128
+ type: 'behold-image',
1129
+ props: {
1130
+ sizes,
1131
+ mediaUrl: thumbnailUrl,
1132
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
1133
+ },
1134
+ });
1135
+ this._imageEl.addEventListener('load', () => {
1136
+ this.to(this.hideBackground, 600, 'mediaLoad');
1137
+ });
1138
+ this.renderPost(this._imageEl);
1139
+ }
1140
+ }
1141
+ /*
1142
+ * Register
1143
+ */
1144
+ static register(name = 'behold-video-post') {
1145
+ if (!customElements.get(name)) {
1146
+ customElements.define(name, VideoPost);
1147
+ }
1148
+ return name;
1149
+ }
1150
+ }
1151
+
1152
+ /**
1153
+ * @description
1154
+ * Required props: 'post'
1155
+ */
1156
+ class AlbumPost extends BasePost {
1157
+ label = 'AlbumPost';
1158
+ // Internal
1159
+ _mediaEl;
1160
+ constructor() {
1161
+ super();
1162
+ // Register child components
1163
+ Image.register();
1164
+ Video.register();
1165
+ // Listen to Prop changes
1166
+ this.onPropChange(this._handlePropChange, ['post', 'widgetSettings'], null, this._render);
1167
+ }
1168
+ /*
1169
+ * Handle prop change
1170
+ */
1171
+ _handlePropChange({ changedProp, oldValue, newValue }) {
1172
+ switch (changedProp) {
1173
+ case 'widgetSettings':
1174
+ if (hasChanges(newValue, oldValue, ['onHover', 'onPostClick'])) {
1175
+ this._render();
1176
+ }
1177
+ break;
1178
+ case 'post':
1179
+ case 'aspectRatio':
1180
+ this._render();
1181
+ break;
1182
+ }
1183
+ }
1184
+ /**
1185
+ * Render
1186
+ */
1187
+ _render() {
1188
+ this.cancelTo('mediaLoad');
1189
+ let { sizes, mediaUrl, children } = this.post;
1190
+ // No sizes or mediaUrl, use children instead
1191
+ if (!sizes.full.mediaUrl && !mediaUrl) {
1192
+ const firstChildWithImage = children.reduce((acc, curr) => {
1193
+ if (curr.mediaType === 'VIDEO') {
1194
+ return curr.sizes.full.mediaUrl || curr.thumbnailUrl ? curr : acc;
1195
+ }
1196
+ return curr.sizes.full.mediaUrl || curr.mediaUrl ? curr : acc;
1197
+ });
1198
+ sizes = firstChildWithImage.sizes;
1199
+ mediaUrl =
1200
+ firstChildWithImage.thumbnailUrl ?? firstChildWithImage.mediaUrl;
1201
+ }
1202
+ if (this.post.mediaUrlIsVideo) {
1203
+ this._mediaEl = createElement({
1204
+ type: 'behold-video',
1205
+ props: {
1206
+ sizes,
1207
+ mediaUrl,
1208
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
1209
+ renderPlaceholder: false,
1210
+ },
1211
+ });
1212
+ }
1213
+ else {
1214
+ this._mediaEl = createElement({
1215
+ type: 'behold-image',
1216
+ props: {
1217
+ sizes,
1218
+ mediaUrl,
1219
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
1220
+ },
1221
+ });
1222
+ }
1223
+ this._mediaEl.addEventListener('load', () => {
1224
+ this.to(this.hideBackground, 600, 'mediaLoad');
1225
+ });
1226
+ this.renderPost(this._mediaEl);
1227
+ }
1228
+ /*
1229
+ * Register
1230
+ */
1231
+ static register(name = 'behold-album-post') {
1232
+ if (!customElements.get(name)) {
1233
+ customElements.define(name, AlbumPost);
1234
+ }
1235
+ return name;
1236
+ }
1237
+ }
1238
+
1239
+ var css_248z = ":host{--post-border-radius:0;--post-aspect-ratio:1;--icon-instagram:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 35 35' xml:space='preserve'%3E%3Cpath fill='%23FFF' d='M17.6 3.2c4.7 0 5.2 0 7.1.1 1.7.1 2.6.4 3.2.6.8.3 1.4.7 2 1.3.6.6 1 1.2 1.3 2 .2.6.5 1.5.6 3.3.1 1.8.1 2.4.1 7.1s0 5.2-.1 7.1c-.1 1.7-.4 2.6-.6 3.2-.6 1.5-1.8 2.7-3.3 3.3-.6.2-1.5.5-3.2.6-1.8.1-2.4.1-7.1.1s-5.2 0-7.1-.1c-1.7-.1-2.6-.4-3.2-.6-.8-.3-1.4-.7-2-1.3-.6-.6-1-1.2-1.3-2-.2-.6-.5-1.5-.6-3.2-.1-1.8-.1-2.4-.1-7.1s0-5.2.1-7.1c0-1.8.3-2.7.6-3.3.3-.8.7-1.4 1.3-2 .6-.6 1.2-1 2-1.3.6-.2 1.5-.5 3.2-.6 1.9-.1 2.4-.1 7.1-.1m0-3.2c-4.8 0-5.3 0-7.2.1-1.9.1-3.2.4-4.3.8C5 1.4 3.9 2 3 2.9c-.9.9-1.5 2-2 3.1C.6 7.1.3 8.4.2 10.2c-.1 1.9-.1 2.5-.1 7.2s0 5.3.1 7.2c.1 2 .4 3.2.8 4.4.4 1.2 1.1 2.2 2 3.1.9.9 1.9 1.6 3.1 2 1.1.4 2.4.7 4.2.8s2.5.1 7.2.1 5.3 0 7.2-.1c1.9-.1 3.1-.4 4.2-.8 2.3-.9 4.2-2.8 5.1-5.1.4-1.1.7-2.4.8-4.2.1-1.9.1-2.5.1-7.2s0-5.3-.1-7.2c-.1-1.9-.4-3.1-.8-4.2-.4-1.2-1.1-2.2-2-3.1-.9-.9-1.9-1.6-3.1-2-1.1-.4-2.4-.7-4.2-.8-1.8-.3-2.4-.3-7.1-.3z'/%3E%3Cpath fill='%23FFF' d='M17.6 8.5c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 14.8c-3.2 0-5.8-2.6-5.8-5.8s2.6-5.8 5.8-5.8 5.8 2.6 5.8 5.8-2.6 5.8-5.8 5.8z'/%3E%3Ccircle fill='%23FFF' cx='26.9' cy='8.2' r='2.1'/%3E%3C/svg%3E\");--icon-video:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 35 35' xml:space='preserve'%3E%3Cpath fill='%23FFF' d='M30.1 15.5 7.2 2.3c-1.5-.9-3.5.2-3.5 1.9v26.5c0 1.7 1.9 2.9 3.4 1.9L30 19.4c1.7-.8 1.7-3 .1-3.9z'/%3E%3C/svg%3E\");--icon-album:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 35 35' xml:space='preserve'%3E%3Cpath fill='%23FFF' d='M27.3 22.7v-17c0-2.6-2.1-4.7-4.7-4.7H5.7C3.1 1 1 3.1 1 5.7v17c0 2.6 2.1 4.7 4.7 4.7h17c2.5-.1 4.6-2.2 4.6-4.7zm4-13.4v14.6c0 4.1-3.4 7.4-7.4 7.4H9.2c-.5 0-.8.6-.5 1 .9 1 2.2 1.6 3.7 1.6h12.1c5.2 0 9.3-4.2 9.3-9.3V12.5c0-1.5-.6-2.8-1.6-3.7-.3-.4-.9 0-.9.5z'/%3E%3C/svg%3E\");align-items:center;border:none;box-shadow:none;box-sizing:border-box;display:flex;flex-wrap:wrap;justify-content:center;margin:0;min-width:50px;outline:none;position:relative;width:100%}:host *{box-sizing:border-box}:host(.keyboard-nav.has-focus){outline:none}:host(.keyboard-nav.has-focus):before{background-color:rgba(0,0,0,.25);border-radius:6px;content:\"\";display:block;height:100%;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%;z-index:1}:host(.keyboard-nav.has-focus):after{background-color:#222;border-radius:6px;box-shadow:0 0 0 2px #4169e1,0 0 0 3px #fff,0 .6px .4px rgba(0,0,0,.042),0 1.3px 1px rgba(0,0,0,.061),0 2.5px 1.9px rgba(0,0,0,.075),0 4.5px 3.4px rgba(0,0,0,.089),0 8.4px 6.3px rgba(0,0,0,.108),0 20px 15px rgba(0,0,0,.15);color:#fff;content:\"Shift + arrow keys to navigate posts\";font-family:sans-serif;font-size:16px;max-width:80%;padding:15px;position:absolute;text-align:center;z-index:1}@media (max-width:1300px){:host(.keyboard-nav.has-focus):after{font-size:15px}}:host(.keyboard-nav.has-focus) .posts{opacity:.65}.posts{display:grid;margin:0;max-width:100%;padding:0;width:100%}.post{-webkit-font-smoothing:inherit;-moz-osx-font-smoothing:inherit;align-self:stretch;border:none;border-radius:var(--post-border-radius) /calc(var(--post-border-radius)*var(--post-aspect-ratio));color:inherit;font:inherit;isolation:isolate;line-height:normal;margin:0 0 -1px;overflow:hidden;transform:translateZ(0);transition:background .3s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:calc(100% + .5px)}:host(.keyboard-nav) .post.post:focus-within{box-shadow:0 0 0 1px #fff,0 0 0 3px #4169e1,0 0 0 4px #fff;z-index:1}:host(.is-previewing-loading-colors) .post *{opacity:0}.post.post--has-row-gap,.post.post--last-row{margin:0}.post:before{background-color:transparent;border-radius:var(--post-border-radius) /calc(var(--post-border-radius)*var(--post-aspect-ratio));content:\"\";height:100%;left:0;pointer-events:none;position:absolute;top:0;transition:all 2s cubic-bezier(.215,.61,.355,1);width:100%;z-index:2}@supports ((-webkit-backdrop-filter:blur(3px)) or (backdrop-filter:blur(3px))){[data-hover-effect*=blur i] .post:before{height:calc(100% - 1px);left:0;opacity:0;top:0;transition:all .6s cubic-bezier(.215,.61,.355,1);width:100%}}.post.post--hover-icon:after{background-image:var(--icon);background-position:50%;background-repeat:no-repeat;background-size:auto 100%;border-radius:var(--post-border-radius) /calc(var(--post-border-radius)*var(--post-aspect-ratio));content:\"\";height:12%;height:calc(min(var(--post-width), var(--post-height))*.12);left:0;max-height:30px;min-height:20px;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translateY(-50%) scale(.75);transition:all .6s cubic-bezier(.215,.61,.355,1);width:100%;will-change:transform;z-index:3}@media (prefers-reduced-motion){.post.post--hover-icon:after{transition:none}}.post behold-album,.post behold-image,.post behold-video{height:calc(100% + 2px);transform:translate(-1px,-1px);width:calc(100% + 2px)}.post>a,.post>button,.post>div{background-color:transparent;border:0;box-shadow:none;color:inherit;display:block;font:inherit;height:100%;line-height:inherit;outline:none;padding:0;transition:opacity .3s ease;width:100%}.post a,.post button{cursor:pointer}behold-image-post{--icon:var(--icon-instagram)}behold-video-post{--icon:var(--icon-video)}behold-album-post{--icon:var(--icon-album)}.post-caption{align-items:center;background-color:var(--overlay-color);display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;font-size:15px;height:100%;justify-content:center;left:0;line-height:1.5;opacity:0;padding:15%;pointer-events:none;position:absolute;top:0;transition:opacity .4s ease;width:100%;z-index:2}.post:hover .post-caption,:host(:host(.keyboard-nav)) .post:focus-within .post-caption{opacity:1}.post--xlarge .post-caption{--lines:12;--innerScale:scale(0.98);padding:20%}.post--large .post-caption{--lines:9;--innerScale:scale(0.98)}.post--medium .post-caption{--lines:6;--innerScale:scale(0.97);font-size:14px}.post--small .post-caption{--lines:4;--innerScale:scale(0.95);font-size:13px;line-height:1.25}.post--xsmall .post-caption{--lines:3;--innerScale:scale(0.95);font-size:12px;line-height:1.25}.post-caption__inner{-webkit-line-clamp:var(--lines);-webkit-box-orient:vertical;color:#fff;display:-webkit-box;opacity:0;overflow:hidden;text-align:center;transform:var(--innerScale);transition:all .3s ease;white-space:pre-line;will-change:transform,opacity;word-break:none}@media (prefers-reduced-motion){.post-caption__inner{transform:none}}.post:hover .post-caption__inner,:host(.keyboard-nav) .post:focus-within .post-caption__inner{opacity:1;transform:none;transition:all .3s ease}:host(.keyboard-nav) .post:focus-within:before{background-color:var(--overlay-color);transition:all .6s cubic-bezier(.215,.61,.355,1)}:host(.keyboard-nav) .post:focus-within:after{opacity:1;transform:translateY(-50%)}:host(.keyboard-nav) [data-hover-effect=fade] .post:focus-within:before,[data-hover-effect=fade] .post:hover:before{background-color:var(--overlay-color);transition:all .6s cubic-bezier(.215,.61,.355,1)}:host(.keyboard-nav) [data-hover-effect=fade] .post:focus-within:after,[data-hover-effect=fade] .post:hover:after{opacity:1;transform:translateY(-50%)}:host(.keyboard-nav) [data-hover-effect=zoomFade] .post:focus-within behold-image img,:host(.keyboard-nav) [data-hover-effect=zoomFade] .post:focus-within behold-video video,[data-hover-effect=zoomFade] .post:hover behold-image img,[data-hover-effect=zoomFade] .post:hover behold-video video{transform:scale(1.05)}@media (prefers-reduced-motion){:host(.keyboard-nav) [data-hover-effect=zoomFade] .post:focus-within behold-image img,:host(.keyboard-nav) [data-hover-effect=zoomFade] .post:focus-within behold-video video,[data-hover-effect=zoomFade] .post:hover behold-image img,[data-hover-effect=zoomFade] .post:hover behold-video video{transform:none}}:host(.keyboard-nav) [data-hover-effect=zoomFade] .post:focus-within:before,[data-hover-effect=zoomFade] .post:hover:before{background-color:var(--overlay-color);transition:all .6s cubic-bezier(.215,.61,.355,1)}:host(.keyboard-nav) [data-hover-effect=zoomFade] .post:focus-within:after,[data-hover-effect=zoomFade] .post:hover:after{opacity:1;transform:translateY(-50%)}@supports not ((-webkit-backdrop-filter:blur(3px)) or (backdrop-filter:blur(3px))){:host(.keyboard-nav) [data-hover-effect=blur] .post:focus-within behold-image,:host(.keyboard-nav) [data-hover-effect=blur] .post:focus-within behold-video,[data-hover-effect=blur] .post:hover behold-image,[data-hover-effect=blur] .post:hover behold-video{filter:brightness(97%) blur(3px);transition:all .6s cubic-bezier(.215,.61,.355,1)}}@supports ((-webkit-backdrop-filter:blur(3px)) or (backdrop-filter:blur(3px))){:host(.keyboard-nav) [data-hover-effect=blur] .post:focus-within:before,[data-hover-effect=blur] .post:hover:before{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);background-color:rgba(0,0,0,.002);opacity:1}}:host(.keyboard-nav) [data-hover-effect=blur] .post:focus-within:after,[data-hover-effect=blur] .post:hover:after{opacity:1;transform:translateY(-50%)}:host(.keyboard-nav) [data-hover-effect=zoomBlur] .post:focus-within behold-image,:host(.keyboard-nav) [data-hover-effect=zoomBlur] .post:focus-within behold-video,[data-hover-effect=zoomBlur] .post:hover behold-image,[data-hover-effect=zoomBlur] .post:hover behold-video{transform:scale(1.05);transition:all .6s cubic-bezier(.215,.61,.355,1)}@media (prefers-reduced-motion){:host(.keyboard-nav) [data-hover-effect=zoomBlur] .post:focus-within behold-image,:host(.keyboard-nav) [data-hover-effect=zoomBlur] .post:focus-within behold-video,[data-hover-effect=zoomBlur] .post:hover behold-image,[data-hover-effect=zoomBlur] .post:hover behold-video{transform:none}}@supports not ((-webkit-backdrop-filter:blur(3px)) or (backdrop-filter:blur(3px))){:host(.keyboard-nav) [data-hover-effect=zoomBlur] .post:focus-within behold-image,:host(.keyboard-nav) [data-hover-effect=zoomBlur] .post:focus-within behold-video,[data-hover-effect=zoomBlur] .post:hover behold-image,[data-hover-effect=zoomBlur] .post:hover behold-video{filter:brightness(97%) blur(3px)}}@supports ((-webkit-backdrop-filter:blur(3px)) or (backdrop-filter:blur(3px))){:host(.keyboard-nav) [data-hover-effect=zoomBlur] .post:focus-within:before,[data-hover-effect=zoomBlur] .post:hover:before{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);background-color:rgba(0,0,0,.002);opacity:1}}:host(.keyboard-nav) [data-hover-effect=zoomBlur] .post:focus-within:after,[data-hover-effect=zoomBlur] .post:hover:after{opacity:1;transform:translateY(-50%)}:host(.keyboard-nav) [data-hover-effect=toGreyscale] .post:focus-within behold-image,:host(.keyboard-nav) [data-hover-effect=toGreyscale] .post:focus-within behold-video,[data-hover-effect=toGreyscale] .post:hover behold-image,[data-hover-effect=toGreyscale] .post:hover behold-video{filter:grayscale(100%);transition:all .6s cubic-bezier(.215,.61,.355,1)}:host(.keyboard-nav) [data-hover-effect=toGreyscale] .post:focus-within:after,[data-hover-effect=toGreyscale] .post:hover:after{opacity:1;transform:translateY(-50%)}:host(.keyboard-nav) [data-hover-effect=zoomToGreyscale] .post:focus-within behold-image,:host(.keyboard-nav) [data-hover-effect=zoomToGreyscale] .post:focus-within behold-video,[data-hover-effect=zoomToGreyscale] .post:hover behold-image,[data-hover-effect=zoomToGreyscale] .post:hover behold-video{filter:grayscale(100%);transform:scale(1.05);transition:all .6s cubic-bezier(.215,.61,.355,1)}@media (prefers-reduced-motion){:host(.keyboard-nav) [data-hover-effect=zoomToGreyscale] .post:focus-within behold-image,:host(.keyboard-nav) [data-hover-effect=zoomToGreyscale] .post:focus-within behold-video,[data-hover-effect=zoomToGreyscale] .post:hover behold-image,[data-hover-effect=zoomToGreyscale] .post:hover behold-video{transform:none}}:host(.keyboard-nav) [data-hover-effect=zoomToGreyscale] .post:focus-within:after,[data-hover-effect=zoomToGreyscale] .post:hover:after{opacity:1;transform:translateY(-50%)}:host(.keyboard-nav) [data-hover-effect=fromGreyscale] .post,[data-hover-effect=fromGreyscale] .post{filter:grayscale(100%)}:host(.keyboard-nav) [data-hover-effect=fromGreyscale] .post:focus,:host(.keyboard-nav) [data-hover-effect=fromGreyscale] .post:hover,[data-hover-effect=fromGreyscale] .post:focus,[data-hover-effect=fromGreyscale] .post:hover{filter:grayscale(0);transition:all .6s cubic-bezier(.215,.61,.355,1)}:host(.keyboard-nav) [data-hover-effect=fromGreyscale] .post:focus.post--hover-caption:before,:host(.keyboard-nav) [data-hover-effect=fromGreyscale] .post:hover.post--hover-caption:before,[data-hover-effect=fromGreyscale] .post:focus.post--hover-caption:before,[data-hover-effect=fromGreyscale] .post:hover.post--hover-caption:before{background-color:var(--overlay-color);transition:all .6s cubic-bezier(.215,.61,.355,1)}:host(.keyboard-nav) [data-hover-effect=fromGreyscale] .post:focus:after,:host(.keyboard-nav) [data-hover-effect=fromGreyscale] .post:hover:after,[data-hover-effect=fromGreyscale] .post:focus:after,[data-hover-effect=fromGreyscale] .post:hover:after{opacity:1;transform:translateY(-50%)}:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post,[data-hover-effect=zoomFromGreyscale] .post{filter:grayscale(100%)}:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:focus,:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:hover,[data-hover-effect=zoomFromGreyscale] .post:focus,[data-hover-effect=zoomFromGreyscale] .post:hover{filter:grayscale(0)}:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:focus behold-image,:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:focus behold-video,:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:hover behold-image,:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:hover behold-video,[data-hover-effect=zoomFromGreyscale] .post:focus behold-image,[data-hover-effect=zoomFromGreyscale] .post:focus behold-video,[data-hover-effect=zoomFromGreyscale] .post:hover behold-image,[data-hover-effect=zoomFromGreyscale] .post:hover behold-video{transform:scale(1.05);transition:all .6s cubic-bezier(.215,.61,.355,1)}@media (prefers-reduced-motion){:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:focus behold-image,:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:focus behold-video,:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:hover behold-image,:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:hover behold-video,[data-hover-effect=zoomFromGreyscale] .post:focus behold-image,[data-hover-effect=zoomFromGreyscale] .post:focus behold-video,[data-hover-effect=zoomFromGreyscale] .post:hover behold-image,[data-hover-effect=zoomFromGreyscale] .post:hover behold-video{transform:none}}:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:focus.post--hover-caption:before,:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:hover.post--hover-caption:before,[data-hover-effect=zoomFromGreyscale] .post:focus.post--hover-caption:before,[data-hover-effect=zoomFromGreyscale] .post:hover.post--hover-caption:before{background-color:var(--overlay-color);transition:all .6s cubic-bezier(.215,.61,.355,1)}:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:focus:after,:host(.keyboard-nav) [data-hover-effect=zoomFromGreyscale] .post:hover:after,[data-hover-effect=zoomFromGreyscale] .post:focus:after,[data-hover-effect=zoomFromGreyscale] .post:hover:after{opacity:1;transform:translateY(-50%)}behold-image{display:block;height:0;overflow:hidden;padding:0;padding-bottom:calc(100%/var(--post-aspect-ratio));position:relative;transition:all .6s cubic-bezier(.215,.61,.355,1);width:100%}behold-image img{border-radius:0;height:100%;left:0;-o-object-fit:cover;object-fit:cover;-o-object-position:center center;object-position:center center;opacity:0;pointer-events:none;position:absolute;top:0;transition:all .6s cubic-bezier(.215,.61,.355,1),opacity .6s ease;vertical-align:middle;width:100%;will-change:transform;z-index:1}@supports not ((-webkit-backdrop-filter:blur(3px)) or (backdrop-filter:blur(3px))){[data-hover-effect=blur] behold-image img,[data-hover-effect=zoomBlur] behold-image img{height:calc(100% + 6px);left:-3px;top:-3px;width:calc(100% + 6px)}}.post--reel behold-image img{-o-object-position:center 25%;object-position:center 25%}behold-image.is-loaded img{opacity:1}behold-video{display:block;height:0;overflow:hidden;padding:0;padding-bottom:calc(100%/var(--post-aspect-ratio));position:relative;transition:all .6s cubic-bezier(.215,.61,.355,1);width:100%}behold-video video{height:100%;left:0;-o-object-fit:cover;object-fit:cover;-o-object-position:center center;object-position:center center;opacity:0;pointer-events:none;position:absolute;top:0;transition:all .6s cubic-bezier(.215,.61,.355,1),opacity .6s ease;vertical-align:middle;width:100%;will-change:transform}.post--reel behold-video video{-o-object-position:center 25%;object-position:center 25%}behold-video.is-loaded video{opacity:1}";
1240
+ var baseGridStyles = css_248z;
1241
+
1242
+ export { AlbumPost as A, BaseWidget as B, ImagePost as I, RGBStringToHSLArray as R, VideoPost as V, Video as a, baseGridStyles as b, Image as c, getMedianHSL as g };