@behold/widget 0.5.56 → 0.5.57

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.
@@ -0,0 +1,1220 @@
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-R4lEDZFo.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'
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.onConnect(() => {
261
+ this.onResize(this, this, this._handleResize);
262
+ });
263
+ }
264
+ /*
265
+ * Handle prop change
266
+ */
267
+ _baseHandlePropChange({ changedProp, oldValue, newValue }) {
268
+ switch (changedProp) {
269
+ case 'post':
270
+ if (hasChanges(newValue, oldValue, ['colorPalette'])) {
271
+ this._setBackgroundColor();
272
+ }
273
+ break;
274
+ case 'widgetSettings':
275
+ if (hasChanges(newValue, oldValue, ['loadingColor', 'loadingColorTone'])) {
276
+ this._setBackgroundColor();
277
+ }
278
+ if (this._innerEl &&
279
+ hasChanges(newValue, oldValue, ['linkTarget']) &&
280
+ newValue?.onPostClick?.toLowerCase().includes('link')) {
281
+ this._innerEl.setAttribute('target', newValue.linkTarget);
282
+ }
283
+ if (this._innerEl &&
284
+ hasChanges(newValue, oldValue, ['customLinkURL']) &&
285
+ newValue.onPostClick === 'customLink') {
286
+ this._innerEl.setAttribute('href', newValue.customLinkURL);
287
+ }
288
+ if (hasChanges(newValue, oldValue, [
289
+ 'hoverOverlayColor',
290
+ 'hoverOverlayCustomColor',
291
+ 'hoverOverlayOpacity',
292
+ ])) {
293
+ this._setOverlayColor();
294
+ }
295
+ this._setContainerStyles();
296
+ break;
297
+ case 'previewLoadingColors':
298
+ this._setBackgroundColor();
299
+ break;
300
+ case 'hasRowGap':
301
+ case 'isLastRow':
302
+ this._setContainerStyles();
303
+ break;
304
+ }
305
+ }
306
+ /*
307
+ * Set overlay color
308
+ */
309
+ _setOverlayColor() {
310
+ let overlayColor = 'rgba(0, 0, 0, 0.3)';
311
+ let overlayCustomColor = this.widgetSettings.hoverOverlayCustomColor ?? '0,0,0';
312
+ let overlayOpacity = this.widgetSettings.hoverOverlayOpacity ?? 65;
313
+ if (this.widgetSettings.hoverOverlayColor === 'auto') {
314
+ const hslArray = RGBStringToHSLArray(this.post.colorPalette?.dominant || '100,100,100').map((val) => Math.round(val));
315
+ overlayColor = `hsl(${hslArray[0]} ${Math.min(hslArray[1], 50)}% ${Math.min(hslArray[2], 40)}% / ${overlayOpacity / 100})`;
316
+ }
317
+ if (this.widgetSettings.hoverOverlayColor === 'custom') {
318
+ const hslArray = overlayCustomColor.split(',');
319
+ overlayColor = `hsl(${hslArray[0]} ${hslArray[1]}% ${hslArray[2]}% / ${overlayOpacity / 100})`;
320
+ }
321
+ setCssVars(this, { '--overlay-color': overlayColor });
322
+ }
323
+ /*
324
+ * Set post styles
325
+ */
326
+ _setContainerStyles() {
327
+ setClasses(this, {
328
+ post: true,
329
+ 'post--hover-icon': this.widgetSettings.onHover === 'showIcon',
330
+ 'post--hover-caption': this.widgetSettings.onHover === 'showCaption',
331
+ 'post--has-row-gap': this.hasRowGap,
332
+ 'post--last-row': this.isLastRow,
333
+ });
334
+ this._setOverlayColor();
335
+ }
336
+ /*
337
+ * Render contents
338
+ */
339
+ renderPost(contentEl) {
340
+ let elementType = 'div';
341
+ let link = this.post.permalink;
342
+ this._setContainerStyles();
343
+ if (this.widgetSettings.onPostClick === 'linkToProfile' &&
344
+ this.feedMetadata.username) {
345
+ link = `https://instagram.com/${this.feedMetadata.username}`;
346
+ }
347
+ if (this.widgetSettings.onPostClick === 'customLink' &&
348
+ this.widgetSettings.customLinkURL) {
349
+ link = this.widgetSettings?.customLinkURL;
350
+ }
351
+ if (this.widgetSettings.onPostClick.toLowerCase().includes('link')) {
352
+ elementType = 'a';
353
+ }
354
+ if (this.widgetSettings.onPostClick.toLowerCase().includes('popup')) {
355
+ elementType = 'button';
356
+ }
357
+ let _captionEl = null;
358
+ if (this.widgetSettings.onHover === 'showCaption') {
359
+ const innerCaptionEl = createElement({
360
+ contents: this.post.prunedCaption?.length
361
+ ? this.post.prunedCaption
362
+ : this.post.caption,
363
+ classes: `post-caption__inner`,
364
+ });
365
+ _captionEl = createElement({
366
+ contents: innerCaptionEl,
367
+ classes: `post-caption`,
368
+ });
369
+ }
370
+ let mediaType = 'image';
371
+ switch (this.post?.mediaType) {
372
+ case 'VIDEO':
373
+ mediaType = this.post.isReel ? 'reel' : 'video';
374
+ break;
375
+ case 'CAROUSEL_ALBUM':
376
+ mediaType = 'album';
377
+ break;
378
+ case 'IMAGE':
379
+ default:
380
+ mediaType = 'image';
381
+ }
382
+ this._innerEl = createElement({
383
+ type: elementType,
384
+ contents: [contentEl, _captionEl || ''],
385
+ attributes: {
386
+ draggable: 'false',
387
+ 'aria-label': `${mediaType}, post ${this.index + 1} of ${this.totalPosts}`,
388
+ tabindex: -1,
389
+ ...(elementType === 'a'
390
+ ? {
391
+ href: link,
392
+ target: this.widgetSettings.linkTarget,
393
+ }
394
+ : {}),
395
+ },
396
+ listeners: {
397
+ ...(elementType === 'button'
398
+ ? {
399
+ click: this._handleButtonClick,
400
+ }
401
+ : {}),
402
+ },
403
+ });
404
+ this.beholdReplaceChildren(this._innerEl);
405
+ }
406
+ /*
407
+ * Set background color
408
+ */
409
+ _setBackgroundColor() {
410
+ const color = this.previewLoadingColors ?? this.widgetSettings.loadingColor;
411
+ this.style.backgroundColor = getLoadingColorString(color, this.post.colorPalette, this.widgetSettings.loadingColorTone, this.medianPaletteHSL);
412
+ }
413
+ /*
414
+ * Handle Resize
415
+ */
416
+ _handleResize(entry) {
417
+ const width = entry?.borderBoxSize?.[0]?.inlineSize || entry?.contentRect?.width || 0;
418
+ const height = entry?.borderBoxSize?.[0]?.blockSize || entry?.contentRect?.height || 0;
419
+ setCssVars(this, {
420
+ '--post-width': width + 'px',
421
+ '--post-height': height + 'px',
422
+ });
423
+ let size = 'xlarge';
424
+ if (width < 600)
425
+ size = 'large';
426
+ if (width < 400)
427
+ size = 'medium';
428
+ if (width < 250)
429
+ size = 'small';
430
+ if (width < 175)
431
+ size = 'xsmall';
432
+ const widths = ['xsmall', 'small', 'medium', 'large', 'xlarge'];
433
+ widths.forEach((sizeString) => {
434
+ setClasses(this, {
435
+ [`post--${sizeString}`]: sizeString === size,
436
+ });
437
+ });
438
+ }
439
+ /**
440
+ * Handle button click
441
+ */
442
+ _handleButtonClick() {
443
+ if (this.onClick) {
444
+ this.onClick(this);
445
+ }
446
+ }
447
+ focus() {
448
+ this._innerEl.focus();
449
+ }
450
+ }
451
+
452
+ /**
453
+ * @description
454
+ * Required props: 'sizes', 'mediaUrl'
455
+ */
456
+ class Image extends BaseElement {
457
+ label = 'Image';
458
+ // Provided
459
+ sizes;
460
+ mediaUrl;
461
+ aspectRatio;
462
+ showLoader = false;
463
+ // Internal
464
+ _imageEl;
465
+ _ldrEl;
466
+ _initialLocalState = {
467
+ isLoaded: false,
468
+ isVisible: false,
469
+ didError: false,
470
+ shouldPreload: false,
471
+ loaderIsShowing: false,
472
+ imageSrc: null,
473
+ sizeObj: null,
474
+ };
475
+ _throttledHandleResize;
476
+ constructor() {
477
+ super();
478
+ // Listen to prop changes
479
+ this.onPropChange(this._handlePropChange, ['sizes', 'mediaUrl', 'aspectRatio', 'showLoader'], ['sizes', 'mediaUrl', 'aspectRatio']);
480
+ // Listen to local state changes
481
+ this.onLocalStateChange(this._handleLocalStateChange, this._initialLocalState);
482
+ // Bind event handlers
483
+ this._handleIntersection = this._handleIntersection.bind(this);
484
+ this._handleImageLoad = this._handleImageLoad.bind(this);
485
+ this._handleImageError = this._handleImageError.bind(this);
486
+ this._throttledHandleResize = throttle(this._handleResize, 50, this);
487
+ this.preload = this.preload.bind(this);
488
+ this.onConnect(() => {
489
+ const height = this.aspectRatio ? 300 : this.sizes?.full.height ?? 300;
490
+ const width = this.aspectRatio
491
+ ? 300 * this.aspectRatio
492
+ : this.sizes?.full.width ?? 300;
493
+ this.style.aspectRatio = this.aspectRatio
494
+ ? `${this.aspectRatio}`
495
+ : `${width}/${height}`;
496
+ let src = !this.sizes?.full.height
497
+ ? this.mediaUrl ?? getPlaceholderImage(width, height)
498
+ : getPlaceholderImage(width, height);
499
+ this._imageEl = createElement({
500
+ type: 'img',
501
+ attributes: {
502
+ alt: '',
503
+ role: 'presentation',
504
+ height: height + 'px',
505
+ width: width + 'px',
506
+ tabindex: -1,
507
+ src,
508
+ draggable: 'false',
509
+ },
510
+ listeners: {
511
+ load: this._handleImageLoad,
512
+ error: this._handleImageError,
513
+ },
514
+ });
515
+ if (this.showLoader) {
516
+ this._ldrEl = createElement({ classes: 'ldr' });
517
+ this.beholdReplaceChildren(this._ldrEl, this._imageEl);
518
+ }
519
+ else {
520
+ this.beholdReplaceChildren(this._imageEl);
521
+ }
522
+ forceLayout();
523
+ this.raf(() => {
524
+ this.onResize(this, this, this._throttledHandleResize);
525
+ this.onIntersection(this, this._handleIntersection);
526
+ }, 'connect');
527
+ });
528
+ this.onDisconnect(() => {
529
+ this.updateLocalState({
530
+ isVisible: false,
531
+ isLoaded: false,
532
+ });
533
+ if (this._imageEl) {
534
+ this._imageEl.removeEventListener('load', this._handleImageLoad);
535
+ this._imageEl.removeEventListener('error', this._handleImageError);
536
+ }
537
+ });
538
+ }
539
+ /*
540
+ * Handle prop change
541
+ */
542
+ _handlePropChange({ changedProp, oldValue, newValue }) {
543
+ switch (changedProp) {
544
+ case 'showLoader':
545
+ if (!oldValue && newValue && this._imageEl) {
546
+ this._ldrEl = createElement({ classes: 'ldr' });
547
+ this.beholdReplaceChildren(this._ldrEl, this._imageEl);
548
+ }
549
+ break;
550
+ case 'sizes':
551
+ if (isEqual(oldValue, newValue))
552
+ return;
553
+ // If _imageEl hasn't rendered yet, skip getting closest size
554
+ // since we don't have its size in the DOM
555
+ this.updateLocalState({
556
+ isLoaded: false,
557
+ sizeObj: this._imageEl?.isConnected
558
+ ? this._getClosestSize(this.offsetWidth, this.offsetHeight)
559
+ : null,
560
+ });
561
+ break;
562
+ }
563
+ }
564
+ /**
565
+ * Handle local state change
566
+ */
567
+ _handleLocalStateChange({ changedProps, newState }) {
568
+ if (changedProps.includes('loaderIsShowing')) {
569
+ if (this._ldrEl) {
570
+ setClasses(this._ldrEl, {
571
+ 'ldr--visible': newState.loaderIsShowing && !newState.isLoaded,
572
+ });
573
+ }
574
+ }
575
+ if (changedProps.includes('imageSrc')) {
576
+ if (this._imageEl &&
577
+ (newState.isVisible || newState.shouldPreload) &&
578
+ newState.imageSrc !== this._imageEl.src) {
579
+ this._imageEl.src = newState.imageSrc;
580
+ }
581
+ }
582
+ if (changedProps.includes('sizeObj')) {
583
+ if (!newState.didError) {
584
+ const backupSrc = this.mediaUrl;
585
+ this.updateLocalState({
586
+ imageSrc: newState.sizeObj?.mediaUrl ?? backupSrc,
587
+ });
588
+ }
589
+ }
590
+ }
591
+ /*
592
+ * Handle intersection
593
+ */
594
+ _handleIntersection(entry) {
595
+ if (entry.isIntersecting) {
596
+ this.updateLocalState({ isVisible: true });
597
+ if (!this.localState.isLoaded && this.showLoader) {
598
+ this.to(() => {
599
+ this.updateLocalState({ loaderIsShowing: true });
600
+ }, 50, 'loader');
601
+ }
602
+ if (this.localState.imageSrc &&
603
+ this._imageEl.src !== this.localState.imageSrc) {
604
+ this._imageEl.src = this.localState.imageSrc;
605
+ }
606
+ }
607
+ else {
608
+ this.updateLocalState({ isVisible: false });
609
+ }
610
+ }
611
+ /*
612
+ * Handle Resize
613
+ */
614
+ _handleResize(entry) {
615
+ let currentWidth = entry.borderBoxSize
616
+ ? entry.borderBoxSize[0].inlineSize
617
+ : entry.contentRect.width || 0;
618
+ let currentHeight = entry.borderBoxSize
619
+ ? entry.borderBoxSize[0].blockSize
620
+ : entry.contentRect.height || 0;
621
+ const closestSize = this._getClosestSize(currentWidth, currentHeight);
622
+ if (!this.localState.sizeObj?.width ||
623
+ this.localState.sizeObj?.width < closestSize?.width ||
624
+ this.localState.sizeObj?.height < closestSize?.height) {
625
+ this.updateLocalState({ sizeObj: closestSize });
626
+ }
627
+ }
628
+ /*
629
+ * Handle image load
630
+ */
631
+ _handleImageLoad() {
632
+ if (this._imageEl.src !== this.localState.imageSrc &&
633
+ !this.localState.shouldPreload &&
634
+ this.sizes?.full.height) {
635
+ return;
636
+ }
637
+ this.cancelTo('loader');
638
+ this.updateLocalState({
639
+ isLoaded: true,
640
+ loaderIsShowing: false,
641
+ });
642
+ this.dispatchEvent(new Event('load'));
643
+ this.classList.add('is-loaded');
644
+ }
645
+ /**
646
+ * Handle error
647
+ */
648
+ _handleImageError() {
649
+ if (this.localState.imageSrc !== this.mediaUrl &&
650
+ !this.localState.didError) {
651
+ this.updateLocalState({ didError: true });
652
+ this.updateLocalState({ imageSrc: this.mediaUrl });
653
+ }
654
+ }
655
+ /**
656
+ * Get closest size to current max dimension
657
+ */
658
+ _getClosestSize(targetWidth, targetHeight) {
659
+ if (!this.sizes)
660
+ return;
661
+ return this.sizes
662
+ ? Object.values(this.sizes).reduce(function (acc, curr) {
663
+ // Is curr width closer to the target width than the accumulator size?
664
+ if (Math.abs(curr.width / 2 - targetWidth) <
665
+ Math.abs(acc.width / 2 - targetWidth)) {
666
+ return curr;
667
+ }
668
+ // Is curr height closer to the target height than the accumulator size?
669
+ if (Math.abs(curr.height / 2 - targetHeight) <
670
+ Math.abs(acc.height / 2 - targetHeight)) {
671
+ return curr;
672
+ }
673
+ // Nope, accumulator size is best
674
+ return acc;
675
+ })
676
+ : null;
677
+ }
678
+ /**
679
+ * Preload
680
+ */
681
+ preload() {
682
+ if (!this.localState.isLoaded) {
683
+ if (this.localState.imageSrc &&
684
+ this.localState.sizeObj &&
685
+ this._imageEl.src !== this.localState.imageSrc) {
686
+ this._imageEl.src = this.localState.imageSrc;
687
+ }
688
+ else {
689
+ this.updateLocalState({ shouldPreload: true });
690
+ }
691
+ }
692
+ }
693
+ /*
694
+ * Register
695
+ */
696
+ static register(name = 'behold-image') {
697
+ if (!customElements.get(name)) {
698
+ customElements.define(name, Image);
699
+ }
700
+ return name;
701
+ }
702
+ }
703
+
704
+ /**
705
+ * @description
706
+ * Required props: 'post'
707
+ */
708
+ class ImagePost extends BasePost {
709
+ label = 'ImagePost';
710
+ // Internal
711
+ _imageEl;
712
+ constructor() {
713
+ super();
714
+ // Register child components
715
+ Image.register();
716
+ // Listen to Prop changes
717
+ this.onPropChange(this._handlePropChange, ['post', 'widgetSettings', 'aspectRatio'], null, this._render);
718
+ }
719
+ /*
720
+ * Handle prop change
721
+ */
722
+ _handlePropChange({ changedProp, oldValue, newValue }) {
723
+ switch (changedProp) {
724
+ case 'widgetSettings':
725
+ if (hasChanges(newValue, oldValue, ['onHover', 'onPostClick'])) {
726
+ this._render();
727
+ }
728
+ break;
729
+ case 'post':
730
+ case 'aspectRatio':
731
+ this._render();
732
+ break;
733
+ }
734
+ }
735
+ /**
736
+ * Render
737
+ */
738
+ _render() {
739
+ const { sizes, mediaUrl } = this.post;
740
+ this._imageEl = createElement({
741
+ type: 'behold-image',
742
+ props: {
743
+ sizes,
744
+ mediaUrl,
745
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
746
+ },
747
+ });
748
+ this.renderPost(this._imageEl);
749
+ }
750
+ /*
751
+ * Register
752
+ */
753
+ static register(name = 'behold-image-post') {
754
+ if (!customElements.get(name)) {
755
+ customElements.define(name, ImagePost);
756
+ }
757
+ return name;
758
+ }
759
+ }
760
+
761
+ /**
762
+ * @description
763
+ * Required props: 'mediaUrl', 'sizes'
764
+ */
765
+ class Video extends BaseElement {
766
+ label = 'Video';
767
+ // Provided
768
+ mediaUrl;
769
+ sizes;
770
+ autoplay;
771
+ aspectRatio;
772
+ renderPlaceholder;
773
+ // Internal
774
+ _isPlaying;
775
+ _isAttemptingToPlay;
776
+ _videoEl;
777
+ _imageEl;
778
+ constructor() {
779
+ super();
780
+ this._isPlaying = this.autoplay || false;
781
+ this._isAttemptingToPlay = false;
782
+ // Bind event handlers
783
+ this._handleIntersection = this._handleIntersection.bind(this);
784
+ this._handleVideoLoad = this._handleVideoLoad.bind(this);
785
+ this._handlePageVisibility = this._handlePageVisibility.bind(this);
786
+ this._handlePlay = this._handlePlay.bind(this);
787
+ this._handlePause = this._handlePause.bind(this);
788
+ this.preload = this.preload.bind(this);
789
+ // Listen to page visibility
790
+ document.addEventListener('visibilitychange', this._handlePageVisibility);
791
+ // On loop
792
+ this.onLoop(async () => {
793
+ if (!this._videoEl || !this.isLoaded)
794
+ return;
795
+ if (!this._isAttemptingToPlay &&
796
+ this._isPlaying &&
797
+ !this._isVideoElPlaying) {
798
+ try {
799
+ this._isAttemptingToPlay = true;
800
+ await this._videoEl.play();
801
+ this._isAttemptingToPlay = false;
802
+ }
803
+ catch (error) {
804
+ this._isAttemptingToPlay = false;
805
+ }
806
+ }
807
+ if (!this._isPlaying && this._isVideoElPlaying) {
808
+ this._videoEl.pause();
809
+ this._isAttemptingToPlay = false;
810
+ }
811
+ }, 15);
812
+ // Listen to prop changes
813
+ this.onPropChange(({ changedProp, newValue }) => {
814
+ if (this.localState.shouldPreload && this.mediaUrl) {
815
+ preloadMedia('video', this.mediaUrl);
816
+ }
817
+ if (changedProp === 'autoplay') {
818
+ if (newValue) {
819
+ this.play();
820
+ }
821
+ else {
822
+ this.pause();
823
+ }
824
+ }
825
+ }, ['mediaUrl', 'sizes', 'autoplay', 'aspectRatio', 'renderPlaceholder'], ['mediaUrl', 'sizes', 'renderPlaceholder']);
826
+ // Listen to local state changes
827
+ this.onLocalStateChange(() => { }, {
828
+ isMuted: true,
829
+ isLoaded: false,
830
+ shouldPreload: false,
831
+ });
832
+ // Connect
833
+ this.onConnect(() => {
834
+ this.onIntersection(this, this._handleIntersection);
835
+ this.render();
836
+ });
837
+ // Cleanup
838
+ this.onDisconnect(() => {
839
+ document.removeEventListener('visibilitychange', this._handlePageVisibility);
840
+ if (this._videoEl) {
841
+ this._videoEl.removeEventListener('play', this._handlePlay);
842
+ this._videoEl.removeEventListener('pause', this._handlePause);
843
+ this._videoEl.removeEventListener('loadeddata', this._handleVideoLoad);
844
+ }
845
+ });
846
+ }
847
+ /**
848
+ * Add isPlaying property
849
+ */
850
+ get isPlaying() {
851
+ return this._isPlaying || false;
852
+ }
853
+ get _isVideoElPlaying() {
854
+ return !!(this._videoEl.currentTime > 0 &&
855
+ !this._videoEl.paused &&
856
+ !this._videoEl.ended &&
857
+ this._videoEl.readyState > 2);
858
+ }
859
+ /**
860
+ * Reflect props from videoEl
861
+ */
862
+ get paused() {
863
+ return this._videoEl?.paused;
864
+ }
865
+ get muted() {
866
+ return this._videoEl?.muted;
867
+ }
868
+ get isLoaded() {
869
+ return this.localState.isLoaded;
870
+ }
871
+ /*
872
+ * Render
873
+ */
874
+ render() {
875
+ this._videoEl = createElement({
876
+ type: 'video',
877
+ attributes: {
878
+ loop: true,
879
+ playsinline: true,
880
+ crossorigin: 'anonymous',
881
+ tabIndex: -1,
882
+ disablePictureInPicture: true,
883
+ disableremoteplayback: true,
884
+ height: this.sizes?.full.height || 100,
885
+ width: this.sizes?.full.width || 100,
886
+ },
887
+ props: {
888
+ muted: this.localState.isMuted,
889
+ autoplay: this.autoplay || false,
890
+ },
891
+ listeners: {
892
+ play: this._handlePlay,
893
+ pause: this._handlePause,
894
+ },
895
+ });
896
+ if (this.renderPlaceholder) {
897
+ this._imageEl = createElement({
898
+ type: 'img',
899
+ attributes: {
900
+ height: this.sizes.full.height,
901
+ width: this.sizes.full.width,
902
+ src: getPlaceholderImage(this.sizes.full.width, this.sizes.full.height),
903
+ },
904
+ });
905
+ this.beholdReplaceChildren(this._imageEl);
906
+ }
907
+ }
908
+ /*
909
+ * Handle intersectionObserver
910
+ */
911
+ _handleIntersection(entry) {
912
+ if (entry.isIntersecting && this._videoEl) {
913
+ if (this._videoEl.src !== this.mediaUrl) {
914
+ this._videoEl.addEventListener('loadeddata', this._handleVideoLoad, {
915
+ once: true,
916
+ });
917
+ this._videoEl.src = this.mediaUrl;
918
+ // Fix for iOS
919
+ this._videoEl.load();
920
+ }
921
+ }
922
+ else if (!this.autoplay) {
923
+ this.pause();
924
+ }
925
+ }
926
+ /*
927
+ * Handle video load
928
+ */
929
+ _handleVideoLoad() {
930
+ this.updateLocalState({ isLoaded: true });
931
+ if (!this.autoplay) {
932
+ this._videoEl.currentTime = 0.25;
933
+ this._videoEl.pause();
934
+ }
935
+ this.dispatchEvent(new Event('load'));
936
+ this.beholdReplaceChildren(this._videoEl);
937
+ forceLayout();
938
+ this.raf(() => {
939
+ this.classList.add('is-loaded');
940
+ }, '_handleVideoLoad');
941
+ }
942
+ /**
943
+ * Handle play
944
+ */
945
+ _handlePlay() {
946
+ this.dispatchEvent(new Event('play'));
947
+ }
948
+ /**
949
+ * Handle pause
950
+ */
951
+ _handlePause() {
952
+ this.dispatchEvent(new Event('pause'));
953
+ }
954
+ /*
955
+ * Play
956
+ */
957
+ play() {
958
+ this._isPlaying = true;
959
+ }
960
+ /*
961
+ * Pause
962
+ */
963
+ pause() {
964
+ this._isPlaying = false;
965
+ }
966
+ /**
967
+ * Mute
968
+ */
969
+ mute() {
970
+ this.updateLocalState({ isMuted: true });
971
+ if (this._videoEl) {
972
+ this._videoEl.muted = true;
973
+ }
974
+ }
975
+ /**
976
+ * Unmute
977
+ */
978
+ unmute() {
979
+ this.updateLocalState({ isMuted: false });
980
+ if (this._videoEl) {
981
+ this._videoEl.muted = false;
982
+ }
983
+ }
984
+ /*
985
+ * Handle page visibility change
986
+ */
987
+ _handlePageVisibility() {
988
+ if (document.hidden) {
989
+ this.pause();
990
+ if (this._videoEl) {
991
+ this._videoEl.pause();
992
+ }
993
+ }
994
+ if (!document.hidden && this.autoplay) {
995
+ this.play();
996
+ }
997
+ }
998
+ /**
999
+ * Preload
1000
+ */
1001
+ preload() {
1002
+ if (!this.localState.isLoaded && this.mediaUrl) {
1003
+ preloadMedia('video', this.mediaUrl);
1004
+ }
1005
+ else {
1006
+ this.updateLocalState({ shouldPreload: true });
1007
+ }
1008
+ }
1009
+ /*
1010
+ * Register
1011
+ */
1012
+ static register(name = 'behold-video') {
1013
+ if (!customElements.get(name)) {
1014
+ customElements.define(name, Video);
1015
+ }
1016
+ return name;
1017
+ }
1018
+ }
1019
+
1020
+ /**
1021
+ * @description
1022
+ * Required props: 'post', 'widgetSettings',
1023
+ */
1024
+ class VideoPost extends BasePost {
1025
+ label = 'VideoPost';
1026
+ // Internal
1027
+ _videoEl;
1028
+ _imageEl;
1029
+ constructor() {
1030
+ super();
1031
+ // Listen to Prop changes
1032
+ this.onPropChange(this._handlePropChange, ['post', 'widgetSettings', 'aspectRatio'], null, this._render);
1033
+ // Register child components
1034
+ Video.register();
1035
+ Image.register();
1036
+ // Bind listeners
1037
+ this._handleMouseover = this._handleMouseover.bind(this);
1038
+ this._handleMouseleave = this._handleMouseleave.bind(this);
1039
+ this.onDisconnect(() => {
1040
+ this.removeEventListener('mouseover', this._handleMouseover);
1041
+ this.removeEventListener('mouseleave', this._handleMouseleave);
1042
+ });
1043
+ }
1044
+ /*
1045
+ * Handle prop change
1046
+ */
1047
+ _handlePropChange({ changedProp, oldValue, newValue }) {
1048
+ switch (changedProp) {
1049
+ case 'widgetSettings':
1050
+ if (hasChanges(oldValue, newValue, [
1051
+ 'onHover',
1052
+ 'onPostClick',
1053
+ 'previewVideosOnHover',
1054
+ ])) {
1055
+ this._render();
1056
+ }
1057
+ if (hasChanges(oldValue, newValue, ['autoplayVideos'])) {
1058
+ if (this.widgetSettings.previewVideosOnHover) {
1059
+ this._videoEl.autoplay = newValue.autoplayVideos;
1060
+ }
1061
+ else {
1062
+ this._render();
1063
+ }
1064
+ }
1065
+ break;
1066
+ case 'post':
1067
+ case 'aspectRatio':
1068
+ this._render();
1069
+ break;
1070
+ }
1071
+ }
1072
+ /**
1073
+ * handle mouseover
1074
+ */
1075
+ _handleMouseover() {
1076
+ this._videoEl?.play();
1077
+ }
1078
+ /**
1079
+ * Handle mouseleave
1080
+ */
1081
+ _handleMouseleave() {
1082
+ if (!this.widgetSettings.autoplayVideos) {
1083
+ this._videoEl?.pause();
1084
+ }
1085
+ }
1086
+ /**
1087
+ * Render
1088
+ */
1089
+ _render() {
1090
+ const { sizes, mediaUrl, thumbnailUrl } = this.post;
1091
+ if (((this.widgetSettings.previewVideosOnHover ||
1092
+ this.widgetSettings.autoplayVideos) &&
1093
+ mediaUrl) ||
1094
+ (!sizes.full.mediaUrl && !thumbnailUrl && mediaUrl)) {
1095
+ this._videoEl = createElement({
1096
+ type: 'behold-video',
1097
+ props: {
1098
+ mediaUrl,
1099
+ sizes,
1100
+ autoplay: this.widgetSettings.autoplayVideos,
1101
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
1102
+ renderPlaceholder: false,
1103
+ },
1104
+ listeners: {
1105
+ mouseover: this._handleMouseover,
1106
+ mouseleave: this._handleMouseleave,
1107
+ },
1108
+ });
1109
+ this.renderPost(this._videoEl);
1110
+ }
1111
+ else {
1112
+ this._imageEl = createElement({
1113
+ type: 'behold-image',
1114
+ props: {
1115
+ sizes,
1116
+ mediaUrl: thumbnailUrl,
1117
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
1118
+ },
1119
+ });
1120
+ this.renderPost(this._imageEl);
1121
+ }
1122
+ }
1123
+ /*
1124
+ * Register
1125
+ */
1126
+ static register(name = 'behold-video-post') {
1127
+ if (!customElements.get(name)) {
1128
+ customElements.define(name, VideoPost);
1129
+ }
1130
+ return name;
1131
+ }
1132
+ }
1133
+
1134
+ /**
1135
+ * @description
1136
+ * Required props: 'post'
1137
+ */
1138
+ class AlbumPost extends BasePost {
1139
+ label = 'AlbumPost';
1140
+ // Internal
1141
+ _mediaEl;
1142
+ constructor() {
1143
+ super();
1144
+ // Register child components
1145
+ Image.register();
1146
+ Video.register();
1147
+ // Listen to Prop changes
1148
+ this.onPropChange(this._handlePropChange, ['post', 'widgetSettings'], null, this._render);
1149
+ }
1150
+ /*
1151
+ * Handle prop change
1152
+ */
1153
+ _handlePropChange({ changedProp, oldValue, newValue }) {
1154
+ switch (changedProp) {
1155
+ case 'widgetSettings':
1156
+ if (hasChanges(newValue, oldValue, ['onHover', 'onPostClick'])) {
1157
+ this._render();
1158
+ }
1159
+ break;
1160
+ case 'post':
1161
+ case 'aspectRatio':
1162
+ this._render();
1163
+ break;
1164
+ }
1165
+ }
1166
+ /**
1167
+ * Render
1168
+ */
1169
+ _render() {
1170
+ let { sizes, mediaUrl, children } = this.post;
1171
+ // No sizes or mediaUrl, use children instead
1172
+ if (!sizes.full.mediaUrl && !mediaUrl) {
1173
+ const firstChildWithImage = children.reduce((acc, curr) => {
1174
+ if (curr.mediaType === 'VIDEO') {
1175
+ return curr.sizes.full.mediaUrl || curr.thumbnailUrl ? curr : acc;
1176
+ }
1177
+ return curr.sizes.full.mediaUrl || curr.mediaUrl ? curr : acc;
1178
+ });
1179
+ sizes = firstChildWithImage.sizes;
1180
+ mediaUrl =
1181
+ firstChildWithImage.thumbnailUrl ?? firstChildWithImage.mediaUrl;
1182
+ }
1183
+ if (this.post.mediaUrlIsVideo) {
1184
+ this._mediaEl = createElement({
1185
+ type: 'behold-video',
1186
+ props: {
1187
+ sizes,
1188
+ mediaUrl,
1189
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
1190
+ renderPlaceholder: false,
1191
+ },
1192
+ });
1193
+ }
1194
+ else {
1195
+ this._mediaEl = createElement({
1196
+ type: 'behold-image',
1197
+ props: {
1198
+ sizes,
1199
+ mediaUrl,
1200
+ aspectRatio: this.aspectRatio.reduce((w, h) => w / h),
1201
+ },
1202
+ });
1203
+ }
1204
+ this.renderPost(this._mediaEl);
1205
+ }
1206
+ /*
1207
+ * Register
1208
+ */
1209
+ static register(name = 'behold-album-post') {
1210
+ if (!customElements.get(name)) {
1211
+ customElements.define(name, AlbumPost);
1212
+ }
1213
+ return name;
1214
+ }
1215
+ }
1216
+
1217
+ 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:100%;width:100%}.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}";
1218
+ var baseGridStyles = css_248z;
1219
+
1220
+ 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 };