vviinn-widgets 2.18.21 → 2.19.1

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.
Files changed (183) hide show
  1. package/dist/cjs/{index-cb410762.js → Campaign-a94a827a.js} +17 -1
  2. package/dist/cjs/cropper-handler_29.cjs.entry.js +1418 -0
  3. package/dist/cjs/{imageSearch.store-98824653.js → index-48c94264.js} +16016 -11171
  4. package/dist/cjs/{index-7f1325a7.js → index-a4becaff.js} +683 -303
  5. package/dist/cjs/loader.cjs.js +4 -3
  6. package/dist/cjs/{vviinn-carousel_3.cjs.entry.js → vviinn-carousel_2.cjs.entry.js} +150 -270
  7. package/dist/cjs/vviinn-recommendations-sidebar.cjs.entry.js +14 -8
  8. package/dist/cjs/vviinn-vpr-button.cjs.entry.js +12 -14
  9. package/dist/cjs/vviinn-widgets.cjs.js +10 -3
  10. package/dist/collection/Image/sizing.spec.js +66 -0
  11. package/dist/collection/collection-manifest.json +2 -2
  12. package/dist/collection/components/image-search/image-view/highlight-box/highlight-box.css +2 -16
  13. package/dist/collection/components/image-search/image-view/highlight-box/highlight-box.js +11 -7
  14. package/dist/collection/components/image-search/image-view/image-cropper/cropper-handler/cropper-handler.css +0 -1
  15. package/dist/collection/components/image-search/image-view/image-cropper/cropper-handler/cropper-handler.js +40 -37
  16. package/dist/collection/components/image-search/image-view/image-cropper/image-cropper.js +73 -67
  17. package/dist/collection/components/image-search/search-filters/search-filters.css +4 -23
  18. package/dist/collection/components/image-search/search-filters/search-filters.js +97 -91
  19. package/dist/collection/components/vviinn-button/vviinn-button.js +34 -31
  20. package/dist/collection/components/vviinn-carousel/vviinn-carousel.css +1 -2
  21. package/dist/collection/components/vviinn-carousel/vviinn-carousel.js +161 -156
  22. package/dist/collection/components/vviinn-error/vviinn-empty-results/vviinn-empty-results.js +12 -14
  23. package/dist/collection/components/vviinn-error/vviinn-error.js +12 -12
  24. package/dist/collection/components/vviinn-error/vviinn-server-error/vviinn-server-error.js +35 -30
  25. package/dist/collection/components/vviinn-error/vviinn-wrong-format/vviinn-wrong-format.js +35 -30
  26. package/dist/collection/components/vviinn-example-images/vviinn-example-image/vviinn-example-image.js +129 -121
  27. package/dist/collection/components/vviinn-example-images/vviinn-example-images.js +75 -75
  28. package/dist/collection/components/vviinn-icons/index.js +10 -27
  29. package/dist/collection/components/vviinn-image-selector/vviinn-image-selector.js +120 -67
  30. package/dist/collection/components/vviinn-image-view/vviinn-detected-object/vviinn-detected-object.js +81 -69
  31. package/dist/collection/components/vviinn-image-view/vviinn-image-view.css +0 -1
  32. package/dist/collection/components/vviinn-image-view/vviinn-image-view.js +27 -28
  33. package/dist/collection/components/vviinn-modal/vviinn-modal.css +7 -36
  34. package/dist/collection/components/vviinn-modal/vviinn-modal.js +115 -93
  35. package/dist/collection/components/vviinn-onboarding/onboarding-cards/vviinn-onboarding-card-1/vviinn-onboarding-card-1.js +12 -14
  36. package/dist/collection/components/vviinn-onboarding/onboarding-cards/vviinn-onboarding-card-2/vviinn-onboarding-card-2.js +12 -14
  37. package/dist/collection/components/vviinn-onboarding/onboarding-cards/vviinn-onboarding-card-3/vviinn-onboarding-card-3.js +12 -14
  38. package/dist/collection/components/vviinn-onboarding/vviinn-onboarding.js +12 -17
  39. package/dist/collection/components/vviinn-overlay/vviinn-overlay.css +1 -12
  40. package/dist/collection/components/vviinn-overlay/vviinn-overlay.js +12 -9
  41. package/dist/collection/components/vviinn-overlayed-modal/vviinn-overlayed-modal.js +107 -78
  42. package/dist/collection/components/vviinn-preloader/vviinn-preloader.css +1 -11
  43. package/dist/collection/components/vviinn-preloader/vviinn-preloader.js +11 -7
  44. package/dist/collection/components/vviinn-privacy-badge/vviinn-privacy-badge.css +0 -1
  45. package/dist/collection/components/vviinn-privacy-badge/vviinn-privacy-badge.js +12 -16
  46. package/dist/collection/components/vviinn-product-card/render-helpers.js +6 -14
  47. package/dist/collection/components/vviinn-product-card/vviinn-product-card.js +425 -415
  48. package/dist/collection/components/vviinn-slider/arrow.js +1 -2
  49. package/dist/collection/components/vviinn-slider/vviinn-slide/vviinn-slide.js +12 -9
  50. package/dist/collection/components/vviinn-slider/vviinn-slider.css +0 -1
  51. package/dist/collection/components/vviinn-slider/vviinn-slider.js +87 -82
  52. package/dist/collection/components/vviinn-teaser/vviinn-teaser.js +12 -18
  53. package/dist/collection/components/vviinn-vpr-button/recommendations-sidebar/recommendations-sidebar.css +12 -64
  54. package/dist/collection/components/vviinn-vpr-button/recommendations-sidebar/recommendations-sidebar.js +371 -360
  55. package/dist/collection/components/vviinn-vpr-button/vviinn-vpr-button.js +448 -444
  56. package/dist/collection/components/vviinn-vpr-widget/vviinn-vpr-vidget.js +545 -542
  57. package/dist/collection/components/vviinn-vps-button/stories/vviinn-vps-button.stories.js +2 -0
  58. package/dist/collection/components/vviinn-vps-button/vviinn-vps-button.js +368 -332
  59. package/dist/collection/components/vviinn-vps-widget/vviinn-vps-widget.css +0 -5
  60. package/dist/collection/components/vviinn-vps-widget/vviinn-vps-widget.e2e.js +26 -0
  61. package/dist/collection/components/vviinn-vps-widget/vviinn-vps-widget.js +502 -425
  62. package/dist/collection/geometry/Clip.spec.js +16 -0
  63. package/dist/collection/geometry/Rectangle.spec.js +66 -0
  64. package/dist/collection/geometry/Sized.spec.js +16 -0
  65. package/dist/collection/interfaces/generated.js +0 -4
  66. package/dist/collection/network/ion/Form.spec.js +43 -0
  67. package/dist/esm/{index-b31d86ce.js → Campaign-4aa53f29.js} +15 -2
  68. package/dist/esm/cropper-handler_29.entry.js +1386 -0
  69. package/dist/esm/{index-590cb67e.js → index-48ef9564.js} +683 -304
  70. package/dist/esm/{imageSearch.store-9dde5360.js → index-976acf7e.js} +16124 -11292
  71. package/dist/esm/loader.js +4 -3
  72. package/dist/esm/polyfills/css-shim.js +1 -1
  73. package/dist/esm/{vviinn-carousel_3.entry.js → vviinn-carousel_2.entry.js} +106 -225
  74. package/dist/esm/vviinn-recommendations-sidebar.entry.js +13 -7
  75. package/dist/esm/vviinn-vpr-button.entry.js +11 -13
  76. package/dist/esm/vviinn-widgets.js +7 -3
  77. package/dist/loader/index.d.ts +9 -0
  78. package/dist/loader/package.json +1 -0
  79. package/dist/types/Image/sizing.d.ts +4 -4
  80. package/dist/types/campaign/Campaign.d.ts +5 -5
  81. package/dist/types/campaign/VCSCampaignResponse.d.ts +1 -1
  82. package/dist/types/components/vviinn-carousel/vviinn-carousel.d.ts +2 -2
  83. package/dist/types/components/vviinn-image-selector/vviinn-image-selector.d.ts +4 -0
  84. package/dist/types/components/vviinn-modal/vviinn-modal.d.ts +2 -0
  85. package/dist/types/components/vviinn-overlayed-modal/vviinn-overlayed-modal.d.ts +2 -0
  86. package/dist/types/components/vviinn-product-card/render-helpers.d.ts +3 -3
  87. package/dist/types/components/vviinn-slider/arrow.d.ts +2 -2
  88. package/dist/types/components/vviinn-vpr-button/recommendations-sidebar/recommendations-sidebar.d.ts +2 -2
  89. package/dist/types/components/vviinn-vps-button/vviinn-vps-button.d.ts +9 -4
  90. package/dist/types/components/vviinn-vps-widget/vviinn-vps-widget.d.ts +8 -0
  91. package/dist/types/components.d.ts +154 -54
  92. package/dist/types/error.d.ts +1 -1
  93. package/dist/types/geometry/Point.d.ts +1 -1
  94. package/dist/types/geometry/Rectangle.d.ts +1 -1
  95. package/dist/types/geometry/Sized.d.ts +1 -1
  96. package/dist/types/interfaces/generated.d.ts +192 -371
  97. package/dist/types/network/ion/File.d.ts +2 -2
  98. package/dist/types/network/ion/Form.d.ts +5 -5
  99. package/dist/types/network/ion/Link.d.ts +1 -1
  100. package/dist/types/network/ion/ValueObject.d.ts +4 -4
  101. package/dist/types/network/utils.d.ts +3 -3
  102. package/dist/types/recommendation/events.d.ts +5 -5
  103. package/dist/types/recommendation/recommendation.d.ts +1 -1
  104. package/dist/types/searchSession/searchSession.d.ts +7 -7
  105. package/dist/types/slider/GridMode.d.ts +1 -1
  106. package/dist/types/stencil-public-runtime.d.ts +98 -23
  107. package/dist/types/store/imageSearch.store.d.ts +1 -1
  108. package/dist/types/tracking/models.d.ts +2 -2
  109. package/dist/types/utils/event/Events.d.ts +1 -1
  110. package/dist/vviinn-widgets/p-312b0eb7.entry.js +1 -0
  111. package/dist/vviinn-widgets/p-414b2291.js +1 -0
  112. package/dist/vviinn-widgets/p-5b50c7e5.entry.js +1 -0
  113. package/dist/vviinn-widgets/p-8deaa5da.entry.js +1 -0
  114. package/dist/vviinn-widgets/p-c6209bc1.entry.js +1 -0
  115. package/{www/build/p-2f9ee951.js → dist/vviinn-widgets/p-d08ce429.js} +1 -1
  116. package/dist/vviinn-widgets/p-fa17e81f.js +2 -0
  117. package/dist/vviinn-widgets/vviinn-widgets.esm.js +1 -1
  118. package/package.json +12 -12
  119. package/www/build/p-312b0eb7.entry.js +1 -0
  120. package/www/build/p-414b2291.js +1 -0
  121. package/www/build/p-5b50c7e5.entry.js +1 -0
  122. package/www/build/p-8deaa5da.entry.js +1 -0
  123. package/www/build/p-c6209bc1.entry.js +1 -0
  124. package/{dist/vviinn-widgets/p-2f9ee951.js → www/build/p-d08ce429.js} +1 -1
  125. package/www/build/p-d39b7d70.js +161 -0
  126. package/www/build/p-fa17e81f.js +2 -0
  127. package/www/build/vviinn-widgets.esm.js +1 -1
  128. package/www/index.html +2 -2
  129. package/dist/cjs/Campaign-13258569.js +0 -18
  130. package/dist/cjs/Handler-176539c8.js +0 -331
  131. package/dist/cjs/cropper-handler.cjs.entry.js +0 -27
  132. package/dist/cjs/customized-slots-6e56c354.js +0 -54
  133. package/dist/cjs/highlight-box_22.cjs.entry.js +0 -770
  134. package/dist/cjs/index-a99edb90.js +0 -3235
  135. package/dist/cjs/vviinn-button.cjs.entry.js +0 -21
  136. package/dist/cjs/vviinn-error.cjs.entry.js +0 -19
  137. package/dist/cjs/vviinn-preloader.cjs.entry.js +0 -26
  138. package/dist/cjs/vviinn-vps-button.cjs.entry.js +0 -65
  139. package/dist/cjs/vviinn-vps-widget.cjs.entry.js +0 -251
  140. package/dist/esm/Campaign-90ba7e06.js +0 -14
  141. package/dist/esm/Handler-f9b8735c.js +0 -309
  142. package/dist/esm/cropper-handler.entry.js +0 -23
  143. package/dist/esm/customized-slots-00afe247.js +0 -51
  144. package/dist/esm/highlight-box_22.entry.js +0 -745
  145. package/dist/esm/index-4d5b52ba.js +0 -3224
  146. package/dist/esm/vviinn-button.entry.js +0 -17
  147. package/dist/esm/vviinn-error.entry.js +0 -15
  148. package/dist/esm/vviinn-preloader.entry.js +0 -22
  149. package/dist/esm/vviinn-vps-button.entry.js +0 -61
  150. package/dist/esm/vviinn-vps-widget.entry.js +0 -247
  151. package/dist/vviinn-widgets/p-11f61564.js +0 -1
  152. package/dist/vviinn-widgets/p-12851e97.entry.js +0 -1
  153. package/dist/vviinn-widgets/p-18fd769b.js +0 -1
  154. package/dist/vviinn-widgets/p-339c6838.js +0 -1
  155. package/dist/vviinn-widgets/p-3b2c91c0.entry.js +0 -1
  156. package/dist/vviinn-widgets/p-45df9f28.entry.js +0 -1
  157. package/dist/vviinn-widgets/p-57ed5303.entry.js +0 -1
  158. package/dist/vviinn-widgets/p-69850e5b.js +0 -1
  159. package/dist/vviinn-widgets/p-7c2f762a.entry.js +0 -1
  160. package/dist/vviinn-widgets/p-7c3b7388.entry.js +0 -1
  161. package/dist/vviinn-widgets/p-85006f41.entry.js +0 -1
  162. package/dist/vviinn-widgets/p-8a3dd76d.entry.js +0 -1
  163. package/dist/vviinn-widgets/p-99e58be7.entry.js +0 -1
  164. package/dist/vviinn-widgets/p-a2b450b6.entry.js +0 -1
  165. package/dist/vviinn-widgets/p-bcc1ccf0.js +0 -1
  166. package/dist/vviinn-widgets/p-e6fee8d2.js +0 -1
  167. package/www/build/p-11f61564.js +0 -1
  168. package/www/build/p-12851e97.entry.js +0 -1
  169. package/www/build/p-18fd769b.js +0 -1
  170. package/www/build/p-339c6838.js +0 -1
  171. package/www/build/p-3b2c91c0.entry.js +0 -1
  172. package/www/build/p-45df9f28.entry.js +0 -1
  173. package/www/build/p-57ed5303.entry.js +0 -1
  174. package/www/build/p-69850e5b.js +0 -1
  175. package/www/build/p-7c2f762a.entry.js +0 -1
  176. package/www/build/p-7c3b7388.entry.js +0 -1
  177. package/www/build/p-85006f41.entry.js +0 -1
  178. package/www/build/p-8a3dd76d.entry.js +0 -1
  179. package/www/build/p-99e58be7.entry.js +0 -1
  180. package/www/build/p-9e2c131a.js +0 -125
  181. package/www/build/p-a2b450b6.entry.js +0 -1
  182. package/www/build/p-bcc1ccf0.js +0 -1
  183. package/www/build/p-e6fee8d2.js +0 -1
@@ -0,0 +1,1386 @@
1
+ import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-48ef9564.js';
2
+ import { g as getCursorValue, p as pipe, O as Option, s as sequenceToOption, i as imageSearchState, a as pointDiffSemigroup, _ as _function, t as transform, m as move, f as fromMouseEvent, b as makeRectangularSearchRequest, c as fromAlt, d as foldValueObject, e as scaleWithSized, h as center, j as detectedObjectEq, k as toFile, l as processSelectedFile, E as Either, n as match, o as fromImage, q as dimensionsFromImage, r as scaleByLargestSide, S as Semigroup, u as state, N as NonEmptyArray, v as createProductViewVpsEvent, w as createProductClickVpsEvent, x as createSearchEvent, y as createFilterEvent, z as v4, A as createTrackingApi, B as createWidgetVpsEvent, C as isEmpty } from './index-976acf7e.js';
3
+ import { C as CheckIcon, V as VisualSearchIcon, c as campaignTypeNames, O as OnboardingCard1Icon, a as OnboardingCard2Icon, b as OnboardingCard3Icon, A as ArrowIcon, d as CameraIcon } from './Campaign-4aa53f29.js';
4
+
5
+ const cropperHandlerCss = ":host{--size:20px;background:transparent;border:4px solid white;box-sizing:content-box;display:block;height:var(--size);touch-action:none;position:absolute;width:var(--size);z-index:4;-webkit-user-select:none;-moz-user-select:none;user-select:none}:host(.disabled){opacity:0.25}:host(.nw-resize){border-bottom:none;border-right:none;top:0;left:0}:host(.ne-resize){border-left:none;border-bottom:none;right:0;top:0}:host(.sw-resize){border-right:none;border-top:none;left:0;bottom:0}:host(.se-resize){border-left:none;border-top:none;bottom:0;right:0}";
6
+
7
+ const CropperHandler = class {
8
+ constructor(hostRef) {
9
+ registerInstance(this, hostRef);
10
+ this.handler = undefined;
11
+ this.disabled = false;
12
+ }
13
+ render() {
14
+ return (h(Host, { part: `handle ${getCursorValue(this.handler.direction)}`, class: {
15
+ disabled: this.disabled,
16
+ [getCursorValue(this.handler.direction)]: true,
17
+ }, style: {
18
+ "--size": "20px",
19
+ cursor: getCursorValue(this.handler.direction),
20
+ }, draggable: false }));
21
+ }
22
+ };
23
+ CropperHandler.style = cropperHandlerCss;
24
+
25
+ const fromRectangle = (shape, target) => {
26
+ const top = `${shape.y}px`;
27
+ const left = `${shape.x}px`;
28
+ const right = `${target.width - (shape.x + shape.width)}px`;
29
+ const bottom = `${target.height - (shape.y + shape.height)}px`;
30
+ return {
31
+ top,
32
+ right,
33
+ bottom,
34
+ left,
35
+ };
36
+ };
37
+ const printClip = (clip) => `inset(${clip.top} ${clip.right} ${clip.bottom} ${clip.left})`;
38
+ const getClipValue = (shape, target) => printClip(fromRectangle(shape, target));
39
+
40
+ // -------------------------------------------------------------------------------------
41
+ // -------------------------------------------------------------------------------------
42
+ // instances
43
+ // -------------------------------------------------------------------------------------
44
+ /**
45
+ * @category instances
46
+ * @since 2.10.0
47
+ */
48
+ var Eq = {
49
+ equals: function (first, second) { return first === second; }
50
+ };
51
+ /**
52
+ * @category instances
53
+ * @since 2.10.0
54
+ */
55
+ var Ord = {
56
+ equals: Eq.equals,
57
+ compare: function (first, second) { return (first < second ? -1 : first > second ? 1 : 0); }
58
+ };
59
+
60
+ const highlightBoxCss = ":host{display:grid;position:absolute;box-sizing:border-box;border:none;width:100%;height:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;--size:10px;--x-position:0;--y-position:0}img{-webkit-user-select:none;-moz-user-select:none;user-select:none}.pointer{position:absolute;width:var(--size);height:var(--size);background:black;border-radius:50%;z-index:2;cursor:pointer;transform:translate(var(--x-position), var(--y-position)) scale(0);animation:0.25s linear fadein;animation-fill-mode:forwards}.pointer::after{content:\"\";cursor:pointer;border:5px solid black;border-radius:50%;width:var(--size);height:var(--size);display:block;transform:translate(calc(-50% + var(--size) * 0.5), calc(-50% + var(--size) * 0.5));padding:calc(var(--size) * 0.5);opacity:.75}@keyframes fadein{from{transform:translate(var(--x-position), var(--y-position)) scale(0)}to{transform:translate(var(--x-position), var(--y-position)) scale(1)}}";
61
+
62
+ const HighlightBox = class {
63
+ constructor(hostRef) {
64
+ registerInstance(this, hostRef);
65
+ }
66
+ getInsetValue() {
67
+ return pipe(sequenceToOption(imageSearchState.searchArea, imageSearchState.imageBounds), Option.map(([selection, image]) => getClipValue(selection, image)), Option.getOrElse(() => ""));
68
+ }
69
+ renderImage() {
70
+ return pipe(sequenceToOption(imageSearchState.imageUrl, imageSearchState.imageBounds), Option.map(([url, bounds]) => (h("img", { src: url, width: bounds.width, height: bounds.height, style: { "clip-path": `${this.getInsetValue()}` } }))), Option.getOrElse(() => ""));
71
+ }
72
+ render() {
73
+ return h(Host, null, this.renderImage());
74
+ }
75
+ };
76
+ HighlightBox.style = highlightBoxCss;
77
+
78
+ const findTarget = (ev) => {
79
+ return ev.target;
80
+ };
81
+
82
+ const imageCropperCss = ":host{display:block;height:100%;left:0;position:absolute;top:0;width:100%}:host(.hidden){visibility:hidden}.crop-area{border:1px solid white;box-sizing:border-box;position:absolute;touch-action:none;transition-property:border-color, opacity;transition-duration:.25s;transition-timing-function:ease-in-out;z-index:2;position:relative;will-change:transform}.crop-area.active{border-color:whitesmoke}.crop-area.disabled{opacity:0.25}";
83
+
84
+ const MIN_SEARCHAREA_SIZE = 40;
85
+ const ImageCropper = class {
86
+ constructor(hostRef) {
87
+ registerInstance(this, hostRef);
88
+ this.vviinnImageCrop = createEvent(this, "vviinnImageCrop", 7);
89
+ this.mouseStartPoint = undefined;
90
+ this.bounds = undefined;
91
+ this.resizeObserver = new ResizeObserver(() => {
92
+ this.bounds = this.el.getBoundingClientRect();
93
+ });
94
+ this.disabled = false;
95
+ this.basicEventData = undefined;
96
+ this.handleMove = false;
97
+ }
98
+ componentDidLoad() {
99
+ this.resizeObserver.observe(this.el);
100
+ }
101
+ disconnectedCallback() {
102
+ this.resizeObserver.disconnect();
103
+ }
104
+ handleHandlerMove(event) {
105
+ event.preventDefault();
106
+ event.stopPropagation();
107
+ const destination = fromMouseEvent(event);
108
+ const distance = pointDiffSemigroup.concat(destination, this.mouseStartPoint);
109
+ const transformedHandler = {
110
+ position: distance,
111
+ direction: this.handlerMoveDirection,
112
+ };
113
+ _function.pipe(imageSearchState.searchArea, Option.map((area) => {
114
+ const newSearchArea = transform(area, transformedHandler);
115
+ if (this.outOfBounds(newSearchArea))
116
+ return;
117
+ imageSearchState.searchArea = Option.some(newSearchArea);
118
+ this.mouseStartPoint = destination;
119
+ imageSearchState.detectedObject = undefined;
120
+ }));
121
+ }
122
+ outOfBounds(area) {
123
+ return (area.width < MIN_SEARCHAREA_SIZE ||
124
+ area.height < MIN_SEARCHAREA_SIZE ||
125
+ area.x < 0 ||
126
+ area.y < 0 ||
127
+ this.bounds.height - (area.y + area.height) < 0 ||
128
+ this.bounds.width - (area.x + area.width) < 0);
129
+ }
130
+ handleCropperMove(ev) {
131
+ ev.preventDefault();
132
+ ev.stopPropagation();
133
+ const destination = fromMouseEvent(ev);
134
+ const distance = pointDiffSemigroup.concat(destination, this.mouseStartPoint);
135
+ _function.pipe(imageSearchState.searchArea, Option.map((searchArea) => {
136
+ const newSearchArea = move(searchArea, distance);
137
+ if (newSearchArea.x < 0 ||
138
+ newSearchArea.y < 0 ||
139
+ this.bounds.height - (newSearchArea.y + newSearchArea.height) < 0 ||
140
+ this.bounds.width - (newSearchArea.x + newSearchArea.width) < 0)
141
+ return;
142
+ imageSearchState.detectedObject = undefined;
143
+ imageSearchState.searchArea = Option.some(newSearchArea);
144
+ this.mouseStartPoint = destination;
145
+ }));
146
+ }
147
+ handlePointerDown(event) {
148
+ event.stopPropagation();
149
+ this.mouseStartPoint = fromMouseEvent(event);
150
+ // should be htmlelement or handler
151
+ const target = findTarget(event);
152
+ if (target.localName === "cropper-handler") {
153
+ this.handlerMoveDirection = target.handler.direction;
154
+ this.pointerMoveListener = this.handleHandlerMove.bind(this);
155
+ }
156
+ else {
157
+ this.pointerMoveListener = this.handleCropperMove.bind(this);
158
+ }
159
+ this.pointerReleaseListener = this.handleSearchAreaRelease.bind(this);
160
+ this.el.addEventListener("pointermove", this.pointerMoveListener);
161
+ window.addEventListener("pointerup", this.pointerReleaseListener, {
162
+ once: true,
163
+ });
164
+ }
165
+ handleSearchAreaRelease() {
166
+ this.el.removeEventListener("pointermove", this.pointerMoveListener);
167
+ document.removeEventListener("pointerup", this.pointerReleaseListener);
168
+ this.mouseStartPoint = undefined;
169
+ makeRectangularSearchRequest();
170
+ this.vviinnImageCrop.emit(this.basicEventData);
171
+ }
172
+ getStyleMap() {
173
+ return _function.pipe(imageSearchState.searchArea, Option.map((rectangle) => {
174
+ return {
175
+ width: `${rectangle.width}px`,
176
+ height: `${rectangle.height}px`,
177
+ transform: `translate3d(${rectangle.x}px, ${rectangle.y}px, 0)`,
178
+ cursor: this.handleMove ? "move" : "default",
179
+ };
180
+ }), Option.getOrElse(() => {
181
+ return {};
182
+ }));
183
+ }
184
+ render() {
185
+ return (h(Host, { exportparts: "handle, e-resize, n-resize, ne-resize, nw-resize, s-resize, se-resize, sw-resize, w-resize" }, h("div", { class: {
186
+ "crop-area": true,
187
+ active: this.handleMove,
188
+ disabled: this.disabled,
189
+ }, draggable: false, style: this.getStyleMap(), onContextMenu: () => false, onPointerDown: (ev) => this.handlePointerDown(ev) }, imageSearchState.cropperHandlers.map((handler) => (h("cropper-handler", { disabled: this.disabled, handler: handler, onPointerDown: (ev) => this.handlePointerDown(ev) }))))));
190
+ }
191
+ get el() { return getElement(this); }
192
+ };
193
+ ImageCropper.style = imageCropperCss;
194
+
195
+ const searchFiltersCss = ":host{display:grid;grid-gap:1rem}.filters{display:flex;flex-direction:row;flex-wrap:wrap;gap:0.5rem}.filter{align-items:center;animation-duration:0.25s;animation-fill-mode:forwards;animation-name:scalein;border:1px solid lightgray;cursor:pointer;display:flex;flex-direction:row;grid-gap:8px;height:-moz-max-content;height:max-content;min-width:-moz-max-content;min-width:max-content;padding:0.1rem;transform:scale(0);transition-property:background;transition-duration:0.25s;transition-timing-function:ease-in-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:6px 16px}.filter.active{border:1px solid black;padding:6px 8px}.filter:hover{border:1px solid gray}.show-more{display:flex}.show-more.hidden{display:none}.show-more::after{content:url(\"data:image/svg+xml,%3Csvg width='16' height='16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 12.2l-6-6L3.2 5 8 9.8 12.8 5 14 6.2l-6 6z' fill='%23525252'/%3E%3C/svg%3E\");display:block;height:16px;margin-top:1px;margin-left:8px}.show-more.active::after{transform:rotateX(180deg)}@keyframes scalein{from{opacity:0;transform:scale(0.5)}to{opacity:1;transform:scale(1)}}@media (max-width: 415px){.show-more::after{transform:rotate(-90deg)}.show-more.active::after{transform:rotate(90deg)}}@media (max-width: 800px){.filters{flex-wrap:nowrap;overflow-x:scroll;scroll-snap-type:x mandatory;grid-gap:unset}.filter{scroll-snap-align:end;margin-right:0.5rem}}";
196
+
197
+ const FILTERS_COUNT = 5;
198
+ const ACTIVE_FILTER_CLASSNAME = ".filter.active";
199
+ const getFilterId = (filter) => filter.href.split("/").reverse()[0];
200
+ const SearchFilters = class {
201
+ constructor(hostRef) {
202
+ registerInstance(this, hostRef);
203
+ this.vviinnSelectFilter = createEvent(this, "vviinnSelectFilter", 7);
204
+ this.filter = null;
205
+ this.basicEventData = undefined;
206
+ this.selectedCategoryId = null;
207
+ this.hideFilters = true;
208
+ }
209
+ handleFilterSelection(filter) {
210
+ return this.isFilterSelected(filter)
211
+ ? this.clearSelectedFilter()
212
+ : this.selectFilter(filter);
213
+ }
214
+ selectFilter(filter) {
215
+ this.selectedCategoryId = getFilterId(filter);
216
+ imageSearchState.activeIonLink = filter;
217
+ this.vviinnSelectFilter.emit(Object.assign(Object.assign({}, this.basicEventData), { action: "select", filterName: filter.name }));
218
+ }
219
+ clearSelectedFilter() {
220
+ this.selectedCategoryId = null;
221
+ imageSearchState.activeIonLink = undefined;
222
+ this.findSelectedFilter().blur();
223
+ this.vviinnSelectFilter.emit(Object.assign(Object.assign({}, this.basicEventData), { action: "deselect" }));
224
+ }
225
+ findSelectedFilter() {
226
+ return this.el.shadowRoot.querySelector(ACTIVE_FILTER_CLASSNAME);
227
+ }
228
+ toggleFilters() {
229
+ this.hideFilters = !this.hideFilters;
230
+ }
231
+ handleEnter(ev, f) {
232
+ if (ev.key !== "Enter")
233
+ return;
234
+ this.handleFilterSelection(f);
235
+ }
236
+ isFilterSelected(filterLink) {
237
+ return this.selectedCategoryId === getFilterId(filterLink);
238
+ }
239
+ render() {
240
+ return (h(Host, { exportparts: "filter, show-more-filters" }, h("div", { class: "filters" }, this.filter.filters
241
+ .filter((_, i) => (this.hideFilters ? i < FILTERS_COUNT : true))
242
+ .map((f, n) => (h("div", { role: "button", tabindex: "0", part: this.isFilterSelected(f) ? "filter active" : "filter", class: {
243
+ filter: true,
244
+ active: this.selectedCategoryId === getFilterId(f),
245
+ }, style: { "animation-delay": `${n * 10}ms` }, onPointerUp: (ev) => {
246
+ ev.stopPropagation();
247
+ this.handleFilterSelection(f);
248
+ }, onKeyPress: (ev) => this.handleEnter(ev, f) }, this.isFilterSelected(f) ? h(CheckIcon, null) : null, f.name))), h("div", { class: {
249
+ filter: true,
250
+ "show-more": true,
251
+ hidden: this.filter.filters.length <= FILTERS_COUNT,
252
+ active: !this.hideFilters,
253
+ }, role: "button", tabindex: "0", "aria-role": "button", onClick: () => this.toggleFilters(), onKeyPress: (ev) => {
254
+ if (ev.key === "Enter") {
255
+ this.toggleFilters();
256
+ }
257
+ }, part: "show-more-filters" }, this.hideFilters ? "Zeige mehr" : "Zeige weniger"))));
258
+ }
259
+ get el() { return getElement(this); }
260
+ };
261
+ SearchFilters.style = searchFiltersCss;
262
+
263
+ const vviinnButtonCss = ":host{display:block}.open-button{align-items:center;background:rgba(255, 255, 255, 0.8);border-radius:50%;border:none;box-shadow:0px 2px 6px rgba(0, 0, 0, 0.15);box-sizing:border-box;cursor:pointer;display:grid;height:40px;justify-items:center;padding:0;width:40px;transition:all 0.25s ease-in-out}.raw-open-button{background:none;border:none;cursor:pointer}.open-button:hover{box-shadow:0px 2px 6px rgba(0, 0, 0, 0.25)}.open-button:focus{border:2px solid rgba(15, 98, 254, 0.5);outline:none}.open-button:active{background:#f4f4f4;outline:none}";
264
+
265
+ const VviinnButton = class {
266
+ constructor(hostRef) {
267
+ registerInstance(this, hostRef);
268
+ this.addStyle = true;
269
+ }
270
+ render() {
271
+ return (h(Host, { exportparts: "button" }, h("button", { class: this.addStyle ? "open-button" : "raw-open-button", part: "button" }, h("slot", null, h(VisualSearchIcon, null)))));
272
+ }
273
+ };
274
+ VviinnButton.style = vviinnButtonCss;
275
+
276
+ const vviinnDetectedObjectCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}:host{--size:32px;--x-position:0;--y-position:0;background:rgba(22, 22, 22, 0.5);border-radius:50%;border:none;cursor:pointer;display:block;height:var(--size);position:absolute;transition:opacity 0.25s;width:var(--size);z-index:2;transform:translate(calc(var(--x-position) - (var(--size) * 0.5)), calc(var(--y-position) - (var(--size) * 0.5)));transition:background 0.1 ease-in-out}:host(:hover){background:rgba(22, 22, 22, 0.75)}:host(.active){background:var(--color-primary, var(--color-primary-system))!important;border:2px solid white}:host::after{--size:32px;border-radius:50%;content:\"\";cursor:pointer;display:block;height:calc(var(--size) * 0.25);transform:translate(calc(-50% + var(--size) * 0.5), calc(-50% + var(--size) * 0.5));width:calc(var(--size) * 0.25);background:white}";
277
+
278
+ const VviinnDetectedObject = class {
279
+ constructor(hostRef) {
280
+ registerInstance(this, hostRef);
281
+ this.vviinnSelectObject = createEvent(this, "vviinnSelectObject", 7);
282
+ this.detectedObject = undefined;
283
+ this.basicEventData = undefined;
284
+ this.position = ["0", "0"];
285
+ }
286
+ getObjectPosition() {
287
+ return _function.pipe(imageSearchState.imageBounds, Option.map((bounds) => {
288
+ const objectRectangle = fromAlt(foldValueObject(this.detectedObject).rectangle);
289
+ const { x, y } = _function.pipe(objectRectangle, scaleWithSized(bounds), center);
290
+ return [`${x}px`, `${y}px`];
291
+ }), Option.getOrElse(() => ["0", "0"]));
292
+ }
293
+ selectDetectedObject() {
294
+ _function.pipe(imageSearchState.imageBounds, Option.map((bounds) => {
295
+ const rectangle = foldValueObject(this.detectedObject).rectangle;
296
+ const transformedRect = fromAlt(rectangle);
297
+ const scaledRect = scaleWithSized(bounds)(transformedRect);
298
+ imageSearchState.detectedObject = this.detectedObject;
299
+ imageSearchState.searchArea = Option.some(scaledRect);
300
+ }));
301
+ makeRectangularSearchRequest();
302
+ this.vviinnSelectObject.emit(Object.assign(Object.assign({}, this.basicEventData), { detectedObject: this.detectedObject }));
303
+ }
304
+ isActive() {
305
+ if (!this.detectedObject)
306
+ return false;
307
+ if (!imageSearchState.detectedObject)
308
+ return false;
309
+ const thisObject = foldValueObject(this.detectedObject);
310
+ const savedObject = foldValueObject(imageSearchState.detectedObject);
311
+ return detectedObjectEq.equals(thisObject, savedObject);
312
+ }
313
+ render() {
314
+ return (h(Host, { class: {
315
+ active: this.isActive(),
316
+ }, onClick: () => this.selectDetectedObject(), style: {
317
+ "--x-position": this.getObjectPosition()[0],
318
+ "--y-position": this.getObjectPosition()[1],
319
+ } }));
320
+ }
321
+ };
322
+ VviinnDetectedObject.style = vviinnDetectedObjectCss;
323
+
324
+ const vviinnEmptyResultsCss = ":host{display:grid}vviinn-error{justify-items:center}";
325
+
326
+ const VviinnEmptyResults = class {
327
+ constructor(hostRef) {
328
+ registerInstance(this, hostRef);
329
+ }
330
+ render() {
331
+ return (h(Host, null, h("vviinn-error", null, h("svg", { slot: "icon", class: "icon", width: "32", height: "32", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M16 2a14 14 0 1 0 0 28 14 14 0 0 0 0-28Zm0 26a12 12 0 1 1 0-24 12 12 0 0 1 0 24Z", fill: "#525252" }), h("path", { d: "M17 8h-2v11h2V8Zm-1 14a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z", fill: "#525252" })), h("h4", { slot: "title" }, "Leider nichts gefunden"), h("span", { slot: "text" }, "Leider konnten wir keine passenden Produkte finden. Bitte versuche es mit einem anderen Bildausschnitt noch einmal."))));
332
+ }
333
+ };
334
+ VviinnEmptyResults.style = vviinnEmptyResultsCss;
335
+
336
+ const vviinnErrorCss = ":host{background:#F4F4F4;border-radius:8px;display:grid;grid-gap:20px;padding:24px;text-align:center}::slotted(svg){display:grid;align-self:center}::slotted(h4){margin:unset;font-weight:600;font-size:18px;line-height:24px}::slotted(span){font-size:14px;line-height:20px}::slotted(button){-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;background:transparent;color:var(--color-primary, var(--color-primary-system));font-weight:600;font-size:16px;line-height:20px;cursor:pointer}";
337
+
338
+ const VviinnError = class {
339
+ constructor(hostRef) {
340
+ registerInstance(this, hostRef);
341
+ }
342
+ render() {
343
+ return (h(Host, null, h("slot", { name: "icon" }), h("slot", { name: "title" }), h("slot", { name: "text" }), h("slot", { name: "action" })));
344
+ }
345
+ };
346
+ VviinnError.style = vviinnErrorCss;
347
+
348
+ const vviinnExampleImageCss = ":host{display:block;margin-bottom:8px;position:relative}:host(:focus){border:2px solid var(--color-primary)}img{width:100%;height:auto;cursor:pointer}.image-preloader{background:rgba(0, 0, 0, 0.25);border-radius:4px;bottom:12px;display:none;padding:4px 6px;position:absolute;right:12px;z-index:4}vviinn-preloader{--preloader-size:12px}@media (max-width: 640px){.image-preloader{display:block}}";
349
+
350
+ const VviinnExampleImage = class {
351
+ constructor(hostRef) {
352
+ registerInstance(this, hostRef);
353
+ this.vviinnImageUpload = createEvent(this, "vviinnImageUpload", 7);
354
+ this.vviinnNoResult = createEvent(this, "vviinnNoResult", 7);
355
+ this.src = "";
356
+ this.width = 0;
357
+ this.height = 0;
358
+ this.basicEventData = undefined;
359
+ this.selected = false;
360
+ }
361
+ async selectImage() {
362
+ this.selected = true;
363
+ const file = await toFile(this.src);
364
+ const processResult = await processSelectedFile(file);
365
+ _function.pipe(processResult, Either.match(() => this.vviinnNoResult.emit(this.basicEventData), () => this.vviinnImageUpload.emit(this.basicEventData)));
366
+ this.selected = false;
367
+ }
368
+ handleKeyPress({ key }) {
369
+ if (key !== "Enter" && key !== " ")
370
+ return;
371
+ this.selectImage();
372
+ }
373
+ showPreloader() {
374
+ return ((imageSearchState.objectDetectionInProgress ||
375
+ imageSearchState.loading) &&
376
+ this.selected);
377
+ }
378
+ render() {
379
+ return (h(Host, { onClick: () => this.selectImage(), onKeyUp: (ev) => this.handleKeyPress(ev) }, this.showPreloader() ? (h("div", { class: "image-preloader" }, h("vviinn-preloader", null))) : null, h("img", { src: this.src, width: this.width, height: this.height, tabindex: 1 })));
380
+ }
381
+ };
382
+ VviinnExampleImage.style = vviinnExampleImageCss;
383
+
384
+ const defaultSlotsNames = [
385
+ "vviinn-onboarding-title",
386
+ "onboarding-card-1-icon",
387
+ "onboarding-card-1-text",
388
+ "onboarding-card-2-icon",
389
+ "onboarding-card-2-text",
390
+ "onboarding-card-3-icon",
391
+ "onboarding-card-3-text",
392
+ "vviinn-example-images-title",
393
+ "vviinn-example-images-1",
394
+ "vviinn-example-images-2",
395
+ "vviinn-example-images-3",
396
+ "vviinn-example-images-4",
397
+ "vviinn-teaser-text",
398
+ "vviinn-image-upload-button-text",
399
+ "vviinn-privacy-badge-text",
400
+ "vviinn-image-search-modal-title",
401
+ ];
402
+ const renderNamedSlot = (name) => h("slot", { name: name });
403
+ const SlotSkeleton = () => defaultSlotsNames.map(renderNamedSlot);
404
+ const getSlots = (element) => Array.from(element.shadowRoot.querySelectorAll("slot"));
405
+ const getNameAttribute = (element) => element.getAttribute("name");
406
+ const getSlotAttribute = (element) => element.getAttribute("slot");
407
+ const elementContainSlot = (slot) => (container) => {
408
+ const name1 = getNameAttribute(slot);
409
+ const name2 = getSlotAttribute(container);
410
+ return name1 === name2;
411
+ };
412
+ const getContentToReplace = (targets) => (acc, content) => {
413
+ const replaceCandidate = targets.find(elementContainSlot(content));
414
+ if (replaceCandidate) {
415
+ acc.set(content, replaceCandidate);
416
+ }
417
+ return acc;
418
+ };
419
+ const replaceSlotContent = (content, target) => {
420
+ target.innerHTML = content.outerHTML;
421
+ };
422
+ const slotChangeListener = (component, element) => {
423
+ component.connectedCallback = function () {
424
+ document.addEventListener("globalSlotsChanged", ({ detail }) => {
425
+ const slotsToReplace = getSlots(element).reduce(getContentToReplace(detail), new Map());
426
+ slotsToReplace.forEach(replaceSlotContent);
427
+ }, true);
428
+ };
429
+ component.connectedCallback.call(component);
430
+ };
431
+
432
+ const vviinnExampleImagesCss = "h3{font-size:22px;font-weight:600;line-height:32px;margin:0;margin-bottom:16px;text-align:center}.images{display:block;-moz-column-count:2;column-count:2;-moz-column-gap:16px;column-gap:16px}";
433
+
434
+ const VviinnExampleImages = class {
435
+ constructor(hostRef) {
436
+ registerInstance(this, hostRef);
437
+ this.vviinnImageUpload = createEvent(this, "vviinnImageUpload", 7);
438
+ this.vviinnNoResult = createEvent(this, "vviinnNoResult", 7);
439
+ this.basicEventData = undefined;
440
+ }
441
+ componentWillLoad() {
442
+ slotChangeListener(this, this.el);
443
+ }
444
+ delegateFocus() {
445
+ const firstSlot = this.imagesBlock.childNodes[0];
446
+ const firstExampleImage = firstSlot.childNodes[0];
447
+ firstExampleImage.focus();
448
+ }
449
+ render() {
450
+ return (h(Host, { onFocus: () => this.delegateFocus() }, h("slot", { name: "vviinn-example-images-title" }, h("h3", null, "Mit den Beispielbildern die Suche direkt ausprobieren")), h("div", { class: "images", ref: (el) => (this.imagesBlock = el) }, h("slot", { name: "vviinn-example-images-1" }, h("vviinn-example-image", { width: 480, height: 640, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDEtTC5qcGc=", basicEventData: this.basicEventData })), h("slot", { name: "vviinn-example-images-2" }, h("vviinn-example-image", { width: 280, height: 480, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDItTS5qcGc=", basicEventData: this.basicEventData })), h("slot", { name: "vviinn-example-images-3" }, h("vviinn-example-image", { width: 280, height: 480, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDMtTS5qcGc=", basicEventData: this.basicEventData })), h("slot", { name: "vviinn-example-images-4" }, h("vviinn-example-image", { width: 480, height: 640, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDQtTC5qcGc=", basicEventData: this.basicEventData })))));
451
+ }
452
+ get el() { return getElement(this); }
453
+ };
454
+ VviinnExampleImages.style = vviinnExampleImagesCss;
455
+
456
+ const vviinnImageSelectorCss = ":host{display:block}:host(::hover){background:whitesmoke}.visually-hidden{clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}label{cursor:pointer;display:grid;width:100%;height:100%;transition:background 0.1s ease-in-out}";
457
+
458
+ const VviinnImageSelector = class {
459
+ constructor(hostRef) {
460
+ registerInstance(this, hostRef);
461
+ this.vviinnImageUpload = createEvent(this, "vviinnImageUpload", 7);
462
+ this.vviinnNoResult = createEvent(this, "vviinnNoResult", 7);
463
+ this.basicEventData = undefined;
464
+ this.startUpload = undefined;
465
+ this.resetVpsButton = undefined;
466
+ }
467
+ async handleInputChange(event) {
468
+ const input = event.target;
469
+ const processingResult = await processSelectedFile(input.files[0]);
470
+ _function.pipe(processingResult, match(() => this.vviinnNoResult.emit(this.basicEventData), () => this.vviinnImageUpload.emit(this.basicEventData)));
471
+ input.value = null;
472
+ }
473
+ isLoading() {
474
+ return imageSearchState.loading;
475
+ }
476
+ startUploadWatcher(upload) {
477
+ if (upload) {
478
+ this.fileInput.click();
479
+ this.resetVpsButton();
480
+ }
481
+ }
482
+ render() {
483
+ return (h(Host, { exportparts: "button" }, this.isLoading() ? h("vviinn-preloader", null) : null, this.isLoading() ? null : (h("label", { htmlFor: "fileInput", part: "button" }, h("slot", { name: "upload-button-text" }, "Upload image"))), h("input", { id: "fileInput", class: "visually-hidden", type: "file", accept: "image/*", onChange: (event) => this.handleInputChange(event), ref: (el) => (this.fileInput = el) })));
484
+ }
485
+ static get watchers() { return {
486
+ "startUpload": ["startUploadWatcher"]
487
+ }; }
488
+ };
489
+ VviinnImageSelector.style = vviinnImageSelectorCss;
490
+
491
+ const vviinnImageViewCss = ":host{display:grid;position:relative;justify-self:center;direction:ltr}img{box-sizing:border-box;filter:brightness(60%);position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:-1}.image-preloader{background:rgba(0, 0, 0, 0.25);border-radius:4px;bottom:18px;padding:4px 6px;pointer-events:none;position:absolute;right:18px;z-index:4}vviinn-preloader{--preloader-size:12px}";
492
+
493
+ const getImageSizes = (i) => {
494
+ const dimensions = dimensionsFromImage(i);
495
+ const resize = scaleByLargestSide(288);
496
+ const newDimensions = resize(dimensions);
497
+ const sizes = newDimensions.map((d) => d.size);
498
+ return [sizes[0], sizes[1]];
499
+ };
500
+ const VviinnImageView = class {
501
+ constructor(hostRef) {
502
+ registerInstance(this, hostRef);
503
+ this.basicEventData = undefined;
504
+ }
505
+ handleInitialImageLoad(ev) {
506
+ const target = ev.target;
507
+ const imageBounds = fromImage(target);
508
+ const padding = 12;
509
+ const { x, y } = move(imageBounds, { x: padding, y: padding });
510
+ const searchArea = {
511
+ x,
512
+ y,
513
+ width: imageBounds.width - padding * 2,
514
+ height: imageBounds.height - padding * 2,
515
+ };
516
+ imageSearchState.imageBounds = Option.some(imageBounds);
517
+ imageSearchState.searchArea = Option.some(searchArea);
518
+ }
519
+ renderDetectedObject(object) {
520
+ return (h("vviinn-detected-object", { detectedObject: object, basicEventData: this.basicEventData }));
521
+ }
522
+ renderImage() {
523
+ return _function.pipe(sequenceToOption(imageSearchState.imageUrl, imageSearchState.image), Option.map(([url, refImage]) => {
524
+ const [width, height] = getImageSizes(refImage);
525
+ const image = (h("img", { decoding: "async", width: width, height: height, src: url, onLoad: (el) => this.handleInitialImageLoad(el), draggable: false }));
526
+ return image;
527
+ }), Option.getOrElse(() => null));
528
+ }
529
+ renderCropper() {
530
+ return _function.pipe(imageSearchState.imageUrl, Option.map(() => h("image-cropper", { basicEventData: this.basicEventData })), Option.getOrElse(() => null));
531
+ }
532
+ render() {
533
+ return (h(Host, null, imageSearchState.loading ||
534
+ imageSearchState.objectDetectionInProgress ? (h("div", { class: "image-preloader" }, h("vviinn-preloader", null))) : null, h("highlight-box", null), this.renderImage(), this.renderCropper(), imageSearchState.detectedObjects.map((o) => this.renderDetectedObject(o))));
535
+ }
536
+ };
537
+ VviinnImageView.style = vviinnImageViewCss;
538
+
539
+ const vviinnModalCss = ":host{background:white;border-radius:4px;box-sizing:border-box;display:grid;grid-template-rows:min-content auto;max-width:960px;overflow:auto}@media (max-width: 415px){:host{animation-name:fade-in;animation-duration:0.5s;animation-fill-mode:forwards}:host(.closed){animation-name:fade-out;animation-fill-mode:none}.body{overflow-y:auto}}@media (max-width: 640px) and (min-width: 415px){:host{max-width:80%}}.head{align-items:center;border-bottom:1px solid #f4f4f4;display:flex;padding:16px}.title{font-weight:600;font-size:18px;line-height:24px;margin:0 auto}button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:grid;padding:unset}@keyframes fade-in{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes fade-out{from{transform:translateY(0)}to{transform:translateY(100%)}}";
540
+
541
+ const VviinnModal = class {
542
+ constructor(hostRef) {
543
+ registerInstance(this, hostRef);
544
+ this.vviinnWidgetClose = createEvent(this, "vviinnWidgetClose", 7);
545
+ this.active = false;
546
+ this.resetState = undefined;
547
+ this.buttonElementId = undefined;
548
+ this.hideBackButton = false;
549
+ this.slider = false;
550
+ }
551
+ componentWillLoad() {
552
+ slotChangeListener(this, this.el);
553
+ }
554
+ close() {
555
+ this.active = false;
556
+ setTimeout(() => {
557
+ this.vviinnWidgetClose.emit({
558
+ widgetType: "VPS",
559
+ campaignTypeId: "VPS",
560
+ campaignTypeName: campaignTypeNames["VPS"],
561
+ widgetId: this.buttonElementId,
562
+ });
563
+ }, this.slider ? 500 : 0);
564
+ }
565
+ handleAnimationEnd(ev) {
566
+ if (ev.animationName !== "fade-in")
567
+ return;
568
+ this.slider = true;
569
+ }
570
+ render() {
571
+ return (h(Host, { exportparts: "secondary-action, title, close-button", class: { closed: !this.active }, onAnimationEnd: (ev) => this.handleAnimationEnd(ev) }, h("div", { class: "head" }, !this.hideBackButton && (h("button", { part: "secondary-action", onClick: () => this.resetState() }, h("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M20.25 12H3.75", stroke: "#161616", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { d: "M10.5 5.25L3.75 12L10.5 18.75", stroke: "#161616", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" })))), h("div", { class: "title", part: "title" }, h("slot", { name: "vviinn-image-search-modal-title" }, "Bildsuche")), h("button", { onClick: () => this.close(), class: "close-button", part: "close-button" }, h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M16 1.4L14.6 0L8 6.6L1.4 0L0 1.4L6.6 8L0 14.6L1.4 16L8 9.4L14.6 16L16 14.6L9.4 8L16 1.4Z", fill: "#333333" })))), h("div", { class: "body" }, h("slot", null))));
572
+ }
573
+ get el() { return getElement(this); }
574
+ };
575
+ VviinnModal.style = vviinnModalCss;
576
+
577
+ const vviinnOnboardingCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}::host{display:block}h3{font-size:22px;font-weight:600;line-height:32px;margin:0;margin-bottom:16px;text-align:center}vviinn-slide{background:#f4f4f4;padding:24px}svg{padding:16px 0}.text{display:grid;grid-gap:8px}.text>h4{color:#161616;font-size:18px;font-weight:600;line-height:24px;margin:unset;text-align:center}.text>p{color:#525252;font-size:14px;font-style:normal;font-weight:normal;line-height:20px;margin:unset;text-align:center}.colored{fill:var(--color-icons, var(--color-icons-system))}";
578
+
579
+ const VviinnOnboarding = class {
580
+ constructor(hostRef) {
581
+ registerInstance(this, hostRef);
582
+ }
583
+ componentWillLoad() {
584
+ slotChangeListener(this, this.el);
585
+ }
586
+ render() {
587
+ return (h(Host, null, h("slot", { name: "vviinn-onboarding-title" }, h("h3", null, "So funktioniert es")), h("vviinn-slider", { showArrows: true }, h("vviinn-slide", null, h("vviinn-onboarding-card-1", null)), h("vviinn-slide", null, h("vviinn-onboarding-card-2", null)), h("vviinn-slide", null, h("vviinn-onboarding-card-3", null)))));
588
+ }
589
+ get el() { return getElement(this); }
590
+ };
591
+ VviinnOnboarding.style = vviinnOnboardingCss;
592
+
593
+ const onboardingCardCss$2 = ":host{align-items:center;background:#f4f4f4;display:grid;grid-template-rows:repeat(2, 1fr);justify-items:center;padding:24px;width:100%}h4{color:#161616;font-size:18px;font-weight:600;line-height:24px;margin:unset;text-align:center}svg{padding:16px 0}p{color:#525252;font-size:14px;font-style:normal;font-weight:normal;line-height:20px;margin:unset;text-align:center}.colored{fill:var(--color-icons, var(--color-icons-system))}.text{display:grid;grid-gap:8px}";
594
+
595
+ const VviinnOnboardingCard1 = class {
596
+ constructor(hostRef) {
597
+ registerInstance(this, hostRef);
598
+ }
599
+ componentWillLoad() {
600
+ slotChangeListener(this, this.el);
601
+ }
602
+ render() {
603
+ return (h(Host, null, h("slot", { name: "onboarding-card-1-icon" }, h(OnboardingCard1Icon, null)), h("slot", { name: "onboarding-card-1-text" }, h("div", { class: "text" }, h("h4", null, "Starte die Bildsuche"), h("p", null, "Lade ein Bild aus Deiner Galerie hoch oder fotografiere ein Produkt mit Deiner Kamera.")))));
604
+ }
605
+ get el() { return getElement(this); }
606
+ };
607
+ VviinnOnboardingCard1.style = onboardingCardCss$2;
608
+
609
+ const onboardingCardCss$1 = ":host{align-items:center;background:#f4f4f4;display:grid;grid-template-rows:repeat(2, 1fr);justify-items:center;padding:24px;width:100%}h4{color:#161616;font-size:18px;font-weight:600;line-height:24px;margin:unset;text-align:center}svg{padding:16px 0}p{color:#525252;font-size:14px;font-style:normal;font-weight:normal;line-height:20px;margin:unset;text-align:center}.colored{fill:var(--color-icons, var(--color-icons-system))}.text{display:grid;grid-gap:8px}";
610
+
611
+ const VviinnOnboardingCard2 = class {
612
+ constructor(hostRef) {
613
+ registerInstance(this, hostRef);
614
+ }
615
+ componentWillLoad() {
616
+ slotChangeListener(this, this.el);
617
+ }
618
+ render() {
619
+ return (h(Host, null, h("slot", { name: "onboarding-card-2-icon" }, h(OnboardingCard2Icon, null)), h("slot", { name: "onboarding-card-2-text" }, h("div", { class: "text" }, h("h4", null, "Verfeiner deine Suche"), h("p", null, "Du kannst den Bildrahmen selber festlegen und so die Produkte genau ausw\u00E4hlen.")))));
620
+ }
621
+ get el() { return getElement(this); }
622
+ };
623
+ VviinnOnboardingCard2.style = onboardingCardCss$1;
624
+
625
+ const onboardingCardCss = ":host{align-items:center;background:#f4f4f4;display:grid;grid-template-rows:repeat(2, 1fr);justify-items:center;padding:24px;width:100%}h4{color:#161616;font-size:18px;font-weight:600;line-height:24px;margin:unset;text-align:center}svg{padding:16px 0}p{color:#525252;font-size:14px;font-style:normal;font-weight:normal;line-height:20px;margin:unset;text-align:center}.colored{fill:var(--color-icons, var(--color-icons-system))}.text{display:grid;grid-gap:8px}";
626
+
627
+ const VviinnOnboardingCard3 = class {
628
+ constructor(hostRef) {
629
+ registerInstance(this, hostRef);
630
+ }
631
+ componentWillLoad() {
632
+ slotChangeListener(this, this.el);
633
+ }
634
+ render() {
635
+ return (h(Host, null, h("slot", { name: "onboarding-card-3-icon" }, h(OnboardingCard3Icon, null)), h("slot", { name: "onboarding-card-3-text" }, h("div", { class: "text" }, h("h4", null, "Ohne Hintergrund"), h("p", null, "Die besten Ergebnisse erh\u00E4ltst Du, wenn das gesuchte Objekt mit einfarbigem und hellem Hintergrund zu sehen ist.")))));
636
+ }
637
+ get el() { return getElement(this); }
638
+ };
639
+ VviinnOnboardingCard3.style = onboardingCardCss;
640
+
641
+ const vviinnOverlayCss = ":host{animation:fade-in 0.5s ease-in-out;background:rgba(0, 0, 0, 0.5);display:block;height:100vh;left:0;overflow:hidden;position:fixed;top:0;width:100vw;z-index:9999}@keyframes fade-in{from{opacity:0.1}to{opacity:1}}";
642
+
643
+ const VviinnOverlay = class {
644
+ constructor(hostRef) {
645
+ registerInstance(this, hostRef);
646
+ }
647
+ render() {
648
+ return (h(Host, null, h("slot", null)));
649
+ }
650
+ };
651
+ VviinnOverlay.style = vviinnOverlayCss;
652
+
653
+ const vviinnOverlayedModalCss = ":host{display:none}:host(.active){display:block}vviinn-overlay{align-items:center;display:grid;justify-items:center;cursor:default}@media (max-width: 415px){vviinn-modal{border-radius:4px 4px 0 0;height:100vh;margin-top:32px;transform:translateY(100%);width:100vw}vviinn-overlay{align-items:end;display:grid;justify-items:center}}";
654
+
655
+ const VviinnOverlayedModal = class {
656
+ constructor(hostRef) {
657
+ registerInstance(this, hostRef);
658
+ this.vviinnWidgetClose = createEvent(this, "vviinnWidgetClose", 7);
659
+ this.active = false;
660
+ this.resetState = undefined;
661
+ this.buttonElementId = undefined;
662
+ this.hideBackButton = false;
663
+ }
664
+ render() {
665
+ return (h(Host, { class: { active: this.active } }, h("vviinn-overlay", null, h("vviinn-modal", { resetState: this.resetState, active: this.active, buttonElementId: this.buttonElementId, hideBackButton: this.hideBackButton }, h("slot", null, "CONTENT")))));
666
+ }
667
+ };
668
+ VviinnOverlayedModal.style = vviinnOverlayedModalCss;
669
+
670
+ const vviinnPreloaderCss = ":host{--preloader-size:24px;--preloader-width:calc(var(--preloader-size) / 6);transform-origin:center;animation:rotate 3s linear infinite;border:var(--preloader-width) solid white;border-radius:50%;border-top-color:transparent;display:none;outline:0;width:var(--preloader-size);height:var(--preloader-size);box-sizing:border-box}:host(.active){display:flex}@keyframes rotate{from{transform:rotate(-360deg)}to{transform:rotate(360deg)}}";
671
+
672
+ const VviinnPreloader = class {
673
+ constructor(hostRef) {
674
+ registerInstance(this, hostRef);
675
+ }
676
+ isActive() {
677
+ return (imageSearchState.loading || imageSearchState.objectDetectionInProgress);
678
+ }
679
+ render() {
680
+ return (h(Host, { class: {
681
+ active: this.isActive(),
682
+ } }));
683
+ }
684
+ };
685
+ VviinnPreloader.style = vviinnPreloaderCss;
686
+
687
+ const vviinnPrivacyBadgeCss = ":host{display:block;background:#F4F4F4;padding:17px}.content{display:grid;grid-template-columns:min-content auto;grid-gap:9px}.content p{color:#525252;font-size:12px;line-height:16px;margin:unset}";
688
+
689
+ const VviinnPrivacyBadge = class {
690
+ constructor(hostRef) {
691
+ registerInstance(this, hostRef);
692
+ }
693
+ componentWillLoad() {
694
+ slotChangeListener(this, this.el);
695
+ }
696
+ render() {
697
+ return (h(Host, null, h("slot", null, h("div", { class: "content" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none" }, h("defs", null), h("path", { fill: "#525252", d: "M8.5 11V7h-2v1h1v3H6v1h4v-1H8.5zM8 4a.75.75 0 100 1.5A.75.75 0 008 4z" }), h("path", { fill: "#525252", d: "M8 15A7 7 0 118 1a7 7 0 010 14zM8 2a6 6 0 100 12A6 6 0 008 2z" })), h("slot", { name: "vviinn-privacy-badge-text" }, h("p", null, "Durch das Hochladen eines Bildes willigen Sie in die Verarbeitung durch unseren Partner Vviinn ein. Das Bild wird nach einer Stunde Inaktivit\u00E4t gel\u00F6scht."))))));
698
+ }
699
+ get el() { return getElement(this); }
700
+ };
701
+ VviinnPrivacyBadge.style = vviinnPrivacyBadgeCss;
702
+
703
+ class GtagAnalytics {
704
+ sendImpression(product) {
705
+ var _a, _b, _c;
706
+ gtag('event', 'view_item_list', {
707
+ items: [
708
+ {
709
+ id: product.productId,
710
+ name: product.title,
711
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
712
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
713
+ list_name: 'VI VPR View',
714
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
715
+ }
716
+ ]
717
+ });
718
+ return undefined;
719
+ }
720
+ sendClick(product) {
721
+ var _a, _b, _c;
722
+ gtag('event', 'select_content', {
723
+ content_type: 'product',
724
+ items: [
725
+ {
726
+ id: product.productId,
727
+ name: product.title,
728
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
729
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
730
+ list_name: 'VI VPR View',
731
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
732
+ }
733
+ ]
734
+ });
735
+ return undefined;
736
+ }
737
+ }
738
+
739
+ class GAnalytics {
740
+ constructor() {
741
+ ga('require', 'ec');
742
+ }
743
+ convertProduct(product) {
744
+ var _a, _b, _c;
745
+ return {
746
+ id: product.productId,
747
+ name: product.title,
748
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
749
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
750
+ list: 'VI VPR View',
751
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
752
+ };
753
+ }
754
+ sendImpression(product) {
755
+ ga('ec:addImpression', this.convertProduct(product));
756
+ return undefined;
757
+ }
758
+ sendClick(product) {
759
+ var _a, _b, _c;
760
+ ga('ec:addProduct', {
761
+ id: product.productId,
762
+ name: product.title,
763
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
764
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
765
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
766
+ });
767
+ ga('ec:setAction', 'click', { list: 'VI VPR View' });
768
+ return undefined;
769
+ }
770
+ }
771
+
772
+ const getGtagAnalytics = () => _function.pipe(Option.fromNullable(window.gtag), Option.map(() => new GtagAnalytics()));
773
+ const getCommonAnalytics = () => _function.pipe(Option.fromNullable(window.ga), Option.map(() => new GAnalytics()));
774
+ const analyticsMonoid = Option.getMonoid(Semigroup.first());
775
+ const getAnalyticsModule = analyticsMonoid.concat(getGtagAnalytics(), getCommonAnalytics());
776
+
777
+ const FIT_EXPR = /fit\/\d+\//;
778
+ const containsFit = (url) => {
779
+ return _function.pipe(url.match(FIT_EXPR), Either.fromNullable(url), Either.map(() => url));
780
+ };
781
+ const processWidth = (url, size) => {
782
+ return _function.pipe(containsFit(url), Either.map((url) => url.replace(FIT_EXPR, `fit/${size}/`)), Either.getOrElse(() => url));
783
+ };
784
+ const Linked = (props, child) => props.deeplink ? (h("a", { class: props.part, part: props.part, href: props.deeplink }, child)) : (child);
785
+ const FormattedPrice = (props) => {
786
+ const locale = props.locale;
787
+ const priceType = props.priceType;
788
+ const formattedPrice = new Intl.NumberFormat(locale, {
789
+ minimumFractionDigits: 2,
790
+ }).format(props.price);
791
+ const prefixElement = props.prefix ? (h("span", { part: "price-prefix" }, props.prefix + " ")) : null;
792
+ const currencyElement = props.currency ? (h("span", { part: "currency" }, " " + props.currency)) : null;
793
+ return (h("span", { class: "price-amount", part: `price-amount${priceType ? "-" + priceType : ""}` },
794
+ prefixElement,
795
+ formattedPrice,
796
+ currencyElement));
797
+ };
798
+ const Price = (props) => {
799
+ return (h("span", { class: "price-container", part: "price-container" }, props.salePrice ? ([
800
+ h("span", { class: "price-sale", part: "price-sale" },
801
+ h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.salePrice, locale: props.locale, priceType: "sale" })),
802
+ h("span", { class: "price-outdated", part: "price-outdated" },
803
+ h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.price, locale: props.locale, priceType: "outdated" })),
804
+ ]) : (h("span", { class: "price-regular", part: "price-regular" },
805
+ h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.price, locale: props.locale, priceType: "regular" })))));
806
+ };
807
+ const Image = (props, onLoadEnd = () => undefined) => (h("picture", null,
808
+ h("img", { loading: props.lazy ? "lazy" : "eager", part: "image", class: "image", width: props.width, height: props.height, src: processWidth(props.src, props.width), alt: props.title, onLoad: onLoadEnd })));
809
+ const ResponsiveImage = (props, onLoadEnd = () => undefined) => (h("picture", null,
810
+ h("img", { loading: props.lazy ? "lazy" : "eager", part: "image", class: "image responsive", src: processWidth(props.src, props.width), alt: props.title, onLoad: onLoadEnd })));
811
+
812
+ const vviinnProductCardCss = ":host{align-items:center;display:flex;flex-direction:column;gap:8px;height:100%}.price-container{display:flex;flex-direction:column}.price-sale,.price-regular{font-style:normal;font-weight:normal;font-size:16px;line-height:24px;color:#161616}.price-outdated{font-style:normal;font-weight:normal;font-size:16px;line-height:24px;color:#757575;text-decoration:line-through}.product-type{word-wrap:anywhere}.image{display:grid;align-content:center;-o-object-position:50% 50%;object-position:50% 50%;-o-object-fit:contain;object-fit:contain;text-align:center;box-sizing:border-box}img.responsive{width:100%;height:auto;aspect-ratio:1}.brand,.type{display:none}.title{-webkit-box-orient:vertical;-webkit-line-clamp:2;color:#161616;display:-webkit-box;font-size:16px;font-style:normal;font-weight:500;line-height:24px;margin-bottom:8px;overflow:hidden}.deeplink{text-decoration:none}.image-link{display:contents}picture{position:relative;width:100%}:host(.dimmed) picture::before{content:\"\";width:100%;height:100%;box-sizing:border-box;background:#f7f7f7;display:block;top:0;left:0;position:absolute;mix-blend-mode:multiply}";
813
+
814
+ const VviinnProductCard = class {
815
+ constructor(hostRef) {
816
+ registerInstance(this, hostRef);
817
+ this.vviinnProductLoad = createEvent(this, "vviinnProductLoad", 7);
818
+ this.vviinnProductView = createEvent(this, "vviinnProductView", 7);
819
+ this.vviinnProductClick = createEvent(this, "vviinnProductClick", 7);
820
+ this.productData = null;
821
+ this.intersectionObserver = new IntersectionObserver(this.intersectionCallback.bind(this), { threshold: 1.0 });
822
+ this.brand = undefined;
823
+ this.currency = undefined;
824
+ this.deeplink = undefined;
825
+ this.image = undefined;
826
+ this.imageRatio = 1;
827
+ this.imageWidth = 200;
828
+ this.locale = undefined;
829
+ this.price = undefined;
830
+ this.pricePrefix = undefined;
831
+ this.productId = undefined;
832
+ this.productTitle = undefined;
833
+ this.productType = undefined;
834
+ this.salePrice = undefined;
835
+ this.responsive = false;
836
+ this.campaignTypeId = undefined;
837
+ this.dimmedBackground = false;
838
+ this.widgetElementId = undefined;
839
+ this.buttonElementId = undefined;
840
+ this.index = 0;
841
+ this.imageLoaded = false;
842
+ }
843
+ connectedCallback() {
844
+ this.productData = this.getProductData();
845
+ }
846
+ getWidgetType() {
847
+ return this.campaignTypeId === "VPR" || this.campaignTypeId === "VCS"
848
+ ? "VPR"
849
+ : "VPS";
850
+ }
851
+ getProductData() {
852
+ var _a;
853
+ return {
854
+ productId: this.productId,
855
+ productRank: this.index,
856
+ productName: this.productTitle,
857
+ widgetType: this.getWidgetType(),
858
+ campaignTypeId: this.campaignTypeId,
859
+ campaignTypeName: campaignTypeNames[this.campaignTypeId],
860
+ widgetId: (_a = this.buttonElementId) !== null && _a !== void 0 ? _a : this.widgetElementId,
861
+ };
862
+ }
863
+ intersectionCallback(data) {
864
+ if (data.some((entry) => entry.isIntersecting)) {
865
+ _function.pipe(getAnalyticsModule, Option.map((analytics) => analytics.sendImpression(this.getProduct())));
866
+ this.vviinnProductView.emit(this.productData);
867
+ this.intersectionObserver.disconnect();
868
+ }
869
+ }
870
+ componentDidLoad() {
871
+ this.vviinnProductLoad.emit(this.productData);
872
+ this.intersectionObserver.observe(this.el);
873
+ const links = this.el.shadowRoot.querySelectorAll("a");
874
+ links.forEach((link) => link.addEventListener("click", (event) => {
875
+ event.preventDefault();
876
+ event.stopImmediatePropagation();
877
+ this.vviinnProductClick.emit(this.productData);
878
+ _function.pipe(getAnalyticsModule, Option.match(() => null, (analytics) => analytics.sendClick(this.getProduct())));
879
+ }));
880
+ }
881
+ getProduct() {
882
+ return imageSearchState.results.find((r) => r.productId === this.productId);
883
+ }
884
+ renderImage() {
885
+ const props = {
886
+ width: this.imageWidth,
887
+ height: this.imageWidth * this.imageRatio,
888
+ src: this.image,
889
+ title: this.productTitle,
890
+ lazy: false,
891
+ };
892
+ return this.responsive ? ResponsiveImage(props) : Image(props);
893
+ }
894
+ render() {
895
+ var _a, _b, _c;
896
+ return (h(Host, { part: "product-card", class: { dimmed: this.dimmedBackground }, exportparts: "brand, currency, deeplink, image, image-link, price-amount-sale, price-amount-outdated, price-amount-regular, price-container, price-outdated, price-regular, price-sale, price-prefix, title" }, h(Linked, { deeplink: this.deeplink, part: "image-link" }, this.renderImage()), h(Linked, { deeplink: this.deeplink, part: "deeplink" }, h("span", { class: "title", part: "title" }, this.productTitle)), h("span", { class: "brand", part: "brand" }, this.brand), h("span", { class: "type", part: "type" }, this.productType), h(Price, { prefix: (_a = this.pricePrefix) !== null && _a !== void 0 ? _a : state.pricePrefix, currency: (_b = this.currency) !== null && _b !== void 0 ? _b : state.currencySign, price: this.price, salePrice: this.salePrice, locale: (_c = this.locale) !== null && _c !== void 0 ? _c : state.locale })));
897
+ }
898
+ get el() { return getElement(this); }
899
+ };
900
+ VviinnProductCard.style = vviinnProductCardCss;
901
+
902
+ const vviinnServerErrorCss = ":host{display:block}";
903
+
904
+ const VviinnServerError = class {
905
+ constructor(hostRef) {
906
+ registerInstance(this, hostRef);
907
+ this.handler = undefined;
908
+ }
909
+ render() {
910
+ return (h(Host, null, h("vviinn-error", null, h("h4", { slot: "title" }, "Keine Verbindung"), h("span", { slot: "text" }, "Etwas hat leider nicht funktioniert. Bitte pr\u00FCfen Sie Ihre Internetverbindung und laden Sie das Bild noch einmal hoch."), h("button", { slot: "action", onClick: this.handler }, "Erneut versuchen"))));
911
+ }
912
+ };
913
+ VviinnServerError.style = vviinnServerErrorCss;
914
+
915
+ const vviinnSlideCss = ":host{display:grid;justify-items:center}";
916
+
917
+ const VviinnSlide = class {
918
+ constructor(hostRef) {
919
+ registerInstance(this, hostRef);
920
+ }
921
+ render() {
922
+ return (h(Host, null, h("slot", null)));
923
+ }
924
+ };
925
+ VviinnSlide.style = vviinnSlideCss;
926
+
927
+ const getStyleMap = (data) => {
928
+ return {
929
+ "arrow-wrapper": true,
930
+ [data.kind]: true,
931
+ disabled: data.disabled,
932
+ };
933
+ };
934
+ const Arrow = ({ kind, tabindex, disabled, onClick, onKeyDown, }) => (h("div", { class: getStyleMap({ kind, disabled }), onClick: onClick, tabindex: tabindex, onKeyDown: onKeyDown },
935
+ h(ArrowIcon, null)));
936
+
937
+ const vviinnSliderCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}:host{--num-items:0;--position:0;display:grid;grid-gap:20px;justify-items:center;position:relative}.items-wrapper{overflow:hidden;width:100%}.items{box-sizing:border-box;display:grid;grid-auto-flow:column;grid-template-columns:repeat(var(--num-items), 100%);transform:translateX(calc(-100% * var(--position)));transition:transform 0.33s ease-in-out}.controls{display:grid;grid-gap:16px;grid-template-columns:repeat(var(--num-items), min-content)}.bullet{background:#e0e0e0;border-radius:50%;box-sizing:border-box;cursor:pointer;height:8px;width:8px;transition:background 0.1s ease-in-out}.bullet:hover{background:#c6c6c6}.bullet.active{background:var(--color-primary, var(--color-primary-system))}.bullet:active{background:transparent;border:2px solid var(--color-primary, var(--color-primary-system))}.arrow-wrapper{align-items:center;cursor:pointer;background:white;border:2px solid white;bottom:0;box-sizing:border-box;display:grid;height:calc(var(--spacer) * 6);justify-items:center;margin:auto;position:absolute;top:0;transform:translate3d(0, -50%, 0);transition:border 0.25ms ease-in-out;width:calc(var(--spacer) * 4)}.arrow-wrapper:active{border-color:var(--color-primary, var(--color-primary-system));opacity:0.75}.arrow-wrapper:focus{border-color:var(--color-primary, var(--color-primary-system));opacity:0.5;outline:none}.prev{left:0}.next{right:0}.next>svg{transform:rotate3d(0, 1, 0, 180deg)}.arrow-wrapper>svg{transition:fill 0.25ms ease-in-out;fill:#a8a8a8}.arrow-wrapper:hover>svg{fill:#8d8d8d}";
938
+
939
+ const VviinnSlider = class {
940
+ constructor(hostRef) {
941
+ registerInstance(this, hostRef);
942
+ this.elementsCount = 0;
943
+ this.internalPosition = 0;
944
+ this.swipeStartPosition = Option.none;
945
+ this.isRTL = false;
946
+ this.showBullets = true;
947
+ this.position = 0;
948
+ this.showArrows = false;
949
+ }
950
+ positionWatchHandler(newValue) {
951
+ this.internalPosition = newValue;
952
+ this.el.style.setProperty("--position", `${this.calculatePosition(newValue)}`);
953
+ this.setActiveCssClassToSlide(newValue);
954
+ }
955
+ componentWillLoad() {
956
+ this.isRTL = document.dir === "rtl";
957
+ }
958
+ connectedCallback() {
959
+ this.handleDomContentChanges();
960
+ }
961
+ handleDomContentChanges() {
962
+ const items = this.el.querySelectorAll("vviinn-slide");
963
+ this.elementsCount = items.length;
964
+ this.el.style.setProperty("--num-items", `${this.elementsCount}`);
965
+ this.setActiveCssClassToSlide(0);
966
+ }
967
+ setActiveCssClassToSlide(index) {
968
+ const items = this.el.querySelectorAll("vviinn-slide");
969
+ items.forEach((i) => i.classList.remove("active"));
970
+ items[index].classList.add("active");
971
+ }
972
+ goToSlide(index) {
973
+ this.internalPosition = index;
974
+ this.el.style.setProperty("--position", `${index}`);
975
+ this.setActiveCssClassToSlide(index);
976
+ }
977
+ renderBullets() {
978
+ return this.showBullets ? (h("div", { class: "controls" }, NonEmptyArray.range(0, this.elementsCount - 1).map((i) => (h("div", { class: {
979
+ bullet: true,
980
+ active: i == Math.abs(this.internalPosition) % this.elementsCount,
981
+ }, onClick: () => this.goToSlide(i) }))))) : null;
982
+ }
983
+ nextSlide() {
984
+ this.internalPosition++;
985
+ this.renderSlidePosition();
986
+ }
987
+ prevSlide() {
988
+ const nextPostion = this.internalPosition - 1;
989
+ this.internalPosition =
990
+ nextPostion > -1 ? nextPostion : this.elementsCount - 1;
991
+ this.renderSlidePosition();
992
+ }
993
+ renderSlidePosition() {
994
+ const position = this.internalPosition % this.elementsCount;
995
+ requestAnimationFrame(() => {
996
+ this.el.style.setProperty("--position", `${this.calculatePosition(position)}`);
997
+ });
998
+ }
999
+ calculatePosition(position) {
1000
+ return this.isRTL ? position * -1 : position;
1001
+ }
1002
+ handleKeyDown(event) {
1003
+ if (event.key !== "Space" && event.key !== "Enter")
1004
+ return;
1005
+ const target = event.target;
1006
+ const direction = target.className.includes("prev") ? "prev" : "next";
1007
+ switch (direction) {
1008
+ case "prev":
1009
+ this.prevSlide();
1010
+ break;
1011
+ case "next":
1012
+ this.nextSlide();
1013
+ break;
1014
+ }
1015
+ }
1016
+ handleTouchStart(event) {
1017
+ if (!this.showBullets)
1018
+ return;
1019
+ this.swipeStartPosition = _function.pipe(event.touches[0], Option.fromNullable, Option.map((t) => t.clientX));
1020
+ }
1021
+ handleTouchEnd(event) {
1022
+ if (!this.showBullets)
1023
+ return;
1024
+ const swipeEndPosition = _function.pipe(event.changedTouches[0], Option.fromNullable, Option.map((t) => t.clientX));
1025
+ _function.pipe(sequenceToOption(this.swipeStartPosition, swipeEndPosition), Option.map(([start, end]) => Ord.compare(start, end)), Option.map((swipeDirection) => {
1026
+ switch (swipeDirection) {
1027
+ case 1:
1028
+ return this.nextSlide();
1029
+ case -1:
1030
+ return this.prevSlide();
1031
+ }
1032
+ }));
1033
+ }
1034
+ render() {
1035
+ return (h(Host, null, h("div", { class: "items-wrapper" }, h("div", { class: "items", onTouchStart: (e) => this.handleTouchStart(e), onTouchEnd: (e) => this.handleTouchEnd(e) }, h("slot", null))), this.showArrows
1036
+ ? [
1037
+ h(Arrow, { kind: "prev", onClick: () => this.isRTL ? this.nextSlide() : this.prevSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 1, disabled: false }),
1038
+ h(Arrow, { kind: "next", onClick: () => this.isRTL ? this.prevSlide() : this.nextSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 0, disabled: false }),
1039
+ ]
1040
+ : null, this.renderBullets()));
1041
+ }
1042
+ get el() { return getElement(this); }
1043
+ static get watchers() { return {
1044
+ "position": ["positionWatchHandler"]
1045
+ }; }
1046
+ };
1047
+ VviinnSlider.style = vviinnSliderCss;
1048
+
1049
+ const vviinnTeaserCss = ":host{align-items:center;display:grid;justify-items:center;grid-gap:16px}.vviinn-teaser-text{font-size:28px;font-weight:600;line-height:40px;size:28px;text-align:center}";
1050
+
1051
+ const VviinnTeaser = class {
1052
+ constructor(hostRef) {
1053
+ registerInstance(this, hostRef);
1054
+ }
1055
+ componentWillLoad() {
1056
+ slotChangeListener(this, this.el);
1057
+ }
1058
+ render() {
1059
+ return (h(Host, null, h("slot", null, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "64", height: "64", fill: "none" }, h("defs", null), h("path", { fill: "#C6C6C6", d: "M48 28a11.98 11.98 0 00-9.77 18.942L28 57.172 30.828 60l10.23-10.23A11.994 11.994 0 1048 28zm0 20a8 8 0 118-8 8.009 8.009 0 01-8 8zM34 24a6 6 0 10-6-6 6.006 6.006 0 006 6zm0-8a2 2 0 110 4 2 2 0 010-4z" }), h("path", { fill: "#C6C6C6", d: "M24 48H8V35.993L18 26l11.172 11.172L32 34.336 20.828 23.165a4 4 0 00-5.656 0L8 30.336V8h40v12h4V8a4.004 4.004 0 00-4-4H8a4.004 4.004 0 00-4 4v40a4.005 4.005 0 004 4h16v-4z" })), h("span", { class: "vviinn-teaser-text" }, h("slot", { name: "vviinn-teaser-text" }, "Finde Produkte auf ", h("br", null), " einem Foto")))));
1060
+ }
1061
+ get el() { return getElement(this); }
1062
+ };
1063
+ VviinnTeaser.style = vviinnTeaserCss;
1064
+
1065
+ const vviinnVpsButtonCss = ":host{display:block}";
1066
+
1067
+ const VviinnVpsButton = class {
1068
+ constructor(hostRef) {
1069
+ registerInstance(this, hostRef);
1070
+ this.globalSlotsChanged = createEvent(this, "globalSlotsChanged", 7);
1071
+ this.vviinnWidgetOpen = createEvent(this, "vviinnWidgetOpen", 7);
1072
+ this.vviinnImageUpload = createEvent(this, "vviinnImageUpload", 7);
1073
+ this.vviinnNoResult = createEvent(this, "vviinnNoResult", 7);
1074
+ this.vviinnWidgetLoad = createEvent(this, "vviinnWidgetLoad", 7);
1075
+ this.vviinnWidgetClose = createEvent(this, "vviinnWidgetClose", 7);
1076
+ this.vviinnProductClick = createEvent(this, "vviinnProductClick", 7);
1077
+ this.vviinnProductView = createEvent(this, "vviinnProductView", 7);
1078
+ this.vviinnProductLoad = createEvent(this, "vviinnProductLoad", 7);
1079
+ this.vviinnImageCrop = createEvent(this, "vviinnImageCrop", 7);
1080
+ this.vviinnSelectObject = createEvent(this, "vviinnSelectObject", 7);
1081
+ this.vviinnSelectFilter = createEvent(this, "vviinnSelectFilter", 7);
1082
+ this.getBasicEventData = () => {
1083
+ return {
1084
+ widgetType: "VPS",
1085
+ campaignTypeId: "VPS",
1086
+ campaignTypeName: campaignTypeNames["VPS"],
1087
+ widgetId: this.el.id,
1088
+ };
1089
+ };
1090
+ this.token = undefined;
1091
+ this.currencySign = "€";
1092
+ this.locale = "de-DE";
1093
+ this.campaignId = undefined;
1094
+ this.addStyle = false;
1095
+ this.mode = "modal";
1096
+ this.apiPath = undefined;
1097
+ this.buttonPressed = false;
1098
+ }
1099
+ handleModalClosed() {
1100
+ this.buttonPressed = false;
1101
+ }
1102
+ componentDidLoad() {
1103
+ const slots = this.el.querySelectorAll("[slot]");
1104
+ this.globalSlotsChanged.emit(Array.from(slots));
1105
+ }
1106
+ handleClick() {
1107
+ this.buttonPressed = true;
1108
+ }
1109
+ resetButton() {
1110
+ this.buttonPressed = false;
1111
+ }
1112
+ render() {
1113
+ return (h(Host, { tabindex: "0", role: "button" }, h("vviinn-button", { onClick: () => {
1114
+ this.handleClick();
1115
+ }, addStyle: this.addStyle, part: "vviinn-button" }, h("slot", null, h(CameraIcon, null))), h(SlotSkeleton, null), h("vviinn-vps-widget", { mode: this.mode, "currency-sign": this.currencySign, token: this.token, locale: this.locale, apiPath: this.apiPath, exportparts: "brand, deeplink, currency, image, image-link, price-amount-sale, price-amount-outdated, price-amount-regular, price-container, price-outdated, price-regular, price-sale, price-prefix, title, product-card, example-images", campaignId: this.campaignId, showingInButton: true, buttonPressed: this.buttonPressed, resetVpsButton: this.resetButton.bind(this), buttonElementId: this.el.id })));
1116
+ }
1117
+ get el() { return getElement(this); }
1118
+ };
1119
+ VviinnVpsButton.style = vviinnVpsButtonCss;
1120
+
1121
+ const vviinnVpsWidgetCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}:host{display:block}.hidden{visibility:hidden;height:1px}vviinn-overlayed-modal.first-screen::part(title),vviinn-overlayed-modal.first-screen::part(secondary-action){visibility:hidden}.start-page{display:grid;grid-template-columns:repeat(2, 1fr);min-height:580px}.start-page_block{align-content:start;border-right:1px solid #f4f4f4;display:grid;padding:48px}.start-page_block.error{align-content:center}#onboarding-block{border-right:unset;box-sizing:border-box;grid-gap:24px;overflow-y:auto;position:relative;width:100%}vviinn-teaser{margin-bottom:32px;margin-top:-24px}vviinn-image-selector{align-items:center;background:var(--color-primary, var(--color-primary-system));border-color:var(--color-primary, var(--color-primary-system));border-radius:2px;color:white;display:grid;font-size:16px;font-weight:600;height:56px;justify-items:center;margin-bottom:16px;transition:background 0.1s ease-in-out}vviinn-image-selector:hover{background:var(--color-primary-hover, var(--color-primary-hover-system));border-color:var(--color-primary-hover, var(--color-primary-hover-system))}vviinn-image-selector:active{border-color:black}.upload-button-content{display:grid;align-items:center;justify-items:start;justify-content:center;grid-template-columns:max-content auto;grid-gap:16px}.results-page{display:grid;grid-template-columns:336px auto;box-sizing:border-box}.results-page>*{padding:24px;box-sizing:border-box}.products{align-content:center;align-items:start;box-sizing:border-box;display:grid;grid-gap:32px 16px;grid-template-columns:repeat(auto-fill, minmax(152px, 1fr));justify-items:center;padding:24px;padding-right:0;position:absolute;width:calc(100% - 16px)}.products.hidden{display:none}vviinn-empty-results{width:280px;align-self:center;justify-self:center}.products-wrapper{display:grid;overflow-y:auto;overflow-x:hidden;padding:unset;position:relative;width:100%}.image-wrapper{border-right:1px solid #f4f4f4;display:grid;grid-template-rows:min-content 170px;grid-gap:24px;min-width:100%}.onboarding-wrapper{position:absolute;width:100%;padding:48px;box-sizing:border-box;display:grid;grid-gap:64px;padding-bottom:24px}vviinn-product-card{gap:0;width:100%}vviinn-product-card::part(image){border:1px solid #eaeaea;margin-bottom:8px}vviinn-product-card::part(price-container),vviinn-product-card::part(deeplink),vviinn-product-card::part(title){align-self:start}search-filters span{display:none}search-filters::part(filter){background:#f4f4f4;border-radius:4px;border:1px solid #f4f4f4;box-sizing:border-box;color:#161616;font-size:14px;font-weight:600;line-height:20px}search-filters::part(show-more-filters){border:1px solid #f4f4f4;border-radius:4px;box-sizing:border-box;color:#161616;font-size:14px;font-weight:600;line-height:20px;padding:6px 16px}search-filters::part(show-more-filters):hover{background:#eaeaea}search-filters::part(filter):hover{background:#eaeaea}search-filters::part(filter):focus{outline:none;border:1px solid var(--color-primary, var(--color-primary-system))}search-filters::part(filter active){background:rgba(15, 98, 254, 0.15);color:var(--color-primary, var(--color-primary-system))}.filters-wrapper{overflow:auto}.results-page:not(.active){display:none}.nothing-found{display:grid;grid-gap:64px;justify-self:center;padding-top:64px;padding-bottom:16px;position:absolute;width:60%}@media (max-width: 768px){.start-page_block{padding:24px}.onboarding-wrapper{padding:24px}}@media (max-width: 640px){.start-page{grid-template-rows:min-content;grid-template-columns:unset;grid-gap:48px;padding:24px 0 48px 0}}@media (max-width: 640px) and (min-width: 415px){.onboarding-wrapper{position:unset}#onboarding-block{overflow:unset}.start-page.active{height:1px;overflow:auto}}@media (max-width: 415px){.results-page>*{box-sizing:border-box;padding:24px}vviinn-slide{padding-bottom:48px}.start-page_block:last-of-type{border-right:unset;overflow-y:unset;position:static;box-sizing:border-box;width:unset}.start-page_block{padding:0 24px}vviinn-teaser{margin-top:24px}.onboarding-wrapper{position:static;width:unset;padding:unset;box-sizing:border-box}.results-page{grid-template-columns:unset;grid-template-rows:min-content auto}.image{margin-bottom:8px}.image-wrapper{grid-template-rows:min-content auto;width:100%}.products-wrapper{align-content:start;position:static;overflow-y:unset;width:100%;padding-top:0}.products{position:static;padding:0;width:unset;grid-gap:32px 16px;justify-content:center}.nothing-found{position:static;grid-gap:64px;padding:unset;align-content:start;width:unset}}@media (max-width: 320px){.products{grid-template-columns:unset}}vviinn-wrong-format,vviinn-server-error{width:280px;align-self:center;justify-self:center}";
1122
+
1123
+ var __rest = (undefined && undefined.__rest) || function (s, e) {
1124
+ var t = {};
1125
+ for (var p in s)
1126
+ if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
1127
+ t[p] = s[p];
1128
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
1129
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
1130
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
1131
+ t[p[i]] = s[p[i]];
1132
+ }
1133
+ return t;
1134
+ };
1135
+ const filterInt = (value) => /^[-+]?(\d+|Infinity)$/.test(value) ? Number(value) : NaN;
1136
+ const notEmptyString = (s) => !isEmpty(s);
1137
+ const notNan = (n) => !isNaN(n);
1138
+ const VviinnVpsWidget = class {
1139
+ constructor(hostRef) {
1140
+ registerInstance(this, hostRef);
1141
+ this.globalSlotsChanged = createEvent(this, "globalSlotsChanged", 7);
1142
+ this.vviinnWidgetLoad = createEvent(this, "vviinnWidgetLoad", 7);
1143
+ this.vviinnWidgetOpen = createEvent(this, "vviinnWidgetOpen", 7);
1144
+ this.vviinnWidgetClose = createEvent(this, "vviinnWidgetClose", 7);
1145
+ this.vviinnProductClick = createEvent(this, "vviinnProductClick", 7);
1146
+ this.vviinnProductView = createEvent(this, "vviinnProductView", 7);
1147
+ this.vviinnProductLoad = createEvent(this, "vviinnProductLoad", 7);
1148
+ this.vviinnImageUpload = createEvent(this, "vviinnImageUpload", 7);
1149
+ this.vviinnImageCrop = createEvent(this, "vviinnImageCrop", 7);
1150
+ this.vviinnSelectObject = createEvent(this, "vviinnSelectObject", 7);
1151
+ this.vviinnSelectFilter = createEvent(this, "vviinnSelectFilter", 7);
1152
+ this.vviinnNoResult = createEvent(this, "vviinnNoResult", 7);
1153
+ this.imageSource = null;
1154
+ this.setTrackingDeactivated = (result) => {
1155
+ if (result.status === "rejected") {
1156
+ this.trackingDeactivated = true;
1157
+ }
1158
+ };
1159
+ this.getBasicEventData = () => {
1160
+ var _a;
1161
+ return {
1162
+ widgetType: "VPS",
1163
+ campaignTypeId: "VPS",
1164
+ campaignTypeName: campaignTypeNames["VPS"],
1165
+ widgetId: (_a = this.buttonElementId) !== null && _a !== void 0 ? _a : this.id,
1166
+ };
1167
+ };
1168
+ this.token = undefined;
1169
+ this.apiPath = "https://api.vviinn.com";
1170
+ this.active = false;
1171
+ this.currencySign = "€";
1172
+ this.locale = "de-DE";
1173
+ this.campaignId = undefined;
1174
+ this.showingInButton = false;
1175
+ this.buttonElementId = undefined;
1176
+ this.buttonPressed = undefined;
1177
+ this.mode = "modal";
1178
+ this.resetVpsButton = undefined;
1179
+ this.slidePosition = 0;
1180
+ this.width = 0;
1181
+ this.wrongImageFormat = false;
1182
+ this.trackingDeactivated = false;
1183
+ }
1184
+ componentDidLoad() {
1185
+ const slots = this.el.querySelectorAll("[slot]");
1186
+ this.globalSlotsChanged.emit(Array.from(slots));
1187
+ }
1188
+ activeWatcher(value) {
1189
+ if (value) {
1190
+ this.overflow = document.body.style.overflow;
1191
+ document.body.style.overflow = "hidden";
1192
+ this.trackOpenEvent();
1193
+ }
1194
+ else {
1195
+ document.body.style.overflow = this.overflow;
1196
+ }
1197
+ }
1198
+ buttonPressedWatcher(pressed) {
1199
+ if (!pressed)
1200
+ return;
1201
+ if (this.mode === "modal") {
1202
+ this.active = true;
1203
+ this.vviinnWidgetOpen.emit(this.getBasicEventData());
1204
+ }
1205
+ }
1206
+ trackProductView({ detail }) {
1207
+ if (this.trackingDeactivated)
1208
+ return;
1209
+ const { productRank, productId, productName, widgetType, widgetId, campaignTypeId, campaignTypeName } = detail, rest = __rest(detail, ["productRank", "productId", "productName", "widgetType", "widgetId", "campaignTypeId", "campaignTypeName"]);
1210
+ const productViewEvent = createProductViewVpsEvent(Object.assign({ session_id: this.uiSessionId, rank: productRank, product: productId }, rest));
1211
+ this.trackingApi
1212
+ .trackEvent(productViewEvent)
1213
+ .then(this.setTrackingDeactivated);
1214
+ }
1215
+ async trackProductClick({ detail }) {
1216
+ const { productRank, productId, productName, widgetType, widgetId, campaignTypeId, campaignTypeName } = detail, rest = __rest(detail, ["productRank", "productId", "productName", "widgetType", "widgetId", "campaignTypeId", "campaignTypeName"]);
1217
+ const productClickEvent = createProductClickVpsEvent(Object.assign({ session_id: this.uiSessionId, rank: productRank, product: productId }, rest));
1218
+ if (!this.trackingDeactivated) {
1219
+ await this.trackingApi
1220
+ .trackEvent(this.trackingDeactivated ? null : productClickEvent)
1221
+ .then(this.setTrackingDeactivated);
1222
+ }
1223
+ const product = imageSearchState.results.find((r) => r.productId === detail.productId);
1224
+ if (!product || !product.deeplink)
1225
+ return;
1226
+ window.location.href = product.deeplink;
1227
+ }
1228
+ trachSearchAreaChanges() {
1229
+ if (this.trackingDeactivated)
1230
+ return;
1231
+ const searchEvent = createSearchEvent({
1232
+ session_id: this.uiSessionId,
1233
+ source: this.imageSource,
1234
+ search_area: "manual-selection",
1235
+ });
1236
+ this.trackingApi.trackEvent(searchEvent).then(this.setTrackingDeactivated);
1237
+ }
1238
+ trackDetectedObject() {
1239
+ if (this.trackingDeactivated)
1240
+ return;
1241
+ const searchEvent = createSearchEvent({
1242
+ session_id: this.uiSessionId,
1243
+ source: this.imageSource,
1244
+ search_area: "attention-point",
1245
+ });
1246
+ this.trackingApi.trackEvent(searchEvent).then(this.setTrackingDeactivated);
1247
+ }
1248
+ trackFilter({ detail }) {
1249
+ if (this.trackingDeactivated)
1250
+ return;
1251
+ const searchEvent = createFilterEvent({
1252
+ session_id: this.uiSessionId,
1253
+ source: this.imageSource,
1254
+ kind: "category",
1255
+ action: detail.action,
1256
+ });
1257
+ this.trackingApi.trackEvent(searchEvent).then(this.setTrackingDeactivated);
1258
+ }
1259
+ connectedCallback() {
1260
+ state.apiPath = this.apiPath;
1261
+ state.currencySign = this.currencySign;
1262
+ state.locale = this.locale;
1263
+ imageSearchState.token = this.token;
1264
+ imageSearchState.campaignId = _function.pipe(this.campaignId, Option.fromNullable, Option.chain(Option.fromPredicate(notEmptyString)), Option.map(filterInt), Option.chain(Option.fromPredicate(notNan)), Option.map((s) => `${s}`));
1265
+ this.uiSessionId = v4();
1266
+ this.trackingApi = createTrackingApi(this.apiPath, this.token);
1267
+ this.id = this.el.id;
1268
+ }
1269
+ componentWillLoad() {
1270
+ slotChangeListener(this, this.el);
1271
+ this.vviinnWidgetLoad.emit(this.getBasicEventData());
1272
+ }
1273
+ trackOpenEvent() {
1274
+ if (this.trackingDeactivated)
1275
+ return;
1276
+ const widgetOpenEvent = createWidgetVpsEvent({
1277
+ action: "open",
1278
+ session_id: this.uiSessionId,
1279
+ });
1280
+ this.trackingApi
1281
+ .trackEvent(widgetOpenEvent)
1282
+ .then(this.setTrackingDeactivated);
1283
+ }
1284
+ handleImageSelection(source) {
1285
+ this.imageSource = source;
1286
+ this.slidePosition = 1;
1287
+ const root = this.el.shadowRoot.querySelector("vviinn-overlayed-modal");
1288
+ const overlay = root.shadowRoot.querySelector("vviinn-overlay");
1289
+ const modal = overlay.querySelector("vviinn-modal");
1290
+ const modalBody = modal.shadowRoot.querySelector(".body");
1291
+ modalBody.scrollTop = 0;
1292
+ this.trackInitialSearch();
1293
+ }
1294
+ trackInitialSearch() {
1295
+ if (this.trackingDeactivated)
1296
+ return;
1297
+ const searchEvent = createSearchEvent({
1298
+ session_id: this.uiSessionId,
1299
+ source: this.imageSource,
1300
+ search_area: "full",
1301
+ });
1302
+ this.trackingApi.trackEvent(searchEvent).then(this.setTrackingDeactivated);
1303
+ }
1304
+ resetState() {
1305
+ this.resetScroll("onboarding-block");
1306
+ this.slidePosition = 0;
1307
+ imageSearchState.image = Option.none;
1308
+ imageSearchState.imageUrl = Option.none;
1309
+ imageSearchState.imageBounds = Option.none;
1310
+ imageSearchState.searchArea = Option.none;
1311
+ imageSearchState.results = [];
1312
+ imageSearchState.filters = [];
1313
+ imageSearchState.detectedObjects = [];
1314
+ imageSearchState.activeIonLink = undefined;
1315
+ imageSearchState.rectangleSearchForm = undefined;
1316
+ imageSearchState.loading = false;
1317
+ this.resetScroll("results-block");
1318
+ }
1319
+ haveErrors() {
1320
+ return this.wrongImageFormat || imageSearchState.serverError;
1321
+ }
1322
+ resetScroll(elementId, behavior = "auto") {
1323
+ const element = this.el.shadowRoot.getElementById(elementId);
1324
+ element.scroll({ top: 0, left: 0, behavior });
1325
+ }
1326
+ handleModalClose() {
1327
+ this.active = false;
1328
+ this.resetState();
1329
+ const elementsToReset = ["onboarding-block", "results-block"];
1330
+ elementsToReset.forEach((name) => this.resetScroll(name));
1331
+ if (this.trackingDeactivated)
1332
+ return;
1333
+ const widgetCloseEvent = createWidgetVpsEvent({
1334
+ action: "close",
1335
+ session_id: this.uiSessionId,
1336
+ });
1337
+ this.trackingApi
1338
+ .trackEvent(widgetCloseEvent)
1339
+ .then(this.setTrackingDeactivated);
1340
+ }
1341
+ render() {
1342
+ var _a;
1343
+ return (h(Host, null, !this.showingInButton && h(SlotSkeleton, null), h("vviinn-overlayed-modal", { class: { "first-screen": this.slidePosition === 0 }, active: this.active, resetState: this.resetState.bind(this), onVviinnWidgetClose: () => this.handleModalClose(), buttonElementId: (_a = this.buttonElementId) !== null && _a !== void 0 ? _a : this.id, hideBackButton: this.mode === "upload", exportparts: "secondary-action, title, close-button, example-images" }, h("vviinn-slider", { showBullets: false, position: this.slidePosition }, h("vviinn-slide", { class: { "start-page": true } }, h("div", { class: {
1344
+ error: this.haveErrors(),
1345
+ "start-page_block": true,
1346
+ } }, h("vviinn-wrong-format", { class: { hidden: !this.wrongImageFormat }, handler: () => (this.wrongImageFormat = false) }), h("vviinn-server-error", { class: { hidden: !imageSearchState.serverError }, handler: () => (imageSearchState.serverError = false) }), h("vviinn-teaser", { class: { hidden: this.haveErrors() } }), h("vviinn-image-selector", { class: { hidden: this.haveErrors() }, onVviinnImageUpload: () => {
1347
+ this.active = true;
1348
+ this.handleImageSelection("upload");
1349
+ if (this.mode === "upload") {
1350
+ this.vviinnWidgetOpen.emit(this.getBasicEventData());
1351
+ }
1352
+ }, onVviinnNoResult: () => (this.wrongImageFormat = true), resetVpsButton: this.resetVpsButton, basicEventData: this.getBasicEventData(), part: "select-image_button", startUpload: this.buttonPressed &&
1353
+ this.showingInButton &&
1354
+ this.mode === "upload" }, h("span", { slot: "upload-button-text", class: "upload-button-content" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "29", height: "28", fill: "none" }, h("defs", null), h("path", { fill: "#fff", "fill-rule": "evenodd", d: "M10.271 3.89A.875.875 0 0111 3.5h7c.293 0 .566.146.728.39l1.49 2.235h3.033a2.625 2.625 0 012.625 2.625V21a2.625 2.625 0 01-2.625 2.625H5.75A2.625 2.625 0 013.125 21V8.75A2.625 2.625 0 015.75 6.125h3.031l1.49-2.235zm1.197 1.36l-1.49 2.235a.875.875 0 01-.729.39H5.75a.875.875 0 00-.875.875V21a.875.875 0 00.875.875h17.5a.875.875 0 00.875-.875V8.75a.875.875 0 00-.875-.875h-3.5a.875.875 0 01-.729-.39l-1.49-2.235h-6.063z", "clip-rule": "evenodd" }), h("path", { fill: "#fff", "fill-rule": "evenodd", d: "M14.5 11.375a3.062 3.062 0 100 6.125 3.062 3.062 0 000-6.125zm-4.813 3.063a4.812 4.812 0 119.625 0 4.812 4.812 0 01-9.625 0z", "clip-rule": "evenodd" })), h("slot", { name: "vviinn-image-upload-button-text" }, h("span", null, "Kamera oder Bild ausw\u00E4hlen")))), h("vviinn-privacy-badge", { class: { hidden: this.haveErrors() } })), h("div", { id: "onboarding-block", class: "start-page_block" }, h("div", { class: "onboarding-wrapper" }, h("vviinn-onboarding", null), h("vviinn-example-images", { part: "example-images", onVviinnImageUpload: () => this.handleImageSelection("example"), onVviinnNoResult: () => this.resetScroll("onboarding-block", "smooth"), basicEventData: this.getBasicEventData() })))), h("vviinn-slide", { class: { "results-page": true, active: this.slidePosition == 1 } }, h("div", { class: "image-wrapper" }, h("vviinn-image-view", { basicEventData: this.getBasicEventData() }), h("div", { class: "filters-wrapper" }, h("div", { class: "filters" }, imageSearchState.filters.map((filter) => (h("search-filters", { filter: filter, basicEventData: this.getBasicEventData() })))))), h("div", { id: "results-block", class: "products-wrapper" }, h("div", { class: {
1355
+ "nothing-found": true,
1356
+ hidden: imageSearchState.results.length > 0,
1357
+ } }, h("vviinn-empty-results", null), h("vviinn-onboarding", null)), h("div", { class: {
1358
+ hidden: imageSearchState.results.length <= 0,
1359
+ products: true,
1360
+ } }, imageSearchState.results.map((p, i) => {
1361
+ var _a;
1362
+ return (h("vviinn-product-card", { key: p.productId, hidden: true, productTitle: p.title, productId: p.productId, brand: p.brand, deeplink: p.deeplink, price: p.price.actual, salePrice: p.price.sale, imageWidth: 160, image: (_a = p.image.thumbnail) !== null && _a !== void 0 ? _a : p.image.original, part: "product-card", campaignTypeId: "VPS", index: i, widgetElementId: this.id, buttonElementId: this.buttonElementId }));
1363
+ }))))))));
1364
+ }
1365
+ get el() { return getElement(this); }
1366
+ static get watchers() { return {
1367
+ "active": ["activeWatcher"],
1368
+ "buttonPressed": ["buttonPressedWatcher"]
1369
+ }; }
1370
+ };
1371
+ VviinnVpsWidget.style = vviinnVpsWidgetCss;
1372
+
1373
+ const vviinnWrongFormatCss = ":host{display:block}";
1374
+
1375
+ const VviinnWrongFormat = class {
1376
+ constructor(hostRef) {
1377
+ registerInstance(this, hostRef);
1378
+ this.handler = undefined;
1379
+ }
1380
+ render() {
1381
+ return (h(Host, null, h("vviinn-error", null, h("h4", { slot: "title" }, "Dateityp wird nicht unterst\u00FCtzt"), h("span", { slot: "text" }, "Leider unterst\u00FCtzen wir dieses Format nicht. Bitte laden Sie eine .jpg, .png oder .webp Bilddatei hoch."), h("button", { slot: "action", onClick: this.handler }, "Neues Bild hochladen"))));
1382
+ }
1383
+ };
1384
+ VviinnWrongFormat.style = vviinnWrongFormatCss;
1385
+
1386
+ export { CropperHandler as cropper_handler, HighlightBox as highlight_box, ImageCropper as image_cropper, SearchFilters as search_filters, VviinnButton as vviinn_button, VviinnDetectedObject as vviinn_detected_object, VviinnEmptyResults as vviinn_empty_results, VviinnError as vviinn_error, VviinnExampleImage as vviinn_example_image, VviinnExampleImages as vviinn_example_images, VviinnImageSelector as vviinn_image_selector, VviinnImageView as vviinn_image_view, VviinnModal as vviinn_modal, VviinnOnboarding as vviinn_onboarding, VviinnOnboardingCard1 as vviinn_onboarding_card_1, VviinnOnboardingCard2 as vviinn_onboarding_card_2, VviinnOnboardingCard3 as vviinn_onboarding_card_3, VviinnOverlay as vviinn_overlay, VviinnOverlayedModal as vviinn_overlayed_modal, VviinnPreloader as vviinn_preloader, VviinnPrivacyBadge as vviinn_privacy_badge, VviinnProductCard as vviinn_product_card, VviinnServerError as vviinn_server_error, VviinnSlide as vviinn_slide, VviinnSlider as vviinn_slider, VviinnTeaser as vviinn_teaser, VviinnVpsButton as vviinn_vps_button, VviinnVpsWidget as vviinn_vps_widget, VviinnWrongFormat as vviinn_wrong_format };