@microsoft/omnichannel-chat-widget 0.1.0-main.47ede4d → 0.1.0-main.72620c9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/lib/cjs/common/Constants.js +32 -4
  2. package/lib/cjs/common/telemetry/TelemetryConstants.js +13 -1
  3. package/lib/cjs/common/telemetry/TelemetryHelper.js +13 -0
  4. package/lib/cjs/common/telemetry/TelemetryManager.js +4 -1
  5. package/lib/cjs/common/telemetry/defaultConfigs/defaultTelemetryConfiguration.js +4 -1
  6. package/lib/cjs/common/telemetry/loggers/ariaTelemetryLogger.js +31 -10
  7. package/lib/cjs/common/utils.js +15 -2
  8. package/lib/cjs/components/confirmationpanestateful/ConfirmationPaneStateful.js +4 -39
  9. package/lib/cjs/components/footerstateful/FooterStateful.js +1 -2
  10. package/lib/cjs/components/headerstateful/HeaderStateful.js +1 -7
  11. package/lib/cjs/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +5 -2
  12. package/lib/cjs/components/livechatwidget/common/endChat.js +37 -1
  13. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +3 -0
  14. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +105 -20
  15. package/lib/cjs/components/livechatwidget/common/registerTelemetryLoggers.js +3 -15
  16. package/lib/cjs/components/livechatwidget/common/startChat.js +38 -29
  17. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +57 -15
  18. package/lib/cjs/components/postchatloadingpanestateful/PostChatLoadingPaneStateful.js +8 -0
  19. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger.js +44 -0
  20. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +15 -16
  21. package/lib/cjs/contexts/createReducer.js +0 -7
  22. package/lib/esm/common/Constants.js +28 -3
  23. package/lib/esm/common/telemetry/TelemetryConstants.js +13 -1
  24. package/lib/esm/common/telemetry/TelemetryHelper.js +13 -1
  25. package/lib/esm/common/telemetry/TelemetryManager.js +4 -1
  26. package/lib/esm/common/telemetry/defaultConfigs/defaultTelemetryConfiguration.js +4 -1
  27. package/lib/esm/common/telemetry/loggers/ariaTelemetryLogger.js +33 -13
  28. package/lib/esm/common/utils.js +11 -1
  29. package/lib/esm/components/confirmationpanestateful/ConfirmationPaneStateful.js +7 -37
  30. package/lib/esm/components/footerstateful/FooterStateful.js +1 -2
  31. package/lib/esm/components/headerstateful/HeaderStateful.js +1 -7
  32. package/lib/esm/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +5 -3
  33. package/lib/esm/components/livechatwidget/common/endChat.js +37 -3
  34. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +2 -0
  35. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +94 -20
  36. package/lib/esm/components/livechatwidget/common/registerTelemetryLoggers.js +3 -13
  37. package/lib/esm/components/livechatwidget/common/startChat.js +39 -30
  38. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +55 -17
  39. package/lib/esm/components/postchatloadingpanestateful/PostChatLoadingPaneStateful.js +6 -0
  40. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger.js +31 -0
  41. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +15 -16
  42. package/lib/esm/contexts/createReducer.js +0 -7
  43. package/lib/types/common/Constants.d.ts +16 -1
  44. package/lib/types/common/interfaces/IContextDataStore.d.ts +1 -1
  45. package/lib/types/common/telemetry/TelemetryConstants.d.ts +9 -2
  46. package/lib/types/common/telemetry/TelemetryHelper.d.ts +1 -0
  47. package/lib/types/common/telemetry/interfaces/ITelemetryConfig.d.ts +3 -3
  48. package/lib/types/common/utils.d.ts +1 -0
  49. package/lib/types/components/confirmationpanestateful/interfaces/IConfirmationPaneStatefulParams.d.ts +4 -4
  50. package/lib/types/components/footerstateful/audionotificationstateful/interfaces/IAudioNotificationStatefulParams.d.ts +0 -1
  51. package/lib/types/components/livechatwidget/common/endChat.d.ts +4 -1
  52. package/lib/types/components/livechatwidget/common/reconnectChatHelper.d.ts +5 -2
  53. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetComponentOverrides.d.ts +1 -0
  54. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +1 -1
  55. package/lib/types/components/reconnectchatpanestateful/interfaces/IReconnectChatPaneStatefulProps.d.ts +1 -0
  56. package/lib/types/components/webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger.d.ts +1 -0
  57. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +15 -16
  58. package/package.json +6 -7
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.WebChatMiddlewareConstants = exports.TranscriptConstants = exports.Regex = exports.MimeTypes = exports.LocaleConstants = exports.HtmlIdNames = exports.HtmlElementSelectors = exports.HtmlClassNames = exports.HtmlAttributeNames = exports.ElementType = exports.Constants = exports.ChatSDKError = void 0;
6
+ exports.WebChatMiddlewareConstants = exports.TranscriptConstants = exports.Regex = exports.MimeTypes = exports.LocaleConstants = exports.HtmlIdNames = exports.HtmlElementSelectors = exports.HtmlClassNames = exports.HtmlAttributeNames = exports.EnvironmentVersion = exports.ElementType = exports.Constants = exports.ChatSDKError = exports.AriaTelemetryConstants = void 0;
7
7
 
8
8
  var _class;
9
9
 
@@ -131,8 +131,6 @@ _defineProperty(Constants, "InputSubmit", "InputSubmit");
131
131
 
132
132
  _defineProperty(Constants, "ReconnectIdAttributeName", "oc.reconnectid");
133
133
 
134
- _defineProperty(Constants, "redirectPageRequest", "redirectPageRequest");
135
-
136
134
  _defineProperty(Constants, "LiveChatWidget", "LiveChatWidgetNew");
137
135
 
138
136
  _defineProperty(Constants, "GuidPattern", "xx-x-4m-ym-xxx");
@@ -284,6 +282,16 @@ exports.ChatSDKError = ChatSDKError;
284
282
  ChatSDKError["WidgetUseOutsideOperatingHour"] = "WidgetUseOutsideOperatingHour";
285
283
  })(ChatSDKError || (exports.ChatSDKError = ChatSDKError = {}));
286
284
 
285
+ let EnvironmentVersion;
286
+ exports.EnvironmentVersion = EnvironmentVersion;
287
+
288
+ (function (EnvironmentVersion) {
289
+ EnvironmentVersion["prod"] = "prod";
290
+ EnvironmentVersion["dogfood"] = "df";
291
+ EnvironmentVersion["int"] = "int";
292
+ EnvironmentVersion["test"] = "test";
293
+ })(EnvironmentVersion || (exports.EnvironmentVersion = EnvironmentVersion = {}));
294
+
287
295
  class TranscriptConstants {}
288
296
 
289
297
  exports.TranscriptConstants = TranscriptConstants;
@@ -306,4 +314,24 @@ _defineProperty(TranscriptConstants, "InternalMode", "internal");
306
314
 
307
315
  _defineProperty(TranscriptConstants, "AgentDialogColor", "#2266E3");
308
316
 
309
- _defineProperty(TranscriptConstants, "AgentFontColor", "white");
317
+ _defineProperty(TranscriptConstants, "AgentFontColor", "white");
318
+
319
+ class AriaTelemetryConstants {}
320
+
321
+ exports.AriaTelemetryConstants = AriaTelemetryConstants;
322
+
323
+ _defineProperty(AriaTelemetryConstants, "GERMANY_ENDPOINT", "https://de.pipe.aria.microsoft.com/Collector/3.0/");
324
+
325
+ _defineProperty(AriaTelemetryConstants, "GCCH_ENDPOINT", "https://tb.pipe.aria.microsoft.com/Collector/3.0/");
326
+
327
+ _defineProperty(AriaTelemetryConstants, "DOD_ENDPOINT", "https://pf.pipe.aria.microsoft.com/Collector/3.0");
328
+
329
+ _defineProperty(AriaTelemetryConstants, "EUROPE_ENDPOINT", "https://eu-mobile.events.data.microsoft.com/Collector/3.0/");
330
+
331
+ _defineProperty(AriaTelemetryConstants, "MOONCAKE_ENDPOINT", "");
332
+
333
+ _defineProperty(AriaTelemetryConstants, "Public", "Public");
334
+
335
+ _defineProperty(AriaTelemetryConstants, "EU", "Europe");
336
+
337
+ _defineProperty(AriaTelemetryConstants, "lcwEUDomainNames", ["crm4.omnichannelengagementhub.com", "crm12.omnichannelengagementhub.com", "crm16.omnichannelengagementhub.com", "crm17.omnichannelengagementhub.com", "crm19.omnichannelengagementhub.com"]);
@@ -37,7 +37,7 @@ exports.BroadcastEvent = BroadcastEvent;
37
37
 
38
38
  (function (BroadcastEvent) {
39
39
  BroadcastEvent["LoadPostChatSurvey"] = "LoadPostChatSurvey";
40
- BroadcastEvent["EndChat"] = "EndChat";
40
+ BroadcastEvent["EndChat"] = "ChatEnded";
41
41
  BroadcastEvent["NewMessageNotification"] = "NewMessageNotification";
42
42
  BroadcastEvent["UnreadMessageCount"] = "UnreadMessageCount";
43
43
  BroadcastEvent["ChatWidgetStateChanged"] = "ChatWidgetStateChanged";
@@ -46,6 +46,9 @@ exports.BroadcastEvent = BroadcastEvent;
46
46
  BroadcastEvent["InvalidAdaptiveCardFormat"] = "InvalidAdaptiveCardFormat";
47
47
  BroadcastEvent["NewMessageSent"] = "NewMessageSent";
48
48
  BroadcastEvent["NewMessageReceived"] = "NewMessageReceived";
49
+ BroadcastEvent["RedirectPageRequest"] = "RedirectPageRequest";
50
+ BroadcastEvent["StartChatSkippingChatButtonRendering"] = "StartChatSkippingChatButtonRendering";
51
+ BroadcastEvent["StartUnauthenticatedReconnectChat"] = "StartUnauthenticatedReconnectChat";
49
52
  })(BroadcastEvent || (exports.BroadcastEvent = BroadcastEvent = {}));
50
53
 
51
54
  let TelemetryEvent;
@@ -97,7 +100,9 @@ exports.TelemetryEvent = TelemetryEvent;
97
100
  TelemetryEvent["PrechatSurveyLoaded"] = "PrechatSurveyLoaded";
98
101
  TelemetryEvent["PrechatSubmitted"] = "PrechatSubmitted";
99
102
  TelemetryEvent["StartChatSDKCall"] = "StartChatCall";
103
+ TelemetryEvent["StartChatEventRecevied"] = "StartChatEventReceived";
100
104
  TelemetryEvent["EndChatSDKCall"] = "EndChatCall";
105
+ TelemetryEvent["EndChatEventReceived"] = "EndChatEventReceived";
101
106
  TelemetryEvent["OnNewMessageFailed"] = "OnNewMessageFailed";
102
107
  TelemetryEvent["OnNewMessageAudioNotificationFailed"] = "OnNewMessageAudioNotificationFailed";
103
108
  TelemetryEvent["DownloadTranscriptResponseNullOrUndefined"] = "DownloadTranscriptResponseNullOrUndefined";
@@ -111,6 +116,7 @@ exports.TelemetryEvent = TelemetryEvent;
111
116
  TelemetryEvent["LoadingPaneLoaded"] = "LoadingPaneLoaded";
112
117
  TelemetryEvent["EmailTranscriptLoaded"] = "EmailTranscriptLoaded";
113
118
  TelemetryEvent["OutOfOfficePaneLoaded"] = "OutOfOfficePaneLoaded";
119
+ TelemetryEvent["PostChatSurveyLoadingPaneLoaded"] = "PostChatSurveyLoadingPaneLoaded";
114
120
  TelemetryEvent["PostChatSurveyLoaded"] = "PostChatSurveyLoaded";
115
121
  TelemetryEvent["ConfirmationPaneLoaded"] = "ConfirmationPaneLoaded";
116
122
  TelemetryEvent["ProactiveChatPaneLoaded"] = "ProactiveChatPaneLoaded";
@@ -132,6 +138,7 @@ exports.TelemetryEvent = TelemetryEvent;
132
138
  TelemetryEvent["InvalidConfiguration"] = "InvalidConfiguration";
133
139
  TelemetryEvent["SendTypingIndicatorSucceeded"] = "SendTypingIndicatorSucceeded";
134
140
  TelemetryEvent["SendTypingIndicatorFailed"] = "SendTypingIndicatorFailed";
141
+ TelemetryEvent["WebChatEvent"] = "WebChatEvent";
135
142
  TelemetryEvent["PreChatSurveyStartChatMethodFailed"] = "PreChatSurveyStartChatMethodFailed";
136
143
  TelemetryEvent["ChatAlreadyTriggered"] = "ChatAlreadyTriggered";
137
144
  TelemetryEvent["StartProactiveChatEventReceived"] = "StartProactiveChatEventReceived";
@@ -160,6 +167,7 @@ class TelemetryConstants {
160
167
  case TelemetryEvent.LCWChatButtonShow:
161
168
  case TelemetryEvent.PrechatSurveyLoaded:
162
169
  case TelemetryEvent.LoadingPaneLoaded:
170
+ case TelemetryEvent.PostChatSurveyLoadingPaneLoaded:
163
171
  case TelemetryEvent.PostChatSurveyLoaded:
164
172
  case TelemetryEvent.EmailTranscriptLoaded:
165
173
  case TelemetryEvent.OutOfOfficePaneLoaded:
@@ -189,12 +197,16 @@ class TelemetryConstants {
189
197
  return ScenarioType.ACTIONS;
190
198
 
191
199
  case TelemetryEvent.StartChatSDKCall:
200
+ case TelemetryEvent.StartChatEventRecevied:
192
201
  case TelemetryEvent.StartChatMethodException:
193
202
  case TelemetryEvent.CloseChatMethodException:
203
+ case TelemetryEvent.StartProactiveChatEventReceived:
194
204
  case TelemetryEvent.StartProactiveChatMethodFailed:
195
205
  case TelemetryEvent.OnNewMessageFailed:
196
206
  case TelemetryEvent.OnNewMessageAudioNotificationFailed:
197
207
  case TelemetryEvent.GetConversationDetailsCallFailed:
208
+ case TelemetryEvent.EndChatSDKCall:
209
+ case TelemetryEvent.EndChatEventReceived:
198
210
  case TelemetryEvent.EndChatSDKCallFailed:
199
211
  case TelemetryEvent.PostChatContextCallFailed:
200
212
  case TelemetryEvent.PostChatContextCallSucceed:
@@ -276,5 +276,18 @@ _defineProperty(TelemetryHelper, "logConfigDataEvent", (logLevel, payload) => {
276
276
  }
277
277
  };
278
278
 
279
+ _omnichannelChatComponents.BroadcastService.postMessage(telemetryEvent);
280
+ });
281
+
282
+ _defineProperty(TelemetryHelper, "logWebChatEvent", (logLevel, payload) => {
283
+ const telemetryEvent = {
284
+ eventName: _TelemetryConstants.TelemetryEvent.WebChatEvent,
285
+ logLevel: logLevel,
286
+ payload: { ...payload,
287
+ type: _TelemetryConstants.TelemetryEvent.WebChatEvent,
288
+ scenarioType: _TelemetryConstants.ScenarioType.WEBCHAT
289
+ }
290
+ };
291
+
279
292
  _omnichannelChatComponents.BroadcastService.postMessage(telemetryEvent);
280
293
  });
@@ -88,8 +88,11 @@ const RegisterLoggers = () => {
88
88
 
89
89
  const logTelemetry = telemetryEvent => {
90
90
  loggers.map(logger => {
91
+ var _payload;
92
+
91
93
  const logLevel = telemetryEvent.logLevel ?? _TelemetryConstants.LogLevel.INFO;
92
- logger.log(logLevel, parseInput(telemetryEvent === null || telemetryEvent === void 0 ? void 0 : telemetryEvent.payload));
94
+ const scenarioType = ((_payload = telemetryEvent.payload) === null || _payload === void 0 ? void 0 : _payload.scenarioType) ?? _TelemetryConstants.ScenarioType.UNDEFINED;
95
+ logger.log(logLevel, parseInput(telemetryEvent === null || telemetryEvent === void 0 ? void 0 : telemetryEvent.payload, scenarioType));
93
96
  });
94
97
  };
95
98
 
@@ -11,6 +11,9 @@ const defaultTelemetryConfiguration = {
11
11
  telemetryDisabled: false,
12
12
  disableConsoleLog: false,
13
13
  telemetryLoggers: [],
14
- ariaConfigurations: _defaultAriaConfig.defaultAriaConfig
14
+ ariaConfigurations: _defaultAriaConfig.defaultAriaConfig,
15
+ chatWidgetVersion: "0.0.0-0",
16
+ chatComponentVersion: "0.0.0-0",
17
+ OCChatSDKVersion: "0.0.0-0"
15
18
  };
16
19
  exports.defaultTelemetryConfiguration = defaultTelemetryConfiguration;
@@ -17,6 +17,8 @@ var _Constants = require("../../Constants");
17
17
 
18
18
  var _TelemetryHelper = require("../TelemetryHelper");
19
19
 
20
+ var _TelemetryManager = require("../TelemetryManager");
21
+
20
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
23
 
22
24
  const ariaTelemetryLogger = (ariaTelemetryKey, disabledCookieUsage, collectiorUriForTelemetry, ariaTelemetryApplicationName) => {
@@ -30,6 +32,21 @@ const ariaTelemetryLogger = (ariaTelemetryKey, disabledCookieUsage, collectiorUr
30
32
 
31
33
  if (!(0, _utils.isNullOrEmptyString)(collectiorUriForTelemetry)) {
32
34
  configuration.collectorUri = collectiorUriForTelemetry;
35
+ } else {
36
+ if (_TelemetryManager.TelemetryManager.InternalTelemetryData.environmentVersion == _Constants.EnvironmentVersion.prod) {
37
+ var _TelemetryManager$Int;
38
+
39
+ const orgUrl = (_TelemetryManager$Int = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int === void 0 ? void 0 : _TelemetryManager$Int.orgUrl;
40
+
41
+ if (!(0, _utils.isNullOrUndefined)(orgUrl)) {
42
+ // If the given org is a Production EU org, modify the Aria collector uri
43
+ const region = (0, _utils.getDomain)(orgUrl);
44
+
45
+ if (region === _Constants.AriaTelemetryConstants.EU) {
46
+ configuration.collectorUri = _Constants.AriaTelemetryConstants.EUROPE_ENDPOINT;
47
+ }
48
+ }
49
+ }
33
50
  }
34
51
 
35
52
  try {
@@ -48,20 +65,24 @@ const ariaTelemetryLogger = (ariaTelemetryKey, disabledCookieUsage, collectiorUr
48
65
 
49
66
  const ariaLogger = {
50
67
  log: (logLevel, telemetryInput) => {
51
- let property;
52
- const eventProperties = new _AWTEventProperties.default();
68
+ try {
69
+ let property;
70
+ const eventProperties = new _AWTEventProperties.default();
53
71
 
54
- const event = _TelemetryHelper.TelemetryHelper.buildTelemetryEvent(logLevel, telemetryInput);
72
+ const event = _TelemetryHelper.TelemetryHelper.buildTelemetryEvent(logLevel, telemetryInput);
55
73
 
56
- eventProperties.setName(telemetryInput.scenarioType);
74
+ eventProperties.setName(telemetryInput.scenarioType);
57
75
 
58
- for (const key of Object.keys(event)) {
59
- property = typeof event[key] === "object" ? JSON.stringify(event[key]) : event[key];
60
- eventProperties.setProperty(key, property);
61
- }
76
+ for (const key of Object.keys(event)) {
77
+ property = typeof event[key] === "object" ? JSON.stringify(event[key]) : event[key];
78
+ eventProperties.setProperty(key, property);
79
+ }
62
80
 
63
- eventProperties.setPropertyWithPii(ariaTelemetryApplicationName, _Constants.Constants.LiveChatWidget, _Enums.AWTPiiKind.GenericData);
64
- logger() ? logger().logEvent(eventProperties) : console.log("Unable to initialize aria logger");
81
+ eventProperties.setPropertyWithPii(ariaTelemetryApplicationName, _Constants.Constants.LiveChatWidget, _Enums.AWTPiiKind.GenericData);
82
+ logger() ? logger().logEvent(eventProperties) : console.log("Unable to initialize aria logger");
83
+ } catch (error) {
84
+ console.error("Error in logging telemetry to Aria logger:" + error);
85
+ }
65
86
  },
66
87
  dispose: () => {
67
88
  _AWTLogManager.default.flush(function () {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.setTabIndices = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isNullOrUndefined = exports.isNullOrEmptyString = exports.getTimestampHourMinute = exports.getLocaleDirection = exports.getIconText = exports.findParentFocusableElementsWithoutChildContainer = exports.findAllFocusableElement = exports.extractPreChatSurveyResponseValues = exports.escapeHtml = exports.createTimer = exports.changeLanguageCodeFormatForWebChat = void 0;
6
+ exports.setTabIndices = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isNullOrUndefined = exports.isNullOrEmptyString = exports.getTimestampHourMinute = exports.getLocaleDirection = exports.getIconText = exports.getDomain = exports.findParentFocusableElementsWithoutChildContainer = exports.findAllFocusableElement = exports.extractPreChatSurveyResponseValues = exports.escapeHtml = exports.createTimer = exports.changeLanguageCodeFormatForWebChat = void 0;
7
7
 
8
8
  var _Constants = require("./Constants");
9
9
 
@@ -332,6 +332,19 @@ const createTimer = () => {
332
332
  }
333
333
 
334
334
  };
335
+ }; // Returns the domain of the org
336
+
337
+
338
+ exports.createTimer = createTimer;
339
+
340
+ const getDomain = hostValue => {
341
+ for (let i = 0; i < _Constants.AriaTelemetryConstants.lcwEUDomainNames.length; i++) {
342
+ if (hostValue.endsWith(_Constants.AriaTelemetryConstants.lcwEUDomainNames[i])) {
343
+ return _Constants.AriaTelemetryConstants.EU;
344
+ }
345
+ }
346
+
347
+ return _Constants.AriaTelemetryConstants.Public;
335
348
  };
336
349
 
337
- exports.createTimer = createTimer;
350
+ exports.getDomain = getDomain;
@@ -13,10 +13,6 @@ var _react = _interopRequireWildcard(require("react"));
13
13
 
14
14
  var _utils = require("../../common/utils");
15
15
 
16
- var _Constants = require("../../common/Constants");
17
-
18
- var _ConversationState = require("../../contexts/common/ConversationState");
19
-
20
16
  var _DimLayer = require("../dimlayer/DimLayer");
21
17
 
22
18
  var _LiveChatWidgetActionType = require("../../contexts/common/LiveChatWidgetActionType");
@@ -25,16 +21,12 @@ var _NotificationHandler = require("../webchatcontainerstateful/webchatcontrolle
25
21
 
26
22
  var _NotificationScenarios = require("../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios");
27
23
 
28
- var _PostChatSurveyMode = require("../postchatsurveypanestateful/enums/PostChatSurveyMode");
29
-
30
24
  var _TelemetryHelper = require("../../common/telemetry/TelemetryHelper");
31
25
 
32
26
  var _useChatAdapterStore = _interopRequireDefault(require("../../hooks/useChatAdapterStore"));
33
27
 
34
28
  var _useChatContextStore = _interopRequireDefault(require("../../hooks/useChatContextStore"));
35
29
 
36
- var _useChatSDKStore = _interopRequireDefault(require("../../hooks/useChatSDKStore"));
37
-
38
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
39
31
 
40
32
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -43,21 +35,15 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
43
35
 
44
36
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
37
  const ConfirmationPaneStateful = props => {
46
- var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _state$domainStates$l4;
47
-
48
38
  const initialTabIndexMap = new Map();
49
- let elements = []; // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
-
51
- const chatSDK = (0, _useChatSDKStore.default)();
39
+ let elements = [];
52
40
  const [state, dispatch] = (0, _useChatContextStore.default)();
53
41
  const {
54
- endChat
42
+ prepareEndChat
55
43
  } = props; // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
44
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
45
 
58
46
  const [adapter] = (0, _useChatAdapterStore.default)();
59
- const isPostChatEnabled = (_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : (_state$domainStates$l2 = _state$domainStates$l.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.msdyn_postconversationsurveyenable;
60
- const postChatSurveyMode = (_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : (_state$domainStates$l4 = _state$domainStates$l3.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l4 === void 0 ? void 0 : _state$domainStates$l4.msdyn_postconversationsurveymode;
61
47
  const controlProps = {
62
48
  id: "oc-lcw-confirmation-pane",
63
49
  dir: state.domainStates.globalDir,
@@ -73,29 +59,8 @@ const ConfirmationPaneStateful = props => {
73
59
  });
74
60
 
75
61
  try {
76
- // check agent has joined conversation
77
- const conversationDetails = await chatSDK.getConversationDetails();
78
-
79
- if (isPostChatEnabled === "true" && (conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.canRenderPostChat) === _Constants.Constants.truePascal) {
80
- if (postChatSurveyMode === _PostChatSurveyMode.PostChatSurveyMode.Embed) {
81
- const loadPostChatEvent = {
82
- eventName: _TelemetryConstants.BroadcastEvent.LoadPostChatSurvey
83
- };
84
-
85
- _omnichannelChatComponents.BroadcastService.postMessage(loadPostChatEvent);
86
- } else if (postChatSurveyMode === _PostChatSurveyMode.PostChatSurveyMode.Link) {
87
- const skipEndChatSDK = false;
88
- const skipCloseChat = true;
89
- await endChat(adapter, skipEndChatSDK, skipCloseChat);
90
- dispatch({
91
- type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
92
- payload: _ConversationState.ConversationState.InActive
93
- });
94
- }
95
- } else {
96
- (0, _utils.setTabIndices)(elements, initialTabIndexMap, true);
97
- await endChat(adapter);
98
- }
62
+ (0, _utils.setTabIndices)(elements, initialTabIndexMap, true);
63
+ await prepareEndChat(adapter, state);
99
64
  } catch (ex) {
100
65
  _TelemetryHelper.TelemetryHelper.logSDKEvent(_TelemetryConstants.LogLevel.ERROR, {
101
66
  Event: _TelemetryConstants.TelemetryEvent.GetConversationDetailsCallFailed,
@@ -123,8 +123,7 @@ const FooterStateful = props => {
123
123
  styleProps: footerProps === null || footerProps === void 0 ? void 0 : footerProps.styleProps
124
124
  }), /*#__PURE__*/_react.default.createElement(_AudioNotificationStateful.default, {
125
125
  audioSrc: (audioNotificationProps === null || audioNotificationProps === void 0 ? void 0 : audioNotificationProps.audioSrc) ?? _Audios.NewMessageNotificationSoundBase64,
126
- hideAudioNotificationButton: (footerProps === null || footerProps === void 0 ? void 0 : (_footerProps$controlP4 = footerProps.controlProps) === null || _footerProps$controlP4 === void 0 ? void 0 : _footerProps$controlP4.hideAudioNotificationButton) ?? false,
127
- isAudioMuted: state.appStates.isAudioMuted ?? false
126
+ isAudioMuted: state.appStates.isAudioMuted === null ? (footerProps === null || footerProps === void 0 ? void 0 : (_footerProps$controlP4 = footerProps.controlProps) === null || _footerProps$controlP4 === void 0 ? void 0 : _footerProps$controlP4.hideAudioNotificationButton) ?? false : state.appStates.isAudioMuted ?? false
128
127
  }));
129
128
  };
130
129
 
@@ -69,13 +69,7 @@ const HeaderStateful = props => {
69
69
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_SHOW_CONFIRMATION,
70
70
  payload: true
71
71
  });
72
- } else if (conversationState.current === _ConversationState.ConversationState.Postchat) {
73
- dispatch({
74
- type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_SHOULD_SHOW_POST_CHAT,
75
- payload: false
76
- });
77
- await endChat(adapter);
78
- } else if (conversationState.current === _ConversationState.ConversationState.InActive) {
72
+ } else {
79
73
  const skipEndChatSDK = true;
80
74
  const skipCloseChat = false;
81
75
  await endChat(adapter, skipEndChatSDK, skipCloseChat);
@@ -27,6 +27,8 @@ var _groupActivitiesMiddleware = require("../../../webchatcontainerstateful/webc
27
27
 
28
28
  var _typingIndicatorMiddleware = require("../../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/typingIndicatorMiddleware");
29
29
 
30
+ var _WebChatLogger = require("../../../webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger");
31
+
30
32
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
33
 
32
34
  /* eslint-disable @typescript-eslint/no-empty-function, @typescript-eslint/no-explicit-any */
@@ -1444,7 +1446,8 @@ const dummyDefaultProps = {
1444
1446
  },
1445
1447
  authClientFunction: undefined,
1446
1448
  isReconnectEnabled: undefined,
1447
- reconnectId: undefined
1449
+ reconnectId: undefined,
1450
+ redirectInSameWindow: undefined
1448
1451
  },
1449
1452
  styleProps: {
1450
1453
  generalStyles: {
@@ -1516,7 +1519,7 @@ const dummyDefaultProps = {
1516
1519
  internalErrorBoxClass: undefined,
1517
1520
  internalRenderErrorBox: undefined,
1518
1521
  locale: "en-US",
1519
- onTelemetry: undefined,
1522
+ onTelemetry: (0, _WebChatLogger.createWebChatTelemetry)(),
1520
1523
  overrideLocalizedStrings: undefined,
1521
1524
  renderMarkdown: (0, _createMarkdown.createMarkdown)(false, false),
1522
1525
  scrollToEndButtonMiddleware: undefined,
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.endChat = void 0;
6
+ exports.prepareEndChat = exports.endChat = void 0;
7
7
 
8
8
  var _TelemetryConstants = require("../../../common/telemetry/TelemetryConstants");
9
9
 
@@ -19,7 +19,43 @@ var _WebChatStoreLoader = require("../../webchatcontainerstateful/webchatcontrol
19
19
 
20
20
  var _defaultWebChatContainerStatefulProps = require("../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps");
21
21
 
22
+ var _PostChatSurveyMode = require("../../postchatsurveypanestateful/enums/PostChatSurveyMode");
23
+
24
+ var _Constants = require("../../../common/Constants");
25
+
22
26
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
+ const prepareEndChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state) => {
28
+ var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _state$domainStates$l4;
29
+
30
+ const isPostChatEnabled = (_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : (_state$domainStates$l2 = _state$domainStates$l.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.msdyn_postconversationsurveyenable;
31
+ const postChatSurveyMode = (_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : (_state$domainStates$l4 = _state$domainStates$l3.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l4 === void 0 ? void 0 : _state$domainStates$l4.msdyn_postconversationsurveymode;
32
+ const conversationDetails = await chatSDK.getConversationDetails();
33
+
34
+ if (isPostChatEnabled === "true" && (conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.canRenderPostChat) === _Constants.Constants.truePascal) {
35
+ const skipEndChatSDK = false;
36
+ const skipCloseChat = true;
37
+ await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat);
38
+
39
+ if (postChatSurveyMode === _PostChatSurveyMode.PostChatSurveyMode.Embed) {
40
+ const loadPostChatEvent = {
41
+ eventName: _TelemetryConstants.BroadcastEvent.LoadPostChatSurvey
42
+ };
43
+
44
+ _omnichannelChatComponents.BroadcastService.postMessage(loadPostChatEvent);
45
+ } else if (postChatSurveyMode === _PostChatSurveyMode.PostChatSurveyMode.Link) {
46
+ dispatch({
47
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
48
+ payload: _ConversationState.ConversationState.InActive
49
+ });
50
+ }
51
+ } else {
52
+ await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter);
53
+ }
54
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+
56
+
57
+ exports.prepareEndChat = prepareEndChat;
58
+
23
59
  const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat) => {
24
60
  if (!skipEndChatSDK) {
25
61
  try {
@@ -43,6 +43,8 @@ var _createMarkdown = require("./createMarkdown");
43
43
 
44
44
  var _maxMessageSizeValidator = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/maxMessageSizeValidator"));
45
45
 
46
+ var _WebChatLogger = require("../../webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger");
47
+
46
48
  var _defaultAttachmentProps = require("../../webchatcontainerstateful/common/defaultProps/defaultAttachmentProps");
47
49
 
48
50
  var _defaultMiddlewareLocalizedTexts = require("../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts");
@@ -141,6 +143,7 @@ const initWebChatComposer = (props, chatSDK, state, dispatch, setWebChatStyles)
141
143
  avatarMiddleware: (_props$webChatContain15 = props.webChatContainerProps) !== null && _props$webChatContain15 !== void 0 && (_props$webChatContain16 = _props$webChatContain15.renderingMiddlewareProps) !== null && _props$webChatContain16 !== void 0 && _props$webChatContain16.disableAvatarMiddleware ? undefined : (0, _avatarMiddleware.createAvatarMiddleware)((_state$domainStates$r5 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r5 === void 0 ? void 0 : _state$domainStates$r5.avatarStyleProps, (_state$domainStates$r6 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r6 === void 0 ? void 0 : _state$domainStates$r6.avatarTextStyleProps),
142
144
  groupActivitiesMiddleware: (_props$webChatContain17 = props.webChatContainerProps) !== null && _props$webChatContain17 !== void 0 && (_props$webChatContain18 = _props$webChatContain17.renderingMiddlewareProps) !== null && _props$webChatContain18 !== void 0 && _props$webChatContain18.disableGroupActivitiesMiddleware ? undefined : (_defaultWebChatContai2 = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.groupActivitiesMiddleware,
143
145
  typingIndicatorMiddleware: (_props$webChatContain19 = props.webChatContainerProps) !== null && _props$webChatContain19 !== void 0 && (_props$webChatContain20 = _props$webChatContain19.renderingMiddlewareProps) !== null && _props$webChatContain20 !== void 0 && _props$webChatContain20.disableTypingIndicatorMiddleware ? undefined : (_defaultWebChatContai3 = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai3 === void 0 ? void 0 : _defaultWebChatContai3.typingIndicatorMiddleware,
146
+ onTelemetry: (0, _WebChatLogger.createWebChatTelemetry)(),
144
147
  ...((_props$webChatContain21 = props.webChatContainerProps) === null || _props$webChatContain21 === void 0 ? void 0 : _props$webChatContain21.webChatProps)
145
148
  };
146
149
  return webChatProps;
@@ -3,13 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.handleUnauthenticatedReconnectChat = exports.getReconnectIdForAuthenticatedChat = void 0;
6
+ exports.startUnauthenticatedReconnectChat = exports.handleUnauthenticatedReconnectChat = exports.handleRedirectUnauthenticatedReconnectChat = exports.getReconnectIdForAuthenticatedChat = exports.getChatReconnectContext = void 0;
7
7
 
8
8
  require("regenerator-runtime/runtime");
9
9
 
10
10
  var _TelemetryConstants = require("../../../common/telemetry/TelemetryConstants");
11
11
 
12
- var _Constants = require("../../../common/Constants");
12
+ var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
13
13
 
14
14
  var _ConversationState = require("../../../contexts/common/ConversationState");
15
15
 
@@ -41,6 +41,8 @@ const getChatReconnectContext = async (chatSDK, reconnectId) => {
41
41
  }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
42
 
43
43
 
44
+ exports.getChatReconnectContext = getChatReconnectContext;
45
+
44
46
  const getReconnectIdForAuthenticatedChat = async (props, chatSDK) => {
45
47
  var _props$reconnectChatP, _props$reconnectChatP2;
46
48
 
@@ -61,33 +63,116 @@ const getReconnectIdForAuthenticatedChat = async (props, chatSDK) => {
61
63
 
62
64
  exports.getReconnectIdForAuthenticatedChat = getReconnectIdForAuthenticatedChat;
63
65
 
64
- const handleUnauthenticatedReconnectChat = async (dispatch, reconnectId, initStartChat) => {
65
- const reconnectAvailabilityResponse = await getChatReconnectContext(reconnectId);
66
+ const handleUnauthenticatedReconnectChat = async (chatSDK, dispatch, setAdapter, reconnectId, initStartChat, redirectInSameWindow) => {
67
+ const reconnectAvailabilityResponse = await getChatReconnectContext(chatSDK, reconnectId);
66
68
 
67
- if (reconnectAvailabilityResponse && reconnectAvailabilityResponse.redirectURL) {
68
- redirectPage(reconnectAvailabilityResponse.redirectURL);
69
+ if (shouldRedirectOrStartNewChat(reconnectAvailabilityResponse)) {
70
+ await redirectOrStartNewChat(reconnectAvailabilityResponse, chatSDK, dispatch, setAdapter, initStartChat, redirectInSameWindow);
69
71
  } else {
70
- const optionalParams = {
71
- reconnectId: reconnectId
72
- };
72
+ await setReconnectIdAndStartChat(chatSDK, dispatch, setAdapter, reconnectId, initStartChat);
73
+ }
74
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+
76
+
77
+ exports.handleUnauthenticatedReconnectChat = handleUnauthenticatedReconnectChat;
78
+
79
+ const startUnauthenticatedReconnectChat = async (chatSDK, dispatch, setAdapter, reconnectId, initStartChat) => {
80
+ const reconnectAvailabilityResponse = await getChatReconnectContext(chatSDK, reconnectId);
81
+
82
+ if (!shouldRedirectOrStartNewChat(reconnectAvailabilityResponse)) {
83
+ await setReconnectIdAndStartChat(chatSDK, dispatch, setAdapter, reconnectId, initStartChat);
84
+ }
85
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
+
87
+
88
+ exports.startUnauthenticatedReconnectChat = startUnauthenticatedReconnectChat;
89
+
90
+ const setReconnectIdAndStartChat = async (chatSDK, dispatch, setAdapter, reconnectId, initStartChat) => {
91
+ const startUnauthenticatedReconnectChat = {
92
+ eventName: _TelemetryConstants.BroadcastEvent.StartUnauthenticatedReconnectChat
93
+ };
94
+
95
+ _omnichannelChatComponents.BroadcastService.postMessage(startUnauthenticatedReconnectChat);
96
+
97
+ const optionalParams = {
98
+ reconnectId: reconnectId
99
+ };
100
+ dispatch({
101
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_RECONNECT_ID,
102
+ payload: reconnectId
103
+ });
104
+ dispatch({
105
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
106
+ payload: _ConversationState.ConversationState.Loading
107
+ });
108
+ await initStartChat(chatSDK, dispatch, setAdapter, optionalParams);
109
+ };
110
+
111
+ const redirectPage = (redirectURL, redirectInSameWindow) => {
112
+ const redirectPageRequest = {
113
+ eventName: _TelemetryConstants.BroadcastEvent.RedirectPageRequest,
114
+ payload: {
115
+ redirectURL: redirectURL
116
+ }
117
+ };
118
+
119
+ _omnichannelChatComponents.BroadcastService.postMessage(redirectPageRequest);
120
+
121
+ if (redirectInSameWindow) {
122
+ window.location.href = redirectURL;
123
+ }
124
+ };
125
+
126
+ const shouldRedirectOrStartNewChat = reconnectAvailabilityResponse => {
127
+ return reconnectAvailabilityResponse && !reconnectAvailabilityResponse.reconnectId;
128
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
+
130
+
131
+ const startNewChatEmptyRedirectionUrl = async (chatSDK, dispatch, setAdapter, initStartChat) => {
132
+ const startUnauthenticatedReconnectChat = {
133
+ eventName: _TelemetryConstants.BroadcastEvent.StartUnauthenticatedReconnectChat
134
+ };
135
+
136
+ _omnichannelChatComponents.BroadcastService.postMessage(startUnauthenticatedReconnectChat); // Getting PreChat Survey Context
137
+
138
+
139
+ const parseToJson = false;
140
+ const preChatSurveyResponse = await chatSDK.getPreChatSurvey(parseToJson);
141
+
142
+ if (preChatSurveyResponse) {
143
+ dispatch({
144
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_PRE_CHAT_SURVEY_RESPONSE,
145
+ payload: preChatSurveyResponse
146
+ });
73
147
  dispatch({
74
- type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_RECONNECT_ID,
75
- payload: reconnectId
148
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
149
+ payload: _ConversationState.ConversationState.Prechat
76
150
  });
151
+ } else {
77
152
  dispatch({
78
153
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
79
154
  payload: _ConversationState.ConversationState.Loading
80
155
  });
81
- await initStartChat(optionalParams);
156
+ await initStartChat(chatSDK, dispatch, setAdapter);
82
157
  }
83
- };
158
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
159
 
85
- exports.handleUnauthenticatedReconnectChat = handleUnauthenticatedReconnectChat;
86
160
 
87
- const redirectPage = newUrl => {
88
- const data = {
89
- messageName: _Constants.Constants.redirectPageRequest,
90
- newUrl: newUrl
91
- };
92
- window.parent.postMessage(data, "*");
161
+ const handleRedirectUnauthenticatedReconnectChat = async (chatSDK, dispatch, setAdapter, initStartChat, reconnectId, redirectInSameWindow) => {
162
+ const reconnectAvailabilityResponse = await getChatReconnectContext(chatSDK, reconnectId);
163
+
164
+ if (shouldRedirectOrStartNewChat(reconnectAvailabilityResponse)) {
165
+ await redirectOrStartNewChat(reconnectAvailabilityResponse, chatSDK, dispatch, setAdapter, initStartChat, redirectInSameWindow);
166
+ }
167
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
168
+
169
+
170
+ exports.handleRedirectUnauthenticatedReconnectChat = handleRedirectUnauthenticatedReconnectChat;
171
+
172
+ const redirectOrStartNewChat = async (reconnectAvailabilityResponse, chatSDK, dispatch, setAdapter, initStartChat, redirectInSameWindow) => {
173
+ if (reconnectAvailabilityResponse.redirectURL) {
174
+ redirectPage(reconnectAvailabilityResponse.redirectURL, redirectInSameWindow);
175
+ } else {
176
+ await startNewChatEmptyRedirectionUrl(chatSDK, dispatch, setAdapter, initStartChat);
177
+ }
93
178
  };