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