bunnyquery 1.8.14 → 1.8.16

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/bunnyquery.js CHANGED
@@ -2438,6 +2438,9 @@ Index the REMAINING windows - one record per row/item, looking at any page image
2438
2438
  // src/engine/scroll_anchor.ts
2439
2439
  var ROW_KEY_ATTR = "data-row-key";
2440
2440
  var ROW_POS_ATTR = "data-row-pos";
2441
+ var MAX_ALTS = 2;
2442
+ var ALT_SCAN_LIMIT = 64;
2443
+ var MAX_RETURN_SETTLES = 3;
2441
2444
  var UNKNOWN_ROW_POS = "\0?";
2442
2445
  function createScrollAnchor(options) {
2443
2446
  var held = null;
@@ -2448,6 +2451,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
2448
2451
  var boxTop = box.getBoundingClientRect().top;
2449
2452
  var kids = box.children;
2450
2453
  var fallback = null;
2454
+ var fallbackAt = -1;
2451
2455
  for (var i = 0; i < kids.length; i++) {
2452
2456
  var el = kids[i];
2453
2457
  if (!el || typeof el.getAttribute !== "function") continue;
@@ -2466,10 +2470,20 @@ Index the REMAINING windows - one record per row/item, looking at any page image
2466
2470
  scrollHeight: box.scrollHeight,
2467
2471
  el
2468
2472
  };
2469
- if (rawPos === null) return cand;
2470
- if (!fallback) fallback = cand;
2473
+ if (rawPos === null) {
2474
+ cand.alts = collectAlts(box, boxTop, i + 1);
2475
+ return cand;
2476
+ }
2477
+ if (!fallback) {
2478
+ fallback = cand;
2479
+ fallbackAt = i;
2480
+ }
2471
2481
  }
2472
- return fallback || {
2482
+ if (fallback) {
2483
+ fallback.alts = collectAlts(box, boxTop, fallbackAt + 1, true);
2484
+ return fallback;
2485
+ }
2486
+ return {
2473
2487
  key: null,
2474
2488
  top: 0,
2475
2489
  pos: null,
@@ -2478,6 +2492,26 @@ Index the REMAINING windows - one record per row/item, looking at any page image
2478
2492
  el: null
2479
2493
  };
2480
2494
  }
2495
+ function collectAlts(box, boxTop, from, ordinaryOnly) {
2496
+ var out = [];
2497
+ var kids = box.children;
2498
+ var stop = Math.min(kids.length, from + ALT_SCAN_LIMIT);
2499
+ for (var i = from; i < stop && out.length < MAX_ALTS; i++) {
2500
+ var el = kids[i];
2501
+ if (!el || typeof el.getAttribute !== "function") continue;
2502
+ var key = el.getAttribute(ROW_KEY_ATTR);
2503
+ if (!key) continue;
2504
+ var rawPos = el.getAttribute(ROW_POS_ATTR);
2505
+ if (ordinaryOnly && rawPos !== null) continue;
2506
+ out.push({
2507
+ key,
2508
+ top: el.getBoundingClientRect().top - boxTop,
2509
+ pos: rawPos === null ? null : rawPos || UNKNOWN_ROW_POS,
2510
+ el
2511
+ });
2512
+ }
2513
+ return out.length ? out : void 0;
2514
+ }
2481
2515
  function findRow(box, anchor) {
2482
2516
  var el = anchor.el;
2483
2517
  if (el && el.parentNode === box) return el;
@@ -2490,31 +2524,80 @@ Index the REMAINING windows - one record per row/item, looking at any page image
2490
2524
  }
2491
2525
  return null;
2492
2526
  }
2493
- function restore(anchor) {
2527
+ var sawFrozen = false;
2528
+ var parked = null;
2529
+ var parkedStuck = false;
2530
+ var returning = false;
2531
+ var returnBudget = 0;
2532
+ var wroteTop = -1;
2533
+ var restoreExact = true;
2534
+ var restorePinned = false;
2535
+ function frozen() {
2536
+ var f = !!options.isFrozen && options.isFrozen();
2537
+ if (f) sawFrozen = true;
2538
+ return f;
2539
+ }
2540
+ function restore(anchor, unbounded) {
2541
+ if (frozen()) return;
2494
2542
  var box = options.getBox();
2495
2543
  if (!box || !anchor || options.isStuck()) return;
2496
2544
  var el = findRow(box, anchor);
2497
2545
  if (el) {
2498
2546
  var livePos = el.getAttribute(ROW_POS_ATTR) || UNKNOWN_ROW_POS;
2499
- if (anchor.pos !== null && anchor.pos !== UNKNOWN_ROW_POS && livePos !== UNKNOWN_ROW_POS && livePos !== anchor.pos) {
2500
- lost(box, anchor);
2501
- return;
2502
- }
2547
+ if (anchor.pos !== null && anchor.pos !== UNKNOWN_ROW_POS && livePos !== UNKNOWN_ROW_POS && livePos !== anchor.pos) el = null;
2548
+ }
2549
+ if (el) {
2503
2550
  var boxTop = box.getBoundingClientRect().top;
2504
2551
  var delta = el.getBoundingClientRect().top - boxTop - anchor.top;
2505
2552
  var slack = Math.abs(box.scrollHeight - anchor.scrollHeight) + box.clientHeight;
2506
- if (delta > slack || delta < -slack) {
2553
+ if (!unbounded && (delta > slack || delta < -slack)) {
2507
2554
  lost(box, anchor);
2508
2555
  return;
2509
2556
  }
2557
+ var want = box.scrollTop + delta;
2510
2558
  if (delta >= 1 || delta <= -1) box.scrollTop += delta;
2559
+ wroteTop = box.scrollTop;
2560
+ restorePinned = true;
2561
+ restoreExact = box.scrollTop >= want - 1 && box.scrollTop <= want + 1;
2511
2562
  held = {
2512
2563
  key: anchor.key,
2513
2564
  top: anchor.top,
2514
2565
  pos: anchor.pos,
2515
2566
  scrollTop: box.scrollTop,
2516
2567
  scrollHeight: box.scrollHeight,
2517
- el
2568
+ el,
2569
+ // Carried, not dropped: one successful restore used to disarm the
2570
+ // standbys for every later hold.
2571
+ alts: anchor.alts
2572
+ };
2573
+ return;
2574
+ }
2575
+ var alts = anchor.alts;
2576
+ for (var ai = 0; alts && ai < alts.length; ai++) {
2577
+ var alt = alts[ai];
2578
+ var ael = findRow(box, { key: alt.key, top: alt.top, pos: alt.pos, scrollTop: anchor.scrollTop, scrollHeight: anchor.scrollHeight, el: alt.el });
2579
+ if (!ael) continue;
2580
+ if (alt.pos !== null && alt.pos !== UNKNOWN_ROW_POS) {
2581
+ var altLive = ael.getAttribute(ROW_POS_ATTR) || UNKNOWN_ROW_POS;
2582
+ if (altLive !== UNKNOWN_ROW_POS && altLive !== alt.pos) continue;
2583
+ }
2584
+ var aboxTop = box.getBoundingClientRect().top;
2585
+ var adelta = ael.getBoundingClientRect().top - aboxTop - alt.top;
2586
+ var aslack = Math.abs(box.scrollHeight - anchor.scrollHeight) + box.clientHeight;
2587
+ if (!unbounded && (adelta > aslack || adelta < -aslack)) continue;
2588
+ var awant = box.scrollTop + adelta;
2589
+ if (adelta >= 1 || adelta <= -1) box.scrollTop += adelta;
2590
+ wroteTop = box.scrollTop;
2591
+ restorePinned = true;
2592
+ restoreExact = box.scrollTop >= awant - 1 && box.scrollTop <= awant + 1;
2593
+ held = {
2594
+ key: alt.key,
2595
+ top: alt.top,
2596
+ pos: alt.pos,
2597
+ scrollTop: box.scrollTop,
2598
+ scrollHeight: box.scrollHeight,
2599
+ el: ael,
2600
+ alts: alts.slice(ai + 1)
2518
2601
  };
2519
2602
  return;
2520
2603
  }
@@ -2525,9 +2608,13 @@ Index the REMAINING windows - one record per row/item, looking at any page image
2525
2608
  var grew = box.scrollHeight - anchor.scrollHeight;
2526
2609
  if (grew > 0) {
2527
2610
  box.scrollTop = anchor.scrollTop + grew;
2611
+ wroteTop = box.scrollTop;
2528
2612
  return;
2529
2613
  }
2530
- if (options.rawFallback) box.scrollTop = anchor.scrollTop;
2614
+ if (options.rawFallback) {
2615
+ box.scrollTop = anchor.scrollTop;
2616
+ wroteTop = box.scrollTop;
2617
+ }
2531
2618
  }
2532
2619
  function preserve(mutate) {
2533
2620
  var anchor = capture();
@@ -2536,9 +2623,17 @@ Index the REMAINING windows - one record per row/item, looking at any page image
2536
2623
  return result;
2537
2624
  }
2538
2625
  function remember() {
2626
+ var b0 = options.getBox();
2627
+ if (returning && b0 && b0.scrollTop !== wroteTop) release();
2628
+ if (frozen()) return;
2539
2629
  held = capture();
2540
2630
  }
2541
2631
  function hold() {
2632
+ if (frozen()) return;
2633
+ if (sawFrozen) {
2634
+ settleReturn();
2635
+ return;
2636
+ }
2542
2637
  var box = options.getBox();
2543
2638
  if (!box || options.isStuck()) {
2544
2639
  held = null;
@@ -2565,12 +2660,86 @@ Index the REMAINING windows - one record per row/item, looking at any page image
2565
2660
  if (prev === void 0) prev = 0;
2566
2661
  var delta = h - prev;
2567
2662
  if (delta === 0) return;
2663
+ if (frozen()) {
2664
+ foldFrozenGrowth(box, el, delta);
2665
+ return;
2666
+ }
2568
2667
  if (el.getBoundingClientRect().top >= box.getBoundingClientRect().top) return;
2569
2668
  box.scrollTop += delta;
2669
+ wroteTop = box.scrollTop;
2570
2670
  if (held) held = capture();
2571
2671
  }
2672
+ function park() {
2673
+ parked = capture();
2674
+ parkedStuck = !!options.isStuck();
2675
+ returning = true;
2676
+ returnBudget = MAX_RETURN_SETTLES;
2677
+ }
2678
+ function release() {
2679
+ parked = null;
2680
+ parkedStuck = false;
2681
+ returning = false;
2682
+ returnBudget = 0;
2683
+ }
2684
+ function pinBottom() {
2685
+ var box = options.getBox();
2686
+ if (!box) return;
2687
+ box.scrollTop = box.scrollHeight;
2688
+ wroteTop = box.scrollTop;
2689
+ }
2690
+ function settleReturn() {
2691
+ if (frozen()) return false;
2692
+ var wasFrozen = sawFrozen;
2693
+ sawFrozen = false;
2694
+ if (!returning && !wasFrozen) return false;
2695
+ if (returning) {
2696
+ if (returnBudget <= 0) {
2697
+ release();
2698
+ return false;
2699
+ }
2700
+ returnBudget--;
2701
+ }
2702
+ if (parkedStuck) {
2703
+ pinBottom();
2704
+ return true;
2705
+ }
2706
+ var target = parked || held;
2707
+ restoreExact = true;
2708
+ restorePinned = false;
2709
+ restore(target, true);
2710
+ parked = !restorePinned || !restoreExact ? target : null;
2711
+ returning = !!parked && returnBudget > 0;
2712
+ if (!returning) {
2713
+ parked = null;
2714
+ parkedStuck = false;
2715
+ returnBudget = 0;
2716
+ }
2717
+ return false;
2718
+ }
2719
+ function isReturning() {
2720
+ return returning;
2721
+ }
2722
+ function thaw() {
2723
+ settleReturn();
2724
+ }
2725
+ function foldFrozenGrowth(box, el, delta) {
2726
+ var elTop = el.getBoundingClientRect().top;
2727
+ foldInto(box, held, elTop, delta);
2728
+ foldInto(box, parked, elTop, delta);
2729
+ }
2730
+ function foldInto(box, a, elTop, delta) {
2731
+ if (!a || a.top >= 0) return;
2732
+ var rowEl = findRow(box, a);
2733
+ if (!rowEl) return;
2734
+ var within = elTop - rowEl.getBoundingClientRect().top;
2735
+ if (within < 0 || within >= rowEl.offsetHeight) return;
2736
+ if (within >= -a.top) return;
2737
+ a.top -= delta;
2738
+ a.scrollHeight += delta;
2739
+ }
2572
2740
  function forget() {
2573
2741
  held = null;
2742
+ release();
2574
2743
  }
2575
2744
  return {
2576
2745
  capture,
@@ -2578,6 +2747,13 @@ Index the REMAINING windows - one record per row/item, looking at any page image
2578
2747
  preserve,
2579
2748
  remember,
2580
2749
  hold,
2750
+ park,
2751
+ settleReturn,
2752
+ isReturning,
2753
+ release,
2754
+ pinBottom,
2755
+ isFrozen: frozen,
2756
+ thaw,
2581
2757
  absorb,
2582
2758
  forget
2583
2759
  };
@@ -5680,6 +5856,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
5680
5856
  releaseBgFlag();
5681
5857
  self.updateHistoryCache();
5682
5858
  self.host.notify();
5859
+ if (self.host.settleScroll) self.host.settleScroll();
5683
5860
  }, function() {
5684
5861
  releaseBgFlag();
5685
5862
  self.host.notify();
@@ -5761,7 +5938,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
5761
5938
  self.drainBgTaskQueue();
5762
5939
  }
5763
5940
  if (!fetchMore) self.refreshLiveIndexState();
5764
- if (!fetchMore) return self.host.scrollToBottomIfSticky();
5941
+ if (!fetchMore) return self.host.settleScroll ? self.host.settleScroll() : self.host.scrollToBottomIfSticky();
5765
5942
  }).catch(function(err) {
5766
5943
  console.warn("[chat-engine] getChatHistory failed", err);
5767
5944
  }).then(function() {
@@ -6388,7 +6565,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
6388
6565
  (function() {
6389
6566
  var MCP_PROD = "https://mcp.broadwayinc.computer";
6390
6567
  var MCP_DEV = "https://mcp-dev.broadwayinc.computer";
6391
- var BQ_VERSION = "1.8.14" ;
6568
+ var BQ_VERSION = "1.8.16" ;
6392
6569
  var ATTACHMENT_URL_EXPIRES_SECONDS = 600;
6393
6570
  var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
6394
6571
  var GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
@@ -8068,10 +8245,10 @@ Index the REMAINING windows - one record per row/item, looking at any page image
8068
8245
  refreshMessageBubble(i);
8069
8246
  },
8070
8247
  scrollToBottom: function(smooth) {
8071
- return scrollToBottom(smooth);
8248
+ return scrollToBottom();
8072
8249
  },
8073
8250
  scrollToBottomIfSticky: function(smooth) {
8074
- return scrollToBottomIfSticky(smooth);
8251
+ return scrollToBottomIfSticky();
8075
8252
  },
8076
8253
  // A first page can render shorter than the box (a file's every indexing
8077
8254
  // pass folds into ONE row), and a box that cannot scroll never fires the
@@ -8080,6 +8257,9 @@ Index the REMAINING windows - one record per row/item, looking at any page image
8080
8257
  onHistoryLoaded: function(fetchMore, token) {
8081
8258
  if (!fetchMore) ensureHistoryFillsViewport(token);
8082
8259
  },
8260
+ settleScroll: function() {
8261
+ settleScrollAfterRefresh();
8262
+ },
8083
8263
  cancelRequest: function(opts) {
8084
8264
  return S.skapi.cancelClientSecretRequest(opts);
8085
8265
  },
@@ -8271,7 +8451,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
8271
8451
  if (job.stageId) session.settleStagedMessage(job.stageId);
8272
8452
  CS.messages.push({ role: "assistant", content: "Something went wrong while uploading attachments. " + (err && err.message || ""), isError: true });
8273
8453
  renderMessages();
8274
- scrollToBottom(true);
8454
+ scrollToBottomIfSticky();
8275
8455
  return null;
8276
8456
  });
8277
8457
  }
@@ -8324,26 +8504,45 @@ Index the REMAINING windows - one record per row/item, looking at any page image
8324
8504
  };
8325
8505
  enqueueAttachmentSend({ text, batchId, stageId, pinned });
8326
8506
  }
8327
- function scrollToBottom(smooth) {
8507
+ function scrollToBottom() {
8508
+ if (chatScrollAnchor.isFrozen()) {
8509
+ CS.stickToBottom = true;
8510
+ chatScrollAnchor.pinBottom();
8511
+ return Promise.resolve();
8512
+ }
8328
8513
  return raf2().then(function() {
8329
8514
  if (!CS.messagesBox) return;
8330
8515
  CS.stickToBottom = true;
8331
- if (smooth) CS.messagesBox.scrollTo({ top: CS.messagesBox.scrollHeight, behavior: "smooth" });
8332
- else CS.messagesBox.scrollTop = CS.messagesBox.scrollHeight;
8516
+ chatScrollAnchor.pinBottom();
8333
8517
  });
8334
8518
  }
8335
- function scrollToBottomIfSticky(smooth) {
8519
+ function scrollToBottomIfSticky() {
8336
8520
  if (!CS.stickToBottom) return Promise.resolve();
8521
+ if (chatScrollAnchor.isFrozen()) {
8522
+ chatScrollAnchor.pinBottom();
8523
+ return Promise.resolve();
8524
+ }
8337
8525
  return raf2().then(function() {
8338
8526
  if (!CS.stickToBottom || !CS.messagesBox) return;
8339
- if (smooth) CS.messagesBox.scrollTo({ top: CS.messagesBox.scrollHeight, behavior: "smooth" });
8340
- else CS.messagesBox.scrollTop = CS.messagesBox.scrollHeight;
8527
+ chatScrollAnchor.pinBottom();
8341
8528
  });
8342
8529
  }
8530
+ function settleScrollAfterRefresh(afterAbsence) {
8531
+ if (afterAbsence || chatScrollAnchor.isReturning()) {
8532
+ if (chatScrollAnchor.settleReturn()) CS.stickToBottom = true;
8533
+ return;
8534
+ }
8535
+ if (CS.stickToBottom) scrollToBottomIfSticky();
8536
+ else chatScrollAnchor.hold();
8537
+ }
8343
8538
  var lastHistoryScrollTop = 0;
8344
8539
  function onHistoryScroll() {
8345
8540
  if (!CS.messagesBox || CS.chatSettingsOpen) return;
8346
8541
  var el = CS.messagesBox;
8542
+ if (chatScrollAnchor.isFrozen()) {
8543
+ lastHistoryScrollTop = el.scrollTop;
8544
+ return;
8545
+ }
8347
8546
  var atBottom = el.scrollHeight - el.scrollTop - el.clientHeight <= 16;
8348
8547
  if (!atBottom) CS.stickToBottom = false;
8349
8548
  else if (el.scrollTop >= lastHistoryScrollTop) CS.stickToBottom = true;
@@ -8361,12 +8560,21 @@ Index the REMAINING windows - one record per row/item, looking at any page image
8361
8560
  }
8362
8561
  var _touchStartY = 0;
8363
8562
  function onMessagesWheel(e) {
8563
+ chatScrollAnchor.release();
8364
8564
  if (e.deltaY < 0) CS.stickToBottom = false;
8365
8565
  }
8366
8566
  function onMessagesTouchStart(e) {
8567
+ chatScrollAnchor.release();
8367
8568
  _touchStartY = e.touches && e.touches[0] ? e.touches[0].clientY : 0;
8368
8569
  }
8570
+ function onMessagesKeyDown() {
8571
+ chatScrollAnchor.release();
8572
+ }
8573
+ function onMessagesPointerDown() {
8574
+ chatScrollAnchor.release();
8575
+ }
8369
8576
  function onMessagesTouchMove(e) {
8577
+ chatScrollAnchor.release();
8370
8578
  var y = e.touches && e.touches[0] ? e.touches[0].clientY : 0;
8371
8579
  if (y > _touchStartY + 4) CS.stickToBottom = false;
8372
8580
  }
@@ -9245,7 +9453,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
9245
9453
  // earlier failure left on this file's chips.
9246
9454
  onLoad: function(path) {
9247
9455
  clearLinkUnavailable(linkUnavailableKeysForPath(path));
9248
- scrollToBottomIfSticky(false);
9456
+ scrollToBottomIfSticky();
9249
9457
  },
9250
9458
  // The resizes an <img> makes with no event of its own to announce
9251
9459
  // them: the src landing, and the src being dropped for a retry (which
@@ -10034,6 +10242,13 @@ Index the REMAINING windows - one record per row/item, looking at any page image
10034
10242
  isStuck: function() {
10035
10243
  return !!CS.stickToBottom;
10036
10244
  },
10245
+ // A hidden tab keeps mutating this list - a resumed poll, the head refresh
10246
+ // and its deferred background batch, a settling request - and every one of
10247
+ // those would otherwise move a scroll position nobody is looking at. Freeze
10248
+ // instead, and put the reader back once they can see it (settleScroll).
10249
+ isFrozen: function() {
10250
+ return typeof document !== "undefined" && !!document.hidden;
10251
+ },
10037
10252
  rawFallback: true
10038
10253
  });
10039
10254
  function captureScrollAnchor() {
@@ -10043,7 +10258,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
10043
10258
  var box = CS.messagesBox;
10044
10259
  if (!box) return;
10045
10260
  if (CS.stickToBottom) {
10046
- box.scrollTop = box.scrollHeight;
10261
+ chatScrollAnchor.pinBottom();
10047
10262
  return;
10048
10263
  }
10049
10264
  chatScrollAnchor.restore(anchor);
@@ -10257,6 +10472,8 @@ Index the REMAINING windows - one record per row/item, looking at any page image
10257
10472
  box.addEventListener("wheel", onMessagesWheel, { passive: true });
10258
10473
  box.addEventListener("touchstart", onMessagesTouchStart, { passive: true });
10259
10474
  box.addEventListener("touchmove", onMessagesTouchMove, { passive: true });
10475
+ box.addEventListener("keydown", onMessagesKeyDown, { passive: true });
10476
+ box.addEventListener("pointerdown", onMessagesPointerDown, { passive: true });
10260
10477
  box.addEventListener("load", onMessagesImageSettled, true);
10261
10478
  box.addEventListener("error", onMessagesImageSettled, true);
10262
10479
  if (document.fonts && document.fonts.addEventListener) {
@@ -10285,7 +10502,7 @@ Index the REMAINING windows - one record per row/item, looking at any page image
10285
10502
  if (drafting !== CS.drafting) {
10286
10503
  CS.drafting = drafting;
10287
10504
  syncDraftingIndicator();
10288
- scrollToBottomIfSticky(false);
10505
+ scrollToBottomIfSticky();
10289
10506
  }
10290
10507
  });
10291
10508
  input.addEventListener("keydown", function(e) {
@@ -10639,18 +10856,26 @@ Index the REMAINING windows - one record per row/item, looking at any page image
10639
10856
  S._resizeBound = true;
10640
10857
  window.addEventListener("resize", function() {
10641
10858
  scheduleAttachmentOverflowRecompute();
10642
- scrollToBottomIfSticky(false);
10859
+ scrollToBottomIfSticky();
10643
10860
  ensureHistoryFillsViewport();
10644
10861
  });
10645
10862
  }
10646
10863
  if (!S._visBound && typeof document !== "undefined" && document.addEventListener) {
10647
10864
  S._visBound = true;
10865
+ window.addEventListener("blur", function() {
10866
+ chatScrollAnchor.park();
10867
+ });
10868
+ window.addEventListener("focus", function() {
10869
+ settleScrollAfterRefresh(true);
10870
+ });
10648
10871
  document.addEventListener("visibilitychange", function() {
10649
10872
  if (document.visibilityState === "hidden") {
10873
+ chatScrollAnchor.park();
10650
10874
  if (session && session.pausePolling) session.pausePolling("hidden");
10651
10875
  return;
10652
10876
  }
10653
10877
  if (document.visibilityState === "visible") {
10878
+ settleScrollAfterRefresh(true);
10654
10879
  var refreshed = S.user ? ensureMcpGrantFresh() : null;
10655
10880
  Promise.resolve(refreshed).catch(function() {
10656
10881
  }).then(function() {