vviinn-widgets 2.7.2 → 2.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/cjs/{index-df6896e2.js → cropper-handler_30.cjs.entry.js} +2323 -165
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/vviinn-widgets.cjs.js +1 -1
  4. package/dist/collection/components/vviinn-product-card/vviinn-product-card.js +5 -2
  5. package/dist/esm/{app-globals-865bc7a7.js → app-globals-2f864b5d.js} +1 -1
  6. package/dist/esm/{index-2fdd499d.js → cropper-handler_30.entry.js} +2294 -119
  7. package/dist/esm/{index-443468c7.js → index-040cfca9.js} +2 -2
  8. package/dist/esm/{index-51f71d18.js → index-2d36a726.js} +1 -1
  9. package/dist/esm/loader.js +3 -3
  10. package/dist/esm/vviinn-recommendations-sidebar.entry.js +2 -2
  11. package/dist/esm/vviinn-vpr-button.entry.js +2 -2
  12. package/dist/esm/vviinn-widgets.js +3 -3
  13. package/dist/types/components/vviinn-product-card/vviinn-product-card.d.ts +1 -0
  14. package/dist/vviinn-widgets/{p-3469b71a.js → p-334db07e.js} +1 -1
  15. package/dist/vviinn-widgets/{p-40bea5b5.entry.js → p-a98df480.entry.js} +1 -1
  16. package/dist/vviinn-widgets/p-da99b592.entry.js +1 -0
  17. package/dist/vviinn-widgets/{p-a6e0710f.entry.js → p-dc124f62.entry.js} +1 -1
  18. package/dist/vviinn-widgets/{p-465d043d.js → p-e5a7f685.js} +1 -1
  19. package/dist/vviinn-widgets/{p-166970f3.js → p-fe8dc0b9.js} +1 -1
  20. package/dist/vviinn-widgets/vviinn-widgets.esm.js +1 -1
  21. package/package.json +1 -1
  22. package/www/build/{p-3469b71a.js → p-334db07e.js} +1 -1
  23. package/www/build/{p-40bea5b5.entry.js → p-a98df480.entry.js} +1 -1
  24. package/www/build/p-c5ef37e7.js +125 -0
  25. package/www/build/p-da99b592.entry.js +1 -0
  26. package/www/build/{p-a6e0710f.entry.js → p-dc124f62.entry.js} +1 -1
  27. package/www/build/p-e0153ae2.css +6 -0
  28. package/www/build/{p-465d043d.js → p-e5a7f685.js} +1 -1
  29. package/www/build/{p-166970f3.js → p-fe8dc0b9.js} +1 -1
  30. package/www/build/vviinn-widgets.esm.js +1 -1
  31. package/www/index.html +2495 -1
  32. package/dist/cjs/cropper-handler_27.cjs.entry.js +0 -1135
  33. package/dist/cjs/customized-slots-06ca4007.js +0 -53
  34. package/dist/cjs/vviinn-carousel_2.cjs.entry.js +0 -1001
  35. package/dist/cjs/vviinn-vps-button.cjs.entry.js +0 -43
  36. package/dist/esm/cropper-handler_27.entry.js +0 -1105
  37. package/dist/esm/customized-slots-96902edf.js +0 -50
  38. package/dist/esm/vviinn-carousel_2.entry.js +0 -996
  39. package/dist/esm/vviinn-vps-button.entry.js +0 -39
  40. package/dist/vviinn-widgets/p-2dd35f19.entry.js +0 -1
  41. package/dist/vviinn-widgets/p-59bd2a99.js +0 -1
  42. package/dist/vviinn-widgets/p-74ed36af.entry.js +0 -1
  43. package/dist/vviinn-widgets/p-9def6b8b.entry.js +0 -1
  44. package/dist/vviinn-widgets/p-cd995515.js +0 -1
  45. package/www/build/p-2dd35f19.entry.js +0 -1
  46. package/www/build/p-59bd2a99.js +0 -1
  47. package/www/build/p-61933b75.js +0 -1
  48. package/www/build/p-74ed36af.entry.js +0 -1
  49. package/www/build/p-9def6b8b.entry.js +0 -1
  50. package/www/build/p-a67898be.css +0 -1
  51. package/www/build/p-cd995515.js +0 -1
@@ -1,12 +1,15 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
3
5
  const index = require('./index-3c3ab815.js');
6
+ const index$1 = require('./index-f66cd8d1.js');
4
7
 
5
8
  // -------------------------------------------------------------------------------------
6
9
  /**
7
10
  * @since 2.0.0
8
11
  */
9
- function identity(a) {
12
+ function identity$1(a) {
10
13
  return a;
11
14
  }
12
15
  function flow(ab, bc, cd, de, ef, fg, gh, hi, ij) {
@@ -200,7 +203,7 @@ var struct = function (semigroups) { return ({
200
203
  * @category instances
201
204
  * @since 2.10.0
202
205
  */
203
- var first = function () { return ({ concat: identity }); };
206
+ var first = function () { return ({ concat: identity$1 }); };
204
207
  /**
205
208
  * Always return the last argument.
206
209
  *
@@ -228,7 +231,7 @@ const semigroupDiff = {
228
231
  concat: (x, y) => x - y,
229
232
  };
230
233
 
231
- const fromRectangle$1 = ({ x, y }) => {
234
+ const fromRectangle$2 = ({ x, y }) => {
232
235
  return {
233
236
  x,
234
237
  y,
@@ -282,27 +285,27 @@ const getCursorValue = (direction) => {
282
285
  return "pointer";
283
286
  }
284
287
  };
285
- const fromRectangle = (r) => [
288
+ const fromRectangle$1 = (r) => [
286
289
  {
287
- position: fromRectangle$1(r),
290
+ position: fromRectangle$2(r),
288
291
  direction: HandlerDirection.NorthWest,
289
292
  },
290
293
  {
291
- position: pointSumSemigroup.concat(fromRectangle$1(r), {
294
+ position: pointSumSemigroup.concat(fromRectangle$2(r), {
292
295
  x: r.width,
293
296
  y: 0,
294
297
  }),
295
298
  direction: HandlerDirection.NorthEast,
296
299
  },
297
300
  {
298
- position: pointSumSemigroup.concat(fromRectangle$1(r), {
301
+ position: pointSumSemigroup.concat(fromRectangle$2(r), {
299
302
  x: 0,
300
303
  y: r.height,
301
304
  }),
302
305
  direction: HandlerDirection.SouthWest,
303
306
  },
304
307
  {
305
- position: pointSumSemigroup.concat(fromRectangle$1(r), {
308
+ position: pointSumSemigroup.concat(fromRectangle$2(r), {
306
309
  x: r.width,
307
310
  y: r.height,
308
311
  }),
@@ -310,6 +313,40 @@ const fromRectangle = (r) => [
310
313
  },
311
314
  ];
312
315
 
316
+ 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;-ms-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}";
317
+
318
+ let CropperHandler = class {
319
+ constructor(hostRef) {
320
+ index.registerInstance(this, hostRef);
321
+ this.disabled = false;
322
+ }
323
+ render() {
324
+ return (index.h(index.Host, { part: `handle ${getCursorValue(this.handler.direction)}`, class: {
325
+ disabled: this.disabled,
326
+ [getCursorValue(this.handler.direction)]: true,
327
+ }, style: {
328
+ "--size": "20px",
329
+ cursor: getCursorValue(this.handler.direction),
330
+ }, draggable: false }));
331
+ }
332
+ };
333
+ CropperHandler.style = cropperHandlerCss;
334
+
335
+ const fromRectangle = (shape, target) => {
336
+ const top = `${shape.y}px`;
337
+ const left = `${shape.x}px`;
338
+ const right = `${target.width - (shape.x + shape.width)}px`;
339
+ const bottom = `${target.height - (shape.y + shape.height)}px`;
340
+ return {
341
+ top,
342
+ right,
343
+ bottom,
344
+ left,
345
+ };
346
+ };
347
+ const printClip = (clip) => `inset(${clip.top} ${clip.right} ${clip.bottom} ${clip.left})`;
348
+ const getClipValue = (shape, target) => printClip(fromRectangle(shape, target));
349
+
313
350
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
314
351
 
315
352
  function createCommonjsModule(fn, basedir, module) {
@@ -1257,7 +1294,7 @@ var concatAll = function (M) { return function (startWith) { return function (as
1257
1294
  exports.concatAll = concatAll;
1258
1295
  });
1259
1296
 
1260
- var Eq = createCommonjsModule(function (module, exports) {
1297
+ var Eq$1 = createCommonjsModule(function (module, exports) {
1261
1298
  Object.defineProperty(exports, "__esModule", { value: true });
1262
1299
  exports.eqDate = exports.eqNumber = exports.eqString = exports.eqBoolean = exports.eq = exports.strictEqual = exports.getStructEq = exports.getTupleEq = exports.Contravariant = exports.getMonoid = exports.getSemigroup = exports.eqStrict = exports.URI = exports.contramap = exports.tuple = exports.struct = exports.fromEquals = void 0;
1263
1300
 
@@ -1447,7 +1484,7 @@ exports.eqDate = {
1447
1484
  };
1448
1485
  });
1449
1486
 
1450
- var Ord = createCommonjsModule(function (module, exports) {
1487
+ var Ord$1 = createCommonjsModule(function (module, exports) {
1451
1488
  Object.defineProperty(exports, "__esModule", { value: true });
1452
1489
  exports.ordDate = exports.ordNumber = exports.ordString = exports.ordBoolean = exports.ord = exports.getDualOrd = exports.getTupleOrd = exports.between = exports.clamp = exports.max = exports.min = exports.geq = exports.leq = exports.gt = exports.lt = exports.equals = exports.trivial = exports.Contravariant = exports.getMonoid = exports.getSemigroup = exports.URI = exports.contramap = exports.reverse = exports.tuple = exports.fromCompare = exports.equalsDefault = void 0;
1453
1490
 
@@ -1758,7 +1795,7 @@ function compare(first, second) {
1758
1795
  return first < second ? -1 : first > second ? 1 : 0;
1759
1796
  }
1760
1797
  var strictOrd = {
1761
- equals: Eq.eqStrict.equals,
1798
+ equals: Eq$1.eqStrict.equals,
1762
1799
  compare: compare
1763
1800
  };
1764
1801
  /**
@@ -1865,7 +1902,7 @@ exports.semigroupProduct = exports.semigroupSum = exports.semigroupString = expo
1865
1902
 
1866
1903
  var _ = __importStar(internal);
1867
1904
  var M = __importStar(Magma);
1868
- var Or = __importStar(Ord);
1905
+ var Or = __importStar(Ord$1);
1869
1906
  // -------------------------------------------------------------------------------------
1870
1907
  // constructors
1871
1908
  // -------------------------------------------------------------------------------------
@@ -3964,7 +4001,7 @@ var mapLeft$2 = function (f) { return function (fa) {
3964
4001
  */
3965
4002
  var FromEither$1 = {
3966
4003
  URI: URI$2,
3967
- fromEither: identity
4004
+ fromEither: identity$1
3968
4005
  };
3969
4006
  // -------------------------------------------------------------------------------------
3970
4007
  // natural transformations
@@ -4193,7 +4230,7 @@ var match = matchW;
4193
4230
  * @category destructors
4194
4231
  * @since 2.0.0
4195
4232
  */
4196
- var fold = match;
4233
+ var fold$1 = match;
4197
4234
  /**
4198
4235
  * Less strict version of [`getOrElse`](#getorelse).
4199
4236
  *
@@ -8021,7 +8058,7 @@ const createBearerHeaders = (token) => new Headers({
8021
8058
  const checkToken = (token) => pipe(token, existAndNotEmpty, Either.mapLeft(() => invalidTokenError));
8022
8059
  const processBearerToken = (token) => pipe(token, checkToken, Either.map(createBearerHeaders));
8023
8060
 
8024
- const sequenceToEither = Apply$1.sequenceT(Either.Apply);
8061
+ const sequenceToEither$1 = Apply$1.sequenceT(Either.Apply);
8025
8062
 
8026
8063
  const imageFormFromFile = (file) => {
8027
8064
  const body = new FormData();
@@ -8042,8 +8079,8 @@ const detectedObjectEq = {
8042
8079
  };
8043
8080
  const searchSessionClient = (initialData, campaignId = none) => {
8044
8081
  const searchUrl = "search/session";
8045
- const requestUrl = _function.pipe(campaignId, fold(() => searchUrl, (campaignId) => `${searchUrl}?campaign-id=${campaignId}`));
8046
- return _function.pipe(sequenceToEither(getApiPath(), createInitPostRequest), fromEither, chainW(makeRequest(requestUrl, initialData)));
8082
+ const requestUrl = _function.pipe(campaignId, fold$1(() => searchUrl, (campaignId) => `${searchUrl}?campaign-id=${campaignId}`));
8083
+ return _function.pipe(sequenceToEither$1(getApiPath(), createInitPostRequest), fromEither, chainW(makeRequest(requestUrl, initialData)));
8047
8084
  };
8048
8085
 
8049
8086
  var ObjectMemberName;
@@ -8071,29 +8108,29 @@ const foldValueObject = (i) => {
8071
8108
  };
8072
8109
 
8073
8110
  const getLink = (item, path) => pipe(item.links, fromNullable, chain$3((linksObject) => fromNullable(linksObject[path])));
8074
- const linkRequest = (link) => (data) => pipe(sequenceToEither(getApiPath(), createRequestFromMethod(link.method)), fromEither, chainW(makeRequest(link.href, data)));
8111
+ const linkRequest = (link) => (data) => pipe(sequenceToEither$1(getApiPath(), createRequestFromMethod(link.method)), fromEither, chainW(makeRequest(link.href, data)));
8075
8112
 
8076
8113
  const move = (origin, position) => {
8077
- const originPosition = fromRectangle$1(origin);
8114
+ const originPosition = fromRectangle$2(origin);
8078
8115
  const newPosition = pointSumSemigroup.concat(originPosition, position);
8079
8116
  return Object.assign(Object.assign({}, newPosition), { width: origin.width, height: origin.height });
8080
8117
  };
8081
8118
  const transformNorthEast = (origin, handler) => {
8082
- const newPosition = pointSumSemigroup.concat(fromRectangle$1(origin), {
8119
+ const newPosition = pointSumSemigroup.concat(fromRectangle$2(origin), {
8083
8120
  x: 0,
8084
8121
  y: handler.position.y,
8085
8122
  });
8086
8123
  return Object.assign(Object.assign({}, newPosition), { width: origin.width + handler.position.x, height: origin.height - handler.position.y });
8087
8124
  };
8088
8125
  const transformNorthWest = (origin, handler) => {
8089
- const newPosition = pointSumSemigroup.concat(fromRectangle$1(origin), handler.position);
8126
+ const newPosition = pointSumSemigroup.concat(fromRectangle$2(origin), handler.position);
8090
8127
  return Object.assign(Object.assign({}, newPosition), { width: origin.width - handler.position.x, height: origin.height - handler.position.y });
8091
8128
  };
8092
8129
  const transformSouthEast = (origin, handler) => {
8093
8130
  return Object.assign(Object.assign({}, origin), { width: origin.width + handler.position.x, height: origin.height + handler.position.y });
8094
8131
  };
8095
8132
  const transformSouthWest = (origin, handler) => {
8096
- const newPosition = pointSumSemigroup.concat(fromRectangle$1(origin), {
8133
+ const newPosition = pointSumSemigroup.concat(fromRectangle$2(origin), {
8097
8134
  x: handler.position.x,
8098
8135
  y: 0,
8099
8136
  });
@@ -8196,7 +8233,7 @@ const transformSendForm = (form, data) => [
8196
8233
  }),
8197
8234
  },
8198
8235
  ];
8199
- const formRequest = (form, data = {}) => (payload) => _function.pipe(sequenceToEither(getApiPath(), _function.pipe(requestFromForm(form, data), mapLeft$2((error) => {
8236
+ const formRequest = (form, data = {}) => (payload) => _function.pipe(sequenceToEither$1(getApiPath(), _function.pipe(requestFromForm(form, data), mapLeft$2((error) => {
8200
8237
  return { kind: "app", inner: error };
8201
8238
  }))), fromEither, chainW((initialData) => {
8202
8239
  const apiPath = initialData[0];
@@ -8222,6 +8259,26 @@ const fromFile = async (f) => {
8222
8259
  const sequenceToOption = Apply$1.sequenceT(Option.Apply);
8223
8260
  const checkEmpryString = (x) => x.length > 0 ? Option.some(x) : Option.none;
8224
8261
 
8262
+ // -------------------------------------------------------------------------------------
8263
+ // -------------------------------------------------------------------------------------
8264
+ // instances
8265
+ // -------------------------------------------------------------------------------------
8266
+ /**
8267
+ * @category instances
8268
+ * @since 2.10.0
8269
+ */
8270
+ var Eq = {
8271
+ equals: function (first, second) { return first === second; }
8272
+ };
8273
+ /**
8274
+ * @category instances
8275
+ * @since 2.10.0
8276
+ */
8277
+ var Ord = {
8278
+ equals: Eq.equals,
8279
+ compare: function (first, second) { return (first < second ? -1 : first > second ? 1 : 0); }
8280
+ };
8281
+
8225
8282
  /**
8226
8283
  * Find the first element returned by an option based selector function
8227
8284
  *
@@ -8962,7 +9019,7 @@ exports.uniq = uniq;
8962
9019
  */
8963
9020
  var sortBy = function (ords) {
8964
9021
  if ((0, exports.isNonEmpty)(ords)) {
8965
- var M = (0, Ord.getMonoid)();
9022
+ var M = (0, Ord$1.getMonoid)();
8966
9023
  return (0, exports.sort)(ords.reduce(M.concat, M.empty));
8967
9024
  }
8968
9025
  return _function.identity;
@@ -9576,7 +9633,7 @@ exports.getSemigroup = getSemigroup;
9576
9633
  * @since 2.5.0
9577
9634
  */
9578
9635
  var getEq = function (E) {
9579
- return (0, Eq.fromEquals)(function (xs, ys) { return xs.length === ys.length && xs.every(function (x, i) { return E.equals(x, ys[i]); }); });
9636
+ return (0, Eq$1.fromEquals)(function (xs, ys) { return xs.length === ys.length && xs.every(function (x, i) { return E.equals(x, ys[i]); }); });
9580
9637
  };
9581
9638
  exports.getEq = getEq;
9582
9639
  /**
@@ -10177,7 +10234,7 @@ exports.uniq = uniq;
10177
10234
  */
10178
10235
  var sortBy = function (ords) {
10179
10236
  if ((0, exports.isNonEmpty)(ords)) {
10180
- var M = (0, Ord.getMonoid)();
10237
+ var M = (0, Ord$1.getMonoid)();
10181
10238
  return (0, exports.sort)(ords.reduce(M.concat, M.empty));
10182
10239
  }
10183
10240
  return exports.copy;
@@ -12687,7 +12744,7 @@ exports.getMonoid = getMonoid;
12687
12744
  * @since 2.5.0
12688
12745
  */
12689
12746
  var getEq = function (E) {
12690
- return (0, Eq.fromEquals)(function (xs, ys) { return xs.length === ys.length && xs.every(function (x, i) { return E.equals(x, ys[i]); }); });
12747
+ return (0, Eq$1.fromEquals)(function (xs, ys) { return xs.length === ys.length && xs.every(function (x, i) { return E.equals(x, ys[i]); }); });
12691
12748
  };
12692
12749
  exports.getEq = getEq;
12693
12750
  /**
@@ -12710,7 +12767,7 @@ exports.getEq = getEq;
12710
12767
  * @since 2.5.0
12711
12768
  */
12712
12769
  var getOrd = function (O) {
12713
- return (0, Ord.fromCompare)(function (a, b) {
12770
+ return (0, Ord$1.fromCompare)(function (a, b) {
12714
12771
  var aLen = a.length;
12715
12772
  var bLen = b.length;
12716
12773
  var len = Math.min(aLen, bLen);
@@ -15920,7 +15977,7 @@ const makeHeight = (size) => {
15920
15977
  size,
15921
15978
  };
15922
15979
  };
15923
- const ordBySize = Ord.contramap((s) => s.size)(number.Ord);
15980
+ const ordBySize = Ord$1.contramap((s) => s.size)(number.Ord);
15924
15981
  const ordByKind = {
15925
15982
  equals: (x, y) => x.kind === y.kind,
15926
15983
  compare: (x, y) => {
@@ -16070,7 +16127,7 @@ const makeRectangularSearchRequest = async () => {
16070
16127
  const uploadFile = (file) => {
16071
16128
  state.loading = true;
16072
16129
  const fileForm = imageFormFromFile(file);
16073
- const tokenWithFile = sequenceToEither(processBearerToken(state.token), right(fileForm));
16130
+ const tokenWithFile = sequenceToEither$1(processBearerToken(state.token), right(fileForm));
16074
16131
  return pipe(tokenWithFile, map$4(([headers, body]) => {
16075
16132
  return {
16076
16133
  headers,
@@ -16100,7 +16157,7 @@ onChange("activeIonLink", async (newLink) => {
16100
16157
  });
16101
16158
  onChange("searchArea", (newSearchArea) => {
16102
16159
  pipe(newSearchArea, Option.map((area) => {
16103
- state.cropperHandlers = fromRectangle(area);
16160
+ state.cropperHandlers = fromRectangle$1(area);
16104
16161
  }));
16105
16162
  });
16106
16163
  onChange("serverError", () => {
@@ -16115,127 +16172,1895 @@ const processSelectedFile = async (file) => {
16115
16172
  const fileResizer = resizeFileTo(RESIZED_IMAGE_WIDTH);
16116
16173
  const resizeFileTask = pipe(originFile, fromEither, chainTaskK(fileResizer));
16117
16174
  const session = await pipe(resizeFileTask, chain(uploadFile))();
16118
- pipe(sequenceToEither(session, originFile), map$4(([sessionObject, file]) => uploadHiresFile(sessionObject, file)));
16175
+ pipe(sequenceToEither$1(session, originFile), map$4(([sessionObject, file]) => uploadHiresFile(sessionObject, file)));
16119
16176
  await pipe(resizeFileTask, chainTaskK(imageFromFileTask), map(setSelectedImage))();
16120
16177
  return session;
16121
16178
  };
16122
16179
 
16123
- // Unique ID creation requires a high quality random # generator. In the browser we therefore
16124
- // require the crypto API and do not support built-in fallback to lower quality random number
16125
- // generators (like Math.random()).
16126
- var getRandomValues;
16127
- var rnds8 = new Uint8Array(16);
16128
- function rng() {
16129
- // lazy load so that environments that need to polyfill have a chance to do so
16130
- if (!getRandomValues) {
16131
- // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
16132
- // find the complete implementation of crypto (msCrypto) on IE11.
16133
- getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
16180
+ 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;-ms-user-select:none;user-select:none;--size:10px;--x-position:0;--y-position:0}img{-webkit-user-select:none;-moz-user-select:none;-ms-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);-webkit-animation:0.25s linear fadein;animation:0.25s linear fadein;-webkit-animation-fill-mode:forwards;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}@-webkit-keyframes fadein{from{transform:translate(var(--x-position), var(--y-position)) scale(0)}to{transform:translate(var(--x-position), var(--y-position)) scale(1)}}@keyframes fadein{from{transform:translate(var(--x-position), var(--y-position)) scale(0)}to{transform:translate(var(--x-position), var(--y-position)) scale(1)}}";
16134
16181
 
16135
- if (!getRandomValues) {
16136
- throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
16182
+ let HighlightBox = class {
16183
+ constructor(hostRef) {
16184
+ index.registerInstance(this, hostRef);
16185
+ }
16186
+ getInsetValue() {
16187
+ return pipe(sequenceToOption(imageSearchState.searchArea, imageSearchState.imageBounds), Option.map(([selection, image]) => getClipValue(selection, image)), Option.getOrElse(() => ""));
16188
+ }
16189
+ renderImage() {
16190
+ return pipe(sequenceToOption(imageSearchState.imageUrl, imageSearchState.imageBounds), Option.map(([url, bounds]) => (index.h("img", { src: url, width: bounds.width, height: bounds.height, style: { "clip-path": `${this.getInsetValue()}` } }))), Option.getOrElse(() => ""));
16191
+ }
16192
+ render() {
16193
+ return index.h(index.Host, null, this.renderImage());
16194
+ }
16195
+ };
16196
+ HighlightBox.style = highlightBoxCss;
16197
+
16198
+ const findTarget = (ev) => {
16199
+ return ev.target;
16200
+ };
16201
+
16202
+ 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}";
16203
+
16204
+ const MIN_SEARCHAREA_SIZE = 40;
16205
+ let ImageCropper = class {
16206
+ constructor(hostRef) {
16207
+ index.registerInstance(this, hostRef);
16208
+ this.cropperChanged = index.createEvent(this, "cropperChanged", 7);
16209
+ this.disabled = false;
16210
+ this.handleMove = false;
16211
+ this.mouseStartPoint = undefined;
16212
+ this.bounds = undefined;
16213
+ }
16214
+ componentDidLoad() {
16215
+ this.bounds = this.el.getBoundingClientRect();
16216
+ }
16217
+ handleHandlerMove(event) {
16218
+ event.preventDefault();
16219
+ event.stopPropagation();
16220
+ const destination = fromMouseEvent(event);
16221
+ const distance = pointDiffSemigroup.concat(destination, this.mouseStartPoint);
16222
+ const transformedHandler = {
16223
+ position: distance,
16224
+ direction: this.handlerMoveDirection,
16225
+ };
16226
+ _function.pipe(imageSearchState.searchArea, Option.map((area) => {
16227
+ const newSearchArea = transform(area, transformedHandler);
16228
+ if (this.outOfBounds(newSearchArea))
16229
+ return;
16230
+ imageSearchState.searchArea = Option.some(newSearchArea);
16231
+ this.mouseStartPoint = destination;
16232
+ imageSearchState.detectedObject = undefined;
16233
+ }));
16234
+ }
16235
+ outOfBounds(area) {
16236
+ return (area.width < MIN_SEARCHAREA_SIZE ||
16237
+ area.height < MIN_SEARCHAREA_SIZE ||
16238
+ area.x < 0 ||
16239
+ area.y < 0 ||
16240
+ this.bounds.height - (area.y + area.height) < 0 ||
16241
+ this.bounds.width - (area.x + area.width) < 0);
16242
+ }
16243
+ handleCropperMove(ev) {
16244
+ ev.preventDefault();
16245
+ ev.stopPropagation();
16246
+ const destination = fromMouseEvent(ev);
16247
+ const distance = pointDiffSemigroup.concat(destination, this.mouseStartPoint);
16248
+ _function.pipe(imageSearchState.searchArea, Option.map((searchArea) => {
16249
+ const newSearchArea = move(searchArea, distance);
16250
+ if (newSearchArea.x < 0 ||
16251
+ newSearchArea.y < 0 ||
16252
+ this.bounds.height - (newSearchArea.y + newSearchArea.height) < 0 ||
16253
+ this.bounds.width - (newSearchArea.x + newSearchArea.width) < 0)
16254
+ return;
16255
+ imageSearchState.detectedObject = undefined;
16256
+ imageSearchState.searchArea = Option.some(newSearchArea);
16257
+ this.mouseStartPoint = destination;
16258
+ }));
16259
+ }
16260
+ handlePointerDown(event) {
16261
+ event.stopPropagation();
16262
+ this.mouseStartPoint = fromMouseEvent(event);
16263
+ // should be htmlelement or handler
16264
+ const target = findTarget(event);
16265
+ if (target.localName === "cropper-handler") {
16266
+ this.handlerMoveDirection = target.handler.direction;
16267
+ this.pointerMoveListener = this.handleHandlerMove.bind(this);
16268
+ }
16269
+ else {
16270
+ this.pointerMoveListener = this.handleCropperMove.bind(this);
16271
+ }
16272
+ this.pointerReleaseListener = this.handleSearchAreaRelease.bind(this);
16273
+ this.el.addEventListener("pointermove", this.pointerMoveListener);
16274
+ window.addEventListener("pointerup", this.pointerReleaseListener, {
16275
+ once: true,
16276
+ });
16277
+ }
16278
+ handleSearchAreaRelease() {
16279
+ this.el.removeEventListener("pointermove", this.pointerMoveListener);
16280
+ document.removeEventListener("pointerup", this.pointerReleaseListener);
16281
+ this.mouseStartPoint = undefined;
16282
+ makeRectangularSearchRequest();
16283
+ this.cropperChanged.emit();
16284
+ }
16285
+ getStyleMap() {
16286
+ return _function.pipe(imageSearchState.searchArea, Option.map((rectangle) => {
16287
+ return {
16288
+ width: `${rectangle.width}px`,
16289
+ height: `${rectangle.height}px`,
16290
+ transform: `translate3d(${rectangle.x}px, ${rectangle.y}px, 0)`,
16291
+ cursor: this.handleMove ? "move" : "default",
16292
+ };
16293
+ }), Option.getOrElse(() => {
16294
+ return {};
16295
+ }));
16296
+ }
16297
+ render() {
16298
+ return (index.h(index.Host, { exportparts: "handle, e-resize, n-resize, ne-resize, nw-resize, s-resize, se-resize, sw-resize, w-resize" }, index.h("div", { class: {
16299
+ "crop-area": true,
16300
+ active: this.handleMove,
16301
+ disabled: this.disabled,
16302
+ }, draggable: false, style: this.getStyleMap(), onContextMenu: () => false, onPointerDown: (ev) => this.handlePointerDown(ev) }, imageSearchState.cropperHandlers.map((handler) => (index.h("cropper-handler", { disabled: this.disabled, handler: handler, onPointerDown: (ev) => this.handlePointerDown(ev) }))))));
16303
+ }
16304
+ get el() { return index.getElement(this); }
16305
+ };
16306
+ ImageCropper.style = imageCropperCss;
16307
+
16308
+ const searchFiltersCss = ":host{display:grid;grid-gap:1rem}.filters{display:flex;flex-direction:row;flex-wrap:wrap;gap:0.5rem}.filter{align-items:center;-webkit-animation-duration:0.25s;animation-duration:0.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-name:scalein;animation-name:scalein;border:1px solid lightgray;cursor:pointer;display:flex;flex-direction:row;grid-gap:8px;height:-webkit-max-content;height:-moz-max-content;height:max-content;min-width:-webkit-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;-ms-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)}@-webkit-keyframes scalein{from{opacity:0;transform:scale(0.5)}to{opacity:1;transform:scale(1)}}@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;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;grid-gap:unset}.filter{scroll-snap-align:end;margin-right:0.5rem}}";
16309
+
16310
+ const FILTERS_COUNT = 5;
16311
+ const ACTIVE_FILTER_CLASSNAME = ".filter.active";
16312
+ const getFilterId = (filter) => filter.href.split("/").reverse()[0];
16313
+ let SearchFilters = class {
16314
+ constructor(hostRef) {
16315
+ index.registerInstance(this, hostRef);
16316
+ this.filterSelected = index.createEvent(this, "filterSelected", 7);
16317
+ this.filter = null;
16318
+ this.selectedCategoryId = null;
16319
+ this.hideFilters = true;
16320
+ }
16321
+ handleFilterSelection(filter) {
16322
+ return this.isFilterSelected(filter)
16323
+ ? this.clearSelectedFilter()
16324
+ : this.selectFilter(filter);
16325
+ }
16326
+ selectFilter(filter) {
16327
+ this.selectedCategoryId = getFilterId(filter);
16328
+ imageSearchState.activeIonLink = filter;
16329
+ this.filterSelected.emit("select");
16330
+ }
16331
+ clearSelectedFilter() {
16332
+ this.selectedCategoryId = null;
16333
+ imageSearchState.activeIonLink = undefined;
16334
+ this.findSelectedFilter().blur();
16335
+ this.filterSelected.emit("deselect");
16336
+ }
16337
+ findSelectedFilter() {
16338
+ return this.el.shadowRoot.querySelector(ACTIVE_FILTER_CLASSNAME);
16339
+ }
16340
+ toggleFilters() {
16341
+ this.hideFilters = !this.hideFilters;
16342
+ }
16343
+ handleEnter(ev, f) {
16344
+ if (ev.key !== "Enter")
16345
+ return;
16346
+ this.handleFilterSelection(f);
16347
+ }
16348
+ isFilterSelected(filterLink) {
16349
+ return this.selectedCategoryId === getFilterId(filterLink);
16350
+ }
16351
+ render() {
16352
+ return (index.h(index.Host, { exportparts: "filter, show-more-filters" }, index.h("div", { class: "filters" }, this.filter.filters
16353
+ .filter((_, i) => (this.hideFilters ? i < FILTERS_COUNT : true))
16354
+ .map((f, n) => (index.h("div", { role: "button", tabindex: "0", part: this.isFilterSelected(f) ? "filter active" : "filter", class: {
16355
+ filter: true,
16356
+ active: this.selectedCategoryId === getFilterId(f),
16357
+ }, style: { "animation-delay": `${n * 10}ms` }, onPointerUp: (ev) => {
16358
+ ev.stopPropagation();
16359
+ this.handleFilterSelection(f);
16360
+ }, onKeyPress: (ev) => this.handleEnter(ev, f) }, this.isFilterSelected(f) ? index.h(index$1.CheckIcon, null) : null, f.name))), index.h("div", { class: {
16361
+ filter: true,
16362
+ "show-more": true,
16363
+ hidden: this.filter.filters.length <= FILTERS_COUNT,
16364
+ active: !this.hideFilters,
16365
+ }, role: "button", tabindex: "0", "aria-role": "button", onClick: () => this.toggleFilters(), onKeyPress: (ev) => {
16366
+ if (ev.key === "Enter") {
16367
+ this.toggleFilters();
16368
+ }
16369
+ }, part: "show-more-filters" }, this.hideFilters ? "Zeige mehr" : "Zeige weniger"))));
16370
+ }
16371
+ get el() { return index.getElement(this); }
16372
+ };
16373
+ SearchFilters.style = searchFiltersCss;
16374
+
16375
+ const vviinnCarouselCss = ":host{--vviinn-progressbar-width:0;--vviinn-carousel-item-width:150px;--vviinn-carousel-columns-internal:var(--vviinn-carousel-columns, 4);--vviinn-carousel-image-width-system:140px}.body{display:flex;position:relative;width:var(--vviinn-carousel-content-width);flex-direction:column}.content-wrapper *{box-sizing:border-box}.content-wrapper{overflow-y:hidden;overflow-x:auto;flex-grow:1}.bullets{margin-top:16px;display:flex;flex-direction:row;grid-gap:24px;justify-content:center}.bullet{width:10px;height:10px;background:#E0E0E0;border-radius:50%;cursor:pointer}.bullet.active{background:#161616}.content:not(.show-scrollbar),.content.grid{scrollbar-color:#fff0 #fff0}.content:not(.show-scrollbar)::-webkit-scrollbar,.content.grid::-webkit-scrollbar{opacity:0}.content{display:flex;flex-direction:row;grid-gap:8px;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;overflow-y:hidden;overflow-x:auto;flex-grow:1;padding-bottom:16px}.content.left>*{scroll-snap-align:start}.content.right>*{scroll-snap-align:end}:host(.continuity) button{border-radius:2px}:host(.grid) button{border-radius:50%}button{align-items:center;background-color:white;border:none;box-shadow:0px 2px 6px rgba(0, 0, 0, 0.15);cursor:pointer;display:grid;height:40px;justify-items:center;position:absolute;top:calc(50% - 20px);width:40px;z-index:1;padding:0;margin:0}button{fill:#525252}button.prev svg{transform:rotate(180deg);margin-left:-5px}.prev{left:0}.next{right:0}.items-group{display:grid;grid-gap:16px;grid-template-columns:repeat(var(--vviinn-carousel-columns-internal), 1fr);min-width:100%}vviinn-product-card::part(price-container){text-align:center}:host(.classic) vviinn-product-card::part(title),:host(.classic) vviinn-product-card::part(brand),:host(.classic) vviinn-product-card::part(type){text-align:center}@media (max-width: 480px){:host(.modern) button{display:none}.items-group{grid-template-columns:repeat(2, 1fr)}}";
16376
+
16377
+ const COLUMNS_NUMBER_CSS_VAR = "--vviinn-carousel-columns-internal";
16378
+ const CAROUSEL_WIDTH_CSS_VAR = "--vviinn-carousel-content-width";
16379
+ const CAROUSEL_IMAGE_WIDTH_CSS_VAR = "--vviinn-carousel-image-width";
16380
+ const CONTENT_GROUP_CSS_CLASS = "items-group";
16381
+ let VviinnCarousel = class {
16382
+ constructor(hostRef) {
16383
+ index.registerInstance(this, hostRef);
16384
+ this.moveDirection = "right";
16385
+ this.contentGroups = [];
16386
+ this.activeContentGroup = 0;
16387
+ this.mode = "continuity";
16388
+ this.imageWidth = 140;
16389
+ this.showScroll = true;
16390
+ this.recommendations = [];
16391
+ this.columns = 0;
16392
+ this.resizeObserver = new ResizeObserver(() => this.handleResize());
16393
+ this.mutationObserver = new MutationObserver(() => this.cloneSlottedContent());
16394
+ }
16395
+ connectedCallback() {
16396
+ this.setItemWidth();
16397
+ }
16398
+ disconnectedCallback() {
16399
+ this.resizeObserver.disconnect();
16400
+ }
16401
+ componentDidLoad() {
16402
+ this.setWidth();
16403
+ this.processScrollbarWidth();
16404
+ this.columns = this.getColumnsNumber();
16405
+ const slot = this.el.querySelector(".content");
16406
+ this.mutationObserver.observe(slot, { subtree: true, childList: true });
16407
+ this.resizeObserver.observe(this.getHostParent());
16408
+ }
16409
+ getItemWidthFromDocument() {
16410
+ return parseInt(getComputedStyle(document.body).getPropertyValue(CAROUSEL_IMAGE_WIDTH_CSS_VAR));
16411
+ }
16412
+ setItemWidth() {
16413
+ const widthInDocument = this.getItemWidthFromDocument();
16414
+ const itemWidth = isNaN(widthInDocument)
16415
+ ? this.imageWidth
16416
+ : widthInDocument;
16417
+ this.el.style.setProperty(CAROUSEL_IMAGE_WIDTH_CSS_VAR, `${itemWidth}px`);
16418
+ }
16419
+ getContentClassMap() {
16420
+ return {
16421
+ content: true,
16422
+ [this.moveDirection]: true,
16423
+ [this.mode]: true,
16424
+ "show-scrollbar": this.showScroll,
16425
+ };
16426
+ }
16427
+ handleResize() {
16428
+ this.setWidth();
16429
+ this.processScrollbarWidth();
16430
+ this.setItemWidth();
16431
+ const newColumns = this.getColumnsNumber();
16432
+ if (newColumns !== this.columns) {
16433
+ this.columns = newColumns;
16137
16434
  }
16138
16435
  }
16436
+ calculateMoveStep() {
16437
+ const contentWidths = this.getContent().map((el) => el.getBoundingClientRect().width);
16438
+ const sum = contentWidths.reduce((acc, val) => acc + val, 0);
16439
+ return sum / contentWidths.length;
16440
+ }
16441
+ getHostParent() {
16442
+ const parent = this.el.parentNode;
16443
+ return parent.host.parentElement;
16444
+ }
16445
+ setWidth() {
16446
+ const parent = this.getHostParent();
16447
+ if (!parent)
16448
+ return;
16449
+ const parentStyles = getComputedStyle(parent);
16450
+ const parentWidth = parent.getBoundingClientRect().width;
16451
+ const width = parentWidth -
16452
+ (parseInt(parentStyles["padding-right"]) +
16453
+ parseInt(parentStyles["padding-left"]));
16454
+ this.el.style.setProperty(CAROUSEL_WIDTH_CSS_VAR, `${width}px`);
16455
+ }
16456
+ getParent() {
16457
+ const parentNode = this.el.parentNode;
16458
+ const host = parentNode.host;
16459
+ return host.parentElement;
16460
+ }
16461
+ cloneSlottedContent() {
16462
+ this.setWidth();
16463
+ }
16464
+ getActiveGroupIndex() {
16465
+ var _a, _b;
16466
+ const contentNodeLeft = (_b = (_a = this.getContentNode()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect()) === null || _b === void 0 ? void 0 : _b.left;
16467
+ if (!contentNodeLeft)
16468
+ return 0;
16469
+ const groups = this.getContentGroups();
16470
+ const groupsPositions = groups.map((g) => g.getBoundingClientRect().left);
16471
+ const indexedPositions = groupsPositions
16472
+ .map((value, index) => [value, index])
16473
+ .filter((x) => x[0] >= 0);
16474
+ return indexedPositions.length > 0 ? indexedPositions[0][1] : 0;
16475
+ }
16476
+ getContentNode() {
16477
+ return this.el.querySelector(".content");
16478
+ }
16479
+ getContent() {
16480
+ const children = this.getContentNode().children;
16481
+ return Array.from(children).map((c) => c);
16482
+ }
16483
+ getColumnsNumber() {
16484
+ const styleSheet = getComputedStyle(this.el);
16485
+ const columnsInCss = styleSheet.getPropertyValue(COLUMNS_NUMBER_CSS_VAR);
16486
+ return parseInt(columnsInCss);
16487
+ }
16488
+ getContentGroups() {
16489
+ return Array.from(this.el.querySelectorAll(`.${CONTENT_GROUP_CSS_CLASS}`));
16490
+ }
16491
+ showNext() {
16492
+ this.moveDirection = "right";
16493
+ const contentContainer = this.getContentNode();
16494
+ requestAnimationFrame(() => {
16495
+ contentContainer.scrollTo({
16496
+ top: 0,
16497
+ left: contentContainer.scrollLeft + this.calculateMoveStep(),
16498
+ behavior: "smooth",
16499
+ });
16500
+ });
16501
+ }
16502
+ showPrev() {
16503
+ this.moveDirection = "left";
16504
+ const contentContainer = this.getContentNode();
16505
+ requestAnimationFrame(() => {
16506
+ contentContainer.scrollTo({
16507
+ top: 0,
16508
+ left: contentContainer.scrollLeft - this.calculateMoveStep(),
16509
+ behavior: "smooth",
16510
+ });
16511
+ });
16512
+ }
16513
+ scroll(index) {
16514
+ const contentContainer = this.getContentNode();
16515
+ requestAnimationFrame(() => {
16516
+ contentContainer.scrollTo({
16517
+ top: 0,
16518
+ left: this.calculateMoveStep() * index,
16519
+ behavior: "smooth",
16520
+ });
16521
+ });
16522
+ }
16523
+ processScrollbarWidth() {
16524
+ const target = this.getContentNode();
16525
+ const scrollRatio = (target.scrollLeft + target.clientWidth) / target.scrollWidth;
16526
+ const scrolledWidth = target.clientWidth * scrollRatio;
16527
+ this.el.style.setProperty("--vviinn-progressbar-width", `${scrolledWidth}px`);
16528
+ this.activeContentGroup = this.getActiveGroupIndex();
16529
+ }
16530
+ showBullets() {
16531
+ return this.mode === "grid" && this.showScroll;
16532
+ }
16533
+ showScrollbar() {
16534
+ return this.mode === "continuity" && this.showScroll;
16535
+ }
16536
+ getClassMap() {
16537
+ return {
16538
+ [this.mode]: true,
16539
+ "show-scrollbar": this.showScrollbar(),
16540
+ };
16541
+ }
16542
+ renderRecommendation(recommendation, rank) {
16543
+ return (index.h("vviinn-product-card", { part: "product-part", productId: recommendation.productId, productTitle: recommendation.title, deeplink: recommendation.deeplink, image: recommendation.image.thumbnail, brand: recommendation.brand, imageWidth: this.imageWidth, imageRatio: 1, price: recommendation.price.actual, salePrice: recommendation.price.sale, responsive: this.mode === "grid", dimmedBackground: this.mode === "continuity", index: rank }));
16544
+ }
16545
+ renderRecommendationGroup(elements) {
16546
+ return index.h("div", { class: CONTENT_GROUP_CSS_CLASS }, elements);
16547
+ }
16548
+ renderRecommendationGroups(elements) {
16549
+ return elements.map((el) => this.renderRecommendationGroup(el));
16550
+ }
16551
+ renderRecommendations() {
16552
+ return this.mode === "grid"
16553
+ ? this.renderGrid()
16554
+ : this.renderRecommendationsElements();
16555
+ }
16556
+ renderRecommendationsElements() {
16557
+ return this.recommendations.map((r, i) => this.renderRecommendation(r, i));
16558
+ }
16559
+ renderGrid() {
16560
+ const recommendations = this.renderRecommendationsElements();
16561
+ const grouppedContent = _Array.chunksOf(this.getColumnsNumber())(recommendations);
16562
+ return this.renderRecommendationGroups(grouppedContent);
16563
+ }
16564
+ renderBullets() {
16565
+ const numberOfBullets = Math.ceil(this.recommendations.length / this.getColumnsNumber());
16566
+ const bulletsArray = Array.from(Array(numberOfBullets).keys());
16567
+ return bulletsArray.map((index$1) => (index.h("div", { class: {
16568
+ bullet: true,
16569
+ active: this.activeContentGroup === index$1,
16570
+ }, onClick: () => this.scroll(index$1) })));
16571
+ }
16572
+ render() {
16573
+ return (index.h(index.Host, { class: this.getClassMap() }, index.h("div", { class: Object.assign({ body: true }, this.getClassMap()) }, index.h("button", { class: "prev", onClick: () => this.showPrev(), part: "carousel-button" }, index.h(index$1.ChevronIcon, null)), index.h("div", { class: this.getContentClassMap(), onScroll: () => this.processScrollbarWidth() }, this.renderRecommendations()), index.h("button", { class: "next", onClick: () => this.showNext(), part: "carousel-button" }, index.h(index$1.ChevronIcon, null))), this.showBullets() ? (index.h("div", { class: "bullets" }, this.renderBullets())) : ("")));
16574
+ }
16575
+ get el() { return index.getElement(this); }
16576
+ };
16577
+ VviinnCarousel.style = vviinnCarouselCss;
16139
16578
 
16140
- return getRandomValues(rnds8);
16141
- }
16579
+ 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}";
16142
16580
 
16143
- const REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
16581
+ let VviinnDetectedObject = class {
16582
+ constructor(hostRef) {
16583
+ index.registerInstance(this, hostRef);
16584
+ this.detectedObjectClicked = index.createEvent(this, "detectedObjectClicked", 7);
16585
+ this.position = ["0", "0"];
16586
+ }
16587
+ getObjectPosition() {
16588
+ return _function.pipe(imageSearchState.imageBounds, Option.map((bounds) => {
16589
+ const objectRectangle = fromAlt(foldValueObject(this.detectedObject).rectangle);
16590
+ const { x, y } = _function.pipe(objectRectangle, scaleWithSized(bounds), center);
16591
+ return [`${x}px`, `${y}px`];
16592
+ }), Option.getOrElse(() => ["0", "0"]));
16593
+ }
16594
+ selectDetectedObject() {
16595
+ _function.pipe(imageSearchState.imageBounds, Option.map((bounds) => {
16596
+ const rectangle = foldValueObject(this.detectedObject).rectangle;
16597
+ const transformedRect = fromAlt(rectangle);
16598
+ const scaledRect = scaleWithSized(bounds)(transformedRect);
16599
+ imageSearchState.detectedObject = this.detectedObject;
16600
+ imageSearchState.searchArea = Option.some(scaledRect);
16601
+ }));
16602
+ makeRectangularSearchRequest();
16603
+ this.detectedObjectClicked.emit();
16604
+ }
16605
+ isActive() {
16606
+ if (!this.detectedObject)
16607
+ return false;
16608
+ if (!imageSearchState.detectedObject)
16609
+ return false;
16610
+ const thisObject = foldValueObject(this.detectedObject);
16611
+ const savedObject = foldValueObject(imageSearchState.detectedObject);
16612
+ return detectedObjectEq.equals(thisObject, savedObject);
16613
+ }
16614
+ render() {
16615
+ return (index.h(index.Host, { class: {
16616
+ active: this.isActive(),
16617
+ }, onClick: () => this.selectDetectedObject(), style: {
16618
+ "--x-position": this.getObjectPosition()[0],
16619
+ "--y-position": this.getObjectPosition()[1],
16620
+ } }));
16621
+ }
16622
+ };
16623
+ VviinnDetectedObject.style = vviinnDetectedObjectCss;
16144
16624
 
16145
- function validate(uuid) {
16146
- return typeof uuid === 'string' && REGEX.test(uuid);
16147
- }
16625
+ const vviinnEmptyResultsCss = ":host{display:grid}vviinn-error{justify-items:center}";
16148
16626
 
16149
- /**
16150
- * Convert array of 16 byte values to UUID string format of the form:
16151
- * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
16152
- */
16627
+ let VviinnEmptyResults = class {
16628
+ constructor(hostRef) {
16629
+ index.registerInstance(this, hostRef);
16630
+ this.actionClick = index.createEvent(this, "actionClick", 7);
16631
+ }
16632
+ render() {
16633
+ return (index.h(index.Host, null, index.h("vviinn-error", null, index.h("svg", { slot: "icon", class: "icon", width: "32", height: "32", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.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" }), index.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" })), index.h("h4", { slot: "title" }, "Leider nichts gefunden"), index.h("span", { slot: "text" }, "Leider konnten wir keine passenden Produkte finden. Bitte versuche es mit einem anderen Bildausschnitt noch einmal."))));
16634
+ }
16635
+ };
16636
+ VviinnEmptyResults.style = vviinnEmptyResultsCss;
16153
16637
 
16154
- var byteToHex = [];
16638
+ 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}";
16155
16639
 
16156
- for (var i = 0; i < 256; ++i) {
16157
- byteToHex.push((i + 0x100).toString(16).substr(1));
16158
- }
16640
+ let VviinnError = class {
16641
+ constructor(hostRef) {
16642
+ index.registerInstance(this, hostRef);
16643
+ }
16644
+ render() {
16645
+ return (index.h(index.Host, null, index.h("slot", { name: "icon" }), index.h("slot", { name: "title" }), index.h("slot", { name: "text" }), index.h("slot", { name: "action" })));
16646
+ }
16647
+ };
16648
+ VviinnError.style = vviinnErrorCss;
16159
16649
 
16160
- function stringify$1(arr) {
16161
- var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
16162
- // Note: Be careful editing this code! It's been tuned for performance
16163
- // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
16164
- var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
16165
- // of the following:
16166
- // - One or more input array values don't map to a hex octet (leading to
16167
- // "undefined" in the uuid)
16168
- // - Invalid input values for the RFC `version` or `variant` fields
16650
+ const vviinnExampleImageCss = ":host{display:block;margin-bottom:8px;position:relative}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;pointer-events:none;position:absolute;right:12px;z-index:4}vviinn-preloader{--preloader-size:12px}@media (max-width: 640px){.image-preloader{display:block}}";
16169
16651
 
16170
- if (!validate(uuid)) {
16171
- throw TypeError('Stringified UUID is invalid');
16652
+ let VviinnExampleImage = class {
16653
+ constructor(hostRef) {
16654
+ index.registerInstance(this, hostRef);
16655
+ this.exampleImageSelected = index.createEvent(this, "exampleImageSelected", 7);
16656
+ this.exampleImageError = index.createEvent(this, "exampleImageError", 7);
16657
+ this.src = "";
16658
+ this.width = 0;
16659
+ this.height = 0;
16660
+ this.selected = false;
16661
+ }
16662
+ async selectImage(_event) {
16663
+ this.selected = true;
16664
+ const file = await toFile(this.src);
16665
+ const processResult = await processSelectedFile(file);
16666
+ _function.pipe(processResult, Either.match(() => this.exampleImageError.emit(), () => this.exampleImageSelected.emit()));
16667
+ this.selected = false;
16668
+ }
16669
+ showPreloader() {
16670
+ return ((imageSearchState.objectDetectionInProgress ||
16671
+ imageSearchState.loading) &&
16672
+ this.selected);
16673
+ }
16674
+ render() {
16675
+ return (index.h(index.Host, null, this.showPreloader() ? (index.h("div", { class: "image-preloader" }, index.h("vviinn-preloader", null))) : null, index.h("img", { onClick: (ev) => this.selectImage(ev), src: this.src, width: this.width, height: this.height })));
16172
16676
  }
16677
+ };
16678
+ VviinnExampleImage.style = vviinnExampleImageCss;
16679
+
16680
+ const defaultSlotsNames = [
16681
+ "vviinn-onboarding-title",
16682
+ "vviinn-onboarding-card-1-icon",
16683
+ "vviinn-onboarding-card-1-text",
16684
+ "vviinn-onboarding-card-2-icon",
16685
+ "vviinn-onboarding-card-2-text",
16686
+ "vviinn-onboarding-card-3-icon",
16687
+ "vviinn-onboarding-card-3-text",
16688
+ "vviinn-example-images-title",
16689
+ "vviinn-example-images-1",
16690
+ "vviinn-example-images-2",
16691
+ "vviinn-example-images-3",
16692
+ "vviinn-example-images-4",
16693
+ "vviinn-teaser-text",
16694
+ "vviinn-image-upload-button-text",
16695
+ "vviinn-privacy-badge-text"
16696
+ ];
16697
+ const renderNamedSlot = (name) => index.h("slot", { name: name });
16698
+ const SlotSkeleton = () => defaultSlotsNames.map(renderNamedSlot);
16699
+ const getSlots = (element) => Array.from(element.shadowRoot.querySelectorAll("slot"));
16700
+ const getNameAttribute = (element) => element.getAttribute("name");
16701
+ const getSlotAttribute = (element) => element.getAttribute("slot");
16702
+ const elementContainSlot = (slot) => (container) => {
16703
+ const name1 = getNameAttribute(slot);
16704
+ const name2 = getSlotAttribute(container);
16705
+ return name1 === name2;
16706
+ };
16707
+ const getContentToReplace = (targets) => (acc, content) => {
16708
+ const replaceCandidate = targets.find(elementContainSlot(content));
16709
+ if (replaceCandidate) {
16710
+ acc.set(content, replaceCandidate);
16711
+ }
16712
+ return acc;
16713
+ };
16714
+ const replaceSlotContent = (content, target) => {
16715
+ target.innerHTML = content.outerHTML;
16716
+ };
16717
+ const slotChangeListener = (component, element) => {
16718
+ component.connectedCallback = function () {
16719
+ document.addEventListener("globalSlotsChanged", ({ detail }) => {
16720
+ const slotsToReplace = getSlots(element).reduce(getContentToReplace(detail), new Map());
16721
+ slotsToReplace.forEach(replaceSlotContent);
16722
+ }, true);
16723
+ };
16724
+ component.connectedCallback.call(component);
16725
+ };
16173
16726
 
16174
- return uuid;
16175
- }
16727
+ 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}";
16176
16728
 
16177
- function v4(options, buf, offset) {
16178
- options = options || {};
16179
- var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
16729
+ let VviinnExampleImages = class {
16730
+ constructor(hostRef) {
16731
+ index.registerInstance(this, hostRef);
16732
+ this.imageSelected = index.createEvent(this, "imageSelected", 7);
16733
+ this.imageSelectedError = index.createEvent(this, "imageSelectedError", 7);
16734
+ }
16735
+ handleImageSelection() {
16736
+ this.imageSelected.emit();
16737
+ }
16738
+ handleImageSelectionError() {
16739
+ this.imageSelectedError.emit();
16740
+ }
16741
+ componentWillLoad() {
16742
+ slotChangeListener(this, this.el);
16743
+ }
16744
+ render() {
16745
+ return (index.h(index.Host, null, index.h("slot", { name: "vviinn-example-images-title" }, index.h("h3", null, "Mit den Beispielbildern die Suche direkt ausprobieren")), index.h("div", { class: "images" }, index.h("slot", { name: "vviinn-example-images-1" }, index.h("vviinn-example-image", { width: 480, height: 640, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDEtTC5qcGc=" })), index.h("slot", { name: "vviinn-example-images-2" }, index.h("vviinn-example-image", { width: 280, height: 480, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDItTS5qcGc=" })), index.h("slot", { name: "vviinn-example-images-3" }, index.h("vviinn-example-image", { width: 280, height: 480, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDMtTS5qcGc=" })), index.h("slot", { name: "vviinn-example-images-4" }, index.h("vviinn-example-image", { width: 480, height: 640, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDQtTC5qcGc=" })))));
16746
+ }
16747
+ get el() { return index.getElement(this); }
16748
+ };
16749
+ VviinnExampleImages.style = vviinnExampleImagesCss;
16180
16750
 
16181
- rnds[6] = rnds[6] & 0x0f | 0x40;
16182
- rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
16751
+ 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;padding:0.5rem;transition:background 0.1s ease-in-out}";
16183
16752
 
16184
- if (buf) {
16185
- offset = offset || 0;
16753
+ let VviinnImageSelector = class {
16754
+ constructor(hostRef) {
16755
+ index.registerInstance(this, hostRef);
16756
+ this.imageSelected = index.createEvent(this, "imageSelected", 7);
16757
+ this.imageSelectedError = index.createEvent(this, "imageSelectedError", 7);
16758
+ }
16759
+ async handleInputChange(event) {
16760
+ const input = event.target;
16761
+ const processingResult = await processSelectedFile(input.files[0]);
16762
+ _function.pipe(processingResult, match$1(() => this.imageSelectedError.emit(), () => this.imageSelected.emit()));
16763
+ input.value = null;
16764
+ }
16765
+ isLoading() {
16766
+ return (imageSearchState.loading || imageSearchState.objectDetectionInProgress);
16767
+ }
16768
+ render() {
16769
+ return (index.h(index.Host, { exportparts: "button" }, this.isLoading() ? index.h("vviinn-preloader", null) : null, this.isLoading() ? null : (index.h("label", { htmlFor: "fileInput", part: "button" }, index.h("slot", { name: "upload-button-text" }, "Upload image"))), index.h("input", { id: "fileInput", class: "visually-hidden", type: "file", accept: "image/*", onChange: (event) => this.handleInputChange(event) })));
16770
+ }
16771
+ };
16772
+ VviinnImageSelector.style = vviinnImageSelectorCss;
16186
16773
 
16187
- for (var i = 0; i < 16; ++i) {
16188
- buf[offset + i] = rnds[i];
16189
- }
16774
+ const vviinnImageViewCss = ":host{display:grid;position:relative;justify-self:center}img{box-sizing:border-box;filter:brightness(60%);position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-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}";
16190
16775
 
16191
- return buf;
16776
+ const getImageSizes = (i) => {
16777
+ const dimensions = dimensionsFromImage(i);
16778
+ const resize = scaleByLargestSide(288);
16779
+ const newDimensions = resize(dimensions);
16780
+ const sizes = newDimensions.map(d => d.size);
16781
+ return [sizes[0], sizes[1]];
16782
+ };
16783
+ let VviinnImageView = class {
16784
+ constructor(hostRef) {
16785
+ index.registerInstance(this, hostRef);
16786
+ }
16787
+ handleInitialImageLoad(ev) {
16788
+ const target = ev.target;
16789
+ const imageBounds = fromImage(target);
16790
+ const padding = 12;
16791
+ const { x, y } = move(imageBounds, { x: padding, y: padding });
16792
+ const searchArea = {
16793
+ x,
16794
+ y,
16795
+ width: imageBounds.width - padding * 2,
16796
+ height: imageBounds.height - padding * 2,
16797
+ };
16798
+ imageSearchState.imageBounds = Option.some(imageBounds);
16799
+ imageSearchState.searchArea = Option.some(searchArea);
16800
+ }
16801
+ renderDetectedObject(object) {
16802
+ return index.h("vviinn-detected-object", { detectedObject: object });
16803
+ }
16804
+ renderImage() {
16805
+ return _function.pipe(sequenceToOption(imageSearchState.imageUrl, imageSearchState.image), Option.map(([url, refImage]) => {
16806
+ const [width, height] = getImageSizes(refImage);
16807
+ const image = (index.h("img", { decoding: "async", width: width, height: height, src: url, onLoad: (el) => this.handleInitialImageLoad(el), draggable: false }));
16808
+ return image;
16809
+ }), Option.getOrElse(() => null));
16192
16810
  }
16811
+ renderCropper() {
16812
+ return _function.pipe(imageSearchState.imageUrl, Option.map(() => index.h("image-cropper", null)), Option.getOrElse(() => null));
16813
+ }
16814
+ render() {
16815
+ return (index.h(index.Host, null, imageSearchState.loading ||
16816
+ imageSearchState.objectDetectionInProgress ? (index.h("div", { class: "image-preloader" }, index.h("vviinn-preloader", null))) : null, index.h("highlight-box", null), this.renderImage(), this.renderCropper(), imageSearchState.detectedObjects.map((o) => this.renderDetectedObject(o))));
16817
+ }
16818
+ };
16819
+ VviinnImageView.style = vviinnImageViewCss;
16193
16820
 
16194
- return stringify$1(rnds);
16195
- }
16821
+ const vviinnModalCss = ":host{background:white;border-radius:4px;box-sizing:border-box;display:grid;grid-template-rows:-webkit-min-content auto;grid-template-rows:min-content auto;max-width:960px}@media (max-width: 415px){:host{-webkit-animation-name:fade-in;animation-name:fade-in;-webkit-animation-duration:0.5s;animation-duration:0.5s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}:host(.closed){-webkit-animation-name:fade-out;animation-name:fade-out;-webkit-animation-fill-mode:none;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:grid;grid-gap:16px;grid-template-columns:-webkit-min-content auto -webkit-min-content;grid-template-columns:min-content auto min-content;justify-items:center;padding:16px}.title{font-weight:600;font-size:18px;line-height:24px}button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:grid;padding:unset}@-webkit-keyframes fade-in{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes fade-in{from{transform:translateY(100%)}to{transform:translateY(0)}}@-webkit-keyframes fade-out{from{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes fade-out{from{transform:translateY(0)}to{transform:translateY(100%)}}";
16196
16822
 
16197
- /**
16198
- * Check if we're required to add a port number.
16199
- *
16200
- * @see https://url.spec.whatwg.org/#default-port
16201
- * @param {Number|String} port Port number we need to check
16202
- * @param {String} protocol Protocol we need to check against.
16203
- * @returns {Boolean} Is it a default port for the given protocol
16204
- * @api private
16205
- */
16206
- var requiresPort = function required(port, protocol) {
16207
- protocol = protocol.split(':')[0];
16208
- port = +port;
16823
+ let VviinnModal = class {
16824
+ constructor(hostRef) {
16825
+ index.registerInstance(this, hostRef);
16826
+ this.modalClosed = index.createEvent(this, "modalClosed", 7);
16827
+ this.secondaryActionClicked = index.createEvent(this, "secondaryActionClicked", 7);
16828
+ this.active = false;
16829
+ this.slider = false;
16830
+ }
16831
+ close() {
16832
+ this.active = false;
16833
+ setTimeout(() => {
16834
+ this.modalClosed.emit();
16835
+ }, this.slider ? 500 : 0);
16836
+ }
16837
+ handleAnimationEnd(ev) {
16838
+ if (ev.animationName !== "fade-in")
16839
+ return;
16840
+ this.slider = true;
16841
+ }
16842
+ render() {
16843
+ return (index.h(index.Host, { exportparts: "secondary-action, title, close-button", class: { closed: !this.active }, onAnimationEnd: (ev) => this.handleAnimationEnd(ev) }, index.h("div", { class: "head" }, index.h("button", { part: "secondary-action", onClick: () => this.secondaryActionClicked.emit() }, index.h("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M20.25 12H3.75", stroke: "#161616", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), index.h("path", { d: "M10.5 5.25L3.75 12L10.5 18.75", stroke: "#161616", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }))), index.h("div", { class: "title", part: "title" }, "Bildsuche"), index.h("button", { onClick: () => this.close(), class: "close-button", part: "close-button" }, index.h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.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" })))), index.h("div", { class: "body" }, index.h("slot", null))));
16844
+ }
16845
+ };
16846
+ VviinnModal.style = vviinnModalCss;
16209
16847
 
16210
- if (!port) return false;
16848
+ 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))}";
16211
16849
 
16212
- switch (protocol) {
16213
- case 'http':
16214
- case 'ws':
16215
- return port !== 80;
16850
+ let VviinnOnboarding = class {
16851
+ constructor(hostRef) {
16852
+ index.registerInstance(this, hostRef);
16853
+ }
16854
+ componentWillLoad() {
16855
+ slotChangeListener(this, this.el);
16856
+ }
16857
+ render() {
16858
+ return (index.h(index.Host, null, index.h("slot", { name: "vviinn-onboarding-title" }, index.h("h3", null, "So funktioniert es")), index.h("vviinn-slider", { showArrows: true }, index.h("vviinn-slide", null, index.h("vviinn-onboarding-card-1", null)), index.h("vviinn-slide", null, index.h("vviinn-onboarding-card-2", null)), index.h("vviinn-slide", null, index.h("vviinn-onboarding-card-3", null)))));
16859
+ }
16860
+ get el() { return index.getElement(this); }
16861
+ };
16862
+ VviinnOnboarding.style = vviinnOnboardingCss;
16216
16863
 
16217
- case 'https':
16218
- case 'wss':
16219
- return port !== 443;
16864
+ 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}";
16220
16865
 
16221
- case 'ftp':
16222
- return port !== 21;
16866
+ let VviinnOnboardingCard1 = class {
16867
+ constructor(hostRef) {
16868
+ index.registerInstance(this, hostRef);
16869
+ }
16870
+ componentWillLoad() {
16871
+ slotChangeListener(this, this.el);
16872
+ }
16873
+ render() {
16874
+ return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-1-icon" }, index.h(index$1.OnboardingCard1Icon, null)), index.h("slot", { name: "onboarding-card-1-text" }, index.h("div", { class: "text" }, index.h("h4", null, "Starte die Bildsuche"), index.h("p", null, "Lade ein Bild aus Deiner Galerie hoch oder fotografiere ein Produkt mit Deiner Kamera.")))));
16875
+ }
16876
+ get el() { return index.getElement(this); }
16877
+ };
16878
+ VviinnOnboardingCard1.style = onboardingCardCss$2;
16223
16879
 
16224
- case 'gopher':
16225
- return port !== 70;
16880
+ 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}";
16226
16881
 
16227
- case 'file':
16228
- return false;
16882
+ let VviinnOnboardingCard2 = class {
16883
+ constructor(hostRef) {
16884
+ index.registerInstance(this, hostRef);
16229
16885
  }
16886
+ componentWillLoad() {
16887
+ slotChangeListener(this, this.el);
16888
+ }
16889
+ render() {
16890
+ return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-2-icon" }, index.h(index$1.OnboardingCard2Icon, null)), index.h("slot", { name: "onboarding-card-2-text" }, index.h("div", { class: "text" }, index.h("h4", null, "Verfeiner deine Suche"), index.h("p", null, "Du kannst den Bildrahmen selber festlegen und so die Produkte genau ausw\u00E4hlen.")))));
16891
+ }
16892
+ get el() { return index.getElement(this); }
16893
+ };
16894
+ VviinnOnboardingCard2.style = onboardingCardCss$1;
16230
16895
 
16231
- return port !== 0;
16896
+ 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}";
16897
+
16898
+ let VviinnOnboardingCard3 = class {
16899
+ constructor(hostRef) {
16900
+ index.registerInstance(this, hostRef);
16901
+ }
16902
+ componentWillLoad() {
16903
+ slotChangeListener(this, this.el);
16904
+ }
16905
+ render() {
16906
+ return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-3-icon" }, index.h(index$1.OnboardingCard3Icon, null)), index.h("slot", { name: "onboarding-card-3-text" }, index.h("div", { class: "text" }, index.h("h4", null, "Ohne Hintergrund"), index.h("p", null, "Die besten Ergebnisse erh\u00E4ltst Du, wenn das gesuchte Objekt mit einfarbigem und hellem Hintergrund zu sehen ist.")))));
16907
+ }
16908
+ get el() { return index.getElement(this); }
16232
16909
  };
16910
+ VviinnOnboardingCard3.style = onboardingCardCss;
16233
16911
 
16234
- var has = Object.prototype.hasOwnProperty
16235
- , undef;
16912
+ const vviinnOverlayCss = ":host{-webkit-animation:fade-in 0.5s ease-in-out;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}@-webkit-keyframes fade-in{from{opacity:0.1}to{opacity:1}}@keyframes fade-in{from{opacity:0.1}to{opacity:1}}";
16236
16913
 
16237
- /**
16238
- * Decode a URI encoded string.
16914
+ let VviinnOverlay = class {
16915
+ constructor(hostRef) {
16916
+ index.registerInstance(this, hostRef);
16917
+ }
16918
+ render() {
16919
+ return (index.h(index.Host, null, index.h("slot", null)));
16920
+ }
16921
+ };
16922
+ VviinnOverlay.style = vviinnOverlayCss;
16923
+
16924
+ const vviinnOverlayedModalCss = ":host{display:none}:host(.active){display:block}vviinn-overlay{align-items:center;display:grid;justify-items:center}@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}}";
16925
+
16926
+ let VviinnOverlayedModal = class {
16927
+ constructor(hostRef) {
16928
+ index.registerInstance(this, hostRef);
16929
+ this.secondaryActionClicked = index.createEvent(this, "secondaryActionClicked", 7);
16930
+ this.modalClosed = index.createEvent(this, "modalClosed", 7);
16931
+ this.active = false;
16932
+ }
16933
+ render() {
16934
+ return (index.h(index.Host, { class: { active: this.active } }, index.h("vviinn-overlay", null, index.h("vviinn-modal", { onSecondaryActionClicked: () => this.secondaryActionClicked.emit(), active: this.active }, index.h("slot", null, "CONTENT")))));
16935
+ }
16936
+ };
16937
+ VviinnOverlayedModal.style = vviinnOverlayedModalCss;
16938
+
16939
+ const vviinnPreloaderCss = ":host{--preloader-size:24px;--preloader-width:calc(var(--preloader-size) / 6);transform-origin:center;-webkit-animation:rotate 3s linear infinite;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}@-webkit-keyframes rotate{from{transform:rotate(-360deg)}to{transform:rotate(360deg)}}@keyframes rotate{from{transform:rotate(-360deg)}to{transform:rotate(360deg)}}";
16940
+
16941
+ let VviinnPreloader = class {
16942
+ constructor(hostRef) {
16943
+ index.registerInstance(this, hostRef);
16944
+ }
16945
+ isActive() {
16946
+ return (imageSearchState.loading || imageSearchState.objectDetectionInProgress);
16947
+ }
16948
+ render() {
16949
+ return (index.h(index.Host, { class: {
16950
+ active: this.isActive(),
16951
+ } }));
16952
+ }
16953
+ };
16954
+ VviinnPreloader.style = vviinnPreloaderCss;
16955
+
16956
+ const vviinnPrivacyBadgeCss = ":host{display:block;background:#F4F4F4;padding:17px}.content{display:grid;grid-template-columns:-webkit-min-content auto;grid-template-columns:min-content auto;grid-gap:9px}.content p{color:#525252;font-size:12px;line-height:16px;margin:unset}";
16957
+
16958
+ let VviinnPrivacyBadge = class {
16959
+ constructor(hostRef) {
16960
+ index.registerInstance(this, hostRef);
16961
+ }
16962
+ componentWillLoad() {
16963
+ slotChangeListener(this, this.el);
16964
+ }
16965
+ render() {
16966
+ return (index.h(index.Host, null, index.h("slot", null, index.h("div", { class: "content" }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none" }, index.h("defs", null), index.h("path", { fill: "#525252", d: "M8.5 11V7h-2v1h1v3H6v1h4v-1H8.5zM8 4a.75.75 0 100 1.5A.75.75 0 008 4z" }), index.h("path", { fill: "#525252", d: "M8 15A7 7 0 118 1a7 7 0 010 14zM8 2a6 6 0 100 12A6 6 0 008 2z" })), index.h("slot", { name: "vviinn-privacy-badge-text" }, index.h("p", null, "Wir gehen sorgf\u00E4ltig mit Deinen Daten um. Deine Bilder werden nur zum Zweck der Bildsuche gespeichert."))))));
16967
+ }
16968
+ get el() { return index.getElement(this); }
16969
+ };
16970
+ VviinnPrivacyBadge.style = vviinnPrivacyBadgeCss;
16971
+
16972
+ class GtagAnalytics {
16973
+ sendImpression(product) {
16974
+ var _a, _b, _c;
16975
+ gtag('event', 'view_item_list', {
16976
+ items: [
16977
+ {
16978
+ id: product.productId,
16979
+ name: product.title,
16980
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
16981
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
16982
+ list_name: 'VI VPR View',
16983
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
16984
+ }
16985
+ ]
16986
+ });
16987
+ return undefined;
16988
+ }
16989
+ sendClick(product) {
16990
+ var _a, _b, _c;
16991
+ gtag('event', 'select_content', {
16992
+ content_type: 'product',
16993
+ items: [
16994
+ {
16995
+ id: product.productId,
16996
+ name: product.title,
16997
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
16998
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
16999
+ list_name: 'VI VPR View',
17000
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
17001
+ }
17002
+ ]
17003
+ });
17004
+ return undefined;
17005
+ }
17006
+ }
17007
+
17008
+ class GAnalytics {
17009
+ constructor() {
17010
+ ga('require', 'ec');
17011
+ }
17012
+ convertProduct(product) {
17013
+ var _a, _b, _c;
17014
+ return {
17015
+ id: product.productId,
17016
+ name: product.title,
17017
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
17018
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
17019
+ list: 'VI VPR View',
17020
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
17021
+ };
17022
+ }
17023
+ sendImpression(product) {
17024
+ ga('ec:addImpression', this.convertProduct(product));
17025
+ return undefined;
17026
+ }
17027
+ sendClick(product) {
17028
+ var _a, _b, _c;
17029
+ ga('ec:addProduct', {
17030
+ id: product.productId,
17031
+ name: product.title,
17032
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
17033
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
17034
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
17035
+ });
17036
+ ga('ec:setAction', 'click', { list: 'VI VPR View' });
17037
+ return undefined;
17038
+ }
17039
+ }
17040
+
17041
+ const getGtagAnalytics = () => _function.pipe(Option.fromNullable(window.gtag), Option.map(() => new GtagAnalytics()));
17042
+ const getCommonAnalytics = () => _function.pipe(Option.fromNullable(window.ga), Option.map(() => new GAnalytics()));
17043
+ const analyticsMonoid = Option.getMonoid(Semigroup$1.first());
17044
+ const getAnalyticsModule = analyticsMonoid.concat(getGtagAnalytics(), getCommonAnalytics());
17045
+
17046
+ const FIT_EXPR = /fit\/\d+\//;
17047
+ const containsFit = (url) => {
17048
+ return _function.pipe(url.match(FIT_EXPR), Either.fromNullable(url), Either.map(() => url));
17049
+ };
17050
+ const processWidth = (url, size) => {
17051
+ return _function.pipe(containsFit(url), Either.map((url) => url.replace(FIT_EXPR, `fit/${size}/`)), Either.getOrElse(() => url));
17052
+ };
17053
+ const Linked = (props, child) => props.deeplink ? (index.h("a", { class: props.part, part: props.part, href: props.deeplink }, child)) : (child);
17054
+ const FormattedPrice = (props) => {
17055
+ var _a;
17056
+ const locale = props.locale;
17057
+ const formattedPrice = new Intl.NumberFormat(locale, {
17058
+ minimumFractionDigits: 2,
17059
+ }).format(props.price);
17060
+ const fullPrice = `${(_a = props.prefix) !== null && _a !== void 0 ? _a : ""} ${formattedPrice} ${props.currency}`;
17061
+ return (index.h("span", { class: "price-amount", part: "price-amount" }, fullPrice));
17062
+ };
17063
+ const Price = (props) => {
17064
+ const priceEl = (index.h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.price, locale: props.locale }));
17065
+ return (index.h("span", { class: "price-container", part: "price-container" }, props.salePrice ? ([
17066
+ index.h("span", { class: "price-sale", part: "price-sale" },
17067
+ index.h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.salePrice, locale: props.locale })),
17068
+ index.h("span", { class: "price-outdated", part: "price-outdated" }, priceEl),
17069
+ ]) : (index.h("span", { class: "price-regular", part: "price-regular" }, priceEl))));
17070
+ };
17071
+ const Image$1 = (props, onLoadEnd = () => undefined) => (index.h("picture", null,
17072
+ index.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 })));
17073
+ const ResponsiveImage = (props, onLoadEnd = () => undefined) => (index.h("picture", null,
17074
+ index.h("img", { loading: props.lazy ? "lazy" : "eager", part: "image", class: "image responsive", src: processWidth(props.src, props.width), alt: props.title, onLoad: onLoadEnd })));
17075
+
17076
+ 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}";
17077
+
17078
+ let VviinnProductCard = class {
17079
+ constructor(hostRef) {
17080
+ index.registerInstance(this, hostRef);
17081
+ this.recommendationLoad = index.createEvent(this, "recommendationLoad", 7);
17082
+ this.recommendationView = index.createEvent(this, "recommendationView", 7);
17083
+ this.recommendationClick = index.createEvent(this, "recommendationClick", 7);
17084
+ this.productImageLoaded = index.createEvent(this, "productImageLoaded", 7);
17085
+ this.currency = undefined;
17086
+ this.imageRatio = 1;
17087
+ this.imageWidth = 200;
17088
+ this.locale = undefined;
17089
+ this.pricePrefix = undefined;
17090
+ this.responsive = false;
17091
+ this.dimmedBackground = false;
17092
+ /** @internal */
17093
+ this.index = 0;
17094
+ this.imageLoaded = false;
17095
+ this.productData = null;
17096
+ this.intersectionObserver = new IntersectionObserver(this.intersectionCallback.bind(this), { threshold: 1.0 });
17097
+ }
17098
+ connectedCallback() {
17099
+ this.productData = this.getProductData();
17100
+ }
17101
+ getProductData() {
17102
+ return {
17103
+ product: this.productId,
17104
+ rank: this.index,
17105
+ };
17106
+ }
17107
+ intersectionCallback(data) {
17108
+ if (data.some((entry) => entry.isIntersecting)) {
17109
+ _function.pipe(getAnalyticsModule, Option.map((analytics) => analytics.sendImpression(this.getProduct())));
17110
+ this.recommendationView.emit(this.productData);
17111
+ this.intersectionObserver.disconnect();
17112
+ }
17113
+ }
17114
+ componentDidLoad() {
17115
+ this.recommendationLoad.emit(this.productData);
17116
+ this.intersectionObserver.observe(this.el);
17117
+ const links = this.el.shadowRoot.querySelectorAll("a");
17118
+ links.forEach((link) => link.addEventListener("click", (event) => {
17119
+ event.preventDefault();
17120
+ event.stopImmediatePropagation();
17121
+ this.recommendationClick.emit(this.getProductData());
17122
+ _function.pipe(getAnalyticsModule, Option.match(() => null, (analytics) => analytics.sendClick(this.getProduct())));
17123
+ }));
17124
+ }
17125
+ getProduct() {
17126
+ return imageSearchState.results.find((r) => r.productId === this.productId);
17127
+ }
17128
+ renderImage() {
17129
+ const props = {
17130
+ width: this.imageWidth,
17131
+ height: this.imageWidth * this.imageRatio,
17132
+ src: this.image,
17133
+ title: this.productTitle,
17134
+ lazy: false,
17135
+ };
17136
+ return this.responsive
17137
+ ? ResponsiveImage(props, () => this.kek())
17138
+ : Image$1(props, () => this.kek());
17139
+ }
17140
+ kek() {
17141
+ this.productImageLoaded.emit(this.productId);
17142
+ }
17143
+ render() {
17144
+ var _a, _b, _c;
17145
+ return (index.h(index.Host, { part: "product-card", class: { dimmed: this.dimmedBackground }, exportparts: "brand, currency, deeplink, image, image-link, price-amount, price-container, price-outdated, price-prefix, price-regular, price-sale, title" }, index.h(Linked, { deeplink: this.deeplink, part: "image-link" }, this.renderImage()), index.h(Linked, { deeplink: this.deeplink, part: "deeplink" }, index.h("span", { class: "title", part: "title" }, this.productTitle)), index.h("span", { class: "brand", part: "brand" }, this.brand), index.h("span", { class: "type", part: "type" }, this.productType), index.h(Price, { prefix: (_a = this.pricePrefix) !== null && _a !== void 0 ? _a : state$1.pricePrefix, currency: (_b = this.currency) !== null && _b !== void 0 ? _b : state$1.currencySign, price: this.price, salePrice: this.salePrice, locale: (_c = this.locale) !== null && _c !== void 0 ? _c : state$1.locale })));
17146
+ }
17147
+ get el() { return index.getElement(this); }
17148
+ };
17149
+ VviinnProductCard.style = vviinnProductCardCss;
17150
+
17151
+ const vviinnServerErrorCss = ":host{display:block}";
17152
+
17153
+ let VviinnServerError = class {
17154
+ constructor(hostRef) {
17155
+ index.registerInstance(this, hostRef);
17156
+ this.actionClick = index.createEvent(this, "actionClick", 7);
17157
+ }
17158
+ render() {
17159
+ return (index.h(index.Host, null, index.h("vviinn-error", null, index.h("h4", { slot: "title" }, "Keine Verbindung"), index.h("span", { slot: "text" }, "Etwas hat leider nicht funktioniert. Bitte pr\u00FCfen Sie Ihre Internetverbindung und laden Sie das Bild noch einmal hoch."), index.h("button", { slot: "action", onClick: () => this.actionClick.emit() }, "Erneut versuchen"))));
17160
+ }
17161
+ };
17162
+ VviinnServerError.style = vviinnServerErrorCss;
17163
+
17164
+ const vviinnSlideCss = ":host{display:grid;justify-items:center}";
17165
+
17166
+ let VviinnSlide = class {
17167
+ constructor(hostRef) {
17168
+ index.registerInstance(this, hostRef);
17169
+ }
17170
+ render() {
17171
+ return (index.h(index.Host, null, index.h("slot", null)));
17172
+ }
17173
+ };
17174
+ VviinnSlide.style = vviinnSlideCss;
17175
+
17176
+ const getStyleMap = (data) => {
17177
+ return {
17178
+ "arrow-wrapper": true,
17179
+ [data.kind]: true,
17180
+ disabled: data.disabled,
17181
+ };
17182
+ };
17183
+ const Arrow = ({ kind, tabindex, disabled, onClick, onKeyDown, }) => (index.h("div", { class: getStyleMap({ kind, disabled }), onClick: onClick, tabindex: tabindex, onKeyDown: onKeyDown },
17184
+ index.h(index$1.ArrowIcon, null)));
17185
+
17186
+ 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), -webkit-min-content);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;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}";
17187
+
17188
+ let VviinnSlider = class {
17189
+ constructor(hostRef) {
17190
+ index.registerInstance(this, hostRef);
17191
+ this.elementsCount = 0;
17192
+ this.internalPosition = 0;
17193
+ this.swipeStartPosition = Option.none;
17194
+ this.showBullets = true;
17195
+ this.position = 0;
17196
+ this.showArrows = false;
17197
+ }
17198
+ positionWatchHandler(newValue) {
17199
+ this.internalPosition = newValue;
17200
+ this.el.style.setProperty("--position", `${newValue}`);
17201
+ this.setActiveCssClassToSlide(newValue);
17202
+ }
17203
+ connectedCallback() {
17204
+ this.handleDomContentChanges();
17205
+ }
17206
+ handleDomContentChanges() {
17207
+ const items = this.el.querySelectorAll("vviinn-slide");
17208
+ this.elementsCount = items.length;
17209
+ this.el.style.setProperty("--num-items", `${this.elementsCount}`);
17210
+ this.setActiveCssClassToSlide(0);
17211
+ }
17212
+ setActiveCssClassToSlide(index) {
17213
+ const items = this.el.querySelectorAll("vviinn-slide");
17214
+ items.forEach((i) => i.classList.remove("active"));
17215
+ items[index].classList.add("active");
17216
+ }
17217
+ goToSlide(index) {
17218
+ this.internalPosition = index;
17219
+ this.el.style.setProperty("--position", `${index}`);
17220
+ this.setActiveCssClassToSlide(index);
17221
+ }
17222
+ renderBullets() {
17223
+ return this.showBullets ? (index.h("div", { class: "controls" }, NonEmptyArray.range(0, this.elementsCount - 1).map((i) => (index.h("div", { class: {
17224
+ bullet: true,
17225
+ active: i == this.internalPosition % this.elementsCount,
17226
+ }, onClick: () => this.goToSlide(i) }))))) : null;
17227
+ }
17228
+ nextSlide() {
17229
+ this.internalPosition++;
17230
+ this.renderSlidePosition();
17231
+ }
17232
+ prevSlide() {
17233
+ const nextPostion = this.internalPosition - 1;
17234
+ this.internalPosition =
17235
+ nextPostion > -1 ? nextPostion : this.elementsCount - 1;
17236
+ this.renderSlidePosition();
17237
+ }
17238
+ renderSlidePosition() {
17239
+ requestAnimationFrame(() => {
17240
+ this.el.style.setProperty("--position", `${this.internalPosition % this.elementsCount}`);
17241
+ });
17242
+ }
17243
+ handleKeyDown(event) {
17244
+ if (event.key !== "Space" && event.key !== "Enter")
17245
+ return;
17246
+ const target = event.target;
17247
+ const direction = target.className.includes("prev") ? "prev" : "next";
17248
+ switch (direction) {
17249
+ case "prev":
17250
+ this.prevSlide();
17251
+ break;
17252
+ case "next":
17253
+ this.nextSlide();
17254
+ break;
17255
+ }
17256
+ }
17257
+ handleTouchStart(event) {
17258
+ if (!this.showBullets)
17259
+ return;
17260
+ this.swipeStartPosition = _function.pipe(event.touches[0], Option.fromNullable, Option.map((t) => t.clientX));
17261
+ }
17262
+ handleTouchEnd(event) {
17263
+ if (!this.showBullets)
17264
+ return;
17265
+ const swipeEndPosition = _function.pipe(event.changedTouches[0], Option.fromNullable, Option.map((t) => t.clientX));
17266
+ _function.pipe(sequenceToOption(this.swipeStartPosition, swipeEndPosition), Option.map(([start, end]) => Ord.compare(start, end)), Option.map((swipeDirection) => {
17267
+ switch (swipeDirection) {
17268
+ case 1:
17269
+ return this.nextSlide();
17270
+ case -1:
17271
+ return this.prevSlide();
17272
+ }
17273
+ }));
17274
+ }
17275
+ render() {
17276
+ return (index.h(index.Host, null, index.h("div", { class: "items-wrapper" }, index.h("div", { class: "items", onTouchStart: (e) => this.handleTouchStart(e), onTouchEnd: (e) => this.handleTouchEnd(e) }, index.h("slot", null))), this.showArrows
17277
+ ? [
17278
+ index.h(Arrow, { kind: "prev", onClick: () => this.prevSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 1, disabled: false }),
17279
+ index.h(Arrow, { kind: "next", onClick: () => this.nextSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 0, disabled: false }),
17280
+ ]
17281
+ : null, this.renderBullets()));
17282
+ }
17283
+ get el() { return index.getElement(this); }
17284
+ static get watchers() { return {
17285
+ "position": ["positionWatchHandler"]
17286
+ }; }
17287
+ };
17288
+ VviinnSlider.style = vviinnSliderCss;
17289
+
17290
+ 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}";
17291
+
17292
+ let VviinnTeaser = class {
17293
+ constructor(hostRef) {
17294
+ index.registerInstance(this, hostRef);
17295
+ }
17296
+ componentWillLoad() {
17297
+ slotChangeListener(this, this.el);
17298
+ }
17299
+ render() {
17300
+ return (index.h(index.Host, null, index.h("slot", null, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "64", height: "64", fill: "none" }, index.h("defs", null), index.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" }), index.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" })), index.h("span", { class: "vviinn-teaser-text" }, index.h("slot", { name: "vviinn-teaser-text" }, "Finde Produkte auf ", index.h("br", null), " einem Foto")))));
17301
+ }
17302
+ get el() { return index.getElement(this); }
17303
+ };
17304
+ VviinnTeaser.style = vviinnTeaserCss;
17305
+
17306
+ const createBearerString = (x) => `Bearer ${x}`;
17307
+ const createAuthedHeader = (x) => new Headers({
17308
+ Authorization: x,
17309
+ });
17310
+ const createFetchAuthOptions = (x) => {
17311
+ return {
17312
+ headers: x,
17313
+ };
17314
+ };
17315
+ const createBearAuthedHeader = _function.flow(createBearerString, createAuthedHeader, createFetchAuthOptions);
17316
+
17317
+ const isVPR = (c) => c._tag === "VPR";
17318
+ function fold(onVPR, onVCS) {
17319
+ return (c) => (isVPR(c) ? onVPR() : onVCS());
17320
+ }
17321
+ function fromString(s) {
17322
+ return s === "VPR" ? { _tag: "VPR" } : { _tag: "VCS" };
17323
+ }
17324
+
17325
+ const sequenceToEither = sequenceT(Apply);
17326
+ const apiGet = (path, data = {}) => pipe(sequenceToEither(getApiPath(), createInitGetRequest), fromEither, chainW(makeRequest(path, data)));
17327
+
17328
+ const getVPRRecommendations = (productId) => (campaigns) => (options) => {
17329
+ const url = _function.pipe(campaigns, map$3(encodeURIComponent), match(() => `product/${productId}/similar-products`, (encodedCampaignsIds) => `product/${productId}/similar-products?campaigns=${encodedCampaignsIds}`));
17330
+ return apiGet(url, options);
17331
+ };
17332
+
17333
+ const getVCSRecommendations = (productId) => (campaigns) => (options) => {
17334
+ const url = _function.pipe(campaigns, map$3(encodeURIComponent), match(() => `product/${productId}/cross-selling-products`, (encodedCampaignsIds) => `product/${productId}/cross-selling-products?campaigns=${encodedCampaignsIds}`));
17335
+ return apiGet(url, options);
17336
+ };
17337
+
17338
+ const getRecommendationsService = (campaignType) => _function.pipe(fromString(campaignType), fold(() => getVPRRecommendations, () => getVCSRecommendations));
17339
+
17340
+ function isFunction(value) {
17341
+ return typeof value === 'function';
17342
+ }
17343
+
17344
+ function createErrorClass(createImpl) {
17345
+ const _super = (instance) => {
17346
+ Error.call(instance);
17347
+ instance.stack = new Error().stack;
17348
+ };
17349
+ const ctorFunc = createImpl(_super);
17350
+ ctorFunc.prototype = Object.create(Error.prototype);
17351
+ ctorFunc.prototype.constructor = ctorFunc;
17352
+ return ctorFunc;
17353
+ }
17354
+
17355
+ const UnsubscriptionError = createErrorClass((_super) => function UnsubscriptionErrorImpl(errors) {
17356
+ _super(this);
17357
+ this.message = errors
17358
+ ? `${errors.length} errors occurred during unsubscription:
17359
+ ${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\n ')}`
17360
+ : '';
17361
+ this.name = 'UnsubscriptionError';
17362
+ this.errors = errors;
17363
+ });
17364
+
17365
+ function arrRemove(arr, item) {
17366
+ if (arr) {
17367
+ const index = arr.indexOf(item);
17368
+ 0 <= index && arr.splice(index, 1);
17369
+ }
17370
+ }
17371
+
17372
+ class Subscription {
17373
+ constructor(initialTeardown) {
17374
+ this.initialTeardown = initialTeardown;
17375
+ this.closed = false;
17376
+ this._parentage = null;
17377
+ this._finalizers = null;
17378
+ }
17379
+ unsubscribe() {
17380
+ let errors;
17381
+ if (!this.closed) {
17382
+ this.closed = true;
17383
+ const { _parentage } = this;
17384
+ if (_parentage) {
17385
+ this._parentage = null;
17386
+ if (Array.isArray(_parentage)) {
17387
+ for (const parent of _parentage) {
17388
+ parent.remove(this);
17389
+ }
17390
+ }
17391
+ else {
17392
+ _parentage.remove(this);
17393
+ }
17394
+ }
17395
+ const { initialTeardown: initialFinalizer } = this;
17396
+ if (isFunction(initialFinalizer)) {
17397
+ try {
17398
+ initialFinalizer();
17399
+ }
17400
+ catch (e) {
17401
+ errors = e instanceof UnsubscriptionError ? e.errors : [e];
17402
+ }
17403
+ }
17404
+ const { _finalizers } = this;
17405
+ if (_finalizers) {
17406
+ this._finalizers = null;
17407
+ for (const finalizer of _finalizers) {
17408
+ try {
17409
+ execFinalizer(finalizer);
17410
+ }
17411
+ catch (err) {
17412
+ errors = errors !== null && errors !== void 0 ? errors : [];
17413
+ if (err instanceof UnsubscriptionError) {
17414
+ errors = [...errors, ...err.errors];
17415
+ }
17416
+ else {
17417
+ errors.push(err);
17418
+ }
17419
+ }
17420
+ }
17421
+ }
17422
+ if (errors) {
17423
+ throw new UnsubscriptionError(errors);
17424
+ }
17425
+ }
17426
+ }
17427
+ add(teardown) {
17428
+ var _a;
17429
+ if (teardown && teardown !== this) {
17430
+ if (this.closed) {
17431
+ execFinalizer(teardown);
17432
+ }
17433
+ else {
17434
+ if (teardown instanceof Subscription) {
17435
+ if (teardown.closed || teardown._hasParent(this)) {
17436
+ return;
17437
+ }
17438
+ teardown._addParent(this);
17439
+ }
17440
+ (this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown);
17441
+ }
17442
+ }
17443
+ }
17444
+ _hasParent(parent) {
17445
+ const { _parentage } = this;
17446
+ return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));
17447
+ }
17448
+ _addParent(parent) {
17449
+ const { _parentage } = this;
17450
+ this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;
17451
+ }
17452
+ _removeParent(parent) {
17453
+ const { _parentage } = this;
17454
+ if (_parentage === parent) {
17455
+ this._parentage = null;
17456
+ }
17457
+ else if (Array.isArray(_parentage)) {
17458
+ arrRemove(_parentage, parent);
17459
+ }
17460
+ }
17461
+ remove(teardown) {
17462
+ const { _finalizers } = this;
17463
+ _finalizers && arrRemove(_finalizers, teardown);
17464
+ if (teardown instanceof Subscription) {
17465
+ teardown._removeParent(this);
17466
+ }
17467
+ }
17468
+ }
17469
+ Subscription.EMPTY = (() => {
17470
+ const empty = new Subscription();
17471
+ empty.closed = true;
17472
+ return empty;
17473
+ })();
17474
+ const EMPTY_SUBSCRIPTION = Subscription.EMPTY;
17475
+ function isSubscription(value) {
17476
+ return (value instanceof Subscription ||
17477
+ (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe)));
17478
+ }
17479
+ function execFinalizer(finalizer) {
17480
+ if (isFunction(finalizer)) {
17481
+ finalizer();
17482
+ }
17483
+ else {
17484
+ finalizer.unsubscribe();
17485
+ }
17486
+ }
17487
+
17488
+ const config = {
17489
+ onUnhandledError: null,
17490
+ onStoppedNotification: null,
17491
+ Promise: undefined,
17492
+ useDeprecatedSynchronousErrorHandling: false,
17493
+ useDeprecatedNextContext: false,
17494
+ };
17495
+
17496
+ const timeoutProvider = {
17497
+ setTimeout(handler, timeout, ...args) {
17498
+ const { delegate } = timeoutProvider;
17499
+ if (delegate === null || delegate === void 0 ? void 0 : delegate.setTimeout) {
17500
+ return delegate.setTimeout(handler, timeout, ...args);
17501
+ }
17502
+ return setTimeout(handler, timeout, ...args);
17503
+ },
17504
+ clearTimeout(handle) {
17505
+ const { delegate } = timeoutProvider;
17506
+ return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearTimeout) || clearTimeout)(handle);
17507
+ },
17508
+ delegate: undefined,
17509
+ };
17510
+
17511
+ function reportUnhandledError(err) {
17512
+ timeoutProvider.setTimeout(() => {
17513
+ const { onUnhandledError } = config;
17514
+ if (onUnhandledError) {
17515
+ onUnhandledError(err);
17516
+ }
17517
+ else {
17518
+ throw err;
17519
+ }
17520
+ });
17521
+ }
17522
+
17523
+ function noop() { }
17524
+
17525
+ const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined))();
17526
+ function errorNotification(error) {
17527
+ return createNotification('E', undefined, error);
17528
+ }
17529
+ function nextNotification(value) {
17530
+ return createNotification('N', value, undefined);
17531
+ }
17532
+ function createNotification(kind, value, error) {
17533
+ return {
17534
+ kind,
17535
+ value,
17536
+ error,
17537
+ };
17538
+ }
17539
+
17540
+ function errorContext(cb) {
17541
+ {
17542
+ cb();
17543
+ }
17544
+ }
17545
+
17546
+ class Subscriber extends Subscription {
17547
+ constructor(destination) {
17548
+ super();
17549
+ this.isStopped = false;
17550
+ if (destination) {
17551
+ this.destination = destination;
17552
+ if (isSubscription(destination)) {
17553
+ destination.add(this);
17554
+ }
17555
+ }
17556
+ else {
17557
+ this.destination = EMPTY_OBSERVER;
17558
+ }
17559
+ }
17560
+ static create(next, error, complete) {
17561
+ return new SafeSubscriber(next, error, complete);
17562
+ }
17563
+ next(value) {
17564
+ if (this.isStopped) {
17565
+ handleStoppedNotification(nextNotification(value), this);
17566
+ }
17567
+ else {
17568
+ this._next(value);
17569
+ }
17570
+ }
17571
+ error(err) {
17572
+ if (this.isStopped) {
17573
+ handleStoppedNotification(errorNotification(err), this);
17574
+ }
17575
+ else {
17576
+ this.isStopped = true;
17577
+ this._error(err);
17578
+ }
17579
+ }
17580
+ complete() {
17581
+ if (this.isStopped) {
17582
+ handleStoppedNotification(COMPLETE_NOTIFICATION, this);
17583
+ }
17584
+ else {
17585
+ this.isStopped = true;
17586
+ this._complete();
17587
+ }
17588
+ }
17589
+ unsubscribe() {
17590
+ if (!this.closed) {
17591
+ this.isStopped = true;
17592
+ super.unsubscribe();
17593
+ this.destination = null;
17594
+ }
17595
+ }
17596
+ _next(value) {
17597
+ this.destination.next(value);
17598
+ }
17599
+ _error(err) {
17600
+ try {
17601
+ this.destination.error(err);
17602
+ }
17603
+ finally {
17604
+ this.unsubscribe();
17605
+ }
17606
+ }
17607
+ _complete() {
17608
+ try {
17609
+ this.destination.complete();
17610
+ }
17611
+ finally {
17612
+ this.unsubscribe();
17613
+ }
17614
+ }
17615
+ }
17616
+ const _bind = Function.prototype.bind;
17617
+ function bind(fn, thisArg) {
17618
+ return _bind.call(fn, thisArg);
17619
+ }
17620
+ class ConsumerObserver {
17621
+ constructor(partialObserver) {
17622
+ this.partialObserver = partialObserver;
17623
+ }
17624
+ next(value) {
17625
+ const { partialObserver } = this;
17626
+ if (partialObserver.next) {
17627
+ try {
17628
+ partialObserver.next(value);
17629
+ }
17630
+ catch (error) {
17631
+ handleUnhandledError(error);
17632
+ }
17633
+ }
17634
+ }
17635
+ error(err) {
17636
+ const { partialObserver } = this;
17637
+ if (partialObserver.error) {
17638
+ try {
17639
+ partialObserver.error(err);
17640
+ }
17641
+ catch (error) {
17642
+ handleUnhandledError(error);
17643
+ }
17644
+ }
17645
+ else {
17646
+ handleUnhandledError(err);
17647
+ }
17648
+ }
17649
+ complete() {
17650
+ const { partialObserver } = this;
17651
+ if (partialObserver.complete) {
17652
+ try {
17653
+ partialObserver.complete();
17654
+ }
17655
+ catch (error) {
17656
+ handleUnhandledError(error);
17657
+ }
17658
+ }
17659
+ }
17660
+ }
17661
+ class SafeSubscriber extends Subscriber {
17662
+ constructor(observerOrNext, error, complete) {
17663
+ super();
17664
+ let partialObserver;
17665
+ if (isFunction(observerOrNext) || !observerOrNext) {
17666
+ partialObserver = {
17667
+ next: observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : undefined,
17668
+ error: error !== null && error !== void 0 ? error : undefined,
17669
+ complete: complete !== null && complete !== void 0 ? complete : undefined,
17670
+ };
17671
+ }
17672
+ else {
17673
+ let context;
17674
+ if (this && config.useDeprecatedNextContext) {
17675
+ context = Object.create(observerOrNext);
17676
+ context.unsubscribe = () => this.unsubscribe();
17677
+ partialObserver = {
17678
+ next: observerOrNext.next && bind(observerOrNext.next, context),
17679
+ error: observerOrNext.error && bind(observerOrNext.error, context),
17680
+ complete: observerOrNext.complete && bind(observerOrNext.complete, context),
17681
+ };
17682
+ }
17683
+ else {
17684
+ partialObserver = observerOrNext;
17685
+ }
17686
+ }
17687
+ this.destination = new ConsumerObserver(partialObserver);
17688
+ }
17689
+ }
17690
+ function handleUnhandledError(error) {
17691
+ {
17692
+ reportUnhandledError(error);
17693
+ }
17694
+ }
17695
+ function defaultErrorHandler(err) {
17696
+ throw err;
17697
+ }
17698
+ function handleStoppedNotification(notification, subscriber) {
17699
+ const { onStoppedNotification } = config;
17700
+ onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));
17701
+ }
17702
+ const EMPTY_OBSERVER = {
17703
+ closed: true,
17704
+ next: noop,
17705
+ error: defaultErrorHandler,
17706
+ complete: noop,
17707
+ };
17708
+
17709
+ const observable = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();
17710
+
17711
+ function identity(x) {
17712
+ return x;
17713
+ }
17714
+
17715
+ function pipeFromArray(fns) {
17716
+ if (fns.length === 0) {
17717
+ return identity;
17718
+ }
17719
+ if (fns.length === 1) {
17720
+ return fns[0];
17721
+ }
17722
+ return function piped(input) {
17723
+ return fns.reduce((prev, fn) => fn(prev), input);
17724
+ };
17725
+ }
17726
+
17727
+ class Observable {
17728
+ constructor(subscribe) {
17729
+ if (subscribe) {
17730
+ this._subscribe = subscribe;
17731
+ }
17732
+ }
17733
+ lift(operator) {
17734
+ const observable = new Observable();
17735
+ observable.source = this;
17736
+ observable.operator = operator;
17737
+ return observable;
17738
+ }
17739
+ subscribe(observerOrNext, error, complete) {
17740
+ const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);
17741
+ errorContext(() => {
17742
+ const { operator, source } = this;
17743
+ subscriber.add(operator
17744
+ ?
17745
+ operator.call(subscriber, source)
17746
+ : source
17747
+ ?
17748
+ this._subscribe(subscriber)
17749
+ :
17750
+ this._trySubscribe(subscriber));
17751
+ });
17752
+ return subscriber;
17753
+ }
17754
+ _trySubscribe(sink) {
17755
+ try {
17756
+ return this._subscribe(sink);
17757
+ }
17758
+ catch (err) {
17759
+ sink.error(err);
17760
+ }
17761
+ }
17762
+ forEach(next, promiseCtor) {
17763
+ promiseCtor = getPromiseCtor(promiseCtor);
17764
+ return new promiseCtor((resolve, reject) => {
17765
+ const subscriber = new SafeSubscriber({
17766
+ next: (value) => {
17767
+ try {
17768
+ next(value);
17769
+ }
17770
+ catch (err) {
17771
+ reject(err);
17772
+ subscriber.unsubscribe();
17773
+ }
17774
+ },
17775
+ error: reject,
17776
+ complete: resolve,
17777
+ });
17778
+ this.subscribe(subscriber);
17779
+ });
17780
+ }
17781
+ _subscribe(subscriber) {
17782
+ var _a;
17783
+ return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber);
17784
+ }
17785
+ [observable]() {
17786
+ return this;
17787
+ }
17788
+ pipe(...operations) {
17789
+ return pipeFromArray(operations)(this);
17790
+ }
17791
+ toPromise(promiseCtor) {
17792
+ promiseCtor = getPromiseCtor(promiseCtor);
17793
+ return new promiseCtor((resolve, reject) => {
17794
+ let value;
17795
+ this.subscribe((x) => (value = x), (err) => reject(err), () => resolve(value));
17796
+ });
17797
+ }
17798
+ }
17799
+ Observable.create = (subscribe) => {
17800
+ return new Observable(subscribe);
17801
+ };
17802
+ function getPromiseCtor(promiseCtor) {
17803
+ var _a;
17804
+ return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : config.Promise) !== null && _a !== void 0 ? _a : Promise;
17805
+ }
17806
+ function isObserver(value) {
17807
+ return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);
17808
+ }
17809
+ function isSubscriber(value) {
17810
+ return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));
17811
+ }
17812
+
17813
+ const ObjectUnsubscribedError = createErrorClass((_super) => function ObjectUnsubscribedErrorImpl() {
17814
+ _super(this);
17815
+ this.name = 'ObjectUnsubscribedError';
17816
+ this.message = 'object unsubscribed';
17817
+ });
17818
+
17819
+ class Subject extends Observable {
17820
+ constructor() {
17821
+ super();
17822
+ this.closed = false;
17823
+ this.currentObservers = null;
17824
+ this.observers = [];
17825
+ this.isStopped = false;
17826
+ this.hasError = false;
17827
+ this.thrownError = null;
17828
+ }
17829
+ lift(operator) {
17830
+ const subject = new AnonymousSubject(this, this);
17831
+ subject.operator = operator;
17832
+ return subject;
17833
+ }
17834
+ _throwIfClosed() {
17835
+ if (this.closed) {
17836
+ throw new ObjectUnsubscribedError();
17837
+ }
17838
+ }
17839
+ next(value) {
17840
+ errorContext(() => {
17841
+ this._throwIfClosed();
17842
+ if (!this.isStopped) {
17843
+ if (!this.currentObservers) {
17844
+ this.currentObservers = Array.from(this.observers);
17845
+ }
17846
+ for (const observer of this.currentObservers) {
17847
+ observer.next(value);
17848
+ }
17849
+ }
17850
+ });
17851
+ }
17852
+ error(err) {
17853
+ errorContext(() => {
17854
+ this._throwIfClosed();
17855
+ if (!this.isStopped) {
17856
+ this.hasError = this.isStopped = true;
17857
+ this.thrownError = err;
17858
+ const { observers } = this;
17859
+ while (observers.length) {
17860
+ observers.shift().error(err);
17861
+ }
17862
+ }
17863
+ });
17864
+ }
17865
+ complete() {
17866
+ errorContext(() => {
17867
+ this._throwIfClosed();
17868
+ if (!this.isStopped) {
17869
+ this.isStopped = true;
17870
+ const { observers } = this;
17871
+ while (observers.length) {
17872
+ observers.shift().complete();
17873
+ }
17874
+ }
17875
+ });
17876
+ }
17877
+ unsubscribe() {
17878
+ this.isStopped = this.closed = true;
17879
+ this.observers = this.currentObservers = null;
17880
+ }
17881
+ get observed() {
17882
+ var _a;
17883
+ return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0;
17884
+ }
17885
+ _trySubscribe(subscriber) {
17886
+ this._throwIfClosed();
17887
+ return super._trySubscribe(subscriber);
17888
+ }
17889
+ _subscribe(subscriber) {
17890
+ this._throwIfClosed();
17891
+ this._checkFinalizedStatuses(subscriber);
17892
+ return this._innerSubscribe(subscriber);
17893
+ }
17894
+ _innerSubscribe(subscriber) {
17895
+ const { hasError, isStopped, observers } = this;
17896
+ if (hasError || isStopped) {
17897
+ return EMPTY_SUBSCRIPTION;
17898
+ }
17899
+ this.currentObservers = null;
17900
+ observers.push(subscriber);
17901
+ return new Subscription(() => {
17902
+ this.currentObservers = null;
17903
+ arrRemove(observers, subscriber);
17904
+ });
17905
+ }
17906
+ _checkFinalizedStatuses(subscriber) {
17907
+ const { hasError, thrownError, isStopped } = this;
17908
+ if (hasError) {
17909
+ subscriber.error(thrownError);
17910
+ }
17911
+ else if (isStopped) {
17912
+ subscriber.complete();
17913
+ }
17914
+ }
17915
+ asObservable() {
17916
+ const observable = new Observable();
17917
+ observable.source = this;
17918
+ return observable;
17919
+ }
17920
+ }
17921
+ Subject.create = (destination, source) => {
17922
+ return new AnonymousSubject(destination, source);
17923
+ };
17924
+ class AnonymousSubject extends Subject {
17925
+ constructor(destination, source) {
17926
+ super();
17927
+ this.destination = destination;
17928
+ this.source = source;
17929
+ }
17930
+ next(value) {
17931
+ var _a, _b;
17932
+ (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);
17933
+ }
17934
+ error(err) {
17935
+ var _a, _b;
17936
+ (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);
17937
+ }
17938
+ complete() {
17939
+ var _a, _b;
17940
+ (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);
17941
+ }
17942
+ _subscribe(subscriber) {
17943
+ var _a, _b;
17944
+ return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : EMPTY_SUBSCRIPTION;
17945
+ }
17946
+ }
17947
+
17948
+ // Unique ID creation requires a high quality random # generator. In the browser we therefore
17949
+ // require the crypto API and do not support built-in fallback to lower quality random number
17950
+ // generators (like Math.random()).
17951
+ var getRandomValues;
17952
+ var rnds8 = new Uint8Array(16);
17953
+ function rng() {
17954
+ // lazy load so that environments that need to polyfill have a chance to do so
17955
+ if (!getRandomValues) {
17956
+ // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
17957
+ // find the complete implementation of crypto (msCrypto) on IE11.
17958
+ getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
17959
+
17960
+ if (!getRandomValues) {
17961
+ throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
17962
+ }
17963
+ }
17964
+
17965
+ return getRandomValues(rnds8);
17966
+ }
17967
+
17968
+ const REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
17969
+
17970
+ function validate(uuid) {
17971
+ return typeof uuid === 'string' && REGEX.test(uuid);
17972
+ }
17973
+
17974
+ /**
17975
+ * Convert array of 16 byte values to UUID string format of the form:
17976
+ * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
17977
+ */
17978
+
17979
+ var byteToHex = [];
17980
+
17981
+ for (var i = 0; i < 256; ++i) {
17982
+ byteToHex.push((i + 0x100).toString(16).substr(1));
17983
+ }
17984
+
17985
+ function stringify$1(arr) {
17986
+ var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
17987
+ // Note: Be careful editing this code! It's been tuned for performance
17988
+ // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
17989
+ var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
17990
+ // of the following:
17991
+ // - One or more input array values don't map to a hex octet (leading to
17992
+ // "undefined" in the uuid)
17993
+ // - Invalid input values for the RFC `version` or `variant` fields
17994
+
17995
+ if (!validate(uuid)) {
17996
+ throw TypeError('Stringified UUID is invalid');
17997
+ }
17998
+
17999
+ return uuid;
18000
+ }
18001
+
18002
+ function v4(options, buf, offset) {
18003
+ options = options || {};
18004
+ var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
18005
+
18006
+ rnds[6] = rnds[6] & 0x0f | 0x40;
18007
+ rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
18008
+
18009
+ if (buf) {
18010
+ offset = offset || 0;
18011
+
18012
+ for (var i = 0; i < 16; ++i) {
18013
+ buf[offset + i] = rnds[i];
18014
+ }
18015
+
18016
+ return buf;
18017
+ }
18018
+
18019
+ return stringify$1(rnds);
18020
+ }
18021
+
18022
+ /**
18023
+ * Check if we're required to add a port number.
18024
+ *
18025
+ * @see https://url.spec.whatwg.org/#default-port
18026
+ * @param {Number|String} port Port number we need to check
18027
+ * @param {String} protocol Protocol we need to check against.
18028
+ * @returns {Boolean} Is it a default port for the given protocol
18029
+ * @api private
18030
+ */
18031
+ var requiresPort = function required(port, protocol) {
18032
+ protocol = protocol.split(':')[0];
18033
+ port = +port;
18034
+
18035
+ if (!port) return false;
18036
+
18037
+ switch (protocol) {
18038
+ case 'http':
18039
+ case 'ws':
18040
+ return port !== 80;
18041
+
18042
+ case 'https':
18043
+ case 'wss':
18044
+ return port !== 443;
18045
+
18046
+ case 'ftp':
18047
+ return port !== 21;
18048
+
18049
+ case 'gopher':
18050
+ return port !== 70;
18051
+
18052
+ case 'file':
18053
+ return false;
18054
+ }
18055
+
18056
+ return port !== 0;
18057
+ };
18058
+
18059
+ var has = Object.prototype.hasOwnProperty
18060
+ , undef;
18061
+
18062
+ /**
18063
+ * Decode a URI encoded string.
16239
18064
  *
16240
18065
  * @param {String} input The URI encoded string.
16241
18066
  * @returns {String|Null} The decoded string.
@@ -19341,52 +21166,385 @@ const createWidgetVpsEvent = createTrackingEvent(vpsWidget);
19341
21166
  const createSearchEvent = createTrackingEvent(searchEvent);
19342
21167
  const createFilterEvent = createTrackingEvent(filterEvent);
19343
21168
 
19344
- exports.Apply = Apply;
19345
- exports.Either = Either;
19346
- exports.NonEmptyArray = NonEmptyArray;
19347
- exports.Option = Option;
19348
- exports.Semigroup = Semigroup$1;
19349
- exports.TaskEither = TaskEither;
19350
- exports._Array = _Array;
19351
- exports._function = _function;
19352
- exports.center = center;
19353
- exports.chainW = chainW;
19354
- exports.checkEmpryString = checkEmpryString;
19355
- exports.createFilterEvent = createFilterEvent;
19356
- exports.createInitGetRequest = createInitGetRequest;
19357
- exports.createProductClickVprEvent = createProductClickVprEvent;
19358
- exports.createProductClickVpsEvent = createProductClickVpsEvent;
19359
- exports.createProductViewVprEvent = createProductViewVprEvent;
19360
- exports.createProductViewVpsEvent = createProductViewVpsEvent;
19361
- exports.createSearchEvent = createSearchEvent;
19362
- exports.createTrackingApi = createTrackingApi;
19363
- exports.createWidgetVprEvent = createWidgetVprEvent;
19364
- exports.createWidgetVpsEvent = createWidgetVpsEvent;
19365
- exports.detectedObjectEq = detectedObjectEq;
19366
- exports.dimensionsFromImage = dimensionsFromImage;
19367
- exports.foldValueObject = foldValueObject;
19368
- exports.fromAlt = fromAlt;
19369
- exports.fromEither = fromEither;
19370
- exports.fromImage = fromImage;
19371
- exports.fromMouseEvent = fromMouseEvent;
19372
- exports.getApiPath = getApiPath;
19373
- exports.getCursorValue = getCursorValue;
19374
- exports.imageSearchState = imageSearchState;
19375
- exports.isEmpty = isEmpty$1;
19376
- exports.makeRectangularSearchRequest = makeRectangularSearchRequest;
19377
- exports.makeRequest = makeRequest;
19378
- exports.map = map$3;
19379
- exports.match = match$1;
19380
- exports.match$1 = match;
19381
- exports.move = move;
19382
- exports.pipe = pipe;
19383
- exports.pointDiffSemigroup = pointDiffSemigroup;
19384
- exports.processSelectedFile = processSelectedFile;
19385
- exports.scaleByLargestSide = scaleByLargestSide;
19386
- exports.scaleWithSized = scaleWithSized;
19387
- exports.sequenceT = sequenceT;
19388
- exports.sequenceToOption = sequenceToOption;
19389
- exports.state = state$1;
19390
- exports.toFile = toFile;
19391
- exports.transform = transform;
19392
- exports.v4 = v4;
21169
+ const vviinnVprWidgetCss = ":host{display:grid;grid-gap:1rem;width:100%}:host(:not(.loaded)){position:absolute;visibility:hidden}:host(.grid) vviinn-product-card::part(image){border:1px solid #DDDDDD;width:100%}h2{margin:0}vviinn-product-card::part(price-container){align-self:flex-start;text-align:left;display:flex}.results{display:grid;grid-gap:1rem}.visually-hidden{position:absolute;top:0;left:0;z-index:-1;height:0;width:0}h2{margin:0}:host(.grid) h2{justify-content:center}:host(.grid) vviinn-product-card::part(image){min-width:100%}:host(.grid) vviinn-product-card::part(image-link){width:100%}:host(.grid) vviinn-product-card::part(title),:host(.grid) vviinn-product-card::part(brand),:host(.grid) vviinn-product-card::part(type){text-align:center}:host(.grid) vviinn-product-card::part(price-container){align-self:center}:host(.continuity) vviinn-product-card::part(title),:host(.continuity) vviinn-product-card::part(brand),:host(.continuity) vviinn-product-card::part(type),:host(.continuity) vviinn-product-card::part(deeplink){text-align:left;max-width:unset;align-self:start}";
21170
+
21171
+ let VviinnVprWidget = class {
21172
+ constructor(hostRef) {
21173
+ index.registerInstance(this, hostRef);
21174
+ this.recommendationsLoaded = index.createEvent(this, "recommendationsLoaded", 7);
21175
+ /** Title for recommendations widget */
21176
+ this.blockTitle = "Recommended products";
21177
+ /** Ratio of each recommended product image */
21178
+ this.imageRatio = 1;
21179
+ /** Width of each recommended product image */
21180
+ this.imageWidth = 300;
21181
+ /** Currency sign will shown after price */
21182
+ this.currencySign = "€";
21183
+ /** Use slider or grid view */
21184
+ this.mode = "continuity";
21185
+ /** Campaign type */
21186
+ this.campaignType = "VPR";
21187
+ /** Locale for currency formatting */
21188
+ this.locale = "de-DE";
21189
+ /** comma-separated list of campaign-ids */
21190
+ this.campaigns = "";
21191
+ /** @internal */
21192
+ this.apiPath = "https://api.vviinn.com";
21193
+ /** @internal */
21194
+ this.useCarousel = true;
21195
+ this.showScroll = true;
21196
+ this.cssUrl = null;
21197
+ this.recommendations = [];
21198
+ this.loaded = false;
21199
+ this.productImageLoadedSubject = new Subject();
21200
+ }
21201
+ handleProductIdChange() {
21202
+ this.getRecommendations();
21203
+ }
21204
+ handleCampaignTypeChange() {
21205
+ this.getRecommendations();
21206
+ }
21207
+ handleCampaignsChange() {
21208
+ this.getRecommendations();
21209
+ }
21210
+ handleApiPathChange(newPath) {
21211
+ state$1.apiPath = newPath;
21212
+ this.getRecommendations();
21213
+ }
21214
+ handleImageLoading({ detail }) {
21215
+ this.productImageLoadedSubject.next(detail);
21216
+ }
21217
+ trackRecommendationView({ detail }) {
21218
+ const recommendationViewEvent = createProductViewVprEvent(Object.assign({ session_id: this.uiSessionId }, detail));
21219
+ this.trackingApi.trackEvent(recommendationViewEvent);
21220
+ }
21221
+ trackRecommendationClick({ detail }) {
21222
+ const recommendationClickEvent = createProductClickVprEvent(Object.assign({ session_id: this.uiSessionId }, detail));
21223
+ this.trackingApi.trackEvent(recommendationClickEvent).finally(() => {
21224
+ const product = this.recommendations.find((r) => r.productId === detail.product);
21225
+ if (!product || !product.deeplink)
21226
+ return;
21227
+ window.location.href = product.deeplink;
21228
+ });
21229
+ }
21230
+ connectedCallback() {
21231
+ state$1.apiPath = this.apiPath;
21232
+ state$1.currencySign = this.currencySign;
21233
+ state$1.locale = this.locale;
21234
+ this.uiSessionId = v4();
21235
+ this.trackingApi = createTrackingApi(this.apiPath, this.token);
21236
+ const widgetOpenEvent = createWidgetVprEvent({
21237
+ action: "open",
21238
+ session_id: this.uiSessionId,
21239
+ });
21240
+ this.trackingApi.trackEvent(widgetOpenEvent);
21241
+ }
21242
+ disconnectedCallback() {
21243
+ const widgetCloseEvent = createWidgetVprEvent({
21244
+ action: "close",
21245
+ session_id: this.uiSessionId,
21246
+ });
21247
+ this.trackingApi.trackEvent(widgetCloseEvent);
21248
+ }
21249
+ async componentWillLoad() {
21250
+ state$1.pricePrefix = this.pricePrefix;
21251
+ state$1.currencySign = this.currencySign;
21252
+ this.getRecommendations();
21253
+ }
21254
+ async getRecommendations() {
21255
+ if (this.productId === undefined || this.token === undefined)
21256
+ return;
21257
+ const campaignType = this.campaignType.length > 0 ? this.campaignType : "VPR";
21258
+ const headers = createBearAuthedHeader(this.token);
21259
+ const request = _function.pipe(TaskEither.of(getRecommendationsService(campaignType)), TaskEither.ap(TaskEither.of(this.productId)), TaskEither.ap(TaskEither.of(checkEmpryString(this.campaigns))), TaskEither.ap(TaskEither.of(headers)), TaskEither.flatten);
21260
+ const runRequest = await request();
21261
+ _function.pipe(runRequest, Either.fold((error) => this.handleError(error), (data) => this.handleRecommendationsSucces(data)));
21262
+ }
21263
+ handleError(error) {
21264
+ console.log("ERROR:", error);
21265
+ }
21266
+ handleRecommendationsSucces(data) {
21267
+ var _a;
21268
+ this.recommendations = (_a = data === null || data === void 0 ? void 0 : data.extended) !== null && _a !== void 0 ? _a : data;
21269
+ imageSearchState.results = this.recommendations;
21270
+ this.loaded = true;
21271
+ this.productIds = this.recommendations.map((r) => r.productId);
21272
+ this.productImageLoadedSubject.subscribe((id) => {
21273
+ this.productIds = this.productIds.filter((x) => x !== id);
21274
+ if (this.productIds.length === 0) {
21275
+ this.recommendationsLoaded.emit();
21276
+ }
21277
+ });
21278
+ }
21279
+ isExternalCSS() {
21280
+ return this.cssUrl && this.cssUrl.length > 0;
21281
+ }
21282
+ renderExternalCSS() {
21283
+ return this.isExternalCSS() ? (index.h("link", { href: this.cssUrl, rel: "stylesheet" })) : ("");
21284
+ }
21285
+ render() {
21286
+ return (index.h(index.Host, { class: {
21287
+ loaded: this.loaded,
21288
+ empty: this.recommendations.length == 0,
21289
+ [this.mode]: true,
21290
+ }, "aria-hidden": this.loaded ? "false" : "true" }, this.renderExternalCSS(), index.h("style", null, state$1.fallbackStyles), index.h("h2", { part: "recommendations-title" }, this.blockTitle), this.useCarousel ? this.renderCarousel() : this.renderResults()));
21291
+ }
21292
+ renderRecommendation(recommendation, index$1) {
21293
+ return (index.h("vviinn-product-card", { part: "product-part", productId: recommendation.productId, productTitle: recommendation.title, deeplink: recommendation.deeplink, image: recommendation.image.thumbnail, brand: recommendation.brand, imageWidth: this.imageWidth, imageRatio: 1, price: recommendation.price.actual, salePrice: recommendation.price.sale, responsive: this.mode === "grid", dimmedBackground: this.useDimmedBackgroundInCard(), index: index$1 }));
21294
+ }
21295
+ useDimmedBackgroundInCard() {
21296
+ return this.mode === "continuity" || !this.useCarousel;
21297
+ }
21298
+ renderResults() {
21299
+ return (index.h("div", { class: "recommendations-grid", part: "recommendations-grid" }, this.recommendations.map((r, i) => this.renderRecommendation(r, i))));
21300
+ }
21301
+ renderCarousel() {
21302
+ return (index.h("vviinn-carousel", { mode: this.mode, imageWidth: this.imageWidth, showScroll: this.showScroll, recommendations: this.recommendations }));
21303
+ }
21304
+ get el() { return index.getElement(this); }
21305
+ static get watchers() { return {
21306
+ "productId": ["handleProductIdChange"],
21307
+ "campaignType": ["handleCampaignTypeChange"],
21308
+ "campaigns": ["handleCampaignsChange"],
21309
+ "apiPath": ["handleApiPathChange"]
21310
+ }; }
21311
+ };
21312
+ VviinnVprWidget.style = vviinnVprWidgetCss;
21313
+
21314
+ const vviinnVpsButtonCss = ":host{cursor:pointer}";
21315
+
21316
+ let VviinnVpsButton = class {
21317
+ constructor(hostRef) {
21318
+ index.registerInstance(this, hostRef);
21319
+ this.globalSlotsChanged = index.createEvent(this, "globalSlotsChanged", 7);
21320
+ /** Currency sign will shown after price */
21321
+ this.currencySign = "€";
21322
+ /** Locale for currency formatting */
21323
+ this.locale = "de-DE";
21324
+ this.pressed = false;
21325
+ }
21326
+ handleModalClosed() {
21327
+ this.pressed = false;
21328
+ }
21329
+ componentDidLoad() {
21330
+ const slots = this.el.querySelectorAll("[slot]");
21331
+ this.globalSlotsChanged.emit(Array.from(slots));
21332
+ }
21333
+ handleKeyDown(ev) {
21334
+ if (ev.code !== "Enter" && ev.code !== "Space")
21335
+ return;
21336
+ this.pressed = true;
21337
+ }
21338
+ handleClick() {
21339
+ this.pressed = true;
21340
+ }
21341
+ render() {
21342
+ return (index.h(index.Host, { tabindex: "0", role: "button", pressed: this.pressed, onClick: () => this.handleClick(), onKeyDown: (ev) => this.handleKeyDown(ev) }, index.h("slot", null, index.h(index$1.CameraIcon, null)), index.h(SlotSkeleton, null), index.h("vviinn-vps-widget", { active: this.pressed, "currency-sign": "\u20AC", token: this.token, locale: this.locale, apiPath: this.apiPath, exportparts: "brand, currency, deeplink, image, image-link, price-amount, price-container, price-outdated, price-prefix, price-regular, price-sale, title, product-card, example-images", campaignId: this.campaignId })));
21343
+ }
21344
+ get el() { return index.getElement(this); }
21345
+ };
21346
+ VviinnVpsButton.style = vviinnVpsButtonCss;
21347
+
21348
+ 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:-webkit-max-content auto;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:-webkit-min-content 170px;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:-webkit-min-content;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:-webkit-min-content auto;grid-template-rows:min-content auto}.image{margin-bottom:8px}.image-wrapper{grid-template-rows:-webkit-min-content auto;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}";
21349
+
21350
+ const filterInt = (value) => /^[-+]?(\d+|Infinity)$/.test(value) ? Number(value) : NaN;
21351
+ const notEmptyString = (s) => !isEmpty$1(s);
21352
+ const notNan = (n) => !isNaN(n);
21353
+ let VviinnVpsWidget = class {
21354
+ constructor(hostRef) {
21355
+ index.registerInstance(this, hostRef);
21356
+ /** @internal */
21357
+ this.apiPath = "https://api.vviinn.com";
21358
+ /** When true modal window with widget will be shown */
21359
+ this.active = false;
21360
+ /** Currency sign will shown after price */
21361
+ this.currencySign = "€";
21362
+ /** Locale for currency formatting */
21363
+ this.locale = "de-DE";
21364
+ this.slidePosition = 0;
21365
+ this.width = 0;
21366
+ this.wrongImageFormat = false;
21367
+ this.imageSource = null;
21368
+ }
21369
+ activeWatcher(value) {
21370
+ if (value) {
21371
+ this.overflow = document.body.style.overflow;
21372
+ document.body.style.overflow = "hidden";
21373
+ this.trackOpenEvent();
21374
+ }
21375
+ else {
21376
+ document.body.style.overflow = this.overflow;
21377
+ }
21378
+ }
21379
+ trackRecommendationView({ detail }) {
21380
+ const recommendationViewEvent = createProductViewVpsEvent(Object.assign({ session_id: this.uiSessionId }, detail));
21381
+ this.trackingApi.trackEvent(recommendationViewEvent);
21382
+ }
21383
+ trackRecommendationClick({ detail }) {
21384
+ const recommendationClickEvent = createProductClickVpsEvent(Object.assign({ session_id: this.uiSessionId }, detail));
21385
+ this.trackingApi.trackEvent(recommendationClickEvent).finally(() => {
21386
+ const product = imageSearchState.results.find((r) => r.productId === detail.product);
21387
+ if (!product || !product.deeplink)
21388
+ return;
21389
+ window.location.href = product.deeplink;
21390
+ });
21391
+ }
21392
+ trachSearchAreaChanges() {
21393
+ const searchEvent = createSearchEvent({
21394
+ session_id: this.uiSessionId,
21395
+ source: this.imageSource,
21396
+ search_area: "manual-selection",
21397
+ });
21398
+ this.trackingApi.trackEvent(searchEvent);
21399
+ }
21400
+ trackDetectedObject() {
21401
+ const searchEvent = createSearchEvent({
21402
+ session_id: this.uiSessionId,
21403
+ source: this.imageSource,
21404
+ search_area: "attention-point",
21405
+ });
21406
+ this.trackingApi.trackEvent(searchEvent);
21407
+ }
21408
+ trackFilter({ detail }) {
21409
+ const searchEvent = createFilterEvent({
21410
+ session_id: this.uiSessionId,
21411
+ source: this.imageSource,
21412
+ kind: "category",
21413
+ action: detail,
21414
+ });
21415
+ this.trackingApi.trackEvent(searchEvent);
21416
+ }
21417
+ componentWillLoad() {
21418
+ slotChangeListener(this, this.el);
21419
+ }
21420
+ connectedCallback() {
21421
+ state$1.apiPath = this.apiPath;
21422
+ state$1.currencySign = this.currencySign;
21423
+ state$1.locale = this.locale;
21424
+ imageSearchState.token = this.token;
21425
+ 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}`));
21426
+ this.uiSessionId = v4();
21427
+ this.trackingApi = createTrackingApi(this.apiPath, this.token);
21428
+ }
21429
+ trackOpenEvent() {
21430
+ const widgetOpenEvent = createWidgetVpsEvent({
21431
+ action: "open",
21432
+ session_id: this.uiSessionId,
21433
+ });
21434
+ this.trackingApi.trackEvent(widgetOpenEvent);
21435
+ }
21436
+ handleImageSelection(source) {
21437
+ this.imageSource = source;
21438
+ this.slidePosition = 1;
21439
+ const root = this.el.shadowRoot.querySelector("vviinn-overlayed-modal");
21440
+ const overlay = root.shadowRoot.querySelector("vviinn-overlay");
21441
+ const modal = overlay.querySelector("vviinn-modal");
21442
+ const modalBody = modal.shadowRoot.querySelector(".body");
21443
+ modalBody.scrollTop = 0;
21444
+ this.trackInitialSearch();
21445
+ }
21446
+ trackInitialSearch() {
21447
+ const searchEvent = createSearchEvent({
21448
+ session_id: this.uiSessionId,
21449
+ source: this.imageSource,
21450
+ search_area: "full",
21451
+ });
21452
+ this.trackingApi.trackEvent(searchEvent);
21453
+ }
21454
+ resetState() {
21455
+ this.resetScroll("onboarding-block");
21456
+ this.slidePosition = 0;
21457
+ imageSearchState.image = Option.none;
21458
+ imageSearchState.imageUrl = Option.none;
21459
+ imageSearchState.imageBounds = Option.none;
21460
+ imageSearchState.searchArea = Option.none;
21461
+ imageSearchState.results = [];
21462
+ imageSearchState.filters = [];
21463
+ imageSearchState.detectedObjects = [];
21464
+ imageSearchState.activeIonLink = undefined;
21465
+ imageSearchState.rectangleSearchForm = undefined;
21466
+ this.resetScroll("results-block");
21467
+ }
21468
+ haveErrors() {
21469
+ return this.wrongImageFormat || imageSearchState.serverError;
21470
+ }
21471
+ resetScroll(elementId, behavior = "auto") {
21472
+ const element = this.el.shadowRoot.getElementById(elementId);
21473
+ element.scroll({ top: 0, left: 0, behavior });
21474
+ }
21475
+ handleModalClose() {
21476
+ this.active = false;
21477
+ this.resetState();
21478
+ const elementsToReset = ["onboarding-block", "results-block"];
21479
+ elementsToReset.forEach((name) => this.resetScroll(name));
21480
+ const widgetOpenEvent = createWidgetVpsEvent({
21481
+ action: "close",
21482
+ session_id: this.uiSessionId,
21483
+ });
21484
+ this.trackingApi.trackEvent(widgetOpenEvent);
21485
+ }
21486
+ render() {
21487
+ return (index.h(index.Host, null, index.h("vviinn-overlayed-modal", { class: { "first-screen": this.slidePosition === 0 }, active: this.active, onSecondaryActionClicked: () => this.resetState(), onModalClosed: () => this.handleModalClose(), exportparts: "secondary-action, title, close-button, example-images" }, index.h("vviinn-slider", { showBullets: false, position: this.slidePosition }, index.h("vviinn-slide", { class: { "start-page": true } }, index.h("div", { class: {
21488
+ error: this.haveErrors(),
21489
+ "start-page_block": true,
21490
+ } }, index.h("vviinn-wrong-format", { class: { hidden: !this.wrongImageFormat }, onActionClick: () => (this.wrongImageFormat = false) }), index.h("vviinn-server-error", { class: { hidden: !imageSearchState.serverError }, onActionClick: () => (imageSearchState.serverError = false) }), index.h("vviinn-teaser", { class: { hidden: this.haveErrors() } }), index.h("vviinn-image-selector", { class: { hidden: this.haveErrors() }, onImageSelected: () => this.handleImageSelection("upload"), onImageSelectedError: () => (this.wrongImageFormat = true), part: "select-image_button" }, index.h("span", { slot: "upload-button-text", class: "upload-button-content" }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "29", height: "28", fill: "none" }, index.h("defs", null), index.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" }), index.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" })), index.h("slot", { name: "vviinn-image-upload-button-text" }, index.h("span", null, "Kamera oder Bild ausw\u00E4hlen")))), index.h("vviinn-privacy-badge", { class: { hidden: this.haveErrors() } })), index.h("div", { id: "onboarding-block", class: "start-page_block" }, index.h("div", { class: "onboarding-wrapper" }, index.h("vviinn-onboarding", null), index.h("vviinn-example-images", { part: "example-images", onImageSelected: () => this.handleImageSelection("example"), onImageSelectedError: () => this.resetScroll("onboarding-block", "smooth") })))), index.h("vviinn-slide", { class: { "results-page": true, active: this.slidePosition == 1 } }, index.h("div", { class: "image-wrapper" }, index.h("vviinn-image-view", null), index.h("div", { class: "filters-wrapper" }, index.h("div", { class: "filters" }, imageSearchState.filters.map((filter) => (index.h("search-filters", { filter: filter })))))), index.h("div", { id: "results-block", class: "products-wrapper" }, index.h("div", { class: {
21491
+ "nothing-found": true,
21492
+ hidden: imageSearchState.results.length > 0,
21493
+ } }, index.h("vviinn-empty-results", null), index.h("vviinn-onboarding", null)), index.h("div", { class: {
21494
+ hidden: imageSearchState.results.length <= 0,
21495
+ products: true,
21496
+ } }, imageSearchState.results.map((p, i) => {
21497
+ var _a;
21498
+ return (index.h("vviinn-product-card", { 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", index: i }));
21499
+ }))))))));
21500
+ }
21501
+ get el() { return index.getElement(this); }
21502
+ static get watchers() { return {
21503
+ "active": ["activeWatcher"]
21504
+ }; }
21505
+ };
21506
+ VviinnVpsWidget.style = vviinnVpsWidgetCss;
21507
+
21508
+ const vviinnWrongFormatCss = ":host{display:block}";
21509
+
21510
+ let VviinnWrongFormat = class {
21511
+ constructor(hostRef) {
21512
+ index.registerInstance(this, hostRef);
21513
+ this.actionClick = index.createEvent(this, "actionClick", 7);
21514
+ }
21515
+ render() {
21516
+ return (index.h(index.Host, null, index.h("vviinn-error", null, index.h("h4", { slot: "title" }, "Dateityp wird nicht unterst\u00FCtzt"), index.h("span", { slot: "text" }, "Leider unterst\u00FCtzen wir dieses Format nicht. Bitte laden Sie eine .jpg, .png oder .webp Bilddatei hoch."), index.h("button", { slot: "action", onClick: () => this.actionClick.emit() }, "Neues Bild hochladen"))));
21517
+ }
21518
+ };
21519
+ VviinnWrongFormat.style = vviinnWrongFormatCss;
21520
+
21521
+ exports.cropper_handler = CropperHandler;
21522
+ exports.highlight_box = HighlightBox;
21523
+ exports.image_cropper = ImageCropper;
21524
+ exports.search_filters = SearchFilters;
21525
+ exports.vviinn_carousel = VviinnCarousel;
21526
+ exports.vviinn_detected_object = VviinnDetectedObject;
21527
+ exports.vviinn_empty_results = VviinnEmptyResults;
21528
+ exports.vviinn_error = VviinnError;
21529
+ exports.vviinn_example_image = VviinnExampleImage;
21530
+ exports.vviinn_example_images = VviinnExampleImages;
21531
+ exports.vviinn_image_selector = VviinnImageSelector;
21532
+ exports.vviinn_image_view = VviinnImageView;
21533
+ exports.vviinn_modal = VviinnModal;
21534
+ exports.vviinn_onboarding = VviinnOnboarding;
21535
+ exports.vviinn_onboarding_card_1 = VviinnOnboardingCard1;
21536
+ exports.vviinn_onboarding_card_2 = VviinnOnboardingCard2;
21537
+ exports.vviinn_onboarding_card_3 = VviinnOnboardingCard3;
21538
+ exports.vviinn_overlay = VviinnOverlay;
21539
+ exports.vviinn_overlayed_modal = VviinnOverlayedModal;
21540
+ exports.vviinn_preloader = VviinnPreloader;
21541
+ exports.vviinn_privacy_badge = VviinnPrivacyBadge;
21542
+ exports.vviinn_product_card = VviinnProductCard;
21543
+ exports.vviinn_server_error = VviinnServerError;
21544
+ exports.vviinn_slide = VviinnSlide;
21545
+ exports.vviinn_slider = VviinnSlider;
21546
+ exports.vviinn_teaser = VviinnTeaser;
21547
+ exports.vviinn_vpr_widget = VviinnVprWidget;
21548
+ exports.vviinn_vps_button = VviinnVpsButton;
21549
+ exports.vviinn_vps_widget = VviinnVpsWidget;
21550
+ exports.vviinn_wrong_format = VviinnWrongFormat;