@inappstory/slide-api 0.1.27 → 0.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -379,6 +379,12 @@ const data = function (elem, name, data) {
379
379
  const getTagData = function (element, key) {
380
380
  return element.dataset[key];
381
381
  };
382
+ const getTagDataAsJson = function (element, key) {
383
+ const data = getTagData(element, key);
384
+ if (!data)
385
+ return data;
386
+ return parseJsonSafe(data);
387
+ };
382
388
  const getTagDataAsNumber = function (element, key) {
383
389
  const data = element.dataset[key];
384
390
  if (data == null) {
@@ -651,6 +657,14 @@ function isScreenSupportsTouch(env) {
651
657
  }
652
658
  return supportsTouch;
653
659
  }
660
+ function parseJsonSafe(json) {
661
+ try {
662
+ return JSON.parse(json);
663
+ }
664
+ catch (e) {
665
+ return json ?? null;
666
+ }
667
+ }
654
668
 
655
669
  var supportAnimate = document.documentElement.animate !== undefined;
656
670
  supportAnimate = false; // tmp off
@@ -819,6 +833,7 @@ var getAnimationFunction = function (element) {
819
833
  return function () { };
820
834
  };
821
835
  const animationApi = {
836
+ animations: [],
822
837
  init: function (slide, animate = false) {
823
838
  if (supportAnimate && animate)
824
839
  return;
@@ -916,8 +931,8 @@ const animationApi = {
916
931
  }
917
932
  }
918
933
  else {
919
- const animations = [];
920
934
  // просто Array
935
+ const self = this;
921
936
  var elements = slide.querySelectorAll(".narrative-element-animation");
922
937
  var isEditorSlide = hasClass(slide, "narrative-editor-slide");
923
938
  for (var i = 0; i < elements.length; i++) {
@@ -946,13 +961,13 @@ const animationApi = {
946
961
  timeout,
947
962
  timerId: window.setTimeout(cb, timeout),
948
963
  };
949
- animations.push(animation);
964
+ self.animations.push(animation);
950
965
  })(elements[i]);
951
966
  }
952
967
  var startAt = new Date().getTime();
953
968
  // onstop && onpause
954
969
  return function (isStop) {
955
- for (var animation of animations) {
970
+ for (var animation of self.animations) {
956
971
  if (animation["timerId"] !== undefined) {
957
972
  clearTimeout(animation["timerId"]);
958
973
  animation["timerId"] = undefined;
@@ -963,7 +978,7 @@ const animationApi = {
963
978
  // resume
964
979
  return function () {
965
980
  startAt = new Date().getTime();
966
- for (const animation of animations) {
981
+ for (const animation of self.animations) {
967
982
  if (animation["timerId"] === undefined && animation["needResume"] === true) {
968
983
  animation["timerId"] = window.setTimeout(animation["cb"], animation["timeout"]);
969
984
  }
@@ -996,6 +1011,7 @@ const animationApi = {
996
1011
  }
997
1012
  }
998
1013
  }
1014
+ this.animations = [];
999
1015
  },
1000
1016
  pause: function (slide) {
1001
1017
  if (supportAnimate) {
@@ -3281,6 +3297,56 @@ class VideoStateAdapter {
3281
3297
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLVideoElement`, `() => void`, `() => void`]; }
3282
3298
  }
3283
3299
 
3300
+ class Timer {
3301
+ _elementNodeRef;
3302
+ _layer;
3303
+ _widgetApi;
3304
+ _widgetCallbacks;
3305
+ _widgetDeps;
3306
+ static _className = "narrative-element-timer";
3307
+ static className() {
3308
+ return Timer._className;
3309
+ }
3310
+ constructor(_elementNodeRef, _layer, _widgetApi, _widgetCallbacks, _widgetDeps) {
3311
+ this._elementNodeRef = _elementNodeRef;
3312
+ this._layer = _layer;
3313
+ this._widgetApi = _widgetApi;
3314
+ this._widgetCallbacks = _widgetCallbacks;
3315
+ this._widgetDeps = _widgetDeps;
3316
+ }
3317
+ mediaElementsLoadingPromises = [];
3318
+ get nodeRef() {
3319
+ return this._elementNodeRef;
3320
+ }
3321
+ init(localData) {
3322
+ try {
3323
+ this._widgetApi.init(this._elementNodeRef, localData, this._widgetCallbacks, this._widgetDeps);
3324
+ }
3325
+ catch (e) {
3326
+ console.error(e);
3327
+ }
3328
+ return Promise.resolve(true);
3329
+ }
3330
+ onPause() { }
3331
+ onResume() { }
3332
+ onStart() {
3333
+ this._widgetApi.onStart(this._elementNodeRef);
3334
+ }
3335
+ onStop() {
3336
+ this._widgetApi.onStop(this._elementNodeRef);
3337
+ }
3338
+ onBeforeUnmount() {
3339
+ return Promise.resolve();
3340
+ }
3341
+ handleClick() {
3342
+ return false;
3343
+ }
3344
+ get isLayerForcePaused() {
3345
+ return false;
3346
+ }
3347
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetTimer.api`, `WidgetCallbacks`, `WidgetDeps`]; }
3348
+ }
3349
+
3284
3350
  // export const tryCreateAtLayer = (layerNodeRef: HTMLElement): IElement {
3285
3351
  // const
3286
3352
  // }
@@ -3341,6 +3407,8 @@ const tryCreateFromHtmlElement = (nodeRef, layer, widgetCallbacks, widgetDeps) =
3341
3407
  return layoutApi.widgetProductsApi ? new Products(nodeRef, layer, layoutApi.widgetProductsApi, widgetCallbacks, widgetDeps) : null;
3342
3408
  case Tooltip.className():
3343
3409
  return layoutApi.widgetTooltipApi ? new Tooltip(nodeRef, layer, layoutApi.widgetTooltipApi, widgetCallbacks, widgetDeps) : null;
3410
+ case Timer.className():
3411
+ return layoutApi.widgetTimerApi ? new Timer(nodeRef, layer, layoutApi.widgetTimerApi, widgetCallbacks, widgetDeps) : null;
3344
3412
  }
3345
3413
  }
3346
3414
  return null;
@@ -6988,626 +7056,1393 @@ class SlideApi extends CardApi {
6988
7056
  }`]; }
6989
7057
  }
6990
7058
 
6991
- // This file is part of the bwip-js project available at:
6992
- //
6993
- // http://metafloor.github.io/bwip-js
6994
- //
6995
- // Copyright (c) 2011-2024 Mark Warren
6996
- //
6997
- // This file contains code automatically generated from:
6998
- // Barcode Writer in Pure PostScript - Version 2024-06-18
6999
- // Copyright (c) 2004-2024 Terry Burton
7000
- //
7001
- // The MIT License
7002
- //
7003
- // Permission is hereby granted, free of charge, to any person obtaining a copy
7004
- // of this software and associated documentation files (the "Software"), to deal
7005
- // in the Software without restriction, including without limitation the rights
7006
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7007
- // copies of the Software, and to permit persons to whom the Software is
7008
- // furnished to do so, subject to the following conditions:
7009
- //
7010
- // The above copyright notice and this permission notice shall be included in
7011
- // all copies or substantial portions of the Software.
7012
- //
7013
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7014
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7015
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7016
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7017
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7018
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
7019
- // THE SOFTWARE.
7020
- //
7021
-
7022
- // bwip-js // Barcode Writer in Pure JavaScript
7023
- // https://github.com/metafloor/bwip-js
7024
- //
7025
- // This code was automatically generated from:
7026
- // Barcode Writer in Pure PostScript - Version 2024-06-18
7027
- //
7028
- // Copyright (c) 2011-2024 Mark Warren
7029
- // Copyright (c) 2004-2024 Terry Burton
7030
- //
7031
- // Licensed MIT. See the LICENSE file in the bwip-js root directory.
7032
- // bwip-js/barcode-hdr.js
7033
- //
7034
- // This code is injected above the cross-compiled barcode.js.
7035
-
7036
- // The BWIPJS object (graphics interface)
7037
- var $$ = null;
7038
- var $j = 0; // stack pointer
7039
- var $k = []; // operand stack
7040
- var $_ = {}; // base of the dictionary stack
7041
-
7042
- // Array ctor
7043
- // $a() : Build a new array up to the Infinity-marker on the stack.
7044
- // $a(arr) : Convert native array to a "view" of the array.
7045
- // $a(len) : Create a new array of length `len`
7046
- function $a(a) {
7047
- if (!arguments.length) {
7048
- for (var i = $j - 1; i >= 0 && $k[i] !== Infinity; i--);
7049
- if (i < 0) {
7050
- throw new Error('array-marker-not-found');
7059
+ class WidgetBase {
7060
+ _widgetCallbacks;
7061
+ widgetDeps;
7062
+ static DEFAULTS = {
7063
+ slide: null,
7064
+ activateAfterCreate: false,
7065
+ create: false,
7066
+ localData: {},
7067
+ };
7068
+ static widgetIndex = 0;
7069
+ env = WidgetBase.widgetsService.env;
7070
+ options = null;
7071
+ element = null;
7072
+ elementId = null;
7073
+ slide = null;
7074
+ slideIndex = null;
7075
+ disableTimer = null;
7076
+ layoutDirection = "ltr";
7077
+ cardId = null;
7078
+ cardType = null;
7079
+ widgetDone = null;
7080
+ showWidgetCompleteToast = null;
7081
+ submitButtonAnimatedView = null;
7082
+ submitButtonView = null;
7083
+ savedData = null;
7084
+ localData = null;
7085
+ firstOpenTime = 0;
7086
+ id;
7087
+ startReadyPromise = null;
7088
+ startReadyResolve = null;
7089
+ constructor(element, options, _widgetCallbacks, widgetDeps, elementIdGetter, slideGetter) {
7090
+ this._widgetCallbacks = _widgetCallbacks;
7091
+ this.widgetDeps = widgetDeps;
7092
+ this.options = extend({}, this.constructor.DEFAULTS, options);
7093
+ this.element = element;
7094
+ if (elementIdGetter) {
7095
+ this.elementId = elementIdGetter(this.element);
7051
7096
  }
7052
- a = $k.splice(i + 1, $j - 1 - i);
7053
- $j = i;
7054
- } else if (!(a instanceof Array)) {
7055
- a = new Array(+arguments[0]);
7056
- for (var i = 0, l = a.length; i < l; i++) {
7057
- a[i] = null;
7097
+ else {
7098
+ this.elementId = getValueOrException(getTagData(this.element, "elementId"), "Empty elementId");
7058
7099
  }
7059
- }
7060
- a.b = a; // base array
7061
- a.o = 0; // offset into base
7062
- return a;
7063
- }
7064
-
7065
- // dict ctor
7066
- // $d() : look for the Infinity marker on the stack
7067
- function $d() {
7068
- // Build the dictionary in the order the keys/values were pushed so enumeration
7069
- // occurs in the correct sequence.
7070
- for (var mark = $j - 1; mark >= 0 && $k[mark] !== Infinity; mark -= 2) {
7071
- if ($k[mark - 1] === Infinity) {
7072
- throw new Error('dict-malformed-stack');
7100
+ if (slideGetter) {
7101
+ this.slide = slideGetter(this.element);
7073
7102
  }
7103
+ else {
7104
+ this.slide = getValueOrException(this.element.closest(".narrative-slide"), "Empty slide");
7105
+ }
7106
+ this.slideIndex = getValueOrException(getTagDataAsNumber(this.slide, "index"), "Empty slideIndex");
7107
+ this.disableTimer = getTagData(this.slide, "disableTimer") === "1";
7108
+ this.cardId = getValueOrException(getTagDataAsNumber(this.slide, "id"), "Empty cardId");
7109
+ this.cardType = getValueOrException(getTagDataAsNumber(this.slide, "cardType"), "Empty card type");
7110
+ this.widgetDeps.getLayoutDirection();
7111
+ this.element.dir = this.layoutDirection;
7112
+ if (this.element.parentElement != null) {
7113
+ this.widgetDone = this.element.parentElement?.nextElementSibling; // geometry + .widget-sent-toast
7114
+ if (this.widgetDone) {
7115
+ if (!this.widgetDone.classList.contains("widget-sent-toast")) {
7116
+ this.widgetDone = null;
7117
+ }
7118
+ }
7119
+ }
7120
+ this.showWidgetCompleteToast = Boolean(getValueOrDefault(getTagDataAsNumber(this.element, "showWidgetCompleteToast"), 0));
7121
+ if (!this.showWidgetCompleteToast) {
7122
+ this.widgetDone = null;
7123
+ }
7124
+ if (this.element != null) {
7125
+ this.submitButtonAnimatedView = this.element.querySelector(".submit-button-animated-view");
7126
+ if (this.submitButtonAnimatedView != null) {
7127
+ this.submitButtonView = this.submitButtonAnimatedView.querySelector(".submit-button-view");
7128
+ }
7129
+ }
7130
+ this.savedData = this.widgetDeps.slideApiDeps.getCardServerData(this.cardId);
7131
+ this.localData = extend({}, this.savedData ?? {}, this.options.localData ?? {});
7132
+ this.id = `w_${this.elementId}_${WidgetBase.widgetIndex}`;
7133
+ ++WidgetBase.widgetIndex;
7134
+ this.resetStartReadyPromise();
7074
7135
  }
7075
- if (mark < 0) {
7076
- throw new Error('dict-marker-not-found');
7077
- }
7078
- var d = new Map;
7079
- for (var i = mark + 1; i < $j; i += 2) {
7080
- // Unlike javascript, postscript dict keys differentiate between
7081
- // numbers and the string representation of a number.
7082
- var k = $k[i]; // "key" into the dict entry
7083
- var t = typeof k;
7084
- if (t == 'number' || t == 'string') {
7085
- d.set(k, $k[i + 1]);
7086
- } else if (k instanceof Uint8Array) {
7087
- d.set($z(k), $k[i + 1]);
7088
- } else {
7089
- throw new Error('dict-not-a-valid-key(' + k + ')');
7136
+ get submitButtonViewHeight() {
7137
+ if (this.submitButtonView != null) {
7138
+ return this.submitButtonView.clientHeight;
7090
7139
  }
7140
+ return 0;
7091
7141
  }
7092
- $j = mark;
7093
- return d;
7094
- }
7095
-
7096
- // string ctor
7097
- // s(number) : create zero-filled string of number-length
7098
- // s(string) : make a copy of the string
7099
- // s(uint8[]) : make a copy of the string
7100
- //
7101
- // Returns a Uint8Array-string.
7102
- function $s(v) {
7103
- var t = typeof v;
7104
- if (t === 'number') {
7105
- return new Uint8Array(v);
7142
+ resetStartReadyPromise() {
7143
+ this.startReadyPromise = new Promise(resolve => {
7144
+ this.startReadyResolve = resolve;
7145
+ });
7106
7146
  }
7107
- if (t !== 'string') {
7108
- v = '' + v;
7147
+ /**
7148
+ * Start or restart widget
7149
+ * @param localData
7150
+ */
7151
+ onRefreshUserData(localData) {
7152
+ this.savedData = this.widgetDeps.slideApiDeps.getCardServerData(this.cardId);
7153
+ this.localData = extend({}, this.savedData ?? {}, localData);
7109
7154
  }
7110
- var s = new Uint8Array(v.length);
7111
- for (var i = 0; i < v.length; i++) {
7112
- s[i] = v.charCodeAt(i);
7155
+ onStart() {
7156
+ this.startReadyResolve();
7113
7157
  }
7114
- return s;
7158
+ onStop() {
7159
+ this.resetStartReadyPromise();
7160
+ }
7161
+ onPause() { }
7162
+ onResume() { }
7163
+ static widgetCacheKey = "ias.story-element";
7164
+ static widgetClassName = "";
7165
+ static getInstance(element) {
7166
+ return data(element, this.widgetCacheKey);
7167
+ }
7168
+ static getInstanceById(slideRoot, id) {
7169
+ const widgetsElements = slice.call(slideRoot.querySelectorAll(`.${this.widgetClassName}`));
7170
+ let widget;
7171
+ forEach(widgetsElements, (element, index) => {
7172
+ const localWidget = data(element, this.widgetCacheKey);
7173
+ if (localWidget && localWidget.id === id) {
7174
+ widget = localWidget;
7175
+ }
7176
+ });
7177
+ return widget;
7178
+ }
7179
+ static createInstance(instantiate, element, options) {
7180
+ // get from objects cache (just Map<key, data> where key assigned to HTMLElement)
7181
+ let instance = WidgetBase.getInstance(element);
7182
+ if (instance == null) {
7183
+ // can throw Error
7184
+ instance = instantiate(element, options);
7185
+ // save object in cache by key associated with HTMLElement
7186
+ data(element, WidgetBase.widgetCacheKey, instance);
7187
+ }
7188
+ return instance;
7189
+ }
7190
+ static initWidget(htmlElement, localData, instantiate) {
7191
+ const widget = this.createInstance(instantiate, htmlElement, {
7192
+ slide: null,
7193
+ localData,
7194
+ });
7195
+ // start widget (just created or cached instance)
7196
+ widget.onRefreshUserData(localData);
7197
+ return Promise.resolve(localData);
7198
+ }
7199
+ static get widgetsService() {
7200
+ return container.get({ identifier: "WidgetsService" });
7201
+ }
7202
+ static getLocalData(slideApiDeps) {
7203
+ return slideApiDeps.getCardLocalData();
7204
+ }
7205
+ getLocalData() {
7206
+ return this.constructor.getLocalData(this.widgetDeps.slideApiDeps);
7207
+ }
7208
+ static setLocalData(slideApiDeps, keyValue, sendToServer, syncWithRuntimeLocalData) {
7209
+ // push json object as string
7210
+ if (sendToServer === undefined) {
7211
+ sendToServer = true;
7212
+ }
7213
+ else {
7214
+ sendToServer = Boolean(sendToServer);
7215
+ }
7216
+ if (syncWithRuntimeLocalData === undefined) {
7217
+ syncWithRuntimeLocalData = true;
7218
+ }
7219
+ else {
7220
+ syncWithRuntimeLocalData = Boolean(syncWithRuntimeLocalData);
7221
+ }
7222
+ if (syncWithRuntimeLocalData) {
7223
+ this.getLocalData(slideApiDeps).then(localData => {
7224
+ // 1 - old values, 2 - new values
7225
+ keyValue = extend({}, localData, keyValue);
7226
+ // todo make async via promise or async
7227
+ slideApiDeps.setCardLocalData(keyValue, sendToServer);
7228
+ });
7229
+ }
7230
+ else {
7231
+ // todo make async via promise or async
7232
+ slideApiDeps.setCardLocalData(keyValue, sendToServer);
7233
+ }
7234
+ }
7235
+ setLocalData(keyValue, sendToServer, syncWithRuntimeLocalData) {
7236
+ return this.constructor.setLocalData(this.widgetDeps.slideApiDeps, keyValue, sendToServer, syncWithRuntimeLocalData);
7237
+ }
7238
+ get statisticEventBaseFieldsShortForm() {
7239
+ return WidgetBase.getStatisticEventBaseFieldsShortForm(this.cardId, this.cardType, this.slideIndex);
7240
+ }
7241
+ static getStatisticEventBaseFieldsShortForm(cardId, cardType, slideIndex) {
7242
+ return {
7243
+ i: cardId,
7244
+ si: slideIndex,
7245
+ ct: cardType,
7246
+ };
7247
+ }
7248
+ get statisticEventBaseFieldsFullForm() {
7249
+ return WidgetBase.getStatisticEventBaseFieldsFullForm(this.cardId, this.cardType, this.slideIndex);
7250
+ }
7251
+ static getStatisticEventBaseFieldsFullForm(cardId, cardType, slideIndex) {
7252
+ const data = { slide_index: slideIndex };
7253
+ switch (cardType) {
7254
+ case 1 /* CARD_TYPE.STORY */:
7255
+ case 2 /* CARD_TYPE.UGC_STORY */:
7256
+ data.story_id = cardId;
7257
+ break;
7258
+ case 4 /* CARD_TYPE.IN_APP_MESSAGING */:
7259
+ data.message_id = cardId;
7260
+ break;
7261
+ case 5 /* CARD_TYPE.BANNER */:
7262
+ data.banner_id = cardId;
7263
+ break;
7264
+ }
7265
+ return data;
7266
+ }
7267
+ static sendStatisticEventToApp(slideApiDeps, name, data, devPayload, options) {
7268
+ sendStatisticEventToApp(slideApiDeps, name, data, devPayload, options);
7269
+ }
7270
+ sendStatisticEventToApp(name, data, devPayload, options) {
7271
+ this.constructor.sendStatisticEventToApp(this.widgetDeps.slideApiDeps, name, data, devPayload, options);
7272
+ }
7273
+ onWidgetComplete() {
7274
+ this._widgetCallbacks.onWidgetComplete(this.cardId, this.slideIndex);
7275
+ }
7276
+ onWidgetRequirePauseUI() {
7277
+ this._widgetCallbacks.onWidgetRequirePauseUI(this.cardId, this.slideIndex);
7278
+ }
7279
+ onWidgetRequireResumeUI() {
7280
+ this._widgetCallbacks.onWidgetRequireResumeUI(this.cardId, this.slideIndex);
7281
+ }
7282
+ _showLayer(layers, selectIndex, withStatEvent = false) {
7283
+ if (this.widgetDeps.slideApiDeps.isExistsShowLayer()) {
7284
+ this.widgetDeps.slideApiDeps.showLayer(selectIndex);
7285
+ }
7286
+ else {
7287
+ forEach(layers, (layer, index) => {
7288
+ if (index === selectIndex) {
7289
+ layer.classList.remove("hidden");
7290
+ this.widgetDeps.slideApiDeps.cardAnimation?.start(layer);
7291
+ }
7292
+ else {
7293
+ layer.classList.add("hidden");
7294
+ }
7295
+ });
7296
+ }
7297
+ if (withStatEvent) {
7298
+ this._statEventLayoutShow(selectIndex);
7299
+ }
7300
+ }
7301
+ _statEventLayoutShow(layoutIndex) {
7302
+ try {
7303
+ this.sendStatisticEventToApp("layout-show", {
7304
+ ...this.statisticEventBaseFieldsShortForm,
7305
+ li: layoutIndex,
7306
+ }, {
7307
+ ...this.statisticEventBaseFieldsFullForm,
7308
+ layout_index: layoutIndex,
7309
+ });
7310
+ }
7311
+ catch (error) {
7312
+ console.error(error);
7313
+ }
7314
+ }
7315
+ static onRefreshUserData(element, localData) {
7316
+ const widgetElement = element.closest(`.${this.widgetClassName}`);
7317
+ if (widgetElement) {
7318
+ const widget = WidgetBase.getInstance(widgetElement);
7319
+ if (widget) {
7320
+ widget.onRefreshUserData(localData);
7321
+ }
7322
+ }
7323
+ }
7324
+ getPromotionalCodeFetchPath(promotionalCodeId) {
7325
+ switch (this.cardType) {
7326
+ case 4 /* CARD_TYPE.IN_APP_MESSAGING */:
7327
+ return `inappmessaging/message/${this.cardId}/widget/${this.elementId}/promo-code/${promotionalCodeId}`;
7328
+ default:
7329
+ return `story/${this.cardId}/widget/${this.elementId}/promo-code/${promotionalCodeId}`;
7330
+ }
7331
+ }
7332
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Partial`, `WidgetCallbacks`, `WidgetDeps`, `(element: HTMLElement) => string`, `(element: HTMLElement) => HTMLElement`]; }
7115
7333
  }
7116
7334
 
7117
- // Primarily designed to convert uint8-string to string, but will call the
7118
- // the toString() method on any value.
7119
- function $z(s) {
7120
- if (s instanceof Uint8Array) {
7121
- return String.fromCharCode.apply(null, s);
7335
+ var TimerTarget;
7336
+ (function (TimerTarget) {
7337
+ TimerTarget["DateTime"] = "dateTime";
7338
+ TimerTarget["Placeholder"] = "placeholder";
7339
+ TimerTarget["CountdownTime"] = "countdownTime";
7340
+ })(TimerTarget || (TimerTarget = {}));
7341
+ var TimerCompletionAction;
7342
+ (function (TimerCompletionAction) {
7343
+ TimerCompletionAction["None"] = "none";
7344
+ TimerCompletionAction["Delete"] = "delete";
7345
+ TimerCompletionAction["ChangeText"] = "changeText";
7346
+ TimerCompletionAction["CloseCard"] = "closeCard";
7347
+ TimerCompletionAction["NextSlide"] = "nextSlide";
7348
+ })(TimerCompletionAction || (TimerCompletionAction = {}));
7349
+ const pulseDurationStep = 200;
7350
+ const maxPulseDuration = 2000;
7351
+ const pulseScaleStep = 0.02;
7352
+
7353
+ class TimerRenderer {
7354
+ digits = {};
7355
+ render(time) {
7356
+ const container = document.createElement("div");
7357
+ container.classList.add("narrative-element-timer__container");
7358
+ const days = this.createGroup("d");
7359
+ const hours = this.createGroup("h");
7360
+ const minutes = this.createGroup("m");
7361
+ const seconds = this.createGroup("s");
7362
+ if (time.days > 0) {
7363
+ container.appendChild(days);
7364
+ container.appendChild(this.createDelimiter());
7365
+ }
7366
+ container.appendChild(hours);
7367
+ container.appendChild(this.createDelimiter());
7368
+ container.appendChild(minutes);
7369
+ container.appendChild(this.createDelimiter());
7370
+ container.appendChild(seconds);
7371
+ this.setTime(time);
7372
+ return container;
7373
+ }
7374
+ pad(num) {
7375
+ return num.toString().padStart(2, "0");
7376
+ }
7377
+ createDigit(type) {
7378
+ const digit = document.createElement("div");
7379
+ digit.classList.add("narrative-element-timer__digit");
7380
+ digit.dataset.mask = "0";
7381
+ const digitValue = document.createElement("div");
7382
+ digitValue.classList.add("narrative-element-timer__digit-value");
7383
+ digit.appendChild(digitValue);
7384
+ this.digits[type] = digitValue;
7385
+ return digit;
7386
+ }
7387
+ createGroup(prefix) {
7388
+ const group = document.createElement("div");
7389
+ group.classList.add("narrative-element-timer__group", `narrative-element-timer__group-${prefix}`);
7390
+ group.appendChild(this.createDigit(prefix + "1"));
7391
+ group.appendChild(this.createDigit(prefix + "2"));
7392
+ return group;
7393
+ }
7394
+ createDelimiter(text = ":") {
7395
+ const delimiter = document.createElement("div");
7396
+ delimiter.classList.add("narrative-element-timer__delimiter");
7397
+ delimiter.textContent = text;
7398
+ return delimiter;
7399
+ }
7400
+ setDays(days) {
7401
+ const padded = this.pad(days);
7402
+ this.digits["d1"].textContent = padded[0];
7403
+ this.digits["d2"].textContent = padded[1];
7404
+ }
7405
+ setHours(hours) {
7406
+ const padded = this.pad(hours);
7407
+ this.digits["h1"].textContent = padded[0];
7408
+ this.digits["h2"].textContent = padded[1];
7409
+ }
7410
+ setMinutes(minutes) {
7411
+ const padded = this.pad(minutes);
7412
+ this.digits["m1"].textContent = padded[0];
7413
+ this.digits["m2"].textContent = padded[1];
7414
+ }
7415
+ setSeconds(seconds) {
7416
+ const padded = this.pad(seconds);
7417
+ this.digits["s1"].textContent = padded[0];
7418
+ this.digits["s2"].textContent = padded[1];
7419
+ }
7420
+ setTime(time) {
7421
+ this.setDays(time.days);
7422
+ this.setHours(time.hours);
7423
+ this.setMinutes(time.minutes);
7424
+ this.setSeconds(time.seconds);
7122
7425
  }
7123
- return '' + s;
7124
7426
  }
7125
7427
 
7126
- // Copies source to dest and returns a view of just the copied characters
7127
- function $strcpy(dst, src) {
7128
- if (typeof dst === 'string') {
7129
- dst = $s(dst);
7428
+ class BackgroundColorEffect {
7429
+ element;
7430
+ config;
7431
+ isAnimationActive = false;
7432
+ startTransition = "";
7433
+ constructor(element, config) {
7434
+ this.element = element;
7435
+ this.config = config;
7130
7436
  }
7131
- if (src instanceof Uint8Array) {
7132
- for (var i = 0, l = src.length; i < l; i++) {
7133
- dst[i] = src[i];
7437
+ isDynamic() {
7438
+ return false;
7439
+ }
7440
+ update(time) {
7441
+ if (time <= 0) {
7442
+ this.element.style.backgroundColor = this.config.color;
7134
7443
  }
7135
- } else {
7136
- for (var i = 0, l = src.length; i < l; i++) {
7137
- dst[i] = src.charCodeAt(i);
7444
+ else if (time <= this.config.time) {
7445
+ if (this.isAnimationActive)
7446
+ return;
7447
+ this.isAnimationActive = true;
7448
+ let transition = "background-color 300ms ease";
7449
+ this.startTransition = getComputedStyle(this.element).transition;
7450
+ transition = this.startTransition.length > 0 ? `${this.startTransition},${transition}` : transition;
7451
+ this.element.style.transition = transition;
7452
+ this.element.style.backgroundColor = this.config.color;
7453
+ }
7454
+ else {
7455
+ this.element.style.backgroundColor = "";
7138
7456
  }
7139
7457
  }
7140
- return src.length < dst.length ? dst.subarray(0, src.length) : dst;
7141
- }
7142
- // cvi operator - converts a numeric string value to integer.
7143
- function $cvi(s) {
7144
- if (s instanceof Uint8Array) {
7145
- // nul-chars on the end of a string are ignored by postscript but cause javascript
7146
- // to return a zero result.
7147
- return String.fromCharCode.apply(null, s).replace(/\0+$/, '') | 0;
7458
+ reset(time) {
7459
+ this.isAnimationActive = false;
7460
+ this.element.style.transition = this.startTransition;
7461
+ if (time > this.config.time) {
7462
+ this.element.style.backgroundColor = "";
7463
+ }
7148
7464
  }
7149
- return ('' + s) | 0;
7465
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `{ time: number; color: string }`]; }
7150
7466
  }
7151
7467
 
7152
- // cvrs operator - convert a number to a radix string
7153
- // s : string to store into
7154
- // n : number
7155
- // r : radix
7156
- function $cvrs(s, n, r) {
7157
- return $strcpy(s, (~~n).toString(r).toUpperCase());
7468
+ class BackgroundPulsationEffect {
7469
+ element;
7470
+ config;
7471
+ isAnimationActive = false;
7472
+ constructor(element, config) {
7473
+ this.element = element;
7474
+ this.config = config;
7475
+ }
7476
+ isDynamic() {
7477
+ return true;
7478
+ }
7479
+ update(time) {
7480
+ if (time > this.config.time || this.isAnimationActive)
7481
+ return;
7482
+ this.isAnimationActive = true;
7483
+ const scale = this.getScaleByAmplitude(this.config.amplitude);
7484
+ const duration = this.getDurationByFrequency(this.config.frequency);
7485
+ this.element.parentNode.classList.add("ias-pulse-animation", "ias-timer-background-pulse");
7486
+ this.element.parentNode.style.setProperty("--ias-background-pulse-scale", scale);
7487
+ this.element.parentNode.style.setProperty("--ias-background-pulse-duration", duration + "ms");
7488
+ }
7489
+ reset(time) {
7490
+ this.isAnimationActive = false;
7491
+ this.element.parentNode.classList.remove("ias-pulse-animation", "ias-timer-background-pulse");
7492
+ }
7493
+ getScaleByAmplitude(amplitude) {
7494
+ return (1 + amplitude * pulseScaleStep).toFixed(2);
7495
+ }
7496
+ getDurationByFrequency(frequency) {
7497
+ return (maxPulseDuration - (frequency - 1) * pulseDurationStep).toFixed(2);
7498
+ }
7499
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `{ time: number; amplitude: number; frequency: number }`]; }
7158
7500
  }
7159
7501
 
7160
- // get operator
7161
- // s : source
7162
- // k : key
7163
- function $get(s, k) {
7164
- if (s instanceof Uint8Array) {
7165
- return s[k];
7502
+ class TextColorEffect {
7503
+ element;
7504
+ config;
7505
+ constructor(element, config) {
7506
+ this.element = element;
7507
+ this.config = config;
7166
7508
  }
7167
- if (typeof s === 'string') {
7168
- return s.charCodeAt(k);
7509
+ isDynamic() {
7510
+ return false;
7169
7511
  }
7170
- if (s instanceof Array) {
7171
- return s.b[s.o + k];
7512
+ update(time) {
7513
+ if (time <= 0) {
7514
+ this.element.style.transition = "none";
7515
+ this.element.style.color = this.config.color;
7516
+ }
7517
+ else if (time <= this.config.time) {
7518
+ this.element.style.transition = "color 300ms ease";
7519
+ this.element.style.color = this.config.color;
7520
+ }
7521
+ else {
7522
+ this.element.style.color = "";
7523
+ }
7172
7524
  }
7173
- if (k instanceof Uint8Array) {
7174
- return s.get($z(k));
7525
+ reset(time) {
7526
+ if (time > this.config.time) {
7527
+ this.element.style.color = "";
7528
+ }
7175
7529
  }
7176
- return s.get(k);
7530
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `{ time: number; color: string }`]; }
7177
7531
  }
7178
7532
 
7179
- // put operator
7180
- // d : dest
7181
- // k : key
7182
- // v : value
7183
- function $put(d, k, v) {
7184
- if (d instanceof Uint8Array) {
7185
- d[k] = v;
7186
- } else if (d instanceof Array) {
7187
- d.b[d.o + k] = v;
7188
- } else if (typeof d == 'object') {
7189
- if (k instanceof Uint8Array) {
7190
- d.set($z(k), v);
7191
- } else {
7192
- d.set(k, v);
7193
- }
7194
- } else {
7195
- throw new Error('put-not-writable-' + (typeof d));
7533
+ class TextPulsationEffect {
7534
+ element;
7535
+ config;
7536
+ constructor(element, config) {
7537
+ this.element = element;
7538
+ this.config = config;
7196
7539
  }
7197
- }
7198
-
7199
- // getinterval operator
7200
- // s : src
7201
- // o : offset
7202
- // l : length
7203
- function $geti(s, o, l) {
7204
- if (s instanceof Uint8Array) {
7205
- return s.subarray(o, o + l);
7540
+ isDynamic() {
7541
+ return true;
7206
7542
  }
7207
- if (s instanceof Array) {
7208
- var a = new Array(l);
7209
- a.b = s.b; // base array
7210
- a.o = s.o + o; // offset into base
7211
- return a;
7543
+ update(time) {
7544
+ if (time > this.config.time)
7545
+ return;
7546
+ const scale = this.getScaleByAmplitude(this.config.amplitude);
7547
+ const duration = this.getDurationByFrequency(this.config.frequency);
7548
+ this.element.classList.add("ias-pulse-animation", "ias-timer-text-pulse");
7549
+ this.element.style.setProperty("--ias-text-pulse-scale", scale);
7550
+ this.element.style.setProperty("--ias-text-pulse-duration", duration + "ms");
7212
7551
  }
7213
- // Must be a string
7214
- return s.substr(o, l);
7552
+ reset(time) {
7553
+ this.element.classList.remove("ias-pulse-animation", "ias-timer-text-pulse");
7554
+ }
7555
+ getScaleByAmplitude(amplitude) {
7556
+ return (1 + amplitude * pulseScaleStep).toFixed(2);
7557
+ }
7558
+ getDurationByFrequency(frequency) {
7559
+ return (maxPulseDuration - (frequency - 1) * pulseDurationStep).toFixed(2);
7560
+ }
7561
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `{ time: number; amplitude: number; frequency: number }`]; }
7215
7562
  }
7216
7563
 
7217
- // putinterval operator
7218
- // d : dst
7219
- // o : offset
7220
- // s : src
7221
- function $puti(d, o, s) {
7222
- if (d instanceof Uint8Array) {
7223
- if (typeof s == 'string') {
7224
- for (var i = 0, l = s.length; i < l; i++) {
7225
- d[o + i] = s.charCodeAt(i);
7564
+ function getMaxTransitionDuration(transitionDuration) {
7565
+ if (!transitionDuration || transitionDuration === "0s") {
7566
+ return 0;
7567
+ }
7568
+ const durations = transitionDuration.split(",").map(d => d.trim());
7569
+ let maxDuration = 0;
7570
+ durations.forEach(duration => {
7571
+ if (duration.endsWith("ms")) {
7572
+ const value = parseFloat(duration);
7573
+ if (!isNaN(value)) {
7574
+ maxDuration = Math.max(maxDuration, value);
7226
7575
  }
7227
- } else {
7228
- // When both d and s are the same, we want to copy
7229
- // backwards, which works for the general case as well.
7230
- for (var i = s.length - 1; i >= 0; i--) {
7231
- d[o + i] = s[i];
7576
+ }
7577
+ else if (duration.endsWith("s")) {
7578
+ const value = parseFloat(duration);
7579
+ if (!isNaN(value)) {
7580
+ maxDuration = Math.max(maxDuration, value * 1000);
7232
7581
  }
7233
7582
  }
7234
- } else if (d instanceof Array) {
7235
- // Operate on the base arrays
7236
- var darr = d.b;
7237
- var doff = o + d.o;
7238
- var sarr = s.b;
7239
- var soff = s.o;
7240
-
7241
- for (var i = 0, l = s.length; i < l; i++) {
7242
- darr[doff + i] = sarr[soff + i];
7583
+ });
7584
+ return maxDuration;
7585
+ }
7586
+ function delayWithAbort(ms, abortSignal) {
7587
+ return new Promise((resolve, reject) => {
7588
+ if (abortSignal?.aborted) {
7589
+ reject(new DOMException("Aborted", "AbortError"));
7590
+ return;
7243
7591
  }
7244
- } else {
7245
- throw new Error('putinterval-not-writable-' + (typeof d));
7246
- }
7592
+ const timeoutId = setTimeout(() => {
7593
+ cleanup();
7594
+ resolve();
7595
+ }, ms);
7596
+ const abortHandler = () => {
7597
+ clearTimeout(timeoutId);
7598
+ reject(new DOMException("Aborted", "AbortError"));
7599
+ };
7600
+ const cleanup = () => {
7601
+ abortSignal?.removeEventListener("abort", abortHandler);
7602
+ };
7603
+ abortSignal?.addEventListener("abort", abortHandler, { once: true });
7604
+ });
7247
7605
  }
7248
7606
 
7249
- // type operator
7250
- function $type(v) {
7251
- // null can be mis-typed - get it out of the way
7252
- if (v == null) {
7253
- return 'nulltype';
7254
- }
7255
- var t = typeof v;
7256
- if (t == 'number') {
7257
- return v % 1 ? 'realtype' : 'integertype';
7607
+ class WidgetTimer extends WidgetBase {
7608
+ static DEFAULTS = {
7609
+ slide: null,
7610
+ activateAfterCreate: false,
7611
+ create: false,
7612
+ localData: {},
7613
+ };
7614
+ static widgetClassName = "narrative-element-timer";
7615
+ model;
7616
+ endTimeMs;
7617
+ timerRenderer;
7618
+ timerGroup;
7619
+ timerInit = false;
7620
+ rafId;
7621
+ effects = [];
7622
+ abortController = new AbortController();
7623
+ constructor(element, options, widgetCallbacks, widgetDeps) {
7624
+ super(element, options, widgetCallbacks, widgetDeps);
7625
+ this.model = this.createTimerModel();
7626
+ this.setTimerEndTime();
7627
+ this.timerRenderer = new TimerRenderer();
7628
+ this.timerGroup = this.mountTimerGroup(this.timerRenderer);
7629
+ this.fillEffects();
7630
+ if (this.isDone()) {
7631
+ this.update();
7632
+ }
7258
7633
  }
7259
- if (t == 'boolean') {
7260
- return 'booleantype';
7634
+ isDone() {
7635
+ const time = this.getCurrentTime();
7636
+ return time.remainingSeconds <= 0;
7637
+ }
7638
+ fillEffects() {
7639
+ this.effects = [];
7640
+ if (this.model.textColorChangeBeforeTimerEnd)
7641
+ this.effects.push(new TextColorEffect(this.timerGroup, this.model.textColorChangeBeforeTimerEnd));
7642
+ if (this.model.backgroundColorChangeBeforeTimerEnd)
7643
+ this.effects.push(new BackgroundColorEffect(this.element, this.model.backgroundColorChangeBeforeTimerEnd));
7644
+ if (this.model.textPulsationBeforeTimerEnd)
7645
+ this.effects.push(new TextPulsationEffect(this.timerGroup, this.model.textPulsationBeforeTimerEnd));
7646
+ if (this.model.backgroundPulsationBeforeTimerEnd)
7647
+ this.effects.push(new BackgroundPulsationEffect(this.element, this.model.backgroundPulsationBeforeTimerEnd));
7648
+ }
7649
+ mountTimerGroup(timerRenderer) {
7650
+ const time = this.getCurrentTime();
7651
+ const content = this.slide.querySelector(".narrative-element-text-lines");
7652
+ content.innerHTML = "";
7653
+ const timerGroup = timerRenderer.render(time);
7654
+ content.appendChild(timerGroup);
7655
+ return timerGroup;
7656
+ }
7657
+ createTimerModel() {
7658
+ return {
7659
+ timerTarget: getTagDataAsJson(this.element, "timerTarget"),
7660
+ timerCompletionAction: getTagDataAsJson(this.element, "timerCompletionAction"),
7661
+ textColorChangeBeforeTimerEnd: getTagDataAsJson(this.element, "textColorChangeBeforeTimerEnd"),
7662
+ backgroundColorChangeBeforeTimerEnd: getTagDataAsJson(this.element, "backgroundColorChangeBeforeTimerEnd"),
7663
+ textPulsationBeforeTimerEnd: getTagDataAsJson(this.element, "textPulsationBeforeTimerEnd"),
7664
+ backgroundPulsationBeforeTimerEnd: getTagDataAsJson(this.element, "backgroundPulsationBeforeTimerEnd"),
7665
+ };
7261
7666
  }
7262
- if (t == 'string' || v instanceof Uint8Array) {
7263
- return 'stringtype';
7667
+ setTimerEndTime() {
7668
+ switch (this.model.timerTarget.type) {
7669
+ case TimerTarget.DateTime:
7670
+ this.endTimeMs = parseInt(this.model.timerTarget.value, 10) * 1000;
7671
+ break;
7672
+ case TimerTarget.Placeholder:
7673
+ this.endTimeMs = parseInt(this.model.timerTarget.value, 10) * 1000;
7674
+ if (Number.isNaN(this.endTimeMs)) {
7675
+ this.endTimeMs = 0;
7676
+ console.warn(`[IAS]: You need to replace the ${this.model.timerTarget.value} placeholder with the time in seconds.`);
7677
+ }
7678
+ break;
7679
+ case TimerTarget.CountdownTime:
7680
+ const seconds = parseInt(this.model.timerTarget.value, 10);
7681
+ this.endTimeMs = Date.now() + seconds * 1000;
7682
+ break;
7683
+ }
7264
7684
  }
7265
- if (t == 'function') {
7266
- return 'operatortype';
7685
+ onStart() {
7686
+ super.onStart();
7687
+ if (this.timerInit)
7688
+ return;
7689
+ this.timerInit = true;
7690
+ this.abortController = new AbortController();
7691
+ this.waitCardAnimationsEnd(this.abortController.signal)
7692
+ .then(() => {
7693
+ if (!this.timerInit)
7694
+ return;
7695
+ this.setTimerEndTime();
7696
+ this.update();
7697
+ })
7698
+ .catch(() => { });
7267
7699
  }
7268
- if (v instanceof Array) {
7269
- return 'arraytype';
7700
+ onStop() {
7701
+ super.onStop();
7702
+ this.abortController.abort();
7703
+ this.reset();
7704
+ this.showElement();
7270
7705
  }
7271
- return 'dicttype';
7272
- // filetype
7273
- // fonttype
7274
- // gstatetype
7275
- // marktype (v === Infinity)
7276
- // nametype
7277
- // savetype
7278
- }
7279
-
7280
- // search operator
7281
- // string seek search suffix match prefix true %if-found
7282
- // string false %if-not-found
7283
- function $search(str, seek) {
7284
- if (!(str instanceof Uint8Array)) {
7285
- str = $s(str);
7706
+ onPause() {
7707
+ this.env.cancelAnimationFrame(this.rafId);
7286
7708
  }
7287
- var ls = str.length;
7288
-
7289
- // Virtually all uses of search in BWIPP are for single-characters.
7290
- // Optimize for that case.
7291
- if (seek.length == 1) {
7292
- var lk = 1;
7293
- var cd = seek instanceof Uint8Array ? seek[0] : seek.charCodeAt(0);
7294
- for (var i = 0; i < ls && str[i] != cd; i++);
7295
- } else {
7296
- // Slow path,
7297
- if (!(seek instanceof Uint8Array)) {
7298
- seek = $s(seek);
7299
- }
7300
- var lk = seek.length;
7301
- var cd = seek[0];
7302
- for (var i = 0; i < ls && str[i] != cd; i++);
7303
- while (i < ls) {
7304
- for (var j = 1; j < lk && str[i + j] === seek[j]; j++);
7305
- if (j === lk) {
7306
- break;
7307
- }
7308
- for (i++; i < ls && str[i] != cd; i++);
7709
+ onResume() {
7710
+ if (this.timerInit) {
7711
+ this.update();
7309
7712
  }
7310
7713
  }
7311
- if (i < ls) {
7312
- $k[$j++] = str.subarray(i + lk);
7313
- $k[$j++] = str.subarray(i, i + lk);
7314
- $k[$j++] = str.subarray(0, i);
7315
- $k[$j++] = true;
7316
- } else {
7317
- $k[$j++] = str;
7318
- $k[$j++] = false;
7714
+ onRefreshUserData(localData) {
7715
+ this.reset();
7319
7716
  }
7320
- }
7321
-
7322
- // The callback is omitted when forall is being used just to push onto the
7323
- // stack. The callback normally returns undefined. A return of true means break.
7324
- function $forall(o, cb) {
7325
- if (o instanceof Uint8Array) {
7326
- for (var i = 0, l = o.length; i < l; i++) {
7327
- $k[$j++] = o[i];
7328
- if (cb && cb()) break;
7329
- }
7330
- } else if (o instanceof Array) {
7331
- // The array may be a view.
7332
- for (var a = o.b, i = o.o, l = o.o + o.length; i < l; i++) {
7333
- $k[$j++] = a[i];
7334
- if (cb && cb()) break;
7335
- }
7336
- } else if (typeof o === 'string') {
7337
- for (var i = 0, l = o.length; i < l; i++) {
7338
- $k[$j++] = o.charCodeAt(i);
7339
- if (cb && cb()) break;
7340
- }
7341
- } else if (o instanceof Map) {
7342
- for (var keys = o.keys(), i = 0, l = o.size; i < l; i++) {
7343
- var id = keys.next().value;
7344
- $k[$j++] = id;
7345
- $k[$j++] = o.get(id);
7346
- if (cb && cb()) break;
7347
- }
7348
- } else {
7349
- for (var id in o) {
7350
- $k[$j++] = id;
7351
- $k[$j++] = o[id];
7352
- if (cb && cb()) break;
7717
+ reset() {
7718
+ if (!this.timerInit)
7719
+ return;
7720
+ this.timerInit = false;
7721
+ this.env.cancelAnimationFrame(this.rafId);
7722
+ this.setTimerEndTime();
7723
+ const { days, hours, minutes, seconds, remainingSeconds } = this.getCurrentTime();
7724
+ this.timerRenderer.setTime({ days, hours, minutes, seconds });
7725
+ this.resetEffects(remainingSeconds);
7726
+ }
7727
+ update() {
7728
+ if (!this.timerInit)
7729
+ return;
7730
+ const { remainingSeconds, days, hours, minutes, seconds } = this.getCurrentTime();
7731
+ this.timerRenderer.setTime({ days, hours, minutes, seconds });
7732
+ this.updateEffects(remainingSeconds);
7733
+ if (remainingSeconds <= 0) {
7734
+ this.complete();
7735
+ return;
7353
7736
  }
7737
+ this.rafId = this.env.requestAnimationFrame(() => this.update());
7354
7738
  }
7355
- }
7356
-
7357
- function $cleartomark() {
7358
- while ($j > 0 && $k[--$j] !== Infinity);
7359
- }
7360
-
7361
- function $counttomark() {
7362
- for (var i = $j - 1; i >= 0 && $k[i] !== Infinity; i--);
7363
- return $j - i - 1;
7364
- }
7365
-
7366
- function $aload(a) {
7367
- for (var i = 0, l = a.length, b = a.b, o = a.o; i < l; i++) {
7368
- $k[$j++] = b[o + i];
7739
+ complete() {
7740
+ this.resetEffects(0);
7741
+ this.doCompletitionAction();
7369
7742
  }
7370
- // This push has been optimized out. See $.aload() in psc.js.
7371
- //$k[$j++] = a;
7372
- }
7373
-
7374
- function $astore(a) {
7375
- for (var i = 0, l = a.length, b = a.b, o = a.o + l - 1; i < l; i++) {
7376
- b[o - i] = $k[--$j];
7743
+ getCurrentTime() {
7744
+ const remainingMs = Math.max(0, this.endTimeMs - Date.now());
7745
+ const remainingSeconds = Math.round(remainingMs / 1000);
7746
+ const days = Math.floor((remainingSeconds / 86400) % 365);
7747
+ const hours = Math.floor((remainingSeconds / 3600) % 24);
7748
+ const minutes = Math.floor((remainingSeconds / 60) % 60);
7749
+ const seconds = remainingSeconds % 60;
7750
+ return {
7751
+ remainingSeconds,
7752
+ days,
7753
+ hours,
7754
+ minutes,
7755
+ seconds,
7756
+ };
7377
7757
  }
7378
- $k[$j++] = a;
7379
- }
7380
-
7381
- function $eq(a, b) {
7382
- if (typeof a === 'string' && typeof b === 'string') {
7383
- return a == b;
7758
+ updateEffects(time) {
7759
+ for (const effect of this.effects)
7760
+ effect.update(time);
7384
7761
  }
7385
- if (a instanceof Uint8Array && b instanceof Uint8Array) {
7386
- if (a.length != b.length) {
7387
- return false;
7388
- }
7389
- for (var i = 0, l = a.length; i < l; i++) {
7390
- if (a[i] != b[i]) {
7391
- return false;
7392
- }
7393
- }
7394
- return true;
7762
+ resetEffects(time) {
7763
+ for (const effect of this.effects)
7764
+ effect.reset(time);
7395
7765
  }
7396
- if (a instanceof Uint8Array && typeof b === 'string' ||
7397
- b instanceof Uint8Array && typeof a === 'string') {
7398
- if (a instanceof Uint8Array) {
7399
- a = $z(a);
7400
- } else {
7401
- b = $z(b);
7766
+ hideElement() {
7767
+ this.element.style.visibility = "hidden";
7768
+ }
7769
+ showElement() {
7770
+ this.element.style.visibility = "visible";
7771
+ }
7772
+ doCompletitionAction() {
7773
+ switch (this.model.timerCompletionAction.action) {
7774
+ case TimerCompletionAction.None:
7775
+ break;
7776
+ case TimerCompletionAction.Delete:
7777
+ this.hideElement();
7778
+ break;
7779
+ case TimerCompletionAction.ChangeText:
7780
+ if (this.model.timerCompletionAction.changeText && this.timerGroup.parentElement) {
7781
+ this.timerGroup.parentElement.innerHTML = this.model.timerCompletionAction.changeText;
7782
+ }
7783
+ break;
7784
+ case TimerCompletionAction.CloseCard:
7785
+ this.widgetDeps.slideApiDeps.closeCard("timer widget");
7786
+ break;
7787
+ case TimerCompletionAction.NextSlide:
7788
+ this.widgetDeps.slideApiDeps.showNextSlide(0);
7789
+ break;
7402
7790
  }
7403
- return a == b;
7404
7791
  }
7405
- return a == b;
7792
+ getMaxCardAnimationsDelay() {
7793
+ const animations = this.widgetDeps.slideApiDeps.cardAnimation?.animations ?? [];
7794
+ const maxDelay = animations.length > 0 ? Math.max(...animations.map(animation => animation.timeout)) : 0;
7795
+ return maxDelay;
7796
+ }
7797
+ async waitCardAnimationsEnd(abortSignal) {
7798
+ const delay = this.getMaxCardAnimationsDelay();
7799
+ await delayWithAbort(delay, abortSignal);
7800
+ const duration = getMaxTransitionDuration(this.env.getComputedStyle(this.element).transitionDuration);
7801
+ await delayWithAbort(duration, abortSignal);
7802
+ }
7803
+ static api = {
7804
+ widgetClassName: WidgetTimer.widgetClassName,
7805
+ onRefreshUserData: WidgetTimer.onRefreshUserData,
7806
+ init: function (element, localData, widgetCallbacks, widgetDeps) {
7807
+ WidgetTimer.initWidget(element, localData, (element, options) => new WidgetTimer(element, options, widgetCallbacks, widgetDeps));
7808
+ },
7809
+ onStart: function (element) {
7810
+ WidgetTimer.getInstance(element)?.onStart();
7811
+ },
7812
+ onStop: function (element) {
7813
+ WidgetTimer.getInstance(element)?.onStop();
7814
+ },
7815
+ click: function (element) {
7816
+ const widgetElement = element.closest(`.${WidgetTimer.widgetClassName}`);
7817
+ if (widgetElement) {
7818
+ WidgetTimer.getInstance(widgetElement);
7819
+ }
7820
+ return false;
7821
+ },
7822
+ };
7823
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Partial`, `WidgetCallbacks`, `WidgetDeps`]; }
7406
7824
  }
7407
7825
 
7408
- function $ne(a, b) {
7409
- return !$eq(a, b);
7410
- }
7826
+ // This file is part of the bwip-js project available at:
7827
+ //
7828
+ // http://metafloor.github.io/bwip-js
7829
+ //
7830
+ // Copyright (c) 2011-2024 Mark Warren
7831
+ //
7832
+ // This file contains code automatically generated from:
7833
+ // Barcode Writer in Pure PostScript - Version 2024-06-18
7834
+ // Copyright (c) 2004-2024 Terry Burton
7835
+ //
7836
+ // The MIT License
7837
+ //
7838
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
7839
+ // of this software and associated documentation files (the "Software"), to deal
7840
+ // in the Software without restriction, including without limitation the rights
7841
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7842
+ // copies of the Software, and to permit persons to whom the Software is
7843
+ // furnished to do so, subject to the following conditions:
7844
+ //
7845
+ // The above copyright notice and this permission notice shall be included in
7846
+ // all copies or substantial portions of the Software.
7847
+ //
7848
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7849
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7850
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7851
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7852
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7853
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
7854
+ // THE SOFTWARE.
7855
+ //
7411
7856
 
7412
- function $lt(a, b) {
7413
- if (a instanceof Uint8Array) {
7414
- a = $z(a);
7415
- }
7416
- if (b instanceof Uint8Array) {
7417
- b = $z(b);
7857
+ // bwip-js // Barcode Writer in Pure JavaScript
7858
+ // https://github.com/metafloor/bwip-js
7859
+ //
7860
+ // This code was automatically generated from:
7861
+ // Barcode Writer in Pure PostScript - Version 2024-06-18
7862
+ //
7863
+ // Copyright (c) 2011-2024 Mark Warren
7864
+ // Copyright (c) 2004-2024 Terry Burton
7865
+ //
7866
+ // Licensed MIT. See the LICENSE file in the bwip-js root directory.
7867
+ // bwip-js/barcode-hdr.js
7868
+ //
7869
+ // This code is injected above the cross-compiled barcode.js.
7870
+
7871
+ // The BWIPJS object (graphics interface)
7872
+ var $$ = null;
7873
+ var $j = 0; // stack pointer
7874
+ var $k = []; // operand stack
7875
+ var $_ = {}; // base of the dictionary stack
7876
+
7877
+ // Array ctor
7878
+ // $a() : Build a new array up to the Infinity-marker on the stack.
7879
+ // $a(arr) : Convert native array to a "view" of the array.
7880
+ // $a(len) : Create a new array of length `len`
7881
+ function $a(a) {
7882
+ if (!arguments.length) {
7883
+ for (var i = $j - 1; i >= 0 && $k[i] !== Infinity; i--);
7884
+ if (i < 0) {
7885
+ throw new Error('array-marker-not-found');
7886
+ }
7887
+ a = $k.splice(i + 1, $j - 1 - i);
7888
+ $j = i;
7889
+ } else if (!(a instanceof Array)) {
7890
+ a = new Array(+arguments[0]);
7891
+ for (var i = 0, l = a.length; i < l; i++) {
7892
+ a[i] = null;
7893
+ }
7418
7894
  }
7419
- return a < b;
7895
+ a.b = a; // base array
7896
+ a.o = 0; // offset into base
7897
+ return a;
7420
7898
  }
7421
7899
 
7422
- function $le(a, b) {
7423
- if (a instanceof Uint8Array) {
7424
- a = $z(a);
7900
+ // dict ctor
7901
+ // $d() : look for the Infinity marker on the stack
7902
+ function $d() {
7903
+ // Build the dictionary in the order the keys/values were pushed so enumeration
7904
+ // occurs in the correct sequence.
7905
+ for (var mark = $j - 1; mark >= 0 && $k[mark] !== Infinity; mark -= 2) {
7906
+ if ($k[mark - 1] === Infinity) {
7907
+ throw new Error('dict-malformed-stack');
7908
+ }
7425
7909
  }
7426
- if (b instanceof Uint8Array) {
7427
- b = $z(b);
7910
+ if (mark < 0) {
7911
+ throw new Error('dict-marker-not-found');
7428
7912
  }
7429
- return a <= b;
7913
+ var d = new Map;
7914
+ for (var i = mark + 1; i < $j; i += 2) {
7915
+ // Unlike javascript, postscript dict keys differentiate between
7916
+ // numbers and the string representation of a number.
7917
+ var k = $k[i]; // "key" into the dict entry
7918
+ var t = typeof k;
7919
+ if (t == 'number' || t == 'string') {
7920
+ d.set(k, $k[i + 1]);
7921
+ } else if (k instanceof Uint8Array) {
7922
+ d.set($z(k), $k[i + 1]);
7923
+ } else {
7924
+ throw new Error('dict-not-a-valid-key(' + k + ')');
7925
+ }
7926
+ }
7927
+ $j = mark;
7928
+ return d;
7430
7929
  }
7431
7930
 
7432
- function $gt(a, b) {
7433
- if (a instanceof Uint8Array) {
7434
- a = $z(a);
7931
+ // string ctor
7932
+ // s(number) : create zero-filled string of number-length
7933
+ // s(string) : make a copy of the string
7934
+ // s(uint8[]) : make a copy of the string
7935
+ //
7936
+ // Returns a Uint8Array-string.
7937
+ function $s(v) {
7938
+ var t = typeof v;
7939
+ if (t === 'number') {
7940
+ return new Uint8Array(v);
7435
7941
  }
7436
- if (b instanceof Uint8Array) {
7437
- b = $z(b);
7942
+ if (t !== 'string') {
7943
+ v = '' + v;
7438
7944
  }
7439
- return a > b;
7945
+ var s = new Uint8Array(v.length);
7946
+ for (var i = 0; i < v.length; i++) {
7947
+ s[i] = v.charCodeAt(i);
7948
+ }
7949
+ return s;
7440
7950
  }
7441
7951
 
7442
- function $ge(a, b) {
7443
- if (a instanceof Uint8Array) {
7444
- a = $z(a);
7445
- }
7446
- if (b instanceof Uint8Array) {
7447
- b = $z(b);
7952
+ // Primarily designed to convert uint8-string to string, but will call the
7953
+ // the toString() method on any value.
7954
+ function $z(s) {
7955
+ if (s instanceof Uint8Array) {
7956
+ return String.fromCharCode.apply(null, s);
7448
7957
  }
7449
- return a >= b;
7958
+ return '' + s;
7450
7959
  }
7451
7960
 
7452
- function $an(a, b) { // and
7453
- return (typeof a === 'boolean') ? a && b : a & b;
7961
+ // Copies source to dest and returns a view of just the copied characters
7962
+ function $strcpy(dst, src) {
7963
+ if (typeof dst === 'string') {
7964
+ dst = $s(dst);
7965
+ }
7966
+ if (src instanceof Uint8Array) {
7967
+ for (var i = 0, l = src.length; i < l; i++) {
7968
+ dst[i] = src[i];
7969
+ }
7970
+ } else {
7971
+ for (var i = 0, l = src.length; i < l; i++) {
7972
+ dst[i] = src.charCodeAt(i);
7973
+ }
7974
+ }
7975
+ return src.length < dst.length ? dst.subarray(0, src.length) : dst;
7454
7976
  }
7455
-
7456
- function $or(a, b) { // or
7457
- return (typeof a === 'boolean') ? a || b : a | b;
7977
+ // cvi operator - converts a numeric string value to integer.
7978
+ function $cvi(s) {
7979
+ if (s instanceof Uint8Array) {
7980
+ // nul-chars on the end of a string are ignored by postscript but cause javascript
7981
+ // to return a zero result.
7982
+ return String.fromCharCode.apply(null, s).replace(/\0+$/, '') | 0;
7983
+ }
7984
+ return ('' + s) | 0;
7458
7985
  }
7459
7986
 
7460
- function $xo(a, b) { // xor
7461
- return (typeof a === 'boolean') ? !a && b || a && !b : a ^ b;
7987
+ // cvrs operator - convert a number to a radix string
7988
+ // s : string to store into
7989
+ // n : number
7990
+ // r : radix
7991
+ function $cvrs(s, n, r) {
7992
+ return $strcpy(s, (~~n).toString(r).toUpperCase());
7462
7993
  }
7463
7994
 
7464
- function $nt(a) {
7465
- return typeof a == 'boolean' ? !a : ~a;
7995
+ // get operator
7996
+ // s : source
7997
+ // k : key
7998
+ function $get(s, k) {
7999
+ if (s instanceof Uint8Array) {
8000
+ return s[k];
8001
+ }
8002
+ if (typeof s === 'string') {
8003
+ return s.charCodeAt(k);
8004
+ }
8005
+ if (s instanceof Array) {
8006
+ return s.b[s.o + k];
8007
+ }
8008
+ if (k instanceof Uint8Array) {
8009
+ return s.get($z(k));
8010
+ }
8011
+ return s.get(k);
7466
8012
  }
7467
- // emulate single-precision floating-point (pseudo-polyfill for Math.fround)
7468
- var $f = (function(fa) {
7469
- return function(v) {
7470
- return Number.isInteger(v) ? v : (fa[0] = v, fa[0]);
7471
- };
7472
- })(new Float32Array(1));
7473
8013
 
7474
- // This is a replacement for the BWIPP raiseerror function.
7475
- function bwipp_raiseerror() {
7476
- var info = $k[--$j];
7477
- var name = $k[--$j];
7478
- throw new Error($z(name) + ": " + $z(info));
8014
+ // put operator
8015
+ // d : dest
8016
+ // k : key
8017
+ // v : value
8018
+ function $put(d, k, v) {
8019
+ if (d instanceof Uint8Array) {
8020
+ d[k] = v;
8021
+ } else if (d instanceof Array) {
8022
+ d.b[d.o + k] = v;
8023
+ } else if (typeof d == 'object') {
8024
+ if (k instanceof Uint8Array) {
8025
+ d.set($z(k), v);
8026
+ } else {
8027
+ d.set(k, v);
8028
+ }
8029
+ } else {
8030
+ throw new Error('put-not-writable-' + (typeof d));
8031
+ }
7479
8032
  }
7480
8033
 
7481
- // This is a replacement for the BWIPP processoptions function.
7482
- // We cannot use the BWIPP version due to two reasons:
7483
- // - legacy code allows strings to be numbers and numbers to be strings
7484
- // - in javascript, there is no way to tell the difference between a real
7485
- // number that is an integer, and an actual integer.
7486
- //
7487
- // options currentdict processoptions exec -> options
7488
- function bwipp_processoptions() {
7489
- var dict = $k[--$j];
7490
- var opts = $k[$j - 1];
7491
- var map = opts instanceof Map;
7492
- for (var id in dict) {
7493
- var val;
7494
- if (map) {
7495
- if (!opts.has(id)) {
7496
- continue;
8034
+ // getinterval operator
8035
+ // s : src
8036
+ // o : offset
8037
+ // l : length
8038
+ function $geti(s, o, l) {
8039
+ if (s instanceof Uint8Array) {
8040
+ return s.subarray(o, o + l);
8041
+ }
8042
+ if (s instanceof Array) {
8043
+ var a = new Array(l);
8044
+ a.b = s.b; // base array
8045
+ a.o = s.o + o; // offset into base
8046
+ return a;
8047
+ }
8048
+ // Must be a string
8049
+ return s.substr(o, l);
8050
+ }
8051
+
8052
+ // putinterval operator
8053
+ // d : dst
8054
+ // o : offset
8055
+ // s : src
8056
+ function $puti(d, o, s) {
8057
+ if (d instanceof Uint8Array) {
8058
+ if (typeof s == 'string') {
8059
+ for (var i = 0, l = s.length; i < l; i++) {
8060
+ d[o + i] = s.charCodeAt(i);
7497
8061
  }
7498
- val = opts.get(id);
7499
8062
  } else {
7500
- if (!opts.hasOwnProperty(id)) {
7501
- continue;
8063
+ // When both d and s are the same, we want to copy
8064
+ // backwards, which works for the general case as well.
8065
+ for (var i = s.length - 1; i >= 0; i--) {
8066
+ d[o + i] = s[i];
7502
8067
  }
7503
- val = opts[id];
7504
8068
  }
7505
- var def = dict[id];
7506
- var typ = typeof def;
8069
+ } else if (d instanceof Array) {
8070
+ // Operate on the base arrays
8071
+ var darr = d.b;
8072
+ var doff = o + d.o;
8073
+ var sarr = s.b;
8074
+ var soff = s.o;
7507
8075
 
7508
- // null is a placeholder for realtype
7509
- if (def == null || typ == 'number') {
7510
- // This allows for numeric strings
7511
- if (!isFinite(+val)) {
7512
- throw new Error('bwipp.invalidOptionType: ' + id +
7513
- ': not a realtype: ' + val);
7514
- }
7515
- if (typeof val == 'string') {
7516
- val = +val;
7517
- map ? opts.set(id, val) : (opts[id] = val);
7518
- }
7519
- } else if (typ == 'boolean') {
7520
- if (val !== true && val !== false) {
7521
- // In keeping with the ethos of javascript, allow a more relaxed
7522
- // interpretation of boolean.
7523
- if (val == null || (val | 0) === val) {
7524
- val = !!val;
7525
- } else if (val == 'true') {
7526
- val = true;
7527
- } else if (val == 'false') {
7528
- val = false;
7529
- } else {
7530
- throw new Error('bwipp.invalidOptionType: ' + id +
7531
- ': not a booleantype: ' + val);
7532
- }
7533
- map ? opts.set(id, val) : (opts[id] = val);
7534
- }
7535
- } else if (typ == 'string' || def instanceof Uint8Array) {
7536
- // This allows numbers to be strings
7537
- if (typeof val == 'number') {
7538
- val = '' + val;
7539
- map ? opts.set(id, val) : (opts[id] = val);
7540
- } else if (typeof val != 'string' && !(val instanceof Uint8Array)) {
7541
- throw new Error('bwipp.invalidOptionType: ' + id +
7542
- ': not a stringtype: ' + val);
8076
+ for (var i = 0, l = s.length; i < l; i++) {
8077
+ darr[doff + i] = sarr[soff + i];
8078
+ }
8079
+ } else {
8080
+ throw new Error('putinterval-not-writable-' + (typeof d));
8081
+ }
8082
+ }
8083
+
8084
+ // type operator
8085
+ function $type(v) {
8086
+ // null can be mis-typed - get it out of the way
8087
+ if (v == null) {
8088
+ return 'nulltype';
8089
+ }
8090
+ var t = typeof v;
8091
+ if (t == 'number') {
8092
+ return v % 1 ? 'realtype' : 'integertype';
8093
+ }
8094
+ if (t == 'boolean') {
8095
+ return 'booleantype';
8096
+ }
8097
+ if (t == 'string' || v instanceof Uint8Array) {
8098
+ return 'stringtype';
8099
+ }
8100
+ if (t == 'function') {
8101
+ return 'operatortype';
8102
+ }
8103
+ if (v instanceof Array) {
8104
+ return 'arraytype';
8105
+ }
8106
+ return 'dicttype';
8107
+ // filetype
8108
+ // fonttype
8109
+ // gstatetype
8110
+ // marktype (v === Infinity)
8111
+ // nametype
8112
+ // savetype
8113
+ }
8114
+
8115
+ // search operator
8116
+ // string seek search suffix match prefix true %if-found
8117
+ // string false %if-not-found
8118
+ function $search(str, seek) {
8119
+ if (!(str instanceof Uint8Array)) {
8120
+ str = $s(str);
8121
+ }
8122
+ var ls = str.length;
8123
+
8124
+ // Virtually all uses of search in BWIPP are for single-characters.
8125
+ // Optimize for that case.
8126
+ if (seek.length == 1) {
8127
+ var lk = 1;
8128
+ var cd = seek instanceof Uint8Array ? seek[0] : seek.charCodeAt(0);
8129
+ for (var i = 0; i < ls && str[i] != cd; i++);
8130
+ } else {
8131
+ // Slow path,
8132
+ if (!(seek instanceof Uint8Array)) {
8133
+ seek = $s(seek);
8134
+ }
8135
+ var lk = seek.length;
8136
+ var cd = seek[0];
8137
+ for (var i = 0; i < ls && str[i] != cd; i++);
8138
+ while (i < ls) {
8139
+ for (var j = 1; j < lk && str[i + j] === seek[j]; j++);
8140
+ if (j === lk) {
8141
+ break;
7543
8142
  }
8143
+ for (i++; i < ls && str[i] != cd; i++);
7544
8144
  }
7545
- // Set the option into the dictionary
7546
- dict[id] = val;
8145
+ }
8146
+ if (i < ls) {
8147
+ $k[$j++] = str.subarray(i + lk);
8148
+ $k[$j++] = str.subarray(i, i + lk);
8149
+ $k[$j++] = str.subarray(0, i);
8150
+ $k[$j++] = true;
8151
+ } else {
8152
+ $k[$j++] = str;
8153
+ $k[$j++] = false;
7547
8154
  }
7548
8155
  }
7549
8156
 
7550
- // Replacement for loadctx which contains complex postscript operations
7551
- // that we don't implement correctly.
7552
- // f is a reference to the enclosing function.
7553
- function bwipp_loadctx(f) {
7554
- if (!f.$ctx) {
7555
- f.$ctx = {};
8157
+ // The callback is omitted when forall is being used just to push onto the
8158
+ // stack. The callback normally returns undefined. A return of true means break.
8159
+ function $forall(o, cb) {
8160
+ if (o instanceof Uint8Array) {
8161
+ for (var i = 0, l = o.length; i < l; i++) {
8162
+ $k[$j++] = o[i];
8163
+ if (cb && cb()) break;
8164
+ }
8165
+ } else if (o instanceof Array) {
8166
+ // The array may be a view.
8167
+ for (var a = o.b, i = o.o, l = o.o + o.length; i < l; i++) {
8168
+ $k[$j++] = a[i];
8169
+ if (cb && cb()) break;
8170
+ }
8171
+ } else if (typeof o === 'string') {
8172
+ for (var i = 0, l = o.length; i < l; i++) {
8173
+ $k[$j++] = o.charCodeAt(i);
8174
+ if (cb && cb()) break;
8175
+ }
8176
+ } else if (o instanceof Map) {
8177
+ for (var keys = o.keys(), i = 0, l = o.size; i < l; i++) {
8178
+ var id = keys.next().value;
8179
+ $k[$j++] = id;
8180
+ $k[$j++] = o.get(id);
8181
+ if (cb && cb()) break;
8182
+ }
8183
+ } else {
8184
+ for (var id in o) {
8185
+ $k[$j++] = id;
8186
+ $k[$j++] = o[id];
8187
+ if (cb && cb()) break;
8188
+ }
7556
8189
  }
7557
- var next = Object.getPrototypeOf($_);
7558
- Object.setPrototypeOf(f.$ctx, next);
7559
- Object.setPrototypeOf($_, f.$ctx);
7560
8190
  }
7561
8191
 
7562
- function bwipp_parseinput() {
7563
- $_ = Object.create($_); //#200
7564
- bwipp_loadctx(bwipp_parseinput); //#202
7565
- $_.fncvals = $k[--$j]; //#204
7566
- $_.barcode = $k[--$j]; //#205
7567
- var _2 = 'parse'; //#207
7568
- $_[_2] = $get($_.fncvals, _2); //#207
7569
- delete $_.fncvals[_2]; //#207
7570
- var _6 = 'parsefnc'; //#208
7571
- $_[_6] = $get($_.fncvals, _6); //#208
7572
- delete $_.fncvals[_6]; //#208
7573
- var _A = 'parseonly'; //#209
7574
- var _C = $get($_.fncvals, _A) !== undefined; //#209
7575
- $_[_A] = _C; //#209
7576
- delete $_.fncvals[_A]; //#209
7577
- var _E = 'eci'; //#210
7578
- var _G = $get($_.fncvals, _E) !== undefined; //#210
7579
- $_[_E] = _G; //#210
7580
- delete $_.fncvals[_E]; //#210
7581
- if (!bwipp_parseinput.__225__) { //#225
7582
- $_ = Object.create($_); //#225
7583
- $k[$j++] = Infinity; //#214
7584
- var _I = $a(['NUL', 'SOH', 'STX', 'ETX', 'EOT', 'ENQ', 'ACK', 'BEL', 'BS', 'TAB', 'LF', 'VT', 'FF', 'CR', "", "", 'DLE', 'DC1', 'DC2', 'DC3', 'DC4', 'NAK', 'SYN', 'ETB', 'CAN', 'EM', 'SUB', 'ESC', 'FS', 'GS', 'RS', 'US']); //#219
7585
- $k[$j++] = 0; //#223
7586
- for (var _J = 0, _K = _I.length; _J < _K; _J++) { //#223
7587
- var _M = $k[--$j]; //#222
7588
- $k[$j++] = $get(_I, _J); //#222
7589
- $k[$j++] = _M; //#222
7590
- $k[$j++] = $f(_M + 1); //#222
7591
- } //#222
7592
- $j--; //#223
7593
- $_.ctrl = $d(); //#224
7594
- for (var id in $_) $_.hasOwnProperty(id) && (bwipp_parseinput.$ctx[id] = $_[id]); //#224
7595
- bwipp_parseinput.__225__ = 1; //#224
7596
- $_ = Object.getPrototypeOf($_); //#224
7597
- } //#224
7598
- $_.msg = $a($_.barcode.length); //#227
7599
- $_.j = 0; //#228
7600
- $k[$j++] = $_.barcode; //#347
7601
- for (;;) { //#347
7602
- $search($k[--$j], "^"); //#230
7603
- var _T = $k[--$j]; //#230
7604
- var _U = $k[--$j]; //#230
7605
- $k[$j++] = _T; //#233
7606
- $k[$j++] = _U.length; //#233
7607
- $k[$j++] = $_.msg; //#233
7608
- $k[$j++] = $_.j; //#233
7609
- $k[$j++] = _U; //#233
7610
- $k[$j++] = Infinity; //#233
8192
+ function $cleartomark() {
8193
+ while ($j > 0 && $k[--$j] !== Infinity);
8194
+ }
8195
+
8196
+ function $counttomark() {
8197
+ for (var i = $j - 1; i >= 0 && $k[i] !== Infinity; i--);
8198
+ return $j - i - 1;
8199
+ }
8200
+
8201
+ function $aload(a) {
8202
+ for (var i = 0, l = a.length, b = a.b, o = a.o; i < l; i++) {
8203
+ $k[$j++] = b[o + i];
8204
+ }
8205
+ // This push has been optimized out. See $.aload() in psc.js.
8206
+ //$k[$j++] = a;
8207
+ }
8208
+
8209
+ function $astore(a) {
8210
+ for (var i = 0, l = a.length, b = a.b, o = a.o + l - 1; i < l; i++) {
8211
+ b[o - i] = $k[--$j];
8212
+ }
8213
+ $k[$j++] = a;
8214
+ }
8215
+
8216
+ function $eq(a, b) {
8217
+ if (typeof a === 'string' && typeof b === 'string') {
8218
+ return a == b;
8219
+ }
8220
+ if (a instanceof Uint8Array && b instanceof Uint8Array) {
8221
+ if (a.length != b.length) {
8222
+ return false;
8223
+ }
8224
+ for (var i = 0, l = a.length; i < l; i++) {
8225
+ if (a[i] != b[i]) {
8226
+ return false;
8227
+ }
8228
+ }
8229
+ return true;
8230
+ }
8231
+ if (a instanceof Uint8Array && typeof b === 'string' ||
8232
+ b instanceof Uint8Array && typeof a === 'string') {
8233
+ if (a instanceof Uint8Array) {
8234
+ a = $z(a);
8235
+ } else {
8236
+ b = $z(b);
8237
+ }
8238
+ return a == b;
8239
+ }
8240
+ return a == b;
8241
+ }
8242
+
8243
+ function $ne(a, b) {
8244
+ return !$eq(a, b);
8245
+ }
8246
+
8247
+ function $lt(a, b) {
8248
+ if (a instanceof Uint8Array) {
8249
+ a = $z(a);
8250
+ }
8251
+ if (b instanceof Uint8Array) {
8252
+ b = $z(b);
8253
+ }
8254
+ return a < b;
8255
+ }
8256
+
8257
+ function $le(a, b) {
8258
+ if (a instanceof Uint8Array) {
8259
+ a = $z(a);
8260
+ }
8261
+ if (b instanceof Uint8Array) {
8262
+ b = $z(b);
8263
+ }
8264
+ return a <= b;
8265
+ }
8266
+
8267
+ function $gt(a, b) {
8268
+ if (a instanceof Uint8Array) {
8269
+ a = $z(a);
8270
+ }
8271
+ if (b instanceof Uint8Array) {
8272
+ b = $z(b);
8273
+ }
8274
+ return a > b;
8275
+ }
8276
+
8277
+ function $ge(a, b) {
8278
+ if (a instanceof Uint8Array) {
8279
+ a = $z(a);
8280
+ }
8281
+ if (b instanceof Uint8Array) {
8282
+ b = $z(b);
8283
+ }
8284
+ return a >= b;
8285
+ }
8286
+
8287
+ function $an(a, b) { // and
8288
+ return (typeof a === 'boolean') ? a && b : a & b;
8289
+ }
8290
+
8291
+ function $or(a, b) { // or
8292
+ return (typeof a === 'boolean') ? a || b : a | b;
8293
+ }
8294
+
8295
+ function $xo(a, b) { // xor
8296
+ return (typeof a === 'boolean') ? !a && b || a && !b : a ^ b;
8297
+ }
8298
+
8299
+ function $nt(a) {
8300
+ return typeof a == 'boolean' ? !a : ~a;
8301
+ }
8302
+ // emulate single-precision floating-point (pseudo-polyfill for Math.fround)
8303
+ var $f = (function(fa) {
8304
+ return function(v) {
8305
+ return Number.isInteger(v) ? v : (fa[0] = v, fa[0]);
8306
+ };
8307
+ })(new Float32Array(1));
8308
+
8309
+ // This is a replacement for the BWIPP raiseerror function.
8310
+ function bwipp_raiseerror() {
8311
+ var info = $k[--$j];
8312
+ var name = $k[--$j];
8313
+ throw new Error($z(name) + ": " + $z(info));
8314
+ }
8315
+
8316
+ // This is a replacement for the BWIPP processoptions function.
8317
+ // We cannot use the BWIPP version due to two reasons:
8318
+ // - legacy code allows strings to be numbers and numbers to be strings
8319
+ // - in javascript, there is no way to tell the difference between a real
8320
+ // number that is an integer, and an actual integer.
8321
+ //
8322
+ // options currentdict processoptions exec -> options
8323
+ function bwipp_processoptions() {
8324
+ var dict = $k[--$j];
8325
+ var opts = $k[$j - 1];
8326
+ var map = opts instanceof Map;
8327
+ for (var id in dict) {
8328
+ var val;
8329
+ if (map) {
8330
+ if (!opts.has(id)) {
8331
+ continue;
8332
+ }
8333
+ val = opts.get(id);
8334
+ } else {
8335
+ if (!opts.hasOwnProperty(id)) {
8336
+ continue;
8337
+ }
8338
+ val = opts[id];
8339
+ }
8340
+ var def = dict[id];
8341
+ var typ = typeof def;
8342
+
8343
+ // null is a placeholder for realtype
8344
+ if (def == null || typ == 'number') {
8345
+ // This allows for numeric strings
8346
+ if (!isFinite(+val)) {
8347
+ throw new Error('bwipp.invalidOptionType: ' + id +
8348
+ ': not a realtype: ' + val);
8349
+ }
8350
+ if (typeof val == 'string') {
8351
+ val = +val;
8352
+ map ? opts.set(id, val) : (opts[id] = val);
8353
+ }
8354
+ } else if (typ == 'boolean') {
8355
+ if (val !== true && val !== false) {
8356
+ // In keeping with the ethos of javascript, allow a more relaxed
8357
+ // interpretation of boolean.
8358
+ if (val == null || (val | 0) === val) {
8359
+ val = !!val;
8360
+ } else if (val == 'true') {
8361
+ val = true;
8362
+ } else if (val == 'false') {
8363
+ val = false;
8364
+ } else {
8365
+ throw new Error('bwipp.invalidOptionType: ' + id +
8366
+ ': not a booleantype: ' + val);
8367
+ }
8368
+ map ? opts.set(id, val) : (opts[id] = val);
8369
+ }
8370
+ } else if (typ == 'string' || def instanceof Uint8Array) {
8371
+ // This allows numbers to be strings
8372
+ if (typeof val == 'number') {
8373
+ val = '' + val;
8374
+ map ? opts.set(id, val) : (opts[id] = val);
8375
+ } else if (typeof val != 'string' && !(val instanceof Uint8Array)) {
8376
+ throw new Error('bwipp.invalidOptionType: ' + id +
8377
+ ': not a stringtype: ' + val);
8378
+ }
8379
+ }
8380
+ // Set the option into the dictionary
8381
+ dict[id] = val;
8382
+ }
8383
+ }
8384
+
8385
+ // Replacement for loadctx which contains complex postscript operations
8386
+ // that we don't implement correctly.
8387
+ // f is a reference to the enclosing function.
8388
+ function bwipp_loadctx(f) {
8389
+ if (!f.$ctx) {
8390
+ f.$ctx = {};
8391
+ }
8392
+ var next = Object.getPrototypeOf($_);
8393
+ Object.setPrototypeOf(f.$ctx, next);
8394
+ Object.setPrototypeOf($_, f.$ctx);
8395
+ }
8396
+
8397
+ function bwipp_parseinput() {
8398
+ $_ = Object.create($_); //#200
8399
+ bwipp_loadctx(bwipp_parseinput); //#202
8400
+ $_.fncvals = $k[--$j]; //#204
8401
+ $_.barcode = $k[--$j]; //#205
8402
+ var _2 = 'parse'; //#207
8403
+ $_[_2] = $get($_.fncvals, _2); //#207
8404
+ delete $_.fncvals[_2]; //#207
8405
+ var _6 = 'parsefnc'; //#208
8406
+ $_[_6] = $get($_.fncvals, _6); //#208
8407
+ delete $_.fncvals[_6]; //#208
8408
+ var _A = 'parseonly'; //#209
8409
+ var _C = $get($_.fncvals, _A) !== undefined; //#209
8410
+ $_[_A] = _C; //#209
8411
+ delete $_.fncvals[_A]; //#209
8412
+ var _E = 'eci'; //#210
8413
+ var _G = $get($_.fncvals, _E) !== undefined; //#210
8414
+ $_[_E] = _G; //#210
8415
+ delete $_.fncvals[_E]; //#210
8416
+ if (!bwipp_parseinput.__225__) { //#225
8417
+ $_ = Object.create($_); //#225
8418
+ $k[$j++] = Infinity; //#214
8419
+ var _I = $a(['NUL', 'SOH', 'STX', 'ETX', 'EOT', 'ENQ', 'ACK', 'BEL', 'BS', 'TAB', 'LF', 'VT', 'FF', 'CR', "", "", 'DLE', 'DC1', 'DC2', 'DC3', 'DC4', 'NAK', 'SYN', 'ETB', 'CAN', 'EM', 'SUB', 'ESC', 'FS', 'GS', 'RS', 'US']); //#219
8420
+ $k[$j++] = 0; //#223
8421
+ for (var _J = 0, _K = _I.length; _J < _K; _J++) { //#223
8422
+ var _M = $k[--$j]; //#222
8423
+ $k[$j++] = $get(_I, _J); //#222
8424
+ $k[$j++] = _M; //#222
8425
+ $k[$j++] = $f(_M + 1); //#222
8426
+ } //#222
8427
+ $j--; //#223
8428
+ $_.ctrl = $d(); //#224
8429
+ for (var id in $_) $_.hasOwnProperty(id) && (bwipp_parseinput.$ctx[id] = $_[id]); //#224
8430
+ bwipp_parseinput.__225__ = 1; //#224
8431
+ $_ = Object.getPrototypeOf($_); //#224
8432
+ } //#224
8433
+ $_.msg = $a($_.barcode.length); //#227
8434
+ $_.j = 0; //#228
8435
+ $k[$j++] = $_.barcode; //#347
8436
+ for (;;) { //#347
8437
+ $search($k[--$j], "^"); //#230
8438
+ var _T = $k[--$j]; //#230
8439
+ var _U = $k[--$j]; //#230
8440
+ $k[$j++] = _T; //#233
8441
+ $k[$j++] = _U.length; //#233
8442
+ $k[$j++] = $_.msg; //#233
8443
+ $k[$j++] = $_.j; //#233
8444
+ $k[$j++] = _U; //#233
8445
+ $k[$j++] = Infinity; //#233
7611
8446
  var _X = $k[--$j]; //#233
7612
8447
  var _Y = $k[--$j]; //#233
7613
8448
  $k[$j++] = _X; //#233
@@ -16237,388 +17072,112 @@ function GetGlyph(font, codepoint, size_x, size_y) {
16237
17072
  var scale_y = size_y / font.ascent;
16238
17073
 
16239
17074
  var glyph = stbtt_FindGlyphIndex(font, codepoint);
16240
- if (!glyph && codepoint) {
16241
- return null;
16242
- }
16243
-
16244
- var vertices = stbtt_GetGlyphShape(font, glyph);
16245
- var rect = stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, 0, 0);
16246
- var width = rect.x1 - rect.x0;
16247
- var height = rect.y1 - rect.y0;
16248
- var pixels = null;
16249
-
16250
- if (width && height) {
16251
- var gbm = {
16252
- pixels : (pixels = new Uint8Array(width * height)),
16253
- w : width,
16254
- h : height,
16255
- stride : width,
16256
- };
16257
- stbtt_Rasterize(gbm, 0.35, vertices, scale_x, scale_y, 0, 0, rect.x0, rect.y0);
16258
- }
16259
-
16260
- var hmetrics = stbtt_GetGlyphHMetrics(font, glyph);
16261
- return {
16262
- glyph:glyph, pixels:pixels, width:width, height:height, top:-rect.y0, left:rect.x0,
16263
- advance:floor(hmetrics.advanceWidth * scale_x),
16264
- }
16265
- }
16266
- function GetPaths(font, codepoint, size_x, size_y) {
16267
- size_y = size_y || size_x;
16268
- var scale_x = size_x / font.ascent;
16269
- var scale_y = size_y / font.ascent;
16270
-
16271
- var glyph = stbtt_FindGlyphIndex(font, codepoint);
16272
- if (!glyph && codepoint) {
16273
- return null;
16274
- }
16275
- var vertices = stbtt_GetGlyphShape(font, glyph);
16276
- var hmetrics = stbtt_GetGlyphHMetrics(font, glyph);
16277
-
16278
- // The hmetrics just give us advance. We need ascent and descent as well.
16279
- var ascent = 0;
16280
- var descent = 0;
16281
-
16282
- // Convert to SVG notation
16283
- var paths = [];
16284
- if (vertices) {
16285
- for (var i = 0, l = vertices.length; i < l; i++) {
16286
- var v = vertices[i];
16287
- var path;
16288
- if (v.type == STBTT_vmove) {
16289
- path = { type:'M', x:v.x * scale_x, y:v.y * scale_y };
16290
- } else if (v.type == STBTT_vline) {
16291
- path = { type:'L', x:v.x * scale_x, y:v.y * scale_y };
16292
- } else if (v.type == STBTT_vcurve) {
16293
- path = { type:'Q', x:v.x * scale_x, y:v.y * scale_y,
16294
- cx:v.cx * scale_x, cy:v.cy * scale_y };
16295
- } else if (v.type == STBTT_vcubic) {
16296
- path = { type:'C', x:v.x * scale_x, y:v.y * scale_y,
16297
- cx1:v.cx * scale_x, cy1:v.cy * scale_y,
16298
- cx2:v.cx1 * scale_x, cy2:v.cy1 * scale_y };
16299
- } else {
16300
- continue;
16301
- }
16302
- if (path.y > ascent) ascent = path.y;
16303
- if (path.y < descent) descent = path.y;
16304
- paths.push(path);
16305
- }
16306
- }
16307
-
16308
- // Add the glyph metrics to the returned array.
16309
- paths.advance = hmetrics.advanceWidth * scale_x;
16310
- paths.ascent = ascent;
16311
- paths.descent = descent;
16312
- return paths;
16313
- }
16314
-
16315
-
16316
- // exports
16317
- return {
16318
- InitFont: InitFont,
16319
- GetGlyph: GetGlyph,
16320
- GetPaths: GetPaths,
16321
- }
16322
-
16323
- })();
16324
- function toUint8Array(data) {
16325
- if (typeof data == "string") {
16326
- var binary = /[^A-Za-z0-9+\/=\s]/.test(data);
16327
- var bstr = binary ? data : atob(data),
16328
- len = bstr.length,
16329
- bytes = new Uint8Array(len);
16330
- for (var i = 0; i < len; i++) {
16331
- bytes[i] = bstr.charCodeAt(i);
16332
- }
16333
- return bytes;
16334
- } else if (data instanceof Uint8Array) {
16335
- return data;
16336
- } else if (data instanceof ArrayBuffer) {
16337
- return new Uint8Array(data);
16338
- }
16339
- throw new ReferenceError("data must be a binary or base64 encoded string or Uint8Array");
16340
- }
16341
-
16342
- FontLib.loadFont("OCR-A", 100, 100, "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");
16343
- FontLib.loadFont("OCR-B", 96, 100, "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");
16344
- function ean13(opts,dwg) { return _ToAny(bwipp_ean13,opts,dwg); }function pdf417(opts,dwg) { return _ToAny(bwipp_pdf417,opts,dwg); }function qrcode(opts,dwg) { return _ToAny(bwipp_qrcode,opts,dwg); }
16345
-
16346
- class WidgetBase {
16347
- _widgetCallbacks;
16348
- widgetDeps;
16349
- static DEFAULTS = {
16350
- slide: null,
16351
- activateAfterCreate: false,
16352
- create: false,
16353
- localData: {},
16354
- };
16355
- static widgetIndex = 0;
16356
- env = WidgetBase.widgetsService.env;
16357
- options = null;
16358
- element = null;
16359
- elementId = null;
16360
- slide = null;
16361
- slideIndex = null;
16362
- disableTimer = null;
16363
- layoutDirection = "ltr";
16364
- cardId = null;
16365
- cardType = null;
16366
- widgetDone = null;
16367
- showWidgetCompleteToast = null;
16368
- submitButtonAnimatedView = null;
16369
- submitButtonView = null;
16370
- savedData = null;
16371
- localData = null;
16372
- firstOpenTime = 0;
16373
- id;
16374
- startReadyPromise = null;
16375
- startReadyResolve = null;
16376
- constructor(element, options, _widgetCallbacks, widgetDeps, elementIdGetter, slideGetter) {
16377
- this._widgetCallbacks = _widgetCallbacks;
16378
- this.widgetDeps = widgetDeps;
16379
- this.options = extend({}, this.constructor.DEFAULTS, options);
16380
- this.element = element;
16381
- if (elementIdGetter) {
16382
- this.elementId = elementIdGetter(this.element);
16383
- }
16384
- else {
16385
- this.elementId = getValueOrException(getTagData(this.element, "elementId"), "Empty elementId");
16386
- }
16387
- if (slideGetter) {
16388
- this.slide = slideGetter(this.element);
16389
- }
16390
- else {
16391
- this.slide = getValueOrException(this.element.closest(".narrative-slide"), "Empty slide");
16392
- }
16393
- this.slideIndex = getValueOrException(getTagDataAsNumber(this.slide, "index"), "Empty slideIndex");
16394
- this.disableTimer = getTagData(this.slide, "disableTimer") === "1";
16395
- this.cardId = getValueOrException(getTagDataAsNumber(this.slide, "id"), "Empty cardId");
16396
- this.cardType = getValueOrException(getTagDataAsNumber(this.slide, "cardType"), "Empty card type");
16397
- this.widgetDeps.getLayoutDirection();
16398
- this.element.dir = this.layoutDirection;
16399
- if (this.element.parentElement != null) {
16400
- this.widgetDone = this.element.parentElement?.nextElementSibling; // geometry + .widget-sent-toast
16401
- if (this.widgetDone) {
16402
- if (!this.widgetDone.classList.contains("widget-sent-toast")) {
16403
- this.widgetDone = null;
16404
- }
16405
- }
16406
- }
16407
- this.showWidgetCompleteToast = Boolean(getValueOrDefault(getTagDataAsNumber(this.element, "showWidgetCompleteToast"), 0));
16408
- if (!this.showWidgetCompleteToast) {
16409
- this.widgetDone = null;
16410
- }
16411
- if (this.element != null) {
16412
- this.submitButtonAnimatedView = this.element.querySelector(".submit-button-animated-view");
16413
- if (this.submitButtonAnimatedView != null) {
16414
- this.submitButtonView = this.submitButtonAnimatedView.querySelector(".submit-button-view");
16415
- }
16416
- }
16417
- this.savedData = this.widgetDeps.slideApiDeps.getCardServerData(this.cardId);
16418
- this.localData = extend({}, this.savedData ?? {}, this.options.localData ?? {});
16419
- this.id = `w_${this.elementId}_${WidgetBase.widgetIndex}`;
16420
- ++WidgetBase.widgetIndex;
16421
- this.resetStartReadyPromise();
16422
- }
16423
- get submitButtonViewHeight() {
16424
- if (this.submitButtonView != null) {
16425
- return this.submitButtonView.clientHeight;
16426
- }
16427
- return 0;
16428
- }
16429
- resetStartReadyPromise() {
16430
- this.startReadyPromise = new Promise(resolve => {
16431
- this.startReadyResolve = resolve;
16432
- });
16433
- }
16434
- /**
16435
- * Start or restart widget
16436
- * @param localData
16437
- */
16438
- onRefreshUserData(localData) {
16439
- this.savedData = this.widgetDeps.slideApiDeps.getCardServerData(this.cardId);
16440
- this.localData = extend({}, this.savedData ?? {}, localData);
16441
- }
16442
- onStart() {
16443
- this.startReadyResolve();
16444
- }
16445
- onStop() {
16446
- this.resetStartReadyPromise();
16447
- }
16448
- onPause() { }
16449
- onResume() { }
16450
- static widgetCacheKey = "ias.story-element";
16451
- static widgetClassName = "";
16452
- static getInstance(element) {
16453
- return data(element, this.widgetCacheKey);
16454
- }
16455
- static getInstanceById(slideRoot, id) {
16456
- const widgetsElements = slice.call(slideRoot.querySelectorAll(`.${this.widgetClassName}`));
16457
- let widget;
16458
- forEach(widgetsElements, (element, index) => {
16459
- const localWidget = data(element, this.widgetCacheKey);
16460
- if (localWidget && localWidget.id === id) {
16461
- widget = localWidget;
16462
- }
16463
- });
16464
- return widget;
16465
- }
16466
- static createInstance(instantiate, element, options) {
16467
- // get from objects cache (just Map<key, data> where key assigned to HTMLElement)
16468
- let instance = WidgetBase.getInstance(element);
16469
- if (instance == null) {
16470
- // can throw Error
16471
- instance = instantiate(element, options);
16472
- // save object in cache by key associated with HTMLElement
16473
- data(element, WidgetBase.widgetCacheKey, instance);
16474
- }
16475
- return instance;
16476
- }
16477
- static initWidget(htmlElement, localData, instantiate) {
16478
- const widget = this.createInstance(instantiate, htmlElement, {
16479
- slide: null,
16480
- localData,
16481
- });
16482
- // start widget (just created or cached instance)
16483
- widget.onRefreshUserData(localData);
16484
- return Promise.resolve(localData);
16485
- }
16486
- static get widgetsService() {
16487
- return container.get({ identifier: "WidgetsService" });
16488
- }
16489
- static getLocalData(slideApiDeps) {
16490
- return slideApiDeps.getCardLocalData();
16491
- }
16492
- getLocalData() {
16493
- return this.constructor.getLocalData(this.widgetDeps.slideApiDeps);
16494
- }
16495
- static setLocalData(slideApiDeps, keyValue, sendToServer, syncWithRuntimeLocalData) {
16496
- // push json object as string
16497
- if (sendToServer === undefined) {
16498
- sendToServer = true;
16499
- }
16500
- else {
16501
- sendToServer = Boolean(sendToServer);
16502
- }
16503
- if (syncWithRuntimeLocalData === undefined) {
16504
- syncWithRuntimeLocalData = true;
16505
- }
16506
- else {
16507
- syncWithRuntimeLocalData = Boolean(syncWithRuntimeLocalData);
16508
- }
16509
- if (syncWithRuntimeLocalData) {
16510
- this.getLocalData(slideApiDeps).then(localData => {
16511
- // 1 - old values, 2 - new values
16512
- keyValue = extend({}, localData, keyValue);
16513
- // todo make async via promise or async
16514
- slideApiDeps.setCardLocalData(keyValue, sendToServer);
16515
- });
16516
- }
16517
- else {
16518
- // todo make async via promise or async
16519
- slideApiDeps.setCardLocalData(keyValue, sendToServer);
16520
- }
16521
- }
16522
- setLocalData(keyValue, sendToServer, syncWithRuntimeLocalData) {
16523
- return this.constructor.setLocalData(this.widgetDeps.slideApiDeps, keyValue, sendToServer, syncWithRuntimeLocalData);
16524
- }
16525
- get statisticEventBaseFieldsShortForm() {
16526
- return WidgetBase.getStatisticEventBaseFieldsShortForm(this.cardId, this.cardType, this.slideIndex);
16527
- }
16528
- static getStatisticEventBaseFieldsShortForm(cardId, cardType, slideIndex) {
16529
- return {
16530
- i: cardId,
16531
- si: slideIndex,
16532
- ct: cardType,
16533
- };
16534
- }
16535
- get statisticEventBaseFieldsFullForm() {
16536
- return WidgetBase.getStatisticEventBaseFieldsFullForm(this.cardId, this.cardType, this.slideIndex);
16537
- }
16538
- static getStatisticEventBaseFieldsFullForm(cardId, cardType, slideIndex) {
16539
- const data = { slide_index: slideIndex };
16540
- switch (cardType) {
16541
- case 1 /* CARD_TYPE.STORY */:
16542
- case 2 /* CARD_TYPE.UGC_STORY */:
16543
- data.story_id = cardId;
16544
- break;
16545
- case 4 /* CARD_TYPE.IN_APP_MESSAGING */:
16546
- data.message_id = cardId;
16547
- break;
16548
- case 5 /* CARD_TYPE.BANNER */:
16549
- data.banner_id = cardId;
16550
- break;
16551
- }
16552
- return data;
16553
- }
16554
- static sendStatisticEventToApp(slideApiDeps, name, data, devPayload, options) {
16555
- sendStatisticEventToApp(slideApiDeps, name, data, devPayload, options);
16556
- }
16557
- sendStatisticEventToApp(name, data, devPayload, options) {
16558
- this.constructor.sendStatisticEventToApp(this.widgetDeps.slideApiDeps, name, data, devPayload, options);
16559
- }
16560
- onWidgetComplete() {
16561
- this._widgetCallbacks.onWidgetComplete(this.cardId, this.slideIndex);
16562
- }
16563
- onWidgetRequirePauseUI() {
16564
- this._widgetCallbacks.onWidgetRequirePauseUI(this.cardId, this.slideIndex);
17075
+ if (!glyph && codepoint) {
17076
+ return null;
16565
17077
  }
16566
- onWidgetRequireResumeUI() {
16567
- this._widgetCallbacks.onWidgetRequireResumeUI(this.cardId, this.slideIndex);
17078
+
17079
+ var vertices = stbtt_GetGlyphShape(font, glyph);
17080
+ var rect = stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, 0, 0);
17081
+ var width = rect.x1 - rect.x0;
17082
+ var height = rect.y1 - rect.y0;
17083
+ var pixels = null;
17084
+
17085
+ if (width && height) {
17086
+ var gbm = {
17087
+ pixels : (pixels = new Uint8Array(width * height)),
17088
+ w : width,
17089
+ h : height,
17090
+ stride : width,
17091
+ };
17092
+ stbtt_Rasterize(gbm, 0.35, vertices, scale_x, scale_y, 0, 0, rect.x0, rect.y0);
16568
17093
  }
16569
- _showLayer(layers, selectIndex, withStatEvent = false) {
16570
- if (this.widgetDeps.slideApiDeps.isExistsShowLayer()) {
16571
- this.widgetDeps.slideApiDeps.showLayer(selectIndex);
16572
- }
16573
- else {
16574
- forEach(layers, (layer, index) => {
16575
- if (index === selectIndex) {
16576
- layer.classList.remove("hidden");
16577
- this.widgetDeps.slideApiDeps.cardAnimation?.start(layer);
16578
- }
16579
- else {
16580
- layer.classList.add("hidden");
16581
- }
16582
- });
16583
- }
16584
- if (withStatEvent) {
16585
- this._statEventLayoutShow(selectIndex);
16586
- }
17094
+
17095
+ var hmetrics = stbtt_GetGlyphHMetrics(font, glyph);
17096
+ return {
17097
+ glyph:glyph, pixels:pixels, width:width, height:height, top:-rect.y0, left:rect.x0,
17098
+ advance:floor(hmetrics.advanceWidth * scale_x),
16587
17099
  }
16588
- _statEventLayoutShow(layoutIndex) {
16589
- try {
16590
- this.sendStatisticEventToApp("layout-show", {
16591
- ...this.statisticEventBaseFieldsShortForm,
16592
- li: layoutIndex,
16593
- }, {
16594
- ...this.statisticEventBaseFieldsFullForm,
16595
- layout_index: layoutIndex,
16596
- });
16597
- }
16598
- catch (error) {
16599
- console.error(error);
16600
- }
17100
+ }
17101
+ function GetPaths(font, codepoint, size_x, size_y) {
17102
+ size_y = size_y || size_x;
17103
+ var scale_x = size_x / font.ascent;
17104
+ var scale_y = size_y / font.ascent;
17105
+
17106
+ var glyph = stbtt_FindGlyphIndex(font, codepoint);
17107
+ if (!glyph && codepoint) {
17108
+ return null;
16601
17109
  }
16602
- static onRefreshUserData(element, localData) {
16603
- const widgetElement = element.closest(`.${this.widgetClassName}`);
16604
- if (widgetElement) {
16605
- const widget = WidgetBase.getInstance(widgetElement);
16606
- if (widget) {
16607
- widget.onRefreshUserData(localData);
17110
+ var vertices = stbtt_GetGlyphShape(font, glyph);
17111
+ var hmetrics = stbtt_GetGlyphHMetrics(font, glyph);
17112
+
17113
+ // The hmetrics just give us advance. We need ascent and descent as well.
17114
+ var ascent = 0;
17115
+ var descent = 0;
17116
+
17117
+ // Convert to SVG notation
17118
+ var paths = [];
17119
+ if (vertices) {
17120
+ for (var i = 0, l = vertices.length; i < l; i++) {
17121
+ var v = vertices[i];
17122
+ var path;
17123
+ if (v.type == STBTT_vmove) {
17124
+ path = { type:'M', x:v.x * scale_x, y:v.y * scale_y };
17125
+ } else if (v.type == STBTT_vline) {
17126
+ path = { type:'L', x:v.x * scale_x, y:v.y * scale_y };
17127
+ } else if (v.type == STBTT_vcurve) {
17128
+ path = { type:'Q', x:v.x * scale_x, y:v.y * scale_y,
17129
+ cx:v.cx * scale_x, cy:v.cy * scale_y };
17130
+ } else if (v.type == STBTT_vcubic) {
17131
+ path = { type:'C', x:v.x * scale_x, y:v.y * scale_y,
17132
+ cx1:v.cx * scale_x, cy1:v.cy * scale_y,
17133
+ cx2:v.cx1 * scale_x, cy2:v.cy1 * scale_y };
17134
+ } else {
17135
+ continue;
16608
17136
  }
17137
+ if (path.y > ascent) ascent = path.y;
17138
+ if (path.y < descent) descent = path.y;
17139
+ paths.push(path);
16609
17140
  }
16610
17141
  }
16611
- getPromotionalCodeFetchPath(promotionalCodeId) {
16612
- switch (this.cardType) {
16613
- case 4 /* CARD_TYPE.IN_APP_MESSAGING */:
16614
- return `inappmessaging/message/${this.cardId}/widget/${this.elementId}/promo-code/${promotionalCodeId}`;
16615
- default:
16616
- return `story/${this.cardId}/widget/${this.elementId}/promo-code/${promotionalCodeId}`;
17142
+
17143
+ // Add the glyph metrics to the returned array.
17144
+ paths.advance = hmetrics.advanceWidth * scale_x;
17145
+ paths.ascent = ascent;
17146
+ paths.descent = descent;
17147
+ return paths;
17148
+ }
17149
+
17150
+
17151
+ // exports
17152
+ return {
17153
+ InitFont: InitFont,
17154
+ GetGlyph: GetGlyph,
17155
+ GetPaths: GetPaths,
17156
+ }
17157
+
17158
+ })();
17159
+ function toUint8Array(data) {
17160
+ if (typeof data == "string") {
17161
+ var binary = /[^A-Za-z0-9+\/=\s]/.test(data);
17162
+ var bstr = binary ? data : atob(data),
17163
+ len = bstr.length,
17164
+ bytes = new Uint8Array(len);
17165
+ for (var i = 0; i < len; i++) {
17166
+ bytes[i] = bstr.charCodeAt(i);
16617
17167
  }
17168
+ return bytes;
17169
+ } else if (data instanceof Uint8Array) {
17170
+ return data;
17171
+ } else if (data instanceof ArrayBuffer) {
17172
+ return new Uint8Array(data);
16618
17173
  }
16619
- static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Partial`, `WidgetCallbacks`, `WidgetDeps`, `(element: HTMLElement) => string`, `(element: HTMLElement) => HTMLElement`]; }
17174
+ throw new ReferenceError("data must be a binary or base64 encoded string or Uint8Array");
16620
17175
  }
16621
17176
 
17177
+ FontLib.loadFont("OCR-A", 100, 100, "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");
17178
+ FontLib.loadFont("OCR-B", 96, 100, "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");
17179
+ function ean13(opts,dwg) { return _ToAny(bwipp_ean13,opts,dwg); }function pdf417(opts,dwg) { return _ToAny(bwipp_pdf417,opts,dwg); }function qrcode(opts,dwg) { return _ToAny(bwipp_qrcode,opts,dwg); }
17180
+
16622
17181
  class WidgetBarcode extends WidgetBase {
16623
17182
  static DEFAULTS = {
16624
17183
  slide: null,
@@ -19105,20 +19664,25 @@ class BottomSheet extends RenderableComponent {
19105
19664
  return this._isOpened;
19106
19665
  }
19107
19666
  renderTemplate() {
19667
+ // TODO: calculate border-radius;
19668
+ const borderRadius = 30;
19108
19669
  return h("div", { class: `ias-bottom-sheet ${this._isOpened ? "ias-bottom-sheet--open" : ""}` }, h("div", {
19109
19670
  class: "ias-bottom-sheet__backdrop",
19110
19671
  onClick: this.handleBackdropClick,
19111
- }), h("div", { class: "ias-bottom-sheet__container" }, h("div", { class: "ias-bottom-sheet__content" },
19672
+ }), h("div", {
19673
+ class: "ias-bottom-sheet__container",
19674
+ style: this.props.minHeight != null ? `min-height: ${this.props.minHeight + borderRadius}px` : "",
19675
+ }, h("div", { class: "ias-bottom-sheet__content" },
19112
19676
  /* h("div", { class: "ias-bottom-sheet__header" }), */
19113
19677
  h("div", { class: "ias-bottom-sheet__body" }, ...(this.props?.children?.map(c => c.render()) ?? [])))));
19114
19678
  }
19115
- setHeight(height) {
19679
+ setMinHeight(height) {
19116
19680
  if (!this._root)
19117
19681
  return;
19118
19682
  const container = this._root.querySelector(".ias-bottom-sheet__container");
19119
19683
  if (!container)
19120
19684
  return;
19121
- container.style.height = height;
19685
+ container.style.minHeight = `${height}px`;
19122
19686
  }
19123
19687
  open() {
19124
19688
  if (this.isOpened)
@@ -19176,6 +19740,7 @@ const ADD_TO_CART_TIMEOUT = 60000;
19176
19740
 
19177
19741
  class ProductDetailsPurchaseAction extends RenderableComponent {
19178
19742
  button;
19743
+ isLoading = false;
19179
19744
  constructor(props) {
19180
19745
  super(props);
19181
19746
  }
@@ -19188,7 +19753,10 @@ class ProductDetailsPurchaseAction extends RenderableComponent {
19188
19753
  return this.button;
19189
19754
  }
19190
19755
  handleClickAddToCart = async () => {
19756
+ if (this.isLoading)
19757
+ return;
19191
19758
  try {
19759
+ this.isLoading = true;
19192
19760
  this.showLoader();
19193
19761
  await this.addToCart();
19194
19762
  }
@@ -19197,6 +19765,7 @@ class ProductDetailsPurchaseAction extends RenderableComponent {
19197
19765
  }
19198
19766
  finally {
19199
19767
  this.hideLoader();
19768
+ this.isLoading = false;
19200
19769
  }
19201
19770
  };
19202
19771
  showLoader() {
@@ -19364,7 +19933,7 @@ class ProductOptionsManager {
19364
19933
  selectOption(option) {
19365
19934
  const compatibleVariants = this.findCompatibleVariants(option);
19366
19935
  this.ensureVariantsExist(option, compatibleVariants);
19367
- const matchingVariant = this.findMatchingVariant(compatibleVariants);
19936
+ const matchingVariant = this.findMatchingVariant(compatibleVariants, option);
19368
19937
  this.selectVariant(matchingVariant);
19369
19938
  }
19370
19939
  selectVariant(variant) {
@@ -19402,8 +19971,15 @@ class ProductOptionsManager {
19402
19971
  throw new Error(`[IAS]: No compatible variant for option <${option.name}:${option.value}>`);
19403
19972
  }
19404
19973
  }
19405
- findMatchingVariant(variants) {
19406
- return (variants.find(variant => this.optionNames.every(name => !this.selectedOptions[name] || variant.options[name]?.value === this.selectedOptions[name]?.value)) ?? variants[0]);
19974
+ findMatchingVariant(variants, option) {
19975
+ return (variants.find(variant => this.optionNames.every(optionName => {
19976
+ if (optionName === option.name) {
19977
+ return variant.options[optionName]?.value === option.value;
19978
+ }
19979
+ else {
19980
+ return this.selectedOptions[optionName]?.value === variant.options[optionName]?.value;
19981
+ }
19982
+ })) ?? variants[0]);
19407
19983
  }
19408
19984
  extractAvailableOptions() {
19409
19985
  const result = {};
@@ -19582,50 +20158,6 @@ class ProductDetails extends RenderableComponent {
19582
20158
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`ProductDetailsProps`]; }
19583
20159
  }
19584
20160
 
19585
- class ProductOfferMapper {
19586
- static fromOfferDtoToProductOffer(offerDto) {
19587
- return {
19588
- id: offerDto.id.toString(),
19589
- offerId: offerDto.offerId,
19590
- available: offerDto.availability !== 0,
19591
- availability: offerDto.availability,
19592
- options: {
19593
- color: offerDto.color ? { name: "color", value: offerDto.color } : { name: "color", value: "Undefined" },
19594
- size: offerDto.size ? { name: "size", value: offerDto.size } : { name: "size", value: "Undefined" },
19595
- },
19596
- name: offerDto.name,
19597
- price: offerDto.price,
19598
- oldPrice: offerDto.oldPrice,
19599
- currency: offerDto.currency,
19600
- description: offerDto.description,
19601
- imageUrls: offerDto.images?.map(image => image.url) ?? [],
19602
- adult: offerDto.adult,
19603
- coverUrl: offerDto.coverUrl,
19604
- groupId: offerDto.groupId,
19605
- url: offerDto.url,
19606
- };
19607
- }
19608
- static fromOfferDtoToProductCartOffer(offerDto, quantity) {
19609
- return {
19610
- offerId: offerDto.offerId,
19611
- imageUrls: offerDto.images?.map(image => image.url) ?? [],
19612
- availability: offerDto.availability,
19613
- quantity,
19614
- groupId: offerDto.groupId,
19615
- name: offerDto.name,
19616
- description: offerDto.description,
19617
- url: offerDto.url,
19618
- coverUrl: offerDto.coverUrl,
19619
- currency: offerDto.currency,
19620
- price: offerDto.price,
19621
- oldPrice: offerDto.oldPrice,
19622
- adult: offerDto.adult,
19623
- size: offerDto.size,
19624
- color: offerDto.color,
19625
- };
19626
- }
19627
- }
19628
-
19629
20161
  const successSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none"><path stroke="#212121" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M40 14 18 36 8 26"></path></svg>`;
19630
20162
  class ProductCheckout extends RenderableComponent {
19631
20163
  constructor(props) {
@@ -19705,21 +20237,20 @@ class ProductComponentsFactory {
19705
20237
  this.widgetDeps = widgetDeps;
19706
20238
  this.props = props;
19707
20239
  }
19708
- createBottomSheet() {
20240
+ createBottomSheet(props) {
19709
20241
  const bs = new BottomSheet({
19710
20242
  onClose: () => {
19711
20243
  bs.destroy();
19712
20244
  },
19713
20245
  children: [],
20246
+ minHeight: props.minHeight,
19714
20247
  });
19715
20248
  return bs;
19716
20249
  }
19717
20250
  createProductDetails(params) {
19718
20251
  return new ProductDetails({
19719
- product: ProductOfferMapper.fromOfferDtoToProductOffer(params.offer),
19720
- relatedProducts: params.offer.subOffersApi
19721
- ? params.offer.subOffersApi.map(subOffer => ProductOfferMapper.fromOfferDtoToProductOffer(subOffer))
19722
- : [],
20252
+ product: params.product,
20253
+ relatedProducts: params.relatedProducts,
19723
20254
  onAddToCart: params.onAddToCart,
19724
20255
  onAddToCartError: ({ error }) => {
19725
20256
  this.widgetDeps.slideApiDeps.showToast(error.message);
@@ -19727,8 +20258,8 @@ class ProductComponentsFactory {
19727
20258
  translations: this.props.translations,
19728
20259
  isCartSupported: params.isCartSupported,
19729
20260
  onOpenUrl: () => {
19730
- if (params.offer.url)
19731
- this.widgetDeps.slideApiDeps.openUrl({ type: "link", link: { type: "url", target: params.offer.url } });
20261
+ if (params.product.url)
20262
+ this.widgetDeps.slideApiDeps.openUrl({ type: "link", link: { type: "url", target: params.product.url } });
19732
20263
  },
19733
20264
  });
19734
20265
  }
@@ -19767,6 +20298,50 @@ class ProductComponentsFactory {
19767
20298
  }`]; }
19768
20299
  }
19769
20300
 
20301
+ class ProductOfferMapper {
20302
+ static fromOfferDtoToProductOffer(offerDto) {
20303
+ return {
20304
+ id: offerDto.id.toString(),
20305
+ offerId: offerDto.offerId,
20306
+ available: offerDto.availability !== 0,
20307
+ availability: offerDto.availability,
20308
+ options: {
20309
+ color: offerDto.color ? { name: "color", value: offerDto.color } : { name: "color", value: "Undefined" },
20310
+ size: offerDto.size ? { name: "size", value: offerDto.size } : { name: "size", value: "Undefined" },
20311
+ },
20312
+ name: offerDto.name,
20313
+ price: offerDto.price,
20314
+ oldPrice: offerDto.oldPrice,
20315
+ currency: offerDto.currency,
20316
+ description: offerDto.description,
20317
+ imageUrls: offerDto.images?.map(image => image.url) ?? [],
20318
+ adult: offerDto.adult,
20319
+ coverUrl: offerDto.coverUrl,
20320
+ groupId: offerDto.groupId,
20321
+ url: offerDto.url,
20322
+ };
20323
+ }
20324
+ static fromOfferDtoToProductCartOffer(offerDto, quantity) {
20325
+ return {
20326
+ offerId: offerDto.offerId,
20327
+ imageUrls: offerDto.images?.map(image => image.url) ?? [],
20328
+ availability: offerDto.availability,
20329
+ quantity,
20330
+ groupId: offerDto.groupId,
20331
+ name: offerDto.name,
20332
+ description: offerDto.description,
20333
+ url: offerDto.url,
20334
+ coverUrl: offerDto.coverUrl,
20335
+ currency: offerDto.currency,
20336
+ price: offerDto.price,
20337
+ oldPrice: offerDto.oldPrice,
20338
+ adult: offerDto.adult,
20339
+ size: offerDto.size,
20340
+ color: offerDto.color,
20341
+ };
20342
+ }
20343
+ }
20344
+
19770
20345
  class ProductDetailsBottomSheet extends RenderableComponent {
19771
20346
  widgetDeps;
19772
20347
  factory;
@@ -19775,7 +20350,7 @@ class ProductDetailsBottomSheet extends RenderableComponent {
19775
20350
  super(props);
19776
20351
  this.widgetDeps = widgetDeps;
19777
20352
  this.factory = new ProductComponentsFactory(this.widgetDeps, this.props);
19778
- this.bottomSheet = this.factory.createBottomSheet();
20353
+ this.bottomSheet = this.factory.createBottomSheet({ minHeight: props.height });
19779
20354
  }
19780
20355
  renderTemplate() {
19781
20356
  return this.bottomSheet.render();
@@ -19790,8 +20365,10 @@ class ProductDetailsBottomSheet extends RenderableComponent {
19790
20365
  this.renderProductDetails({ factory, offer, offerDtos, isCartSupported });
19791
20366
  };
19792
20367
  renderProductDetails({ factory, offer, offerDtos, isCartSupported, }) {
20368
+ const { product, relatedProducts } = this.getProductAndRelatedProducts(offer);
19793
20369
  const productDetails = factory.createProductDetails({
19794
- offer,
20370
+ product,
20371
+ relatedProducts,
19795
20372
  onAddToCart: async (payload) => {
19796
20373
  await this.productCartUpdate({
19797
20374
  offerDtos,
@@ -19807,7 +20384,6 @@ class ProductDetailsBottomSheet extends RenderableComponent {
19807
20384
  showProductCheckout({ offerDtos }) {
19808
20385
  const productCheckout = this.factory.createProductCheckout(this.bottomSheet, offerDtos);
19809
20386
  this.updateBottomSheetContent(productCheckout);
19810
- this.bottomSheet.setHeight("auto");
19811
20387
  }
19812
20388
  updateBottomSheetContent(content) {
19813
20389
  const cartButton = this.factory.createProductCartButton();
@@ -19830,6 +20406,16 @@ class ProductDetailsBottomSheet extends RenderableComponent {
19830
20406
  ]);
19831
20407
  return productCart.offers;
19832
20408
  }
20409
+ getProductAndRelatedProducts(offerDto) {
20410
+ return {
20411
+ product: ProductOfferMapper.fromOfferDtoToProductOffer(offerDto),
20412
+ relatedProducts: offerDto.subOffersApi
20413
+ ? offerDto.subOffersApi
20414
+ .filter(subOffer => subOffer.size != null && subOffer.color != null)
20415
+ .map(subOffer => ProductOfferMapper.fromOfferDtoToProductOffer(subOffer))
20416
+ : [],
20417
+ };
20418
+ }
19833
20419
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`WidgetDeps`, `ProductDetailsBottomSheetProps`]; }
19834
20420
  }
19835
20421
 
@@ -19898,6 +20484,7 @@ class WidgetProducts extends WidgetBase {
19898
20484
  }
19899
20485
  onStart() {
19900
20486
  super.onStart();
20487
+ this.isLoading = false;
19901
20488
  // reinit for case when we returned to slide from other slide and onStop destroyed SwipeGestureDetector
19902
20489
  this.initSwipeGestureDetector();
19903
20490
  }
@@ -19982,6 +20569,16 @@ class WidgetProducts extends WidgetBase {
19982
20569
  console.error(error);
19983
20570
  }
19984
20571
  }
20572
+ async getOrFetchProducts() {
20573
+ if (this.currentModels.length > 0)
20574
+ return this.currentModels;
20575
+ const result = await this.fetchProducts();
20576
+ if (result.models.length > 0) {
20577
+ this.currentModels = result.models;
20578
+ return result.models;
20579
+ }
20580
+ throw new Error(result.message);
20581
+ }
19985
20582
  async fetchProducts() {
19986
20583
  const fetchAndCacheMedia = async () => {
19987
20584
  if (!this.linkTarget.length) {
@@ -20096,12 +20693,13 @@ class WidgetProducts extends WidgetBase {
20096
20693
  }
20097
20694
  productsView = null;
20098
20695
  isOpen = false;
20696
+ isLoading = false;
20099
20697
  get isForcePaused() {
20100
20698
  return this.isOpen;
20101
20699
  }
20102
20700
  currentModels = [];
20103
20701
  async openProductsView() {
20104
- if (this.isOpen) {
20702
+ if (this.isOpen || this.isLoading) {
20105
20703
  return;
20106
20704
  }
20107
20705
  this._statEventWidgetClick();
@@ -20111,14 +20709,10 @@ class WidgetProducts extends WidgetBase {
20111
20709
  if (!this.isTransparentElement()) {
20112
20710
  this.element.classList.add("loader");
20113
20711
  }
20114
- // const start = window.performance.now();
20115
- const result = await this.fetchProducts();
20116
- // @ts-ignore
20117
- // _log(`fetched for ${window.performance.now() - start}ms`, true);
20118
- // console.log({result})
20119
- if (result.models.length > 0) {
20120
- this.currentModels = result.models;
20121
- this.productsView = this.createProductsView(this.currentModels, this.closeProductsView.bind(this));
20712
+ try {
20713
+ this.isLoading = true;
20714
+ const models = await this.getOrFetchProducts();
20715
+ this.productsView = this.createProductsView(models, this.closeProductsView.bind(this));
20122
20716
  this.productsView.classList.add("ias-products-container-view--visible");
20123
20717
  this.slide.appendChild(this.productsView);
20124
20718
  this.element.classList.add("hidden");
@@ -20128,15 +20722,16 @@ class WidgetProducts extends WidgetBase {
20128
20722
  this.widgetDeps.slideApiDeps.disableHorizontalSwipeGesture();
20129
20723
  this.widgetDeps.slideApiDeps.disableVerticalSwipeGesture();
20130
20724
  this.widgetDeps.slideApiDeps.disableBackpress();
20131
- this._statEventWidgetOpen(this.currentModels);
20725
+ this._statEventWidgetOpen(models);
20132
20726
  this.initSwipeGestureDetector();
20133
20727
  }
20134
- else {
20135
- if (result.message) {
20136
- this.widgetDeps.slideApiDeps.showToast(result.message);
20137
- }
20728
+ catch (error) {
20729
+ this.widgetDeps.slideApiDeps.showToast(error.message);
20730
+ }
20731
+ finally {
20732
+ this.isLoading = false;
20733
+ this.element.classList.remove("loader");
20138
20734
  }
20139
- this.element.classList.remove("loader");
20140
20735
  }
20141
20736
  closeProductsView() {
20142
20737
  if (!this.isOpen) {
@@ -20221,6 +20816,11 @@ class WidgetProducts extends WidgetBase {
20221
20816
  showProductDetails = ({ card, offer }) => {
20222
20817
  if (!this.productsView)
20223
20818
  return;
20819
+ const backgroundView = this.slide.querySelector(".ias-products-container-background-view");
20820
+ const scrollViewGroup = this.slide.querySelector(".ias-products-scroll-view-group");
20821
+ const backgroundViewHeight = backgroundView?.clientHeight ?? 0;
20822
+ let scrollViewGroupHeight = scrollViewGroup?.offsetTop ?? 0;
20823
+ scrollViewGroupHeight = scrollViewGroupHeight > 0 ? 0 : -scrollViewGroupHeight;
20224
20824
  const bs = new ProductDetailsBottomSheet(this.widgetDeps, {
20225
20825
  translations: {
20226
20826
  color: getTagData(this.element, "msgColor") ?? "",
@@ -20233,6 +20833,7 @@ class WidgetProducts extends WidgetBase {
20233
20833
  continueBtn: getTagData(this.element, "msgContinue") ?? "",
20234
20834
  openUrl: getTagData(this.element, "msgOpenUrl") ?? "",
20235
20835
  },
20836
+ height: backgroundViewHeight + scrollViewGroupHeight,
20236
20837
  });
20237
20838
  const isCartEnabled = getTagData(this.element, "isCartEnabled") === "true";
20238
20839
  const isCartSupported = this.widgetDeps.slideApiDeps.isSdkSupportProductCart && isCartEnabled;
@@ -23340,6 +23941,9 @@ class EsModuleLayoutApi {
23340
23941
  get widgetTooltipApi() {
23341
23942
  return WidgetTooltip.api;
23342
23943
  }
23944
+ get widgetTimerApi() {
23945
+ return WidgetTimer.api;
23946
+ }
23343
23947
  get VideoPlayer() {
23344
23948
  return this.slideApiPeerDeps().VODPlayer;
23345
23949
  }