@formulaxjs/kity-runtime 0.3.0 → 0.4.0

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
@@ -1080,6 +1080,22 @@ var init_toolbar_assets = __esm({
1080
1080
  }
1081
1081
  });
1082
1082
 
1083
+ // src/i18n.ts
1084
+ function normalizeFormulaXLocale(locale) {
1085
+ if (locale === "zh_CN") {
1086
+ return "zh_CN";
1087
+ }
1088
+ return DEFAULT_FORMULAX_LOCALE;
1089
+ }
1090
+ var FORMULAX_LOCALES, DEFAULT_FORMULAX_LOCALE;
1091
+ var init_i18n = __esm({
1092
+ "src/i18n.ts"() {
1093
+ "use strict";
1094
+ FORMULAX_LOCALES = ["en_US", "zh_CN"];
1095
+ DEFAULT_FORMULAX_LOCALE = "en_US";
1096
+ }
1097
+ });
1098
+
1083
1099
  // src/vendor/kity-formula/binary-expression.ts
1084
1100
  var BinaryExpressionModule, createBinaryExpressionClass;
1085
1101
  var init_binary_expression = __esm({
@@ -1944,15 +1960,13 @@ var init_expression = __esm({
1944
1960
  });
1945
1961
 
1946
1962
  // src/vendor/kity-formula/font-installer.ts
1947
- var MAIN_FONT_FAMILY, FontInstallerModule, createFontInstallerClass;
1963
+ var FontInstallerModule, createFontInstallerClass;
1948
1964
  var init_font_installer = __esm({
1949
1965
  "src/vendor/kity-formula/font-installer.ts"() {
1950
1966
  "use strict";
1951
- MAIN_FONT_FAMILY = "KF AMS MAIN";
1952
1967
  FontInstallerModule = class {
1953
1968
  static create(kity26, FontManager, fontConfig, checkerTemplate) {
1954
1969
  let nodeList = [];
1955
- let checkerNode = null;
1956
1970
  return kity26.createClass("FontInstaller", {
1957
1971
  constructor: function(doc, resource) {
1958
1972
  const normalized = typeof resource === "string" ? { path: resource } : resource ?? {};
@@ -1962,26 +1976,22 @@ var init_font_installer = __esm({
1962
1976
  },
1963
1977
  mount: function(callback) {
1964
1978
  const fontList = FontManager.getFontList();
1979
+ let count = 0;
1965
1980
  kity26.Utils.each(fontList, (fontInfo) => {
1981
+ count += 1;
1966
1982
  fontInfo.meta.src = resolveFontSource(this.fonts, this.resource, fontInfo.meta.src);
1967
1983
  this.createFontStyle(fontInfo);
1968
- if (fontInfo.meta.fontFamily === MAIN_FONT_FAMILY) {
1969
- checkerNode = createFontCheckerNode(this.doc);
1970
- return;
1971
- }
1972
1984
  applyFonts(this.doc, fontInfo);
1985
+ count -= 1;
1986
+ if (count === 0) {
1987
+ complete(this.doc, callback);
1988
+ }
1973
1989
  });
1974
- complete(this.doc, callback);
1975
1990
  },
1976
1991
  createFontStyle: function(fontInfo) {
1977
- const styleId = createFontStyleId(fontInfo);
1978
- if (this.doc.getElementById(styleId)) {
1979
- return;
1980
- }
1981
1992
  const stylesheet = this.doc.createElement("style");
1982
1993
  const tpl = '@font-face{\nfont-family: "${fontFamily}";\nsrc: url("${src}");\n}';
1983
1994
  stylesheet.setAttribute("type", "text/css");
1984
- stylesheet.id = styleId;
1985
1995
  stylesheet.innerHTML = tpl.replace("${fontFamily}", fontInfo.meta.fontFamily).replace("${src}", fontInfo.meta.src);
1986
1996
  this.doc.head.appendChild(stylesheet);
1987
1997
  }
@@ -1998,29 +2008,34 @@ var init_font_installer = __esm({
1998
2008
  }
1999
2009
  return resourceBase + originalSrc;
2000
2010
  }
2001
- function createFontStyleId(fontInfo) {
2002
- const raw = `${fontInfo.meta.fontFamily}::${fontInfo.meta.src}`;
2003
- let hash = 0;
2004
- for (let index = 0; index < raw.length; index += 1) {
2005
- hash = (hash << 5) - hash + raw.charCodeAt(index) | 0;
2006
- }
2007
- return `formulax-kity-font-${Math.abs(hash).toString(36)}`;
2008
- }
2009
- function waitForFontsReady(doc) {
2011
+ function waitForFontsReady(doc, fontList) {
2010
2012
  const view = doc.defaultView ?? window;
2011
2013
  if (view.document.fonts) {
2012
- return view.document.fonts.ready.then(() => void 0);
2014
+ const fontLoadPromises = fontList.map((fontInfo) => {
2015
+ return view.document.fonts.load(`50px "${fontInfo.meta.fontFamily}"`);
2016
+ });
2017
+ return Promise.all(fontLoadPromises).then(() => view.document.fonts.ready).then(() => {
2018
+ return new Promise((resolve) => {
2019
+ requestAnimationFrame(() => {
2020
+ requestAnimationFrame(() => {
2021
+ resolve();
2022
+ });
2023
+ });
2024
+ });
2025
+ });
2013
2026
  }
2014
2027
  return Promise.resolve();
2015
2028
  }
2016
2029
  function complete(doc, callback) {
2017
2030
  const view = doc.defaultView ?? window;
2018
- waitForFontsReady(doc).then(() => {
2019
- return waitForNextFrames(view, 2);
2020
- }).then(() => {
2021
- initFontSystemInfo(doc);
2022
- removeTmpNode();
2023
- callback();
2031
+ const fontList = FontManager.getFontList();
2032
+ const fontArray = Object.values(fontList);
2033
+ waitForFontsReady(doc, fontArray).then(() => {
2034
+ view.setTimeout(() => {
2035
+ initFontSystemInfo(doc);
2036
+ removeTmpNode();
2037
+ callback();
2038
+ }, 100);
2024
2039
  }).catch(() => {
2025
2040
  view.setTimeout(() => {
2026
2041
  initFontSystemInfo(doc);
@@ -2041,37 +2056,12 @@ var init_font_installer = __esm({
2041
2056
  doc.body.appendChild(node);
2042
2057
  nodeList.push(node);
2043
2058
  }
2044
- function createFontCheckerNode(doc) {
2045
- if (checkerNode) {
2046
- return checkerNode;
2047
- }
2048
- const node = doc.createElement("div");
2049
- node.style.cssText = "position: absolute; top: 0; left: -100000px;";
2050
- node.innerHTML = checkerTemplate.join("");
2051
- doc.body.appendChild(node);
2052
- checkerNode = node;
2053
- return node;
2054
- }
2055
- function waitForNextFrames(view, frameCount) {
2056
- if (typeof view.requestAnimationFrame !== "function") {
2057
- return Promise.resolve();
2058
- }
2059
- return new Promise((resolve) => {
2060
- const step = (remaining) => {
2061
- if (remaining <= 0) {
2062
- resolve();
2063
- return;
2064
- }
2065
- view.requestAnimationFrame(() => {
2066
- step(remaining - 1);
2067
- });
2068
- };
2069
- step(frameCount);
2070
- });
2071
- }
2072
2059
  function initFontSystemInfo(doc) {
2073
- const activeCheckerNode = checkerNode ?? createFontCheckerNode(doc);
2074
- const rectBox = activeCheckerNode.getElementsByTagName("text")[0].getBBox();
2060
+ const tmpNode = doc.createElement("div");
2061
+ tmpNode.style.cssText = "position: absolute; top: 0; left: -100000px;";
2062
+ tmpNode.innerHTML = checkerTemplate.join("");
2063
+ doc.body.appendChild(tmpNode);
2064
+ const rectBox = tmpNode.getElementsByTagName("text")[0].getBBox();
2075
2065
  fontConfig.spaceHeight = rectBox.height;
2076
2066
  fontConfig.topSpace = -rectBox.y - fontConfig.baseline;
2077
2067
  fontConfig.bottomSpace = fontConfig.spaceHeight - fontConfig.topSpace - fontConfig.baseHeight;
@@ -2080,8 +2070,7 @@ var init_font_installer = __esm({
2080
2070
  fontConfig.meanlinePosition = (fontConfig.topSpace + fontConfig.meanline) / fontConfig.spaceHeight;
2081
2071
  fontConfig.ascenderPosition = fontConfig.topSpace / fontConfig.spaceHeight;
2082
2072
  fontConfig.descenderPosition = (fontConfig.topSpace + fontConfig.baseHeight) / fontConfig.spaceHeight;
2083
- activeCheckerNode.parentNode?.removeChild(activeCheckerNode);
2084
- checkerNode = null;
2073
+ doc.body.removeChild(tmpNode);
2085
2074
  }
2086
2075
  function removeTmpNode() {
2087
2076
  kity26.Utils.each(nodeList, (node) => {
@@ -2164,11 +2153,11 @@ var init_formula = __esm({
2164
2153
  bg;
2165
2154
  exp;
2166
2155
  config;
2167
- constructor(kity26, exp, config2) {
2156
+ constructor(kity26, exp, config) {
2168
2157
  this.wrap = new kity26.Group();
2169
2158
  this.bg = new kity26.Rect(0, 0, 0, 0).fill("transparent");
2170
2159
  this.exp = exp;
2171
- this.config = config2;
2160
+ this.config = config;
2172
2161
  this.wrap.setAttr("data-type", "kf-exp-wrap");
2173
2162
  this.bg.setAttr("data-type", "kf-exp-wrap-bg");
2174
2163
  this.wrap.addShape(this.bg);
@@ -2197,14 +2186,14 @@ var init_formula = __esm({
2197
2186
  static create(kity26, GTYPE2, FontManager, FontInstaller, FPaper, Output) {
2198
2187
  const Formula = kity26.createClass("Formula", {
2199
2188
  base: FPaper,
2200
- constructor: function(container, config2) {
2189
+ constructor: function(container, config) {
2201
2190
  if (this.__FORMULAX_PRESERVE_CALL_BASE__) {
2202
2191
  this.callBase(container);
2203
2192
  }
2204
2193
  FPaper.call(this, container);
2205
2194
  this.expressions = [];
2206
2195
  this.fontInstaller = new FontInstaller(this);
2207
- this.config = kity26.Utils.extend({}, DEFAULT_OPTIONS, config2);
2196
+ this.config = kity26.Utils.extend({}, DEFAULT_OPTIONS, config);
2208
2197
  this.initEnvironment();
2209
2198
  this.initInnerFont();
2210
2199
  },
@@ -9669,7 +9658,7 @@ function registerAssemblyModule(context) {
9669
9658
  value: function() {
9670
9659
  const kf7 = window2.kf;
9671
9660
  const CONSTRUCT_MAPPING = {};
9672
- const CURSOR_CHAR3 = "\uF155";
9661
+ const CURSOR_CHAR4 = "\uF155";
9673
9662
  class Assembly {
9674
9663
  formula;
9675
9664
  constructor(formula) {
@@ -9706,7 +9695,7 @@ function registerAssemblyModule(context) {
9706
9695
  if (tree.name.indexOf("text") === -1) {
9707
9696
  for (let i2 = 0, len = operand.length; i2 < len; i2 += 1) {
9708
9697
  currentOperand = operand[i2];
9709
- if (currentOperand === CURSOR_CHAR3) {
9698
+ if (currentOperand === CURSOR_CHAR4) {
9710
9699
  cursorLocation.push(i2);
9711
9700
  if (!Object.prototype.hasOwnProperty.call(selectInfo, "startOffset")) {
9712
9701
  selectInfo.startOffset = i2;
@@ -12878,6 +12867,35 @@ function each(list, callback) {
12878
12867
  }
12879
12868
  Object.keys(list).forEach((key) => callback(list[key], key));
12880
12869
  }
12870
+ function translateToolbarText(value, locale) {
12871
+ if (locale === "zh_CN") {
12872
+ return value;
12873
+ }
12874
+ const normalizedValue = value.replace(/<br\s*\/?>/gi, "").trim();
12875
+ const translatedValue = zhCnToEnUsText.get(normalizedValue);
12876
+ if (!translatedValue) {
12877
+ return value;
12878
+ }
12879
+ const lineBreakMatch = value.match(/<br\s*\/?>/i);
12880
+ return lineBreakMatch ? `${translatedValue}${lineBreakMatch[0]}` : translatedValue;
12881
+ }
12882
+ function localizeToolbarConfig(value, locale) {
12883
+ if (Array.isArray(value)) {
12884
+ return value.map((item) => localizeToolbarConfig(item, locale));
12885
+ }
12886
+ if (!value || typeof value !== "object") {
12887
+ return value;
12888
+ }
12889
+ const result = {};
12890
+ for (const [key, currentValue] of Object.entries(value)) {
12891
+ if ((key === "label" || key === "title") && typeof currentValue === "string") {
12892
+ result[key] = translateToolbarText(currentValue, locale);
12893
+ continue;
12894
+ }
12895
+ result[key] = localizeToolbarConfig(currentValue, locale);
12896
+ }
12897
+ return result;
12898
+ }
12881
12899
  function getUnicodeContents(keySet) {
12882
12900
  let result = [];
12883
12901
  each(keySet, function(key) {
@@ -12897,7 +12915,13 @@ function getUnicodeContents(keySet) {
12897
12915
  });
12898
12916
  return result;
12899
12917
  }
12900
- var UI_ELE_TYPE, BOX_TYPE2, OTHER_POSITION, config, toolbar_config_default;
12918
+ function createToolbarConfig(locale = DEFAULT_FORMULAX_LOCALE) {
12919
+ return localizeToolbarConfig(
12920
+ baseToolbarConfig,
12921
+ normalizeFormulaXLocale(locale)
12922
+ );
12923
+ }
12924
+ var UI_ELE_TYPE, BOX_TYPE2, OTHER_POSITION, zhCnToEnUsText, baseToolbarConfig, toolbar_config_default;
12901
12925
  var init_toolbar_config = __esm({
12902
12926
  "src/legacy/toolbar-config.ts"() {
12903
12927
  "use strict";
@@ -12906,10 +12930,45 @@ var init_toolbar_config = __esm({
12906
12930
  init_other_position();
12907
12931
  init_toolbar_assets();
12908
12932
  init_formula_symbols();
12933
+ init_i18n();
12909
12934
  UI_ELE_TYPE = legacyEleType;
12910
12935
  BOX_TYPE2 = legacyBoxType;
12911
12936
  OTHER_POSITION = legacyOtherPosition;
12912
- config = [{
12937
+ zhCnToEnUsText = /* @__PURE__ */ new Map([
12938
+ ["\u9884\u8BBE", "Presets"],
12939
+ ["\u9884\u8BBE\u516C\u5F0F", "Preset formulas"],
12940
+ ["\u4E8C\u6B21\u516C\u5F0F", "Quadratic formula"],
12941
+ ["\u4E8C\u9879\u5F0F\u5B9A\u7406", "Binomial theorem"],
12942
+ ["\u52FE\u80A1\u5B9A\u7406", "Pythagorean theorem"],
12943
+ ["\u57FA\u7840\u6570\u5B66", "Basic math"],
12944
+ ["\u5E0C\u814A\u5B57\u6BCD", "Greek letters"],
12945
+ ["\u6C42\u53CD\u5173\u7CFB\u8FD0\u7B97\u7B26", "Negated operators"],
12946
+ ["\u5B57\u6BCD\u7C7B\u7B26\u53F7", "Letter-like symbols"],
12947
+ ["\u7BAD\u5934", "Arrows"],
12948
+ ["\u624B\u5199\u4F53", "Script"],
12949
+ ["\u5206\u6570", "Fraction"],
12950
+ ["\u5E38\u7528\u5206\u6570", "Common fractions"],
12951
+ ["\u4E0A\u4E0B\u6807", "Scripts"],
12952
+ ["\u4E0A\u6807\u548C\u4E0B\u6807", "Superscripts and subscripts"],
12953
+ ["\u5E38\u7528\u7684\u4E0A\u6807\u548C\u4E0B\u6807", "Common superscripts and subscripts"],
12954
+ ["\u6839\u5F0F", "Radicals"],
12955
+ ["\u5E38\u7528\u6839\u5F0F", "Common radicals"],
12956
+ ["\u79EF\u5206", "Integrals"],
12957
+ ["\u5927\u578B\u8FD0\u7B97\u7B26", "Large operators"],
12958
+ ["\u6C42\u548C", "Summations"],
12959
+ ["\u62EC\u53F7", "Brackets"],
12960
+ ["\u65B9\u62EC\u53F7", "Brackets"],
12961
+ ["\u51FD\u6570", "Functions"],
12962
+ ["\u4E09\u89D2\u51FD\u6570", "Trigonometric functions"],
12963
+ ["\u5E38\u7528\u51FD\u6570", "Common functions"],
12964
+ ["\u5C0F\u5199", "Lowercase"],
12965
+ ["\u5927\u5199", "Uppercase"],
12966
+ ["\u53D8\u4F53", "Variants"],
12967
+ ["\u82B1\u4F53", "Fraktur"],
12968
+ ["\u53CC\u7EBF", "Double-struck"],
12969
+ ["\u7F57\u9A6C", "Roman"]
12970
+ ]);
12971
+ baseToolbarConfig = [{
12913
12972
  type: UI_ELE_TYPE.DRAPDOWN_BOX,
12914
12973
  options: {
12915
12974
  button: {
@@ -13315,7 +13374,7 @@ var init_toolbar_config = __esm({
13315
13374
  }];
13316
13375
  (function() {
13317
13376
  let tmp = [], otherImageSrc = resolveToolbarAssetPath("other.png"), currentConf = [];
13318
- each(config, function(conf) {
13377
+ each(baseToolbarConfig, function(conf) {
13319
13378
  if (conf.type === UI_ELE_TYPE.DELIMITER) {
13320
13379
  return;
13321
13380
  }
@@ -13387,7 +13446,7 @@ var init_toolbar_config = __esm({
13387
13446
  "aleph",
13388
13447
  "beth",
13389
13448
  "blacksquare"
13390
- ], configList = config[2].options.box.group[0].items;
13449
+ ], configList = baseToolbarConfig[2].options.box.group[0].items;
13391
13450
  configList.push({
13392
13451
  title: "\u57FA\u7840\u6570\u5B66",
13393
13452
  content: getUnicodeContents(list)
@@ -13403,7 +13462,7 @@ var init_toolbar_config = __esm({
13403
13462
  }, {
13404
13463
  title: "\u53D8\u4F53",
13405
13464
  values: ["digamma", "varepsilon", "varkappa", "varphi", "varpi", "varrho", "varsigma", "vartheta"]
13406
- }], greekConfigList = config[2].options.box.group[1].items;
13465
+ }], greekConfigList = baseToolbarConfig[2].options.box.group[1].items;
13407
13466
  greekConfigList.push({
13408
13467
  title: greekList[0].title,
13409
13468
  content: getUnicodeContents(greekList[0].values)
@@ -13452,7 +13511,7 @@ var init_toolbar_config = __esm({
13452
13511
  "nVDash",
13453
13512
  "nexists"
13454
13513
  ]
13455
- }], greekConfigList = config[2].options.box.group[2].items;
13514
+ }], greekConfigList = baseToolbarConfig[2].options.box.group[2].items;
13456
13515
  greekConfigList.push({
13457
13516
  title: greekList[0].title,
13458
13517
  content: getUnicodeContents(greekList[0].values)
@@ -13478,7 +13537,7 @@ var init_toolbar_config = __esm({
13478
13537
  "Game",
13479
13538
  "Im",
13480
13539
  "Re"
13481
- ], configList = config[2].options.box.group[3].items;
13540
+ ], configList = baseToolbarConfig[2].options.box.group[3].items;
13482
13541
  configList.push({
13483
13542
  title: "\u5B57\u6BCD\u7C7B\u7B26\u53F7",
13484
13543
  content: getUnicodeContents(list)
@@ -13546,7 +13605,7 @@ var init_toolbar_config = __esm({
13546
13605
  "twoheadleftarrow",
13547
13606
  "twoheadrightarrow",
13548
13607
  "rightsquigarrow"
13549
- ], configList = config[2].options.box.group[4].items;
13608
+ ], configList = baseToolbarConfig[2].options.box.group[4].items;
13550
13609
  configList.push({
13551
13610
  title: "\u7BAD\u5934",
13552
13611
  content: getUnicodeContents(list)
@@ -13725,7 +13784,7 @@ var init_toolbar_config = __esm({
13725
13784
  "y",
13726
13785
  "z"
13727
13786
  ]
13728
- }], configList = config[2].options.box.group[5].items;
13787
+ }], configList = baseToolbarConfig[2].options.box.group[5].items;
13729
13788
  each(list[0].values, function(item, index) {
13730
13789
  list[0].values[index] = "mathcal{" + item + "}";
13731
13790
  });
@@ -13755,7 +13814,7 @@ var init_toolbar_config = __esm({
13755
13814
  content: getUnicodeContents(list[3].values)
13756
13815
  });
13757
13816
  })();
13758
- toolbar_config_default = config;
13817
+ toolbar_config_default = createToolbarConfig;
13759
13818
  }
13760
13819
  });
13761
13820
 
@@ -13798,6 +13857,7 @@ var init_ui = __esm({
13798
13857
  init_toolbar();
13799
13858
  init_scrollbar();
13800
13859
  init_toolbar_config();
13860
+ init_i18n();
13801
13861
  $$8 = createLegacyUiUtils();
13802
13862
  VIEW_STATE = legacyUiDef.VIEW_STATE;
13803
13863
  DEFAULT_EDIT_AREA_HEIGHT = 100;
@@ -13828,7 +13888,8 @@ var init_ui = __esm({
13828
13888
  this.initScrollEvent();
13829
13889
  },
13830
13890
  initComponents() {
13831
- this.components.toolbar = new toolbar_default(this, this.kfEditor, toolbar_config_default);
13891
+ const toolbarConfig = toolbar_config_default(normalizeFormulaXLocale(this.options.locale));
13892
+ this.components.toolbar = new toolbar_default(this, this.kfEditor, toolbarConfig);
13832
13893
  this.components.scrollbar = new scrollbar_default(this, this.kfEditor);
13833
13894
  },
13834
13895
  updateContainerSize(container, toolbar, editArea) {
@@ -15095,6 +15156,21 @@ var init_syntax_move = __esm({
15095
15156
  });
15096
15157
 
15097
15158
  // src/legacy/syntax.ts
15159
+ function clampOffset(offset, maxOffset) {
15160
+ return Math.max(0, Math.min(offset, maxOffset));
15161
+ }
15162
+ function normalizeCursorRecord(objTree, cursor) {
15163
+ const fallbackGroupId = objTree.mapping.root.strGroup.attr.id;
15164
+ const targetGroupId = cursor.groupId && objTree.mapping[cursor.groupId] ? cursor.groupId : fallbackGroupId;
15165
+ const operandCount = objTree.mapping[targetGroupId].strGroup.operand.length;
15166
+ const startOffset = clampOffset(cursor.startOffset, operandCount);
15167
+ const endOffset = clampOffset(cursor.endOffset, operandCount);
15168
+ return {
15169
+ groupId: targetGroupId,
15170
+ startOffset: Math.min(startOffset, endOffset),
15171
+ endOffset: Math.max(startOffset, endOffset)
15172
+ };
15173
+ }
15098
15174
  var CURSOR_CHAR2, kity19, SyntaxComponent, syntax_default;
15099
15175
  var init_syntax = __esm({
15100
15176
  "src/legacy/syntax.ts"() {
@@ -15155,10 +15231,14 @@ var init_syntax = __esm({
15155
15231
  },
15156
15232
  updateObjTree(objTree) {
15157
15233
  const selectInfo = objTree.select;
15234
+ this.objTree = objTree;
15158
15235
  if (selectInfo?.groupId) {
15159
15236
  this.updateCursor(selectInfo.groupId, selectInfo.startOffset, selectInfo.endOffset);
15237
+ return;
15238
+ }
15239
+ if (this.record.cursor.groupId !== null) {
15240
+ this.record.cursor = normalizeCursorRecord(objTree, this.record.cursor);
15160
15241
  }
15161
- this.objTree = objTree;
15162
15242
  },
15163
15243
  hasCursorInfo() {
15164
15244
  return this.record.cursor.groupId !== null;
@@ -15204,7 +15284,8 @@ var init_syntax = __esm({
15204
15284
  return this.objTree;
15205
15285
  },
15206
15286
  getGroupObject(id) {
15207
- return this.objTree.mapping[id].objGroup || null;
15287
+ const groupInfo = this.objTree.mapping[id];
15288
+ return groupInfo ? groupInfo.objGroup : null;
15208
15289
  },
15209
15290
  getCursorRecord() {
15210
15291
  return kity19.Utils.extend({}, this.record.cursor);
@@ -15280,7 +15361,7 @@ var init_syntax = __esm({
15280
15361
  return this.hasRootplaceholder();
15281
15362
  },
15282
15363
  serialization() {
15283
- const cursor = this.record.cursor;
15364
+ const cursor = normalizeCursorRecord(this.objTree, this.record.cursor);
15284
15365
  const objGroup = this.objTree.mapping[cursor.groupId];
15285
15366
  const curStrGroup = objGroup.strGroup;
15286
15367
  let strStartIndex = Math.min(cursor.endOffset, cursor.startOffset);
@@ -15316,11 +15397,12 @@ var init_syntax = __esm({
15316
15397
  endOffset = startOffset;
15317
15398
  startOffset = tmp;
15318
15399
  }
15319
- this.record.cursor = {
15400
+ const nextCursor = {
15320
15401
  groupId,
15321
15402
  startOffset,
15322
15403
  endOffset
15323
15404
  };
15405
+ this.record.cursor = this.objTree ? normalizeCursorRecord(this.objTree, nextCursor) : nextCursor;
15324
15406
  },
15325
15407
  leftMove() {
15326
15408
  this.components.move.leftMove();
@@ -15361,12 +15443,20 @@ var init_syntax = __esm({
15361
15443
  });
15362
15444
 
15363
15445
  // src/legacy/input.ts
15364
- var KEY_CODE, kity20, InputComponent, input_default;
15446
+ function insertCursorMarkers(value, selectionStart, selectionEnd) {
15447
+ const normalizedStart = Math.max(0, Math.min(selectionStart ?? value.length, value.length));
15448
+ const normalizedEnd = Math.max(0, Math.min(selectionEnd ?? normalizedStart, value.length));
15449
+ const rangeStart = Math.min(normalizedStart, normalizedEnd);
15450
+ const rangeEnd = Math.max(normalizedStart, normalizedEnd);
15451
+ return value.slice(0, rangeStart) + CURSOR_CHAR3 + value.slice(rangeStart, rangeEnd) + CURSOR_CHAR3 + value.slice(rangeEnd);
15452
+ }
15453
+ var KEY_CODE, CURSOR_CHAR3, kity20, InputComponent, input_default;
15365
15454
  var init_input = __esm({
15366
15455
  "src/legacy/input.ts"() {
15367
15456
  "use strict";
15368
15457
  init_legacy_utils();
15369
15458
  init_legacy_input_filter();
15459
+ init_legacy_sysconf();
15370
15460
  init_runtime_interop();
15371
15461
  KEY_CODE = {
15372
15462
  LEFT: 37,
@@ -15374,6 +15464,7 @@ var init_input = __esm({
15374
15464
  DELETE: 8,
15375
15465
  INPUT: 229
15376
15466
  };
15467
+ CURSOR_CHAR3 = legacySysconf.cursorCharacter;
15377
15468
  kity20 = getLegacyKity();
15378
15469
  InputComponent = kity20.createClass("InputComponent", {
15379
15470
  constructor(parentComponent, kfEditor) {
@@ -15546,7 +15637,12 @@ var init_input = __esm({
15546
15637
  return `${e.shiftKey ? "s+" : ""}${e.keyCode}`;
15547
15638
  },
15548
15639
  processingInput() {
15549
- this.restruct(this.inputBox.value);
15640
+ const latexWithCursor = insertCursorMarkers(
15641
+ this.inputBox.value,
15642
+ this.inputBox.selectionStart,
15643
+ this.inputBox.selectionEnd
15644
+ );
15645
+ this.restruct(latexWithCursor);
15550
15646
  this.kfEditor.requestService("ui.update.canvas.view");
15551
15647
  },
15552
15648
  restruct(latexStr) {
@@ -16096,6 +16192,8 @@ var init_start = __esm({
16096
16192
  // src/index.ts
16097
16193
  var index_exports = {};
16098
16194
  __export(index_exports, {
16195
+ DEFAULT_FORMULAX_LOCALE: () => DEFAULT_FORMULAX_LOCALE,
16196
+ FORMULAX_LOCALES: () => FORMULAX_LOCALES,
16099
16197
  FormulaXEditor: () => FormulaXEditor,
16100
16198
  addEvent: () => addEvent,
16101
16199
  createElement: () => createElement,
@@ -16125,6 +16223,7 @@ __export(index_exports, {
16125
16223
  legacyUiDef: () => legacyUiDef,
16126
16224
  legacyUiUtils: () => legacyUiUtils,
16127
16225
  mountKityEditor: () => mountKityEditor,
16226
+ normalizeFormulaXLocale: () => normalizeFormulaXLocale,
16128
16227
  normalizeMouseEvent: () => normalizeMouseEvent,
16129
16228
  publish: () => publish,
16130
16229
  subscribe: () => subscribe
@@ -19612,6 +19711,7 @@ function clearFormulaXPerfMarks(...marks) {
19612
19711
 
19613
19712
  // src/create-editor.ts
19614
19713
  init_toolbar_assets();
19714
+ init_i18n();
19615
19715
  var DEFAULT_LATEX = "x=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}";
19616
19716
  var DEFAULT_EDITOR_HEIGHT = "auto";
19617
19717
  var KITY_STYLE_ID = "formulax-kity-editor-styles";
@@ -19762,6 +19862,7 @@ async function createKityEditor(container, options = {}) {
19762
19862
  const createEditorStart = markFormulaXPerf("fx:create-kity-editor:total");
19763
19863
  const fontsize = options.render?.fontsize ?? 40;
19764
19864
  const editorHeight = normalizeCssSize(options.height, DEFAULT_EDITOR_HEIGHT);
19865
+ const locale = normalizeFormulaXLocale(options.locale ?? DEFAULT_FORMULAX_LOCALE);
19765
19866
  const assets = resolveEditorAssets(options.assets);
19766
19867
  try {
19767
19868
  const stylesheetInserted = ensureKityStylesheet(document, assets.styles.editor);
@@ -19790,6 +19891,9 @@ async function createKityEditor(container, options = {}) {
19790
19891
  render: {
19791
19892
  fontsize
19792
19893
  },
19894
+ ui: {
19895
+ locale
19896
+ },
19793
19897
  resource: {
19794
19898
  path: "",
19795
19899
  fonts: assets.fonts
@@ -19872,6 +19976,7 @@ if (typeof window !== "undefined") {
19872
19976
 
19873
19977
  // src/index.ts
19874
19978
  init_dom_utils();
19979
+ init_i18n();
19875
19980
  init_legacy_box_type();
19876
19981
  init_legacy_component();
19877
19982
  init_legacy_ele_type();
@@ -19898,6 +20003,8 @@ init_legacy_ui_utils();
19898
20003
  init_legacy_utils();
19899
20004
  // Annotate the CommonJS export names for ESM import in node:
19900
20005
  0 && (module.exports = {
20006
+ DEFAULT_FORMULAX_LOCALE,
20007
+ FORMULAX_LOCALES,
19901
20008
  FormulaXEditor,
19902
20009
  addEvent,
19903
20010
  createElement,
@@ -19927,6 +20034,7 @@ init_legacy_utils();
19927
20034
  legacyUiDef,
19928
20035
  legacyUiUtils,
19929
20036
  mountKityEditor,
20037
+ normalizeFormulaXLocale,
19930
20038
  normalizeMouseEvent,
19931
20039
  publish,
19932
20040
  subscribe