@procore/ai-translations 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,10 +20,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ ACTION: () => ACTION,
23
24
  AITranslateText: () => AITranslateText,
24
25
  AITranslationProvider: () => AITranslationProvider,
25
26
  AI_TRANSLATION_FEATURE_FLAG_KEY: () => AI_TRANSLATION_FEATURE_FLAG_KEY,
27
+ BUTTON_TYPE: () => BUTTON_TYPE,
28
+ buildAnalyticEvent: () => buildAnalyticEvent,
29
+ buildEventKey: () => buildEventKey,
30
+ buildObject: () => buildObject,
26
31
  getAITranslationLDId: () => getAITranslationLDId,
32
+ useAIAnalytics: () => useAIAnalytics,
27
33
  useAITranslation: () => useAITranslation,
28
34
  useConfig: () => useConfig
29
35
  });
@@ -77,6 +83,9 @@ var Config = class _Config {
77
83
  setToolName(name) {
78
84
  this.toolName = name;
79
85
  }
86
+ isBackendTranslationStrategy() {
87
+ return this.ToolConfig.strategy === "backend_translations";
88
+ }
80
89
  getToolName() {
81
90
  return this.toolName;
82
91
  }
@@ -414,6 +423,19 @@ var Storage = class _Storage {
414
423
  }
415
424
  }
416
425
  // ------------------------------------
426
+ // 🗑️ Clear Translation by ID
427
+ // ------------------------------------
428
+ static async deleteById(id) {
429
+ try {
430
+ const db = await _Storage.getDB();
431
+ await db.delete(_Storage.STORE_NAME, id);
432
+ return true;
433
+ } catch (error) {
434
+ console.error("[Storage] Failed to delete by id:", error);
435
+ return false;
436
+ }
437
+ }
438
+ // ------------------------------------
417
439
  // 🗑️ Clear All Translations
418
440
  // ------------------------------------
419
441
  static async clearAll() {
@@ -508,7 +530,9 @@ var TranslationRegistry = class _TranslationRegistry {
508
530
  async removeTextsFromEnqueued(texts, targetLanguage, strategy) {
509
531
  for (const text of texts) {
510
532
  const id = await Storage.generateId(text, targetLanguage, this.tool);
511
- _TranslationRegistry.enqueuedItems.delete(`${id}:${strategy}`);
533
+ _TranslationRegistry.enqueuedItems.delete(
534
+ this.generateEnqueuedKey(id, strategy)
535
+ );
512
536
  }
513
537
  }
514
538
  static removeFromEnqueued(key) {
@@ -517,10 +541,19 @@ var TranslationRegistry = class _TranslationRegistry {
517
541
  generateEnqueuedKey(id, strategy) {
518
542
  return `${id}:${strategy}`;
519
543
  }
520
- async get(text, targetLanguage, tool) {
544
+ async get(text, targetLanguage, tool, config2) {
521
545
  const key = await Hash.generateFromMultiple([text, targetLanguage, tool]);
522
- if (_TranslationRegistry.memoryCache.has(key)) {
523
- return _TranslationRegistry.memoryCache.get(key);
546
+ const cached = _TranslationRegistry.memoryCache.get(key);
547
+ if (cached) {
548
+ if (cached.translationStrategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
549
+ _TranslationRegistry.memoryCache.delete(key);
550
+ if (cached.translatedText) {
551
+ _TranslationRegistry.originalTextIndex.delete(cached.translatedText);
552
+ }
553
+ await Storage.deleteById(key);
554
+ return void 0;
555
+ }
556
+ return cached;
524
557
  }
525
558
  const translation = await Storage.getTranslation(
526
559
  text,
@@ -528,6 +561,10 @@ var TranslationRegistry = class _TranslationRegistry {
528
561
  tool
529
562
  );
530
563
  if (translation !== void 0) {
564
+ if (translation.translation_strategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
565
+ await Storage.deleteById(translation.id);
566
+ return void 0;
567
+ }
531
568
  return this.toTranslationRegistryEntry(translation);
532
569
  }
533
570
  return void 0;
@@ -774,19 +811,21 @@ var TranslationManager = class {
774
811
  this.translationProgress.total = queueManager.queueSize(
775
812
  this.currentTranslatorStrategy
776
813
  );
777
- for (const batch of queueManager.generateBatches(
778
- this.translator.getConfig()
779
- )) {
780
- batch.forEach((entry) => this.mfeToBeNotified.add(entry.tool));
781
- const result = await this.translator.processTranslations(
782
- batch.map(
783
- (entry) => this.convertTranslationQueueEntryToTranslationRequest(entry)
784
- )
785
- );
786
- this.setTranslationProgress(batch.length);
787
- await this.updateDatabaseWithTranslations(result);
788
- await this.notifyTranslationCompleted();
789
- }
814
+ do {
815
+ for (const batch of queueManager.generateBatches(
816
+ this.translator.getConfig()
817
+ )) {
818
+ batch.forEach((entry) => this.mfeToBeNotified.add(entry.tool));
819
+ const result = await this.translator.processTranslations(
820
+ batch.map(
821
+ (entry) => this.convertTranslationQueueEntryToTranslationRequest(entry)
822
+ )
823
+ );
824
+ this.setTranslationProgress(batch.length);
825
+ await this.updateDatabaseWithTranslations(result);
826
+ await this.notifyTranslationCompleted();
827
+ }
828
+ } while (queueManager.queueSize(this.currentTranslatorStrategy) > 0);
790
829
  this.resetTranslationProgress();
791
830
  this.publishTranslationProgress();
792
831
  if (this.currentTranslatorStrategy === "frontend_translations") {
@@ -940,8 +979,16 @@ var Client = class {
940
979
  method: "POST",
941
980
  body: JSON.stringify(requests)
942
981
  });
982
+ const responseBody = Array.isArray(data) ? data.map((group) => ({
983
+ ...group,
984
+ translations: Array.isArray(group.translations) ? group.translations.map((t) => ({
985
+ ...t,
986
+ isTranslated: t.isTranslated ?? (!!t.translation && t.translation !== ""),
987
+ retryable: t.retryable ?? true
988
+ })) : []
989
+ })) : data;
943
990
  return {
944
- responseBody: data,
991
+ responseBody,
945
992
  success: true
946
993
  };
947
994
  } catch (error) {
@@ -1018,12 +1065,55 @@ var getModelDownloadEventHandler = () => {
1018
1065
  }
1019
1066
  return _modelDownloadEventHandler;
1020
1067
  };
1068
+ var SUPPORTED_LANGUAGES = /* @__PURE__ */ new Set([
1069
+ "ar",
1070
+ "bn",
1071
+ "bg",
1072
+ "zh",
1073
+ "hr",
1074
+ "cs",
1075
+ "da",
1076
+ "nl",
1077
+ "en",
1078
+ "fi",
1079
+ "fr",
1080
+ "de",
1081
+ "el",
1082
+ "he",
1083
+ "hi",
1084
+ "hu",
1085
+ "id",
1086
+ "it",
1087
+ "ja",
1088
+ "kn",
1089
+ "ko",
1090
+ "lt",
1091
+ "mr",
1092
+ "no",
1093
+ "pl",
1094
+ "pt",
1095
+ "ro",
1096
+ "ru",
1097
+ "sk",
1098
+ "sl",
1099
+ "es",
1100
+ "sv",
1101
+ "ta",
1102
+ "te",
1103
+ "th",
1104
+ "tr",
1105
+ "uk",
1106
+ "vi"
1107
+ ]);
1021
1108
  var ChromeTranslator = class _ChromeTranslator {
1022
1109
  translator;
1023
1110
  constructor(translator) {
1024
1111
  this.translator = translator;
1025
1112
  }
1026
- static translatorReadyPromise = Promise.resolve();
1113
+ static translatorReadyPromises = /* @__PURE__ */ new Map();
1114
+ static isSupportedLanguage(lang) {
1115
+ return SUPPORTED_LANGUAGES.has(lang) || SUPPORTED_LANGUAGES.has(lang.split("-")[0] ?? "");
1116
+ }
1027
1117
  static ensureRegistry() {
1028
1118
  if (!globalThis.chromeTranslatorRegistry) {
1029
1119
  globalThis.chromeTranslatorRegistry = /* @__PURE__ */ new Map();
@@ -1045,30 +1135,31 @@ var ChromeTranslator = class _ChromeTranslator {
1045
1135
  );
1046
1136
  }
1047
1137
  static async createTranslator(source, target) {
1138
+ const key = this.generateKey(source, target);
1048
1139
  let resolveReady;
1049
- this.translatorReadyPromise = new Promise((resolve) => {
1140
+ const readyPromise = new Promise((resolve) => {
1050
1141
  resolveReady = resolve;
1051
1142
  });
1143
+ this.translatorReadyPromises.set(key, readyPromise);
1052
1144
  let isDownloading = false;
1053
1145
  const translator = await Translator.create({
1054
1146
  sourceLanguage: source,
1055
1147
  targetLanguage: target,
1056
1148
  monitor(m) {
1057
- m.addEventListener(
1058
- "downloadprogress",
1059
- (e) => {
1060
- isDownloading = true;
1061
- const progress = e.total > 0 ? Math.round(e.loaded / e.total * 100) : 0;
1062
- getModelDownloadEventHandler().publishModelDownloadProgressEvent(
1063
- e.loaded,
1064
- e.total,
1065
- progress
1066
- );
1067
- if (e.loaded === e.total) {
1068
- resolveReady();
1069
- }
1149
+ m.addEventListener("downloadprogress", (e) => {
1150
+ isDownloading = true;
1151
+ const loaded = e.loaded ?? 0;
1152
+ const total = e.total ?? 0;
1153
+ const progress = total > 0 ? Math.round(loaded / total * 100) : 0;
1154
+ getModelDownloadEventHandler().publishModelDownloadProgressEvent(
1155
+ loaded,
1156
+ total,
1157
+ progress
1158
+ );
1159
+ if (total > 0 && loaded >= total) {
1160
+ resolveReady();
1070
1161
  }
1071
- );
1162
+ });
1072
1163
  }
1073
1164
  });
1074
1165
  if (!isDownloading) {
@@ -1076,8 +1167,8 @@ var ChromeTranslator = class _ChromeTranslator {
1076
1167
  }
1077
1168
  return translator;
1078
1169
  }
1079
- static waitForReady() {
1080
- return this.translatorReadyPromise;
1170
+ static waitForReady(key) {
1171
+ return this.translatorReadyPromises.get(key) ?? Promise.resolve();
1081
1172
  }
1082
1173
  static async translate(text, targetLanguage) {
1083
1174
  this.ensureRegistry();
@@ -1085,8 +1176,17 @@ var ChromeTranslator = class _ChromeTranslator {
1085
1176
  const detector = await ChromeLanguageDetector.getInstance();
1086
1177
  const sourceLanguage = await detector.detectLanguage(text);
1087
1178
  const key = this.generateKey(sourceLanguage, targetLanguage);
1088
- let instance = globalThis.chromeTranslatorRegistry.get(key);
1089
- if (!instance) {
1179
+ if (!this.isSupportedLanguage(sourceLanguage) || !this.isSupportedLanguage(targetLanguage)) {
1180
+ return {
1181
+ translation: text,
1182
+ sourceLanguage,
1183
+ success: false,
1184
+ retryable: false,
1185
+ errorMessage: `Unsupported language pair: ${sourceLanguage} \u2192 ${targetLanguage}`
1186
+ };
1187
+ }
1188
+ const existingInstance = globalThis.chromeTranslatorRegistry.get(key);
1189
+ if (!existingInstance) {
1090
1190
  const translatorCapabilities = await Translator.availability({
1091
1191
  sourceLanguage,
1092
1192
  targetLanguage
@@ -1104,10 +1204,16 @@ var ChromeTranslator = class _ChromeTranslator {
1104
1204
  sourceLanguage,
1105
1205
  targetLanguage
1106
1206
  );
1107
- instance = new _ChromeTranslator(chromeTranslator);
1108
- globalThis.chromeTranslatorRegistry.set(key, instance);
1207
+ if (!globalThis.chromeTranslatorRegistry.has(key)) {
1208
+ globalThis.chromeTranslatorRegistry.set(
1209
+ key,
1210
+ new _ChromeTranslator(chromeTranslator)
1211
+ );
1212
+ }
1109
1213
  }
1110
- await this.waitForReady();
1214
+ const instance = globalThis.chromeTranslatorRegistry.get(key);
1215
+ await this.waitForReady(key);
1216
+ this.translatorReadyPromises.delete(key);
1111
1217
  const translation = await instance.translator?.translate(text);
1112
1218
  if (!translation) {
1113
1219
  return {
@@ -1115,7 +1221,7 @@ var ChromeTranslator = class _ChromeTranslator {
1115
1221
  sourceLanguage,
1116
1222
  success: false,
1117
1223
  errorMessage: "Translation failed",
1118
- retryable: true
1224
+ retryable: false
1119
1225
  };
1120
1226
  }
1121
1227
  return {
@@ -1125,11 +1231,12 @@ var ChromeTranslator = class _ChromeTranslator {
1125
1231
  retryable: true
1126
1232
  };
1127
1233
  } catch (error) {
1234
+ const message = error instanceof Error ? error.message : "Unknown error";
1128
1235
  return {
1129
1236
  translation: text,
1130
1237
  sourceLanguage: targetLanguage,
1131
1238
  success: false,
1132
- errorMessage: error instanceof Error ? error.message : "Unknown error",
1239
+ errorMessage: message,
1133
1240
  retryable: true
1134
1241
  };
1135
1242
  }
@@ -1286,7 +1393,8 @@ var aitFunction = async (text, translationRegistry, config2, tool) => {
1286
1393
  const existingByOriginal = await translationRegistry.get(
1287
1394
  text,
1288
1395
  targetLanguage,
1289
- tool
1396
+ tool,
1397
+ config2
1290
1398
  );
1291
1399
  if (existingByOriginal && existingByOriginal.isTranslated && existingByOriginal.translatedText && existingByOriginal.translatedText.trim() !== "") {
1292
1400
  return existingByOriginal.translatedText;
@@ -1347,7 +1455,12 @@ function AITranslationInnerProvider(props) {
1347
1455
  companyId,
1348
1456
  userId,
1349
1457
  projectId,
1350
- enableAIT = true
1458
+ enableAIT = true,
1459
+ companyLocale,
1460
+ projectLocale,
1461
+ onTrackAnalyticsEvent,
1462
+ page,
1463
+ scope
1351
1464
  } = props;
1352
1465
  const [translationProgress, setTranslationProgress] = (0, import_react.useState)(null);
1353
1466
  const [modelDownloadProgress, setModelDownloadProgress] = (0, import_react.useState)(null);
@@ -1403,15 +1516,15 @@ function AITranslationInnerProvider(props) {
1403
1516
  return () => unsubscribe();
1404
1517
  }, []);
1405
1518
  (0, import_react.useEffect)(() => {
1406
- if (isFetched && remoteConfig && remoteConfig[tool]) {
1407
- setConfig((prevConfig) => {
1408
- const clonedConfig = prevConfig.clone();
1409
- clonedConfig.setTargetLanguage(locale);
1410
- clonedConfig.setToolConfig(remoteConfig[tool]);
1411
- translator.current.updateConfig(clonedConfig);
1412
- return clonedConfig;
1413
- });
1414
- }
1519
+ if (!isFetched || !remoteConfig) return;
1520
+ const toolConfig = remoteConfig[tool] ?? remoteConfig;
1521
+ setConfig((prevConfig) => {
1522
+ const clonedConfig = prevConfig.clone();
1523
+ clonedConfig.setTargetLanguage(locale);
1524
+ clonedConfig.setToolConfig(toolConfig);
1525
+ translator.current.updateConfig(clonedConfig);
1526
+ return clonedConfig;
1527
+ });
1415
1528
  }, [tool, remoteConfig, isFetched, locale]);
1416
1529
  config2.setTargetLanguage(locale);
1417
1530
  config2.setToolName(tool);
@@ -1424,10 +1537,15 @@ function AITranslationInnerProvider(props) {
1424
1537
  const contextValue = {
1425
1538
  ait,
1426
1539
  locale,
1540
+ companyLocale,
1541
+ projectLocale,
1427
1542
  renderVersion: renderVersionManager.getVersion(),
1428
1543
  translationProgress,
1429
1544
  modelDownloadProgress,
1430
- tool
1545
+ tool,
1546
+ onTrackAnalyticsEvent,
1547
+ page,
1548
+ scope
1431
1549
  };
1432
1550
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AITranslationContext.Provider, { value: contextValue, children });
1433
1551
  }
@@ -1447,15 +1565,143 @@ function useAITranslation() {
1447
1565
  return ctx;
1448
1566
  }
1449
1567
 
1568
+ // src/hooks/useAIAnalytics.ts
1569
+ var import_react3 = require("react");
1570
+
1571
+ // src/analytics/events.ts
1572
+ var BUTTON_TYPE = {
1573
+ TRANSLATE: "translate",
1574
+ HIGHLIGHT: "highlight"
1575
+ };
1576
+ var ACTION = {
1577
+ CLICKED: "clicked"
1578
+ };
1579
+ function buildObject(pageContext, buttonType) {
1580
+ return `${pageContext}_${buttonType}_button`;
1581
+ }
1582
+ function buildEventKey(parts) {
1583
+ const { scope, tool, object, action } = parts;
1584
+ return `ux.web.feature.${scope}.${tool}.${object}.${action}`;
1585
+ }
1586
+ function buildAnalyticEvent(params) {
1587
+ const {
1588
+ scope,
1589
+ tool,
1590
+ pageContext,
1591
+ buttonType,
1592
+ baseProperties,
1593
+ action,
1594
+ additionalProperties
1595
+ } = params;
1596
+ const resolvedAction = action ?? ACTION.CLICKED;
1597
+ const object = buildObject(pageContext, buttonType);
1598
+ const key = buildEventKey({
1599
+ scope,
1600
+ tool,
1601
+ object,
1602
+ action: resolvedAction
1603
+ });
1604
+ const properties = {
1605
+ ...baseProperties,
1606
+ ...additionalProperties
1607
+ };
1608
+ return { key, properties };
1609
+ }
1610
+
1611
+ // src/hooks/useAIAnalytics.ts
1612
+ function useAIAnalytics() {
1613
+ const ctx = (0, import_react3.useContext)(AITranslationContext);
1614
+ if (!ctx) {
1615
+ throw new Error(
1616
+ "useAIAnalytics must be used inside an AITranslationProvider"
1617
+ );
1618
+ }
1619
+ const {
1620
+ locale,
1621
+ companyLocale,
1622
+ projectLocale,
1623
+ tool,
1624
+ page,
1625
+ scope,
1626
+ onTrackAnalyticsEvent
1627
+ } = ctx;
1628
+ const isTrackingEnabled = Boolean(onTrackAnalyticsEvent);
1629
+ const buildBaseProperties = (0, import_react3.useCallback)(() => {
1630
+ const props = {
1631
+ user_locale: locale,
1632
+ tool,
1633
+ page: page ?? ""
1634
+ };
1635
+ if (companyLocale) props.company_locale = companyLocale;
1636
+ if (projectLocale) props.project_locale = projectLocale;
1637
+ return props;
1638
+ }, [locale, tool, page, companyLocale, projectLocale]);
1639
+ const trackTranslateButtonClicked = (0, import_react3.useCallback)(
1640
+ (additionalProperties) => {
1641
+ if (!onTrackAnalyticsEvent || !page || !scope) return;
1642
+ onTrackAnalyticsEvent(
1643
+ buildAnalyticEvent({
1644
+ scope,
1645
+ tool,
1646
+ pageContext: page,
1647
+ buttonType: BUTTON_TYPE.TRANSLATE,
1648
+ baseProperties: buildBaseProperties(),
1649
+ additionalProperties
1650
+ })
1651
+ );
1652
+ },
1653
+ [onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
1654
+ );
1655
+ const trackHighlightButtonClicked = (0, import_react3.useCallback)(
1656
+ (additionalProperties) => {
1657
+ if (!onTrackAnalyticsEvent || !page || !scope) return;
1658
+ onTrackAnalyticsEvent(
1659
+ buildAnalyticEvent({
1660
+ scope,
1661
+ tool,
1662
+ pageContext: page,
1663
+ buttonType: BUTTON_TYPE.HIGHLIGHT,
1664
+ baseProperties: buildBaseProperties(),
1665
+ additionalProperties
1666
+ })
1667
+ );
1668
+ },
1669
+ [onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
1670
+ );
1671
+ const trackCustomEvent = (0, import_react3.useCallback)(
1672
+ (buttonType, action, additionalProperties) => {
1673
+ if (!onTrackAnalyticsEvent || !page || !scope) return;
1674
+ onTrackAnalyticsEvent(
1675
+ buildAnalyticEvent({
1676
+ scope,
1677
+ tool,
1678
+ pageContext: page,
1679
+ buttonType,
1680
+ baseProperties: buildBaseProperties(),
1681
+ action,
1682
+ additionalProperties
1683
+ })
1684
+ );
1685
+ },
1686
+ [onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
1687
+ );
1688
+ return {
1689
+ trackTranslateButtonClicked,
1690
+ trackHighlightButtonClicked,
1691
+ trackCustomEvent,
1692
+ isTrackingEnabled
1693
+ };
1694
+ }
1695
+
1450
1696
  // src/components/AITranslateText.tsx
1451
- var import_react4 = require("react");
1697
+ var import_react5 = require("react");
1452
1698
 
1453
1699
  // src/components/TranslatedIcon.tsx
1454
- var import_react3 = require("react");
1700
+ var import_react4 = require("react");
1455
1701
  var import_jsx_runtime2 = require("react/jsx-runtime");
1456
1702
  var TranslatedIcon = ({
1457
- width = 14,
1458
- height = 14,
1703
+ width = 24,
1704
+ height = 24,
1459
1705
  className,
1460
1706
  color = "#000000"
1461
1707
  }) => {
@@ -1468,11 +1714,12 @@ var TranslatedIcon = ({
1468
1714
  className,
1469
1715
  xmlns: "http://www.w3.org/2000/svg",
1470
1716
  "aria-hidden": "true",
1717
+ style: { marginRight: "10px", flexShrink: 0 },
1471
1718
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1472
1719
  "path",
1473
1720
  {
1474
1721
  fill: color,
1475
- d: "M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"
1722
+ d: "M11.99 2C6.47 2 2 6.48 2 12C2 17.52 6.47 22 11.99 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 11.99 2ZM18.92 8H15.97C15.65 6.75 15.19 5.55 14.59 4.44C16.43 5.07 17.96 6.35 18.92 8ZM12 4.04C12.83 5.24 13.48 6.57 13.91 8H10.09C10.52 6.57 11.17 5.24 12 4.04ZM4.26 14C4.1 13.36 4 12.69 4 12C4 11.31 4.1 10.64 4.26 10H7.64C7.56 10.66 7.5 11.32 7.5 12C7.5 12.68 7.56 13.34 7.64 14H4.26ZM5.08 16H8.03C8.35 17.25 8.81 18.45 9.41 19.56C7.57 18.93 6.04 17.66 5.08 16ZM8.03 8H5.08C6.04 6.34 7.57 5.07 9.41 4.44C8.81 5.55 8.35 6.75 8.03 8ZM12 19.96C11.17 18.76 10.52 17.43 10.09 16H13.91C13.48 17.43 12.83 18.76 12 19.96ZM14.34 14H9.66C9.57 13.34 9.5 12.68 9.5 12C9.5 11.32 9.57 10.65 9.66 10H14.34C14.43 10.65 14.5 11.32 14.5 12C14.5 12.68 14.43 13.34 14.34 14ZM14.59 19.56C15.19 18.45 15.65 17.25 15.97 16H18.92C17.96 17.65 16.43 18.93 14.59 19.56ZM16.36 14C16.44 13.34 16.5 12.68 16.5 12C16.5 11.32 16.44 10.66 16.36 10H19.74C19.9 10.64 20 11.31 20 12C20 12.69 19.9 13.36 19.74 14H16.36Z"
1476
1723
  }
1477
1724
  )
1478
1725
  }
@@ -1487,11 +1734,11 @@ var AITranslateText = ({
1487
1734
  showHighlight = false,
1488
1735
  translatedIconProps
1489
1736
  }) => {
1490
- const context = (0, import_react4.useContext)(AITranslationContext);
1491
- const [displayText, setDisplayText] = (0, import_react4.useState)(text ?? "");
1492
- const [showHighlightState, setShowHighlightState] = (0, import_react4.useState)(showHighlight);
1493
- const eventHandlerRef = (0, import_react4.useRef)(null);
1494
- (0, import_react4.useEffect)(() => {
1737
+ const context = (0, import_react5.useContext)(AITranslationContext);
1738
+ const [displayText, setDisplayText] = (0, import_react5.useState)(text ?? "");
1739
+ const [showHighlightState, setShowHighlightState] = (0, import_react5.useState)(showHighlight);
1740
+ const eventHandlerRef = (0, import_react5.useRef)(null);
1741
+ (0, import_react5.useEffect)(() => {
1495
1742
  if (!context) return;
1496
1743
  if (!eventHandlerRef.current) {
1497
1744
  eventHandlerRef.current = new EventHandler(context.tool);
@@ -1510,14 +1757,14 @@ var AITranslateText = ({
1510
1757
  );
1511
1758
  return () => unsubscribe();
1512
1759
  }, [context, text, showHighlight]);
1513
- const reset = (0, import_react4.useCallback)(
1760
+ const reset = (0, import_react5.useCallback)(
1514
1761
  (displayValue = text) => {
1515
1762
  setDisplayText(displayValue);
1516
1763
  setShowHighlightState(false);
1517
1764
  },
1518
1765
  [text]
1519
1766
  );
1520
- (0, import_react4.useEffect)(() => {
1767
+ (0, import_react5.useEffect)(() => {
1521
1768
  if (text == null || text === "") {
1522
1769
  reset(text ?? "");
1523
1770
  return;
@@ -1544,8 +1791,8 @@ var AITranslateText = ({
1544
1791
  };
1545
1792
  }, [text, shouldTranslate, context, showHighlight, reset]);
1546
1793
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1547
- displayText,
1548
- showHighlightState && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TranslatedIcon, { ...translatedIconProps })
1794
+ showHighlightState && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TranslatedIcon, { ...translatedIconProps }),
1795
+ displayText
1549
1796
  ] });
1550
1797
  };
1551
1798
 
@@ -1569,10 +1816,16 @@ var getAITranslationLDId = (domain) => {
1569
1816
  };
1570
1817
  // Annotate the CommonJS export names for ESM import in node:
1571
1818
  0 && (module.exports = {
1819
+ ACTION,
1572
1820
  AITranslateText,
1573
1821
  AITranslationProvider,
1574
1822
  AI_TRANSLATION_FEATURE_FLAG_KEY,
1823
+ BUTTON_TYPE,
1824
+ buildAnalyticEvent,
1825
+ buildEventKey,
1826
+ buildObject,
1575
1827
  getAITranslationLDId,
1828
+ useAIAnalytics,
1576
1829
  useAITranslation,
1577
1830
  useConfig
1578
1831
  });