@eko-ai/eko 3.1.0 → 3.1.2

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.esm.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const config$1 = {
2
2
  name: "Eko",
3
+ mode: "normal",
3
4
  platform: "mac",
4
5
  maxReactNum: 500,
5
6
  maxTokens: 16000,
@@ -12,6 +13,7 @@ const config$1 = {
12
13
  maxDialogueImgFileNum: 1,
13
14
  toolResultMultimodal: true,
14
15
  parallelToolCalls: true,
16
+ markImageMode: "dom",
15
17
  expertMode: false,
16
18
  expertModeTodoLoopNum: 10,
17
19
  };
@@ -31937,7 +31939,7 @@ class Eko {
31937
31939
  results.push(agent_results.join("\n\n"));
31938
31940
  }
31939
31941
  context.conversation.splice(0, context.conversation.length);
31940
- if (config$1.expertMode &&
31942
+ if ((config$1.mode == "expert" || config$1.expertMode) &&
31941
31943
  !workflow.modified &&
31942
31944
  agentTree.nextAgent &&
31943
31945
  lastAgent?.AgentContext &&
@@ -34184,12 +34186,12 @@ class Agent {
34184
34186
  const finalResult = await this.handleCallResult(agentContext, messages, agentTools, results);
34185
34187
  loopNum++;
34186
34188
  if (!finalResult) {
34187
- if (config$1.expertMode && loopNum % config$1.expertModeTodoLoopNum == 0) {
34189
+ if ((config$1.mode == "expert" || config$1.expertMode) && loopNum % config$1.expertModeTodoLoopNum == 0) {
34188
34190
  await doTodoListManager(agentContext, rlm, messages, llm_tools);
34189
34191
  }
34190
34192
  continue;
34191
34193
  }
34192
- if (config$1.expertMode && checkNum == 0) {
34194
+ if ((config$1.mode == "expert" || config$1.expertMode) && checkNum == 0) {
34193
34195
  checkNum++;
34194
34196
  const { completionStatus } = await doTaskResultCheck(agentContext, rlm, messages, llm_tools);
34195
34197
  if (completionStatus == "incomplete") {
@@ -35081,10 +35083,145 @@ function extract_page_content(max_url_length = 200, max_content_length = 50000)
35081
35083
  result = result.replace(/\s*\n/g, "\n").replace(/\n+/g, "\n").trim();
35082
35084
  if (result.length > max_content_length) {
35083
35085
  // result = result.slice(0, max_content_length) + "...";
35084
- result = Array.from(result).slice(0, max_content_length).join('') + "...";
35086
+ result = Array.from(result).slice(0, max_content_length).join("") + "...";
35085
35087
  }
35086
35088
  return result;
35087
35089
  }
35090
+ function mark_screenshot_highlight_elements(screenshot, area_map, client_rect) {
35091
+ return new Promise(async (resolve, reject) => {
35092
+ try {
35093
+ // Convert base64 to Blob
35094
+ const base64Data = screenshot.imageBase64;
35095
+ const binaryString = atob(base64Data);
35096
+ const bytes = new Uint8Array(binaryString.length);
35097
+ for (let i = 0; i < binaryString.length; i++) {
35098
+ bytes[i] = binaryString.charCodeAt(i);
35099
+ }
35100
+ const blob = new Blob([bytes], { type: screenshot.imageType });
35101
+ const imageBitmap = await createImageBitmap(blob, {
35102
+ resizeQuality: "high",
35103
+ resizeWidth: client_rect.width,
35104
+ resizeHeight: client_rect.height,
35105
+ });
35106
+ const canvas = new OffscreenCanvas(imageBitmap.width, imageBitmap.height);
35107
+ const ctx = canvas.getContext("2d");
35108
+ if (!ctx) {
35109
+ reject(new Error("Failed to get canvas context"));
35110
+ return;
35111
+ }
35112
+ ctx.imageSmoothingEnabled = true;
35113
+ ctx.imageSmoothingQuality = "high";
35114
+ ctx.drawImage(imageBitmap, 0, 0);
35115
+ const sortedEntries = Object.entries(area_map)
35116
+ .filter(([id, area]) => area.width > 0 && area.height > 0)
35117
+ .sort((a, b) => {
35118
+ const areaA = a[1].width * a[1].height;
35119
+ const areaB = b[1].width * b[1].height;
35120
+ return areaA - areaB;
35121
+ });
35122
+ const colors = [
35123
+ "#FF0000",
35124
+ "#00FF00",
35125
+ "#0000FF",
35126
+ "#FFA500",
35127
+ "#800080",
35128
+ "#008080",
35129
+ "#FF69B4",
35130
+ "#4B0082",
35131
+ "#FF4500",
35132
+ "#2E8B57",
35133
+ "#DC143C",
35134
+ "#4682B4",
35135
+ ];
35136
+ sortedEntries.forEach(([id, area], index) => {
35137
+ const color = colors[index % colors.length];
35138
+ // Draw a border
35139
+ ctx.strokeStyle = color;
35140
+ ctx.lineWidth = 2;
35141
+ ctx.strokeRect(area.x, area.y, area.width, area.height);
35142
+ // Draw ID tag background
35143
+ const fontSize = Math.min(12, Math.max(8, area.height / 2));
35144
+ ctx.font = `${fontSize}px sans-serif`;
35145
+ const textMetrics = ctx.measureText(id);
35146
+ const padding = 4;
35147
+ const labelWidth = textMetrics.width + padding * 2;
35148
+ const labelHeight = fontSize + padding * 2;
35149
+ // The tag position is in the upper right corner.
35150
+ const labelX = area.x + area.width - labelWidth;
35151
+ let labelY = area.y;
35152
+ // Adjust if box is too small
35153
+ if (area.width < labelWidth + 4 || area.height < labelHeight + 4) {
35154
+ // Position outside the box if it's too small
35155
+ labelY = area.y - labelHeight;
35156
+ }
35157
+ // Draw label background
35158
+ ctx.fillStyle = color;
35159
+ ctx.fillRect(labelX, labelY, labelWidth, labelHeight);
35160
+ // Draw ID text
35161
+ ctx.fillStyle = "#FFFFFF";
35162
+ ctx.textBaseline = "top";
35163
+ ctx.fillText(id, labelX + padding, labelY + padding);
35164
+ });
35165
+ // Convert OffscreenCanvas to Blob, then to base64
35166
+ const resultBlob = await canvas.convertToBlob({
35167
+ type: screenshot.imageType,
35168
+ });
35169
+ const reader = new FileReader();
35170
+ reader.onloadend = () => {
35171
+ const resultBase64 = reader.result;
35172
+ resolve(resultBase64);
35173
+ };
35174
+ reader.onerror = () => {
35175
+ reject(new Error("Failed to convert blob to base64"));
35176
+ };
35177
+ reader.readAsDataURL(resultBlob);
35178
+ }
35179
+ catch (error) {
35180
+ reject(error);
35181
+ }
35182
+ });
35183
+ }
35184
+ async function compress_image(imageBase64, imageType, compress, quality = 1) {
35185
+ const base64Data = imageBase64;
35186
+ const binaryString = atob(base64Data);
35187
+ const bytes = new Uint8Array(binaryString.length);
35188
+ for (let i = 0; i < binaryString.length; i++) {
35189
+ bytes[i] = binaryString.charCodeAt(i);
35190
+ }
35191
+ const blob = new Blob([bytes], { type: imageType });
35192
+ const bitmap = await createImageBitmap(blob);
35193
+ const width = compress.scale
35194
+ ? bitmap.width * compress.scale
35195
+ : compress.resizeWidth;
35196
+ const height = compress.scale
35197
+ ? bitmap.height * compress.scale
35198
+ : compress.resizeHeight;
35199
+ if (bitmap.width == width && bitmap.height == height && quality == 1) {
35200
+ return {
35201
+ imageBase64: imageBase64,
35202
+ imageType: imageType,
35203
+ };
35204
+ }
35205
+ const canvas = new OffscreenCanvas(width, height);
35206
+ const ctx = canvas.getContext("2d");
35207
+ ctx.drawImage(bitmap, 0, 0, width, height);
35208
+ const resultBlob = await canvas.convertToBlob({
35209
+ type: "image/jpeg",
35210
+ quality: quality,
35211
+ });
35212
+ return new Promise((resolve) => {
35213
+ const reader = new FileReader();
35214
+ reader.onloadend = () => {
35215
+ let imageDataUrl = reader.result;
35216
+ let imageBase64 = imageDataUrl.substring(imageDataUrl.indexOf("base64,") + 7);
35217
+ resolve({
35218
+ imageBase64: imageBase64,
35219
+ imageType: "image/jpeg",
35220
+ });
35221
+ };
35222
+ reader.readAsDataURL(resultBlob);
35223
+ });
35224
+ }
35088
35225
 
35089
35226
  const AGENT_NAME = "Browser";
35090
35227
  class BaseBrowserAgent extends Agent {
@@ -35266,19 +35403,30 @@ function run_build_dom_tree() {
35266
35403
  /**
35267
35404
  * Get clickable elements on the page
35268
35405
  *
35269
- * @param {*} doHighlightElements Is highlighted
35406
+ * @param {*} markHighlightElements Is mark highlighted
35270
35407
  * @param {*} includeAttributes [attr_names...]
35271
- * @returns { element_str, selector_map }
35408
+ * @returns { element_str, client_rect, selector_map, area_map }
35272
35409
  */
35273
- function get_clickable_elements(doHighlightElements = true, includeAttributes) {
35410
+ function get_clickable_elements(markHighlightElements = true, includeAttributes) {
35274
35411
  window.clickable_elements = {};
35275
35412
  computedStyleCache = new WeakMap();
35276
35413
  document.querySelectorAll("[eko-user-highlight-id]").forEach(ele => ele.removeAttribute("eko-user-highlight-id"));
35277
- let page_tree = build_dom_tree(doHighlightElements);
35414
+ let page_tree = build_dom_tree(markHighlightElements);
35278
35415
  let element_tree = parse_node(page_tree);
35279
- let selector_map = create_selector_map(element_tree);
35280
35416
  let element_str = clickable_elements_to_string(element_tree, includeAttributes);
35281
- return { element_str, selector_map };
35417
+ let client_rect = {
35418
+ width: window.innerWidth || document.documentElement.clientWidth,
35419
+ height: window.innerHeight || document.documentElement.clientHeight,
35420
+ };
35421
+ if (markHighlightElements) {
35422
+ let selector_map = {};
35423
+ // selector_map = create_selector_map(element_tree);
35424
+ return { element_str, client_rect, selector_map };
35425
+ }
35426
+ else {
35427
+ let area_map = create_area_map(element_tree);
35428
+ return { element_str, client_rect, area_map };
35429
+ }
35282
35430
  }
35283
35431
  function get_highlight_element(highlightIndex) {
35284
35432
  let element = document.querySelector(`[eko-user-highlight-id="eko-highlight-${highlightIndex}"]`);
@@ -35377,12 +35525,13 @@ function run_build_dom_tree() {
35377
35525
  process_node(element_tree);
35378
35526
  return formatted_text.join('\n');
35379
35527
  }
35380
- function create_selector_map(element_tree) {
35381
- let selector_map = {};
35528
+ function create_area_map(element_tree) {
35529
+ let area_map = {};
35382
35530
  function process_node(node) {
35383
35531
  if (node.tagName) {
35384
35532
  if (node.highlightIndex != null) {
35385
- selector_map[node.highlightIndex] = node;
35533
+ const element = window.clickable_elements[node.highlightIndex];
35534
+ area_map[node.highlightIndex] = get_element_real_bounding_rect(element);
35386
35535
  }
35387
35536
  for (let i = 0; i < node.children.length; i++) {
35388
35537
  process_node(node.children[i]);
@@ -35390,7 +35539,38 @@ function run_build_dom_tree() {
35390
35539
  }
35391
35540
  }
35392
35541
  process_node(element_tree);
35393
- return selector_map;
35542
+ return area_map;
35543
+ }
35544
+ function get_element_real_bounding_rect(element) {
35545
+ if (!element || !(element instanceof Element)) {
35546
+ return { x: 0, y: 0, width: 0, height: 0 };
35547
+ }
35548
+ let rect = element.getBoundingClientRect();
35549
+ let x = rect.left;
35550
+ let y = rect.top;
35551
+ let width = rect.width;
35552
+ let height = rect.height;
35553
+ let win = element.ownerDocument.defaultView;
35554
+ let maxDepth = 10;
35555
+ let depth = 0;
35556
+ while (win && win !== win.parent && depth < maxDepth) {
35557
+ depth++;
35558
+ const frameElement = win.frameElement;
35559
+ if (!frameElement) {
35560
+ break;
35561
+ }
35562
+ const frameRect = frameElement.getBoundingClientRect();
35563
+ x += frameRect.left;
35564
+ y += frameRect.top;
35565
+ // Consider the border and padding of the iframe.
35566
+ const frameStyle = getCachedComputedStyle(frameElement);
35567
+ x += parseFloat(frameStyle.borderLeftWidth) || 0;
35568
+ y += parseFloat(frameStyle.borderTopWidth) || 0;
35569
+ x += parseFloat(frameStyle.paddingLeft) || 0;
35570
+ y += parseFloat(frameStyle.paddingTop) || 0;
35571
+ win = win.parent;
35572
+ }
35573
+ return { x, y, width, height };
35394
35574
  }
35395
35575
  function parse_node(node_data, parent) {
35396
35576
  if (!node_data) {
@@ -35430,7 +35610,7 @@ function run_build_dom_tree() {
35430
35610
  }
35431
35611
  return element_node;
35432
35612
  }
35433
- function build_dom_tree(doHighlightElements) {
35613
+ function build_dom_tree(markHighlightElements) {
35434
35614
  let highlightIndex = 0; // Reset highlight index
35435
35615
  function highlightElement(element, index, parentIframe = null) {
35436
35616
  // Create or get highlight container
@@ -35630,13 +35810,10 @@ function run_build_dom_tree() {
35630
35810
  interactiveRoles.has(ariaRole) ||
35631
35811
  (tabIndex !== null && tabIndex !== '-1') ||
35632
35812
  element.getAttribute('data-action') === 'a-dropdown-select' ||
35633
- element.getAttribute('data-action') === 'a-dropdown-button';
35813
+ element.getAttribute('data-action') === 'a-dropdown-button' ||
35814
+ element.getAttribute('contenteditable') === 'true';
35634
35815
  if (hasInteractiveRole)
35635
35816
  return true;
35636
- // Get computed style
35637
- const style = getCachedComputedStyle(element);
35638
- // Check if element has click-like styling
35639
- const hasClickStyling = style.cursor === 'pointer' || element.style.cursor === 'pointer';
35640
35817
  // Check for event listeners
35641
35818
  const hasClickHandler = element.onclick !== null ||
35642
35819
  element.getAttribute('onclick') !== null ||
@@ -35644,10 +35821,13 @@ function run_build_dom_tree() {
35644
35821
  element.hasAttribute('@click') ||
35645
35822
  element.hasAttribute('v-on:click');
35646
35823
  // Helper function to safely get event listeners
35647
- function getEventListeners(el) {
35648
- // if (window.getEventListeners) {
35649
- // return window.getEventListeners?.(el) || {};
35650
- // }
35824
+ function getElementEventListeners(el) {
35825
+ if (window.getEventListeners) {
35826
+ const listeners = window.getEventListeners?.(el);
35827
+ if (listeners) {
35828
+ return listeners;
35829
+ }
35830
+ }
35651
35831
  // List of common event types to check
35652
35832
  const listeners = {};
35653
35833
  const eventTypes = [
@@ -35675,7 +35855,7 @@ function run_build_dom_tree() {
35675
35855
  return listeners;
35676
35856
  }
35677
35857
  // Check for click-related events on the element itself
35678
- const listeners = getEventListeners(element);
35858
+ const listeners = getElementEventListeners(element);
35679
35859
  const hasClickListeners = listeners &&
35680
35860
  (listeners.click?.length > 0 ||
35681
35861
  listeners.mousedown?.length > 0 ||
@@ -35687,18 +35867,27 @@ function run_build_dom_tree() {
35687
35867
  element.hasAttribute('aria-pressed') ||
35688
35868
  element.hasAttribute('aria-selected') ||
35689
35869
  element.hasAttribute('aria-checked');
35690
- // Check for form-related functionality
35691
- element.form !== undefined ||
35692
- element.hasAttribute('contenteditable') ||
35693
- (style && style.userSelect !== 'none');
35694
35870
  // Check if element is draggable
35695
35871
  const isDraggable = element.draggable || element.getAttribute('draggable') === 'true';
35696
- return (hasAriaProps ||
35697
- hasClickStyling ||
35698
- hasClickHandler ||
35699
- hasClickListeners ||
35700
- // isFormRelated ||
35701
- isDraggable);
35872
+ if (hasAriaProps || hasClickHandler || hasClickListeners || isDraggable) {
35873
+ return true;
35874
+ }
35875
+ // Check if element has click-like styling
35876
+ let hasClickStyling = element.style.cursor === 'pointer' || getCachedComputedStyle(element).cursor === 'pointer';
35877
+ if (hasClickStyling) {
35878
+ let count = 0;
35879
+ let current = element.parentElement;
35880
+ while (current && current !== document.documentElement) {
35881
+ hasClickStyling = current.style.cursor === 'pointer' || getCachedComputedStyle(current).cursor === 'pointer';
35882
+ if (hasClickStyling)
35883
+ return false;
35884
+ current = current.parentElement;
35885
+ if (++count > 10)
35886
+ break;
35887
+ }
35888
+ return true;
35889
+ }
35890
+ return false;
35702
35891
  }
35703
35892
  // Helper function to check if element is visible
35704
35893
  function isElementVisible(element) {
@@ -35728,11 +35917,14 @@ function run_build_dom_tree() {
35728
35917
  if (!topEl)
35729
35918
  return false;
35730
35919
  // Check if the element or any of its parents match our target element
35920
+ let count = 0;
35731
35921
  let current = topEl;
35732
35922
  while (current && current !== shadowRoot) {
35733
35923
  if (current === element)
35734
35924
  return true;
35735
35925
  current = current.parentElement;
35926
+ if (++count > 15)
35927
+ break;
35736
35928
  }
35737
35929
  return false;
35738
35930
  }
@@ -35747,11 +35939,14 @@ function run_build_dom_tree() {
35747
35939
  const topEl = document.elementFromPoint(point.x, point.y);
35748
35940
  if (!topEl)
35749
35941
  return false;
35942
+ let count = 0;
35750
35943
  let current = topEl;
35751
35944
  while (current && current !== document.documentElement) {
35752
35945
  if (current === element)
35753
35946
  return true;
35754
35947
  current = current.parentElement;
35948
+ if (++count > 15)
35949
+ break;
35755
35950
  }
35756
35951
  return false;
35757
35952
  }
@@ -35821,7 +36016,7 @@ function run_build_dom_tree() {
35821
36016
  if (shouldHighlight) {
35822
36017
  nodeData.highlightIndex = highlightIndex++;
35823
36018
  window.clickable_elements[nodeData.highlightIndex] = node;
35824
- if (doHighlightElements) {
36019
+ if (markHighlightElements) {
35825
36020
  highlightElement(node, nodeData.highlightIndex, parentIframe);
35826
36021
  }
35827
36022
  }
@@ -35982,26 +36177,37 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
35982
36177
  }
35983
36178
  async screenshot_and_html(agentContext) {
35984
36179
  try {
35985
- let element_result = null;
36180
+ let element_result;
36181
+ let double_screenshots;
35986
36182
  for (let i = 0; i < 5; i++) {
35987
36183
  await sleep(200);
35988
36184
  await this.execute_script(agentContext, run_build_dom_tree, []);
35989
36185
  await sleep(50);
35990
- element_result = (await this.execute_script(agentContext, () => {
35991
- return window.get_clickable_elements(true);
35992
- }, []));
36186
+ element_result = (await this.execute_script(agentContext, (markHighlightElements) => {
36187
+ return window.get_clickable_elements(markHighlightElements);
36188
+ }, [config$1.mode != "fast" && config$1.markImageMode == "dom"]));
35993
36189
  if (element_result) {
35994
36190
  break;
35995
36191
  }
35996
36192
  }
35997
36193
  await sleep(100);
35998
- let screenshot = await this.screenshot(agentContext);
35999
- // agentContext.variables.set("selector_map", element_result.selector_map);
36000
- let pseudoHtml = element_result?.element_str || "";
36194
+ const screenshot = config$1.mode == "fast"
36195
+ ? undefined
36196
+ : await this.screenshot_and_compress(agentContext, element_result.client_rect);
36197
+ if (config$1.markImageMode == "draw" &&
36198
+ screenshot?.imageBase64 &&
36199
+ element_result.area_map) {
36200
+ double_screenshots = { ...screenshot };
36201
+ const markImageBase64 = await mark_screenshot_highlight_elements(screenshot, element_result.area_map, element_result.client_rect);
36202
+ screenshot.imageBase64 = markImageBase64;
36203
+ }
36204
+ const pseudoHtml = element_result.element_str || "";
36001
36205
  return {
36002
- imageBase64: screenshot.imageBase64,
36003
- imageType: screenshot.imageType,
36206
+ double_screenshots: double_screenshots,
36207
+ imageBase64: screenshot?.imageBase64,
36208
+ imageType: screenshot?.imageType,
36004
36209
  pseudoHtml: pseudoHtml,
36210
+ client_rect: element_result.client_rect,
36005
36211
  };
36006
36212
  }
36007
36213
  finally {
@@ -36013,6 +36219,20 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
36013
36219
  catch (e) { }
36014
36220
  }
36015
36221
  }
36222
+ async screenshot_and_compress(agentContext, client_rect) {
36223
+ const screenshot = await this.screenshot(agentContext);
36224
+ if (!client_rect || !screenshot) {
36225
+ return screenshot;
36226
+ }
36227
+ const compressedImage = await compress_image(screenshot.imageBase64, screenshot.imageType, {
36228
+ resizeWidth: client_rect.width,
36229
+ resizeHeight: client_rect.height,
36230
+ });
36231
+ return {
36232
+ imageBase64: compressedImage.imageBase64,
36233
+ imageType: compressedImage.imageType,
36234
+ };
36235
+ }
36016
36236
  get_element_script(index) {
36017
36237
  return `window.get_highlight_element(${index});`;
36018
36238
  }
@@ -36272,7 +36492,7 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
36272
36492
  ];
36273
36493
  }
36274
36494
  async double_screenshots(agentContext, messages, tools) {
36275
- return true;
36495
+ return config$1.mode != "fast";
36276
36496
  }
36277
36497
  async handleMessages(agentContext, messages, tools) {
36278
36498
  const pseudoHtmlDescription = "This is the environmental information after the operation, including the latest browser screenshot and page elements. Please perform the next operation based on the environmental information. Do not output the following elements and index information in your response.\n\nIndex and elements:\n";
@@ -36282,23 +36502,27 @@ class BaseBrowserLabelsAgent extends BaseBrowserAgent {
36282
36502
  lastTool.toolName !== "get_all_tabs" &&
36283
36503
  lastTool.toolName !== "variable_storage") {
36284
36504
  await sleep(300);
36285
- let image_contents = [];
36505
+ const image_contents = [];
36506
+ const result = await this.screenshot_and_html(agentContext);
36286
36507
  if (await this.double_screenshots(agentContext, messages, tools)) {
36287
- let imageResult = await this.screenshot(agentContext);
36288
- let image = toImage(imageResult.imageBase64);
36508
+ const imageResult = result.double_screenshots
36509
+ ? result.double_screenshots
36510
+ : await this.screenshot_and_compress(agentContext, result.client_rect);
36511
+ const image = toImage(imageResult.imageBase64);
36289
36512
  image_contents.push({
36290
36513
  type: "file",
36291
36514
  data: image,
36292
36515
  mediaType: imageResult.imageType,
36293
36516
  });
36294
36517
  }
36295
- let result = await this.screenshot_and_html(agentContext);
36296
- let image = toImage(result.imageBase64);
36297
- image_contents.push({
36298
- type: "file",
36299
- data: image,
36300
- mediaType: result.imageType,
36301
- });
36518
+ if (result.imageBase64) {
36519
+ const image = toImage(result.imageBase64);
36520
+ image_contents.push({
36521
+ type: "file",
36522
+ data: image,
36523
+ mediaType: result.imageType || "image/png",
36524
+ });
36525
+ }
36302
36526
  messages.push({
36303
36527
  role: "user",
36304
36528
  content: [
@@ -36447,7 +36671,7 @@ function do_click(params) {
36447
36671
  cancelable: true,
36448
36672
  button, // 0 left; 1 middle; 2 right
36449
36673
  });
36450
- if (eventType === 'click' && element.click) {
36674
+ if (eventType === "click" && element.click) {
36451
36675
  // support shadow dom element
36452
36676
  element.click();
36453
36677
  }