@kyralabs/m3e-motion 1.4.0 → 1.6.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.js CHANGED
@@ -379,16 +379,17 @@ var SpringAnimatable = class {
379
379
  }
380
380
  /**
381
381
  * Animates to `target` from the value and velocity at `now` (ms); a null spec (e.g. a spatial
382
- * spring under reduced motion) jumps there.
382
+ * spring under reduced motion) jumps there. `velocity` (units per second) overrides the current
383
+ * velocity, e.g. after the value was driven by something else (a drag, a tween).
383
384
  */
384
- animateTo(target, spec, now) {
385
+ animateTo(target, spec, now, velocity) {
385
386
  this.sample(now);
386
387
  if (spec === null) {
387
388
  this.snapTo(target);
388
389
  return;
389
390
  }
390
391
  this.#from = this.#value;
391
- this.#velocity0 = this.#velocity;
392
+ this.#velocity0 = velocity ?? this.#velocity;
392
393
  this.#target = target;
393
394
  this.#start = now;
394
395
  this.#spec = spec;
@@ -437,8 +438,21 @@ function menuNavigationTarget(key, count, current) {
437
438
  }
438
439
  }
439
440
 
441
+ // src/type-select.ts
442
+ var TYPEAHEAD_TIMEOUT_MS = 1e3;
443
+ var collator;
444
+ function typeSelectTarget(texts, from, search) {
445
+ collator ??= new Intl.Collator(void 0, { usage: "search", sensitivity: "base" });
446
+ const compare = collator;
447
+ const matches = (text) => text !== "" && compare.compare(text.slice(0, search.length), search) === 0;
448
+ const start = Math.max(from, 0);
449
+ for (let i = start; i < texts.length; i++) if (matches(texts[i] ?? "")) return i;
450
+ for (let i = 0; i < start; i++) if (matches(texts[i] ?? "")) return i;
451
+ return -1;
452
+ }
453
+
440
454
  // src/toolbar-navigation.ts
441
- function toolbarNavigationTarget(key, count, current, orientation = "horizontal", rtl = false) {
455
+ function toolbarNavigationTarget(key, count, current, orientation = "horizontal", rtl = false, wrap = false) {
442
456
  if (count === 0) return null;
443
457
  let step;
444
458
  switch (key) {
@@ -448,19 +462,21 @@ function toolbarNavigationTarget(key, count, current, orientation = "horizontal"
448
462
  return count - 1;
449
463
  case "ArrowRight":
450
464
  case "ArrowLeft":
451
- if (orientation !== "horizontal") return null;
465
+ if (orientation === "vertical") return null;
452
466
  step = key === "ArrowRight" !== rtl ? 1 : -1;
453
467
  break;
454
468
  case "ArrowDown":
455
469
  case "ArrowUp":
456
- if (orientation !== "vertical") return null;
470
+ if (orientation === "horizontal") return null;
457
471
  step = key === "ArrowDown" ? 1 : -1;
458
472
  break;
459
473
  default:
460
474
  return null;
461
475
  }
462
476
  if (current < 0) return step > 0 ? 0 : count - 1;
463
- return Math.min(Math.max(current + step, 0), count - 1);
477
+ const next = current + step;
478
+ if (wrap) return (next + count) % count;
479
+ return Math.min(Math.max(next, 0), count - 1);
464
480
  }
465
481
 
466
482
  // src/cubic-bezier.ts
@@ -1031,6 +1047,1403 @@ function buttonGroupWidths(items, pressed, expandedRatio, visibleCount = items.l
1031
1047
  return widths.slice(0, last);
1032
1048
  }
1033
1049
 
1034
- export { AmplitudeAnimation, DEFAULT_DISPLACEMENT_THRESHOLD, FAST_OUT_LINEAR_IN_EASING, SEARCH_BAR_EXPANDED_THRESHOLD, SEARCH_DROPDOWN_VISIBLE_PROGRESS, SearchBarAnimation, SpringAnimatable, SpringSimulation, TOP_TITLE_ALPHA_EASING, TweenAnimatable, animatedInt, appBarScrollState, buttonGroupVisibleCount, buttonGroupWidths, circularIndeterminateFrame, collapsedFraction, cubicBezier, dampingCoefficient, dampingRatioFromCoefficient, estimateAnimationDurationMillis, estimateAnimationDurationMillisDouble, fabMenuItemVisible, floatingToolbarScrollState, indeterminateFrame, indicatorAmplitude, initialIndeterminateFrame, isScrolledUnder, linearIndeterminateFractions, menuNavigationTarget, menuPosition, menuTransformOrigin, morphSpringDurationMillis, overlappedFraction, parseCubicBezier, scrollAppBar, scrollFloatingToolbar, scrollToolbarExpansion, searchNavigationTarget, searchViewFrame, settleTarget, springDurationMillis, springToLinear, springValue, springVelocity, toolbarCollapsedFraction, toolbarExpansionScroll, toolbarNavigationTarget, toolbarSettleTarget, twoRowsFrame, waveOffset, waveTravelMillis, withHeight, withHeightOffset, withToolbarOffset, withToolbarOffsetLimit };
1050
+ // src/window-size-class.ts
1051
+ var WINDOW_WIDTH_BREAKPOINTS = /* @__PURE__ */ Object.freeze({
1052
+ compact: 0,
1053
+ medium: 600,
1054
+ expanded: 840,
1055
+ large: 1200,
1056
+ "extra-large": 1600
1057
+ });
1058
+ var WINDOW_HEIGHT_BREAKPOINTS = /* @__PURE__ */ Object.freeze({ compact: 0, medium: 480, expanded: 900 });
1059
+ var WIDTH_CLASSES = [
1060
+ "compact",
1061
+ "medium",
1062
+ "expanded",
1063
+ "large",
1064
+ "extra-large"
1065
+ ];
1066
+ var HEIGHT_CLASSES = ["compact", "medium", "expanded"];
1067
+ function bucket(size, compact, classes, bounds) {
1068
+ let match = compact;
1069
+ for (const c of classes) if (size >= bounds[c]) match = c;
1070
+ return match;
1071
+ }
1072
+ function windowWidthSizeClass(widthPx, options = {}) {
1073
+ const classes = options.largeAndExtraLargeWidth === false ? WIDTH_CLASSES.slice(0, 3) : WIDTH_CLASSES;
1074
+ return bucket(widthPx, "compact", classes, WINDOW_WIDTH_BREAKPOINTS);
1075
+ }
1076
+ function windowHeightSizeClass(heightPx) {
1077
+ return bucket(heightPx, "compact", HEIGHT_CLASSES, WINDOW_HEIGHT_BREAKPOINTS);
1078
+ }
1079
+ function windowSizeClass(size, options = {}) {
1080
+ const widthClass = windowWidthSizeClass(size.width, options);
1081
+ const heightClass = windowHeightSizeClass(size.height);
1082
+ return {
1083
+ widthClass,
1084
+ heightClass,
1085
+ minWidth: WINDOW_WIDTH_BREAKPOINTS[widthClass],
1086
+ minHeight: WINDOW_HEIGHT_BREAKPOINTS[heightClass]
1087
+ };
1088
+ }
1089
+ function sameWindowSizeClass(a, b) {
1090
+ return a.minWidth === b.minWidth && a.minHeight === b.minHeight;
1091
+ }
1092
+ var widthBound = (b) => typeof b === "number" ? b : WINDOW_WIDTH_BREAKPOINTS[b];
1093
+ var heightBound = (b) => typeof b === "number" ? b : WINDOW_HEIGHT_BREAKPOINTS[b];
1094
+ function isWidthAtLeastBreakpoint(sizeClass, breakpoint) {
1095
+ return sizeClass.minWidth >= widthBound(breakpoint);
1096
+ }
1097
+ function isHeightAtLeastBreakpoint(sizeClass, breakpoint) {
1098
+ return sizeClass.minHeight >= heightBound(breakpoint);
1099
+ }
1100
+ function isAtLeastBreakpoint(sizeClass, widthBreakpoint, heightBreakpoint) {
1101
+ return isWidthAtLeastBreakpoint(sizeClass, widthBreakpoint) && isHeightAtLeastBreakpoint(sizeClass, heightBreakpoint);
1102
+ }
1103
+ var PARTITION_SPACER = 24;
1104
+ var DEFAULT_PREFERRED_WIDTH = 360;
1105
+ var DEFAULT_PREFERRED_WIDTH_XL = 412;
1106
+ var DEFAULT_PREFERRED_HEIGHT = 420;
1107
+ function paneScaffoldDirective(sizeClass, options = {}) {
1108
+ let maxHorizontalPartitions;
1109
+ let horizontalPartitionSpacerSize;
1110
+ let defaultPanePreferredWidth;
1111
+ switch (sizeClass.minWidth) {
1112
+ case WINDOW_WIDTH_BREAKPOINTS.compact:
1113
+ case WINDOW_WIDTH_BREAKPOINTS.medium:
1114
+ maxHorizontalPartitions = 1;
1115
+ horizontalPartitionSpacerSize = 0;
1116
+ defaultPanePreferredWidth = DEFAULT_PREFERRED_WIDTH;
1117
+ break;
1118
+ case WINDOW_WIDTH_BREAKPOINTS.expanded:
1119
+ maxHorizontalPartitions = 2;
1120
+ horizontalPartitionSpacerSize = PARTITION_SPACER;
1121
+ defaultPanePreferredWidth = DEFAULT_PREFERRED_WIDTH;
1122
+ break;
1123
+ default:
1124
+ maxHorizontalPartitions = 3;
1125
+ horizontalPartitionSpacerSize = PARTITION_SPACER;
1126
+ defaultPanePreferredWidth = DEFAULT_PREFERRED_WIDTH_XL;
1127
+ }
1128
+ const stacked = options.isTabletop === true || maxHorizontalPartitions === 1 && sizeClass.minHeight === WINDOW_HEIGHT_BREAKPOINTS.expanded;
1129
+ return {
1130
+ maxHorizontalPartitions,
1131
+ horizontalPartitionSpacerSize,
1132
+ maxVerticalPartitions: stacked ? 2 : 1,
1133
+ verticalPartitionSpacerSize: stacked ? PARTITION_SPACER : 0,
1134
+ defaultPanePreferredWidth,
1135
+ defaultPanePreferredHeight: DEFAULT_PREFERRED_HEIGHT
1136
+ };
1137
+ }
1138
+ var NAVIGATION_SUITE_TYPES = [
1139
+ "short-navigation-bar-compact",
1140
+ "short-navigation-bar-medium",
1141
+ "wide-navigation-rail-collapsed",
1142
+ "wide-navigation-rail-expanded",
1143
+ "navigation-drawer",
1144
+ "none"
1145
+ ];
1146
+ function isNavigationBarType(type) {
1147
+ return type === "short-navigation-bar-compact" || type === "short-navigation-bar-medium";
1148
+ }
1149
+ var NAVIGATION_SUITE_EXPANDED_FROM = "large";
1150
+ function navigationSuiteType(sizeClass, options = {}) {
1151
+ if (sizeClass.minWidth === WINDOW_WIDTH_BREAKPOINTS.compact)
1152
+ return "short-navigation-bar-compact";
1153
+ if (options.isTabletop === true || sizeClass.minHeight === WINDOW_HEIGHT_BREAKPOINTS.compact) {
1154
+ return "short-navigation-bar-medium";
1155
+ }
1156
+ const { expandedFrom } = options;
1157
+ if (expandedFrom !== void 0 && expandedFrom !== null && isWidthAtLeastBreakpoint(sizeClass, expandedFrom)) {
1158
+ return options.expandedType ?? "wide-navigation-rail-expanded";
1159
+ }
1160
+ return "wide-navigation-rail-collapsed";
1161
+ }
1162
+
1163
+ // src/navigation-suite.ts
1164
+ var HIDDEN = 0;
1165
+ var VISIBLE = 1;
1166
+ var NavigationSuiteScaffoldAnimation = class {
1167
+ #state;
1168
+ #progress;
1169
+ #spec = null;
1170
+ /** `hidden`: rememberNavigationSuiteScaffoldState(initialValue = Hidden); rendered at rest. */
1171
+ constructor(hidden = false) {
1172
+ const value = hidden ? HIDDEN : VISIBLE;
1173
+ this.#state = new SpringAnimatable(value);
1174
+ this.#progress = new SpringAnimatable(value);
1175
+ }
1176
+ /** NavigationSuiteScaffoldState.targetValue == Hidden. */
1177
+ get targetHidden() {
1178
+ return this.#state.target !== VISIBLE;
1179
+ }
1180
+ /** NavigationSuiteScaffoldState.currentValue == Hidden (anything but exactly Visible). */
1181
+ get currentHidden() {
1182
+ return this.#state.value !== VISIBLE;
1183
+ }
1184
+ /** NavigationSuiteScaffoldState.isAnimating (the state's spring, not the layout's). */
1185
+ get isAnimating() {
1186
+ return this.#state.isRunning;
1187
+ }
1188
+ /** NavigationSuiteScaffoldState.hide(). */
1189
+ hide(spec, now) {
1190
+ this.#animate(HIDDEN, spec, now);
1191
+ }
1192
+ /** NavigationSuiteScaffoldState.show(). */
1193
+ show(spec, now) {
1194
+ this.#animate(VISIBLE, spec, now);
1195
+ }
1196
+ /** NavigationSuiteScaffoldState.toggle(): towards the opposite of the target. */
1197
+ toggle(spec, now) {
1198
+ this.#animate(this.targetHidden ? VISIBLE : HIDDEN, spec, now);
1199
+ }
1200
+ /** NavigationSuiteScaffoldState.snapTo(): the state jumps; the layout animates from `now`. */
1201
+ snapTo(hidden, spec, now) {
1202
+ this.#spec = spec;
1203
+ this.#state.snapTo(hidden ? HIDDEN : VISIBLE);
1204
+ this.sample(now);
1205
+ }
1206
+ #animate(target, spec, now) {
1207
+ this.#spec = spec;
1208
+ this.#state.animateTo(target, spec, now);
1209
+ this.sample(now);
1210
+ }
1211
+ /** Advances both springs to `now`; the layout retargets when currentValue changes. */
1212
+ sample(now) {
1213
+ this.#state.sample(now);
1214
+ const target = this.currentHidden ? HIDDEN : VISIBLE;
1215
+ if (this.#progress.target !== target) this.#progress.animateTo(target, this.#spec, now);
1216
+ const progress = this.#progress.sample(now);
1217
+ return { progress, running: this.#state.isRunning || this.#progress.isRunning };
1218
+ }
1219
+ };
1220
+ function navigationSuiteOffset(size, progress) {
1221
+ return size - Math.trunc(size * progress);
1222
+ }
1223
+
1224
+ // src/wide-navigation-rail.ts
1225
+ var MODAL_RAIL_EXPANDED_PROGRESS = 0.3;
1226
+ var to = (expanded) => expanded ? 1 : 0;
1227
+ var WideNavigationRailAnimation = class {
1228
+ modal;
1229
+ hideOnCollapse;
1230
+ #expanded;
1231
+ #item;
1232
+ #width;
1233
+ #layout;
1234
+ #position;
1235
+ #scrim = new SpringAnimatable(0);
1236
+ #slide;
1237
+ #specs = null;
1238
+ #open = false;
1239
+ #modalExpanded = false;
1240
+ /** hideOnCollapse: positionProgress waits for the slide out (animateToDismiss). */
1241
+ #closeAfterSlide = false;
1242
+ constructor(options) {
1243
+ this.modal = Boolean(options.modal);
1244
+ this.hideOnCollapse = this.modal && Boolean(options.hideOnCollapse);
1245
+ this.#expanded = options.expanded;
1246
+ const v = to(options.expanded);
1247
+ const laidOut = this.hideOnCollapse ? 1 : this.modal ? options.expanded ? 1 : 0 : v;
1248
+ this.#item = new SpringAnimatable(this.hideOnCollapse ? 1 : v);
1249
+ this.#width = new SpringAnimatable(laidOut, options.widthThreshold ?? 0.01 / 264);
1250
+ this.#layout = new SpringAnimatable(laidOut, options.layoutThreshold ?? 0.01 / 16);
1251
+ this.#position = new SpringAnimatable(this.modal ? v : 0);
1252
+ this.#slide = new SpringAnimatable(v, 0.01 / 360);
1253
+ if (this.modal && options.expanded) {
1254
+ this.#open = true;
1255
+ this.#modalExpanded = true;
1256
+ this.#scrim.snapTo(1);
1257
+ }
1258
+ }
1259
+ /** WideNavigationRailState.targetValue. */
1260
+ get expanded() {
1261
+ return this.#expanded;
1262
+ }
1263
+ get isRunning() {
1264
+ return this.#item.isRunning || this.#width.isRunning || this.#layout.isRunning || this.#position.isRunning || this.#scrim.isRunning || this.#slide.isRunning || this.#closeAfterSlide;
1265
+ }
1266
+ /** expand() / collapse() at `now` (ms). */
1267
+ setExpanded(expanded, specs, now) {
1268
+ this.sample(now);
1269
+ this.#specs = specs;
1270
+ if (expanded === this.#expanded) return;
1271
+ this.#expanded = expanded;
1272
+ const v = to(expanded);
1273
+ if (!this.modal) {
1274
+ this.#item.animateTo(v, specs.iconPosition, now);
1275
+ this.#width.animateTo(v, specs.width, now);
1276
+ this.#layout.animateTo(v, specs.width, now);
1277
+ return;
1278
+ }
1279
+ if (this.hideOnCollapse) {
1280
+ this.#slide.animateTo(v, specs.slide, now);
1281
+ this.#scrim.animateTo(v, specs.scrim, now);
1282
+ if (expanded) {
1283
+ this.#closeAfterSlide = false;
1284
+ this.#position.animateTo(1, specs.position, now);
1285
+ } else {
1286
+ this.#closeAfterSlide = true;
1287
+ }
1288
+ this.sample(now);
1289
+ return;
1290
+ }
1291
+ this.#item.animateTo(v, specs.iconPosition, now);
1292
+ this.#position.animateTo(v, specs.position, now);
1293
+ this.sample(now);
1294
+ }
1295
+ /** WideNavigationRailState.snapTo. */
1296
+ snapTo(expanded) {
1297
+ this.#expanded = expanded;
1298
+ const v = to(expanded);
1299
+ this.#closeAfterSlide = false;
1300
+ if (!this.modal) {
1301
+ for (const a of [this.#item, this.#width, this.#layout]) a.snapTo(v);
1302
+ return;
1303
+ }
1304
+ this.#position.snapTo(v);
1305
+ this.#slide.snapTo(v);
1306
+ this.#scrim.snapTo(v);
1307
+ this.#open = expanded;
1308
+ this.#modalExpanded = expanded;
1309
+ if (!this.hideOnCollapse) {
1310
+ for (const a of [this.#item, this.#width, this.#layout]) a.snapTo(v);
1311
+ }
1312
+ }
1313
+ sample(now) {
1314
+ const item = this.#item.sample(now);
1315
+ if (this.modal) this.#sampleModal(now);
1316
+ const width = this.#width.sample(now);
1317
+ const layout = this.#layout.sample(now);
1318
+ return {
1319
+ item: Math.max(item, 0),
1320
+ // iconPositionProgress.coerceAtLeast(0f) (NavigationItem.kt L544)
1321
+ width,
1322
+ layout,
1323
+ open: this.#open,
1324
+ railExpanded: !this.modal ? this.#expanded : this.#open && (this.hideOnCollapse || this.#modalExpanded),
1325
+ scrim: Math.min(Math.max(this.#scrim.value, 0), 1),
1326
+ slide: this.#slide.value,
1327
+ running: this.isRunning
1328
+ };
1329
+ }
1330
+ #sampleModal(now) {
1331
+ const specs = this.#specs;
1332
+ if (this.hideOnCollapse) {
1333
+ this.#slide.sample(now);
1334
+ this.#scrim.sample(now);
1335
+ if (this.#closeAfterSlide && !this.#slide.isRunning) {
1336
+ this.#closeAfterSlide = false;
1337
+ this.#position.animateTo(0, specs?.position ?? null, now);
1338
+ }
1339
+ this.#open = this.#position.sample(now) > 0;
1340
+ return;
1341
+ }
1342
+ const position = this.#position.sample(now);
1343
+ const open = position > 0;
1344
+ const modalExpanded = position >= MODAL_RAIL_EXPANDED_PROGRESS;
1345
+ if (!open) {
1346
+ this.#width.snapTo(0);
1347
+ this.#layout.snapTo(0);
1348
+ this.#scrim.snapTo(0);
1349
+ } else if (!this.#open) {
1350
+ const v = to(modalExpanded);
1351
+ this.#width.snapTo(v);
1352
+ this.#layout.snapTo(v);
1353
+ this.#scrim.snapTo(v);
1354
+ } else if (modalExpanded !== this.#modalExpanded) {
1355
+ const v = to(modalExpanded);
1356
+ this.#width.animateTo(v, specs?.modalWidth ?? null, now);
1357
+ this.#layout.animateTo(v, specs?.width ?? null, now);
1358
+ this.#scrim.animateTo(v, specs?.scrim ?? null, now);
1359
+ }
1360
+ this.#scrim.sample(now);
1361
+ this.#open = open;
1362
+ this.#modalExpanded = open && modalExpanded;
1363
+ }
1364
+ };
1365
+ var lerp2 = (a, b, t) => a + (b - a) * t;
1366
+ function wideNavigationRailItemWidth(content, progress, m, maxWidth) {
1367
+ const pad = m.itemHorizontalPadding;
1368
+ const indicatorPadding = lerp2(m.collapsedIndicatorPadding, m.expandedIndicatorPadding, progress);
1369
+ if (content === null)
1370
+ return Math.min(m.iconSize + 2 * m.collapsedIndicatorPadding + 2 * pad, maxWidth);
1371
+ const gapAndLabel = content - m.iconSize - 2 * m.expandedIndicatorPadding;
1372
+ const label = gapAndLabel - m.iconLabelSpace;
1373
+ const widthTop = Math.min(Math.max(label, m.iconSize + 2 * pad + 2 * indicatorPadding), maxWidth);
1374
+ const ripple = lerp2(m.iconSize, m.iconSize + gapAndLabel, progress) + 2 * indicatorPadding;
1375
+ const widthStart = Math.min(ripple + pad, maxWidth);
1376
+ return widthTop + (widthStart - widthTop) * progress;
1377
+ }
1378
+ function wideNavigationRailWidth(input) {
1379
+ const m = input.metrics;
1380
+ const max = Math.min(input.maxWidth ?? m.expandedMaxWidth, m.expandedMaxWidth);
1381
+ const minWidth = Math.min(lerp2(m.collapsedWidth, m.expandedMinWidth, input.widthProgress), max);
1382
+ const fullRange = lerp2(m.collapsedWidth, m.expandedMaxWidth, input.widthProgress);
1383
+ const expandedMin = Math.min(m.expandedMinWidth, max);
1384
+ if (input.expanded) {
1385
+ const itemMax = max - m.itemHorizontalPadding;
1386
+ let widestItem = 0;
1387
+ for (const content of input.items) {
1388
+ const w = wideNavigationRailItemWidth(content, input.itemProgress, m, itemMax);
1389
+ widestItem = Math.max(widestItem, w + m.itemHorizontalPadding);
1390
+ }
1391
+ const widest = Math.max(widestItem, input.header);
1392
+ if (widest > minWidth && widest > expandedMin) {
1393
+ const constrain = Math.min(Math.max(widest, expandedMin), max);
1394
+ return { width: Math.min(fullRange, constrain), wide: true };
1395
+ }
1396
+ return { width: minWidth, wide: input.wide };
1397
+ }
1398
+ if (input.wide) {
1399
+ const upper = Math.max(input.previousWidth, minWidth);
1400
+ return { width: Math.min(Math.max(fullRange, minWidth), upper), wide: true };
1401
+ }
1402
+ return { width: minWidth, wide: false };
1403
+ }
1404
+
1405
+ // src/navigation-drawer.ts
1406
+ var DRAWER_POSITIONAL_THRESHOLD = 0.5;
1407
+ var DRAWER_VELOCITY_THRESHOLD = 400;
1408
+ var DRAWER_SETTLE_MILLIS = 256;
1409
+ var DECAY_FRICTION = -4.2;
1410
+ var DECAY_VELOCITY_THRESHOLD = 0.1;
1411
+ function exponentialDecayTarget(value, velocity) {
1412
+ if (Math.abs(velocity) <= DECAY_VELOCITY_THRESHOLD) return value;
1413
+ const duration = Math.log(Math.abs(DECAY_VELOCITY_THRESHOLD / velocity)) / DECAY_FRICTION * 1e3;
1414
+ return value - velocity / DECAY_FRICTION + velocity / DECAY_FRICTION * Math.exp(DECAY_FRICTION * duration / 1e3);
1415
+ }
1416
+ function drawerSettlesOpen(offset, velocity, width, velocityThreshold = DRAWER_VELOCITY_THRESHOLD) {
1417
+ const closed = -width;
1418
+ if (velocity === 0) return Math.abs(offset) <= Math.abs(offset - closed);
1419
+ const forward = velocity > 0;
1420
+ if (Math.abs(velocity) >= Math.abs(velocityThreshold)) return forward;
1421
+ const threshold = Math.abs(width * DRAWER_POSITIONAL_THRESHOLD);
1422
+ const fromStart = Math.abs((forward ? closed : 0) - offset);
1423
+ return fromStart >= threshold ? forward : !forward;
1424
+ }
1425
+ var DrawerAnimation = class {
1426
+ #width;
1427
+ #open;
1428
+ #settled;
1429
+ #mode = "rest";
1430
+ #spring;
1431
+ #offset;
1432
+ #velocity = 0;
1433
+ // Tween / decay state.
1434
+ #from = 0;
1435
+ #to = 0;
1436
+ #v0 = 0;
1437
+ #start = 0;
1438
+ #duration = 0;
1439
+ #easing = (t) => t;
1440
+ /** @param open initial value (at rest); @param width the sheet width in px. */
1441
+ constructor(open, width) {
1442
+ this.#width = Math.max(0, width);
1443
+ this.#open = open;
1444
+ this.#settled = open;
1445
+ this.#offset = open ? 0 : -this.#width;
1446
+ this.#spring = new SpringAnimatable(this.#offset);
1447
+ }
1448
+ /** DrawerState.targetValue === Open. */
1449
+ get isOpen() {
1450
+ return this.#open;
1451
+ }
1452
+ /** DrawerState.currentValue === Open: the last anchor it settled on. */
1453
+ get isSettledOpen() {
1454
+ return this.#settled;
1455
+ }
1456
+ get isDragging() {
1457
+ return this.#mode === "drag";
1458
+ }
1459
+ get width() {
1460
+ return this.#width;
1461
+ }
1462
+ /** Units: px per second, positive towards open (AnchoredDraggableState.lastVelocity). */
1463
+ get velocity() {
1464
+ return this.#velocity;
1465
+ }
1466
+ /** New anchors (the sheet was measured): at rest the offset follows its anchor. */
1467
+ setWidth(width) {
1468
+ const w = Math.max(0, width);
1469
+ if (w === this.#width) return;
1470
+ const previous = this.#width;
1471
+ this.#width = w;
1472
+ if (this.#mode === "rest") {
1473
+ this.#offset = this.#open ? 0 : -w;
1474
+ this.#spring.snapTo(this.#offset);
1475
+ } else if (this.#mode !== "drag" && !this.#open && this.#to === -previous) {
1476
+ this.#to = -w;
1477
+ }
1478
+ }
1479
+ /** Jumps (DrawerState.snapTo). */
1480
+ snapTo(open) {
1481
+ this.#mode = "rest";
1482
+ this.#open = open;
1483
+ this.#settled = open;
1484
+ this.#offset = open ? 0 : -this.#width;
1485
+ this.#velocity = 0;
1486
+ this.#spring.snapTo(this.#offset);
1487
+ }
1488
+ /** DrawerState.open() / close() at `now` (ms): springs from the current offset and velocity. */
1489
+ animateTo(open, specs, now) {
1490
+ this.sample(now);
1491
+ if (this.#mode === "drag") this.#mode = "rest";
1492
+ this.#open = open;
1493
+ const target = open ? 0 : -this.#width;
1494
+ const spec = open ? specs.open : specs.close;
1495
+ if (spec === null || this.#offset === target && this.#velocity === 0) {
1496
+ this.snapTo(open);
1497
+ return;
1498
+ }
1499
+ const velocity = this.#velocity;
1500
+ this.#spring.snapTo(this.#offset);
1501
+ this.#spring.animateTo(target, spec, now, velocity);
1502
+ if (this.#spring.isRunning) this.#mode = "spring";
1503
+ else this.snapTo(open);
1504
+ }
1505
+ /** Grabs the sheet (pointer down past the slop): stops any animation where it is. */
1506
+ startDrag(now) {
1507
+ this.sample(now);
1508
+ this.#mode = "drag";
1509
+ this.#velocity = 0;
1510
+ }
1511
+ /** Moves the offset by `delta` px (positive towards open), coerced between the anchors. */
1512
+ dragBy(delta) {
1513
+ if (this.#mode !== "drag") return;
1514
+ this.#offset = Math.min(0, Math.max(-this.#width, this.#offset + delta));
1515
+ }
1516
+ /**
1517
+ * Ends a drag with the pointer `velocity` (px/s, positive towards open): picks the target
1518
+ * (computeTarget) and settles on it (animateToWithDecay). Returns whether it settles open.
1519
+ * `velocityThreshold`: DrawerVelocityThreshold in px/s.
1520
+ */
1521
+ release(velocity, specs, now, velocityThreshold = DRAWER_VELOCITY_THRESHOLD, confirm = () => true) {
1522
+ if (this.#mode !== "drag") return this.#open;
1523
+ const proposed = drawerSettlesOpen(this.#offset, velocity, this.#width, velocityThreshold);
1524
+ const open = proposed === this.#settled || confirm(proposed) ? proposed : this.#settled;
1525
+ this.#open = open;
1526
+ const target = open ? 0 : -this.#width;
1527
+ const prev = this.#offset;
1528
+ this.#start = now;
1529
+ this.#from = prev;
1530
+ this.#to = target;
1531
+ this.#v0 = velocity;
1532
+ this.#velocity = velocity;
1533
+ if (prev === target) {
1534
+ this.snapTo(open);
1535
+ return open;
1536
+ }
1537
+ const towards = velocity * (target - prev) > 0;
1538
+ if (towards) {
1539
+ const projected = exponentialDecayTarget(prev, velocity);
1540
+ if (velocity > 0 ? projected >= target : projected <= target) {
1541
+ this.#mode = "decay";
1542
+ this.#duration = 1e3 * Math.log(DECAY_VELOCITY_THRESHOLD / Math.abs(velocity)) / DECAY_FRICTION;
1543
+ return open;
1544
+ }
1545
+ }
1546
+ if (specs.settle === null || specs.settle.duration <= 0) {
1547
+ this.snapTo(open);
1548
+ return open;
1549
+ }
1550
+ this.#mode = "tween";
1551
+ this.#duration = specs.settle.duration;
1552
+ this.#easing = specs.settle.easing;
1553
+ return open;
1554
+ }
1555
+ /** Advances to `now` (ms). */
1556
+ sample(now) {
1557
+ switch (this.#mode) {
1558
+ case "spring": {
1559
+ this.#offset = this.#spring.sample(now);
1560
+ this.#velocity = this.#spring.velocity;
1561
+ if (!this.#spring.isRunning) this.#settle();
1562
+ break;
1563
+ }
1564
+ case "tween": {
1565
+ const elapsed = now - this.#start;
1566
+ if (elapsed >= this.#duration) {
1567
+ this.#settle();
1568
+ break;
1569
+ }
1570
+ const f = (t) => {
1571
+ const p = Math.min(1, Math.max(0, t / this.#duration));
1572
+ return this.#from + (this.#to - this.#from) * this.#easing(p);
1573
+ };
1574
+ const value = f(elapsed);
1575
+ this.#velocity = (f(elapsed + 1) - value) * 1e3;
1576
+ this.#offset = value;
1577
+ break;
1578
+ }
1579
+ case "decay": {
1580
+ const t = (now - this.#start) / 1e3;
1581
+ const value = this.#from - this.#v0 / DECAY_FRICTION + this.#v0 / DECAY_FRICTION * Math.exp(DECAY_FRICTION * t);
1582
+ const crossed = this.#v0 > 0 ? value >= this.#to : value <= this.#to;
1583
+ if (crossed || now - this.#start >= this.#duration) {
1584
+ this.#settle();
1585
+ break;
1586
+ }
1587
+ this.#offset = value;
1588
+ this.#velocity = this.#v0 * Math.exp(DECAY_FRICTION * t);
1589
+ break;
1590
+ }
1591
+ }
1592
+ const w = this.#width;
1593
+ const fraction = w <= 0 ? this.#open ? 1 : 0 : Math.min(1, Math.max(0, (this.#offset + w) / w));
1594
+ return {
1595
+ offset: this.#offset,
1596
+ fraction,
1597
+ running: this.#mode !== "rest",
1598
+ visible: fraction !== 0
1599
+ };
1600
+ }
1601
+ #settle() {
1602
+ this.#mode = "rest";
1603
+ this.#offset = this.#open ? 0 : -this.#width;
1604
+ this.#velocity = 0;
1605
+ this.#settled = this.#open;
1606
+ this.#spring.snapTo(this.#offset);
1607
+ }
1608
+ };
1609
+
1610
+ // src/slider.ts
1611
+ var SLIDER_KEY_DIVISIONS = 100;
1612
+ var SLIDER_PAGE_DIVISOR = 10;
1613
+ var SLIDER_PAGE_MAX_STEPS = 10;
1614
+ var clamp = (v, lo, hi) => Math.min(Math.max(v, lo), hi);
1615
+ var lerp3 = (a, b, t) => a + (b - a) * t;
1616
+ function sliderSteps(min, max, step) {
1617
+ if (step === void 0 || !(step > 0) || !(max > min)) return 0;
1618
+ return Math.max(0, Math.round((max - min) / step) - 1);
1619
+ }
1620
+ function sliderTickFractions(steps) {
1621
+ if (steps <= 0) return [];
1622
+ return Array.from({ length: steps + 2 }, (_, i) => i / (steps + 1));
1623
+ }
1624
+ function sliderFraction(value, min, max) {
1625
+ return clamp(max - min === 0 ? 0 : (value - min) / (max - min), 0, 1);
1626
+ }
1627
+ var sliderValueAt = (fraction, min, max) => lerp3(min, max, fraction);
1628
+ function sliderSnap(value, steps, min, max) {
1629
+ const ticks = sliderTickFractions(steps);
1630
+ if (ticks.length === 0) return value;
1631
+ let best = value;
1632
+ let distance = Infinity;
1633
+ for (const t of ticks) {
1634
+ const v = lerp3(min, max, t);
1635
+ const d = Math.abs(v - value);
1636
+ if (d < distance) {
1637
+ distance = d;
1638
+ best = v;
1639
+ }
1640
+ }
1641
+ return best;
1642
+ }
1643
+ function sliderThumbValue(value, bounds, steps, min, max) {
1644
+ return sliderSnap(clamp(value, bounds.min, bounds.max), steps, min, max);
1645
+ }
1646
+ function sliderThumbBounds(values, index, min, max) {
1647
+ return {
1648
+ min: index > 0 ? values[index - 1] ?? min : min,
1649
+ max: index < values.length - 1 ? values[index + 1] ?? max : max
1650
+ };
1651
+ }
1652
+ function sliderKeyDelta(steps, min, max) {
1653
+ const actual = steps > 0 ? steps + 1 : SLIDER_KEY_DIVISIONS;
1654
+ return Math.abs(max - min) / actual;
1655
+ }
1656
+ function sliderPageSteps(steps) {
1657
+ const actual = steps > 0 ? steps + 1 : SLIDER_KEY_DIVISIONS;
1658
+ return clamp(Math.floor(actual / SLIDER_PAGE_DIVISOR), 1, SLIDER_PAGE_MAX_STEPS);
1659
+ }
1660
+ function sliderKeyAction(key, options = {}) {
1661
+ const { vertical = false, rtl = false, shiftKey = false } = options;
1662
+ const page = (up) => shiftKey ? up ? "page-increment" : "page-decrement" : up ? "increment" : "decrement";
1663
+ switch (key) {
1664
+ case "ArrowUp":
1665
+ return page(true);
1666
+ case "ArrowDown":
1667
+ return page(false);
1668
+ case "ArrowRight":
1669
+ return page(vertical || !rtl);
1670
+ case "ArrowLeft":
1671
+ return page(!(vertical || !rtl));
1672
+ case "PageUp":
1673
+ return "page-increment";
1674
+ case "PageDown":
1675
+ return "page-decrement";
1676
+ case "Home":
1677
+ return "min";
1678
+ case "End":
1679
+ return "max";
1680
+ default:
1681
+ return null;
1682
+ }
1683
+ }
1684
+ function sliderKeyValue(action, values, index, steps, min, max) {
1685
+ const value = values[index] ?? min;
1686
+ const bounds = sliderThumbBounds(values, index, min, max);
1687
+ const delta = sliderKeyDelta(steps, min, max);
1688
+ const page = sliderPageSteps(steps) * delta;
1689
+ const target = action === "increment" ? value + delta : action === "decrement" ? value - delta : action === "page-increment" ? value + page : action === "page-decrement" ? value - page : action === "min" ? bounds.min : bounds.max;
1690
+ return sliderThumbValue(target, bounds, steps, min, max);
1691
+ }
1692
+ function sliderClosestThumb(values, value) {
1693
+ const [start, end] = values;
1694
+ if (start === void 0 || end === void 0) return 0;
1695
+ const diffStart = Math.abs(start - value);
1696
+ const diffEnd = Math.abs(end - value);
1697
+ if (diffStart !== diffEnd) return diffStart < diffEnd ? 0 : 1;
1698
+ return start > value ? 0 : 1;
1699
+ }
1700
+ function sliderTrackGeometry(input) {
1701
+ const {
1702
+ length,
1703
+ cornerSize: c,
1704
+ insideCornerSize: inside,
1705
+ thumbWidth,
1706
+ gapSize,
1707
+ steps,
1708
+ fraction,
1709
+ centered = false,
1710
+ cornerShrinking = false,
1711
+ stopIndicator = true
1712
+ } = input;
1713
+ const range = input.startFraction !== void 0;
1714
+ const ticks = sliderTickFractions(steps);
1715
+ const onEdge = (f) => f === ticks[0] || f === ticks[ticks.length - 1];
1716
+ const position = (f) => ticks.length > 0 && !onEdge(f) ? (length - c * 2) * f + c : length * f;
1717
+ const end = position(fraction);
1718
+ const start = range ? position(input.startFraction) : 0;
1719
+ const centre = length / 2;
1720
+ const before = fraction < 0.5;
1721
+ const after = fraction > 0.5;
1722
+ const startThumb = centered ? !after ? thumbWidth : 0 : range ? thumbWidth : 0;
1723
+ const endThumb = centered ? !before ? thumbWidth : 0 : thumbWidth;
1724
+ const startGapSize = centered || range ? gapSize : 0;
1725
+ const startGap = startGapSize > 0 ? startThumb / 2 + startGapSize : 0;
1726
+ const endGap = gapSize > 0 ? endThumb / 2 + gapSize : 0;
1727
+ const thresholdCorner = !cornerShrinking || ticks.length > 0;
1728
+ const parts = [];
1729
+ const stops = [];
1730
+ const adjustedEnd = centered ? Math.min(end, centre) : start;
1731
+ const rangeThreshold = startGap + (thresholdCorner ? c : 0);
1732
+ if ((centered || range) && adjustedEnd > rangeThreshold) {
1733
+ parts.push({
1734
+ kind: "inactive-start",
1735
+ start: 0,
1736
+ end: adjustedEnd - startGap,
1737
+ startRadius: c,
1738
+ endRadius: inside
1739
+ });
1740
+ if (stopIndicator) stops.push(c);
1741
+ }
1742
+ const adjustedStart = centered ? Math.max(end, centre) : end;
1743
+ const inactiveThreshold = length - endGap - (thresholdCorner ? c : 0);
1744
+ if (adjustedStart < inactiveThreshold) {
1745
+ parts.push({
1746
+ kind: "inactive-end",
1747
+ start: adjustedStart + endGap,
1748
+ end: length,
1749
+ startRadius: inside,
1750
+ endRadius: c
1751
+ });
1752
+ if (stopIndicator) stops.push(length - c);
1753
+ }
1754
+ const activeStart = centered ? adjustedEnd + (adjustedEnd < centre ? startGap : 0) : range ? start + startGap : 0;
1755
+ const activeEnd = centered ? adjustedStart - (adjustedStart > centre ? endGap : 0) : end - endGap;
1756
+ const activeStartRadius = centered || range ? inside : c;
1757
+ const activeThreshold = thresholdCorner ? activeStartRadius : 0;
1758
+ if (activeEnd - activeStart > activeThreshold) {
1759
+ parts.push({
1760
+ kind: "active",
1761
+ start: activeStart,
1762
+ end: activeEnd,
1763
+ startRadius: activeStartRadius,
1764
+ endRadius: inside
1765
+ });
1766
+ }
1767
+ const tickList = [];
1768
+ const centreGap = centered ? end > centre ? startGap : endGap : 0;
1769
+ const thumbGap = centered ? end > centre ? endGap : startGap : endGap;
1770
+ ticks.forEach((t, i) => {
1771
+ if (stopIndicator && ((centered || range) && i === 0 || i === ticks.length - 1)) return;
1772
+ const p = lerp3(c, length - c, t);
1773
+ const within = (centreOf, gap) => p >= centreOf - gap && p <= centreOf + gap;
1774
+ if (centered && within(centre, centreGap) || range && within(start, startGap) || within(end, thumbGap)) {
1775
+ return;
1776
+ }
1777
+ tickList.push({ position: p, active: p >= activeStart && p <= activeEnd });
1778
+ });
1779
+ return { thumbs: range ? [start, end] : [end], parts, stops, ticks: tickList };
1780
+ }
1781
+
1782
+ // src/tabs.ts
1783
+ var TAB_INDICATOR_MIN_WIDTH = 24;
1784
+ var THRESHOLD = 0.01;
1785
+ function tabPositions(tabs, start = 0, minIndicatorWidth = TAB_INDICATOR_MIN_WIDTH) {
1786
+ let left = start;
1787
+ return tabs.map(({ width, contentWidth }) => {
1788
+ const position = { left, width, contentWidth: Math.max(contentWidth, minIndicatorWidth) };
1789
+ left += width;
1790
+ return position;
1791
+ });
1792
+ }
1793
+ function tabIndicatorTarget(position, variant) {
1794
+ return {
1795
+ offset: position.left,
1796
+ width: variant === "primary" ? position.contentWidth : position.width
1797
+ };
1798
+ }
1799
+ var TabIndicatorAnimation = class {
1800
+ #offset;
1801
+ #width;
1802
+ /** Starts at rest on the first layout's target (Compose: initialOffset / initialWidth). */
1803
+ constructor(offset, width) {
1804
+ this.#offset = new SpringAnimatable(offset, THRESHOLD);
1805
+ this.#width = new SpringAnimatable(width, THRESHOLD);
1806
+ }
1807
+ get offset() {
1808
+ return this.#offset;
1809
+ }
1810
+ get width() {
1811
+ return this.#width;
1812
+ }
1813
+ get running() {
1814
+ return this.#offset.isRunning || this.#width.isRunning;
1815
+ }
1816
+ /**
1817
+ * Retargets each Animatable whose target changed, from its value and velocity at `now`; a null
1818
+ * spec (reduced motion) jumps.
1819
+ */
1820
+ animateTo(offset, width, spec, now) {
1821
+ if (width !== this.#width.target) this.#width.animateTo(width, spec, now);
1822
+ if (offset !== this.#offset.target) this.#offset.animateTo(offset, spec, now);
1823
+ }
1824
+ snapTo(offset, width) {
1825
+ this.#offset.snapTo(offset);
1826
+ this.#width.snapTo(width);
1827
+ }
1828
+ sample(now) {
1829
+ const offset = this.#offset.sample(now);
1830
+ const width = this.#width.sample(now);
1831
+ return { offset, width, running: this.running };
1832
+ }
1833
+ };
1834
+ var tabIndicatorShift = (sample, selected) => sample.offset - selected.left;
1835
+ function scrollableTabOffset(tab, scrollWidth, visibleWidth) {
1836
+ const centered = tab.left - (visibleWidth / 2 - tab.width / 2);
1837
+ const available = Math.max(scrollWidth - visibleWidth, 0);
1838
+ return Math.min(Math.max(centered, 0), available);
1839
+ }
1840
+ var TabScrollAnimation = class {
1841
+ value;
1842
+ constructor(position) {
1843
+ this.value = new SpringAnimatable(position, THRESHOLD);
1844
+ }
1845
+ /** Starts a new scroll from `from` (the scroll state's value), velocity 0. */
1846
+ animateTo(from, target, spec, now) {
1847
+ this.value.snapTo(from);
1848
+ this.value.animateTo(target, spec, now, 0);
1849
+ }
1850
+ };
1851
+
1852
+ // src/three-pane-scaffold.ts
1853
+ var THREE_PANE_SCAFFOLD_ROLES = [
1854
+ "primary",
1855
+ "secondary",
1856
+ "tertiary"
1857
+ ];
1858
+ var PRIORITY = {
1859
+ primary: 10,
1860
+ secondary: 5,
1861
+ tertiary: 1
1862
+ };
1863
+ var LIST_DETAIL_ADAPT_STRATEGIES = {
1864
+ primary: "hide",
1865
+ secondary: "hide",
1866
+ tertiary: "hide"
1867
+ };
1868
+ var SUPPORTING_PANE_ADAPT_STRATEGIES = {
1869
+ primary: "hide",
1870
+ secondary: { reflowUnder: "primary" },
1871
+ tertiary: "hide"
1872
+ };
1873
+ var ListDetailPaneScaffoldRole = /* @__PURE__ */ Object.freeze({
1874
+ List: "secondary",
1875
+ Detail: "primary",
1876
+ Extra: "tertiary"
1877
+ });
1878
+ var SupportingPaneScaffoldRole = /* @__PURE__ */ Object.freeze({
1879
+ Main: "primary",
1880
+ Supporting: "secondary",
1881
+ Extra: "tertiary"
1882
+ });
1883
+ var LIST_DETAIL_PANE_ORDER = [
1884
+ "secondary",
1885
+ "primary",
1886
+ "tertiary"
1887
+ ];
1888
+ var SUPPORTING_PANE_ORDER = [
1889
+ "primary",
1890
+ "secondary",
1891
+ "tertiary"
1892
+ ];
1893
+ function sameThreePaneScaffoldValue(a, b) {
1894
+ return a.primary === b.primary && a.secondary === b.secondary && a.tertiary === b.tertiary;
1895
+ }
1896
+ function calculateThreePaneScaffoldValue(maxHorizontalPartitions, adaptStrategies, destinationHistory, maxVerticalPartitions = 1) {
1897
+ let expandedCount = 0;
1898
+ const values = {};
1899
+ let checkReflowedPane = maxHorizontalPartitions === 1 && maxVerticalPartitions > 1 && THREE_PANE_SCAFFOLD_ROLES.some((r) => adaptStrategies[r] !== "hide");
1900
+ const order = [...destinationHistory.map((d) => d.pane).reverse(), ...THREE_PANE_SCAFFOLD_ROLES];
1901
+ for (const pane of order) {
1902
+ const hasAvailablePartition = expandedCount < maxHorizontalPartitions;
1903
+ if (!hasAvailablePartition && !checkReflowedPane) break;
1904
+ if (values[pane] !== void 0) continue;
1905
+ let reflowedPane = null;
1906
+ let anchorPane = pane;
1907
+ let anchorValue;
1908
+ const strategy = adaptStrategies[pane];
1909
+ if (checkReflowedPane && strategy !== "hide") {
1910
+ reflowedPane = pane;
1911
+ anchorPane = strategy.reflowUnder;
1912
+ anchorValue = values[anchorPane];
1913
+ }
1914
+ if (anchorValue === void 0) {
1915
+ if (!hasAvailablePartition) continue;
1916
+ values[anchorPane] = "expanded";
1917
+ expandedCount++;
1918
+ } else if (anchorValue !== "expanded") {
1919
+ continue;
1920
+ }
1921
+ if (reflowedPane !== null) {
1922
+ values[reflowedPane] = "reflowed";
1923
+ checkReflowedPane = false;
1924
+ }
1925
+ }
1926
+ return {
1927
+ primary: values.primary ?? "hidden",
1928
+ secondary: values.secondary ?? "hidden",
1929
+ tertiary: values.tertiary ?? "hidden",
1930
+ currentDestination: destinationHistory[destinationHistory.length - 1]?.pane ?? null
1931
+ };
1932
+ }
1933
+ function expandedPanes(value, order) {
1934
+ return order.filter((r) => value[r] === "expanded");
1935
+ }
1936
+ var RECOMMENDED_MAX_PANES = /* @__PURE__ */ Object.freeze({
1937
+ compact: 1,
1938
+ medium: 1,
1939
+ expanded: 2,
1940
+ large: 2,
1941
+ "extra-large": 3
1942
+ });
1943
+ function threePaneScaffoldDirective(sizeClass, options = {}) {
1944
+ const directive = paneScaffoldDirective(sizeClass, options);
1945
+ if (options.paneRule === "compose") return directive;
1946
+ return {
1947
+ ...directive,
1948
+ maxHorizontalPartitions: Math.min(
1949
+ directive.maxHorizontalPartitions,
1950
+ RECOMMENDED_MAX_PANES[sizeClass.widthClass]
1951
+ )
1952
+ };
1953
+ }
1954
+ var LIST_DETAIL_INITIAL_HISTORY = [
1955
+ { pane: "secondary" }
1956
+ ];
1957
+ var SUPPORTING_PANE_INITIAL_HISTORY = [
1958
+ { pane: "primary" }
1959
+ ];
1960
+ var ThreePaneScaffoldNavigator = class {
1961
+ #history;
1962
+ #directive;
1963
+ #strategies;
1964
+ #historyAware;
1965
+ #value;
1966
+ #listeners = /* @__PURE__ */ new Set();
1967
+ constructor(options) {
1968
+ this.#history = [...options.initialDestinationHistory];
1969
+ this.#directive = options.scaffoldDirective;
1970
+ this.#strategies = options.adaptStrategies;
1971
+ this.#historyAware = options.isDestinationHistoryAware ?? true;
1972
+ this.#value = this.#calculate(this.#history.length - 1);
1973
+ }
1974
+ get scaffoldDirective() {
1975
+ return this.#directive;
1976
+ }
1977
+ set scaffoldDirective(directive) {
1978
+ this.#directive = directive;
1979
+ this.#recalculate();
1980
+ }
1981
+ get adaptStrategies() {
1982
+ return this.#strategies;
1983
+ }
1984
+ set adaptStrategies(strategies) {
1985
+ this.#strategies = strategies;
1986
+ this.#recalculate();
1987
+ }
1988
+ get isDestinationHistoryAware() {
1989
+ return this.#historyAware;
1990
+ }
1991
+ set isDestinationHistoryAware(aware) {
1992
+ this.#historyAware = aware;
1993
+ this.#recalculate();
1994
+ }
1995
+ /** The destination history, oldest first. */
1996
+ get destinationHistory() {
1997
+ return this.#history;
1998
+ }
1999
+ get currentDestination() {
2000
+ return this.#history[this.#history.length - 1] ?? null;
2001
+ }
2002
+ get scaffoldValue() {
2003
+ return this.#value;
2004
+ }
2005
+ /** Calls `listener` after every change of the history or the value; returns the unsubscriber. */
2006
+ subscribe(listener) {
2007
+ this.#listeners.add(listener);
2008
+ return () => {
2009
+ this.#listeners.delete(listener);
2010
+ };
2011
+ }
2012
+ peekPreviousScaffoldValue(behavior = "pop-until-scaffold-value-change") {
2013
+ const index = this.#previousIndex(behavior);
2014
+ return index === -1 ? this.#value : this.#calculate(index);
2015
+ }
2016
+ navigateTo(pane, contentKey) {
2017
+ this.#history.push({ pane, contentKey });
2018
+ this.#recalculate(true);
2019
+ }
2020
+ canNavigateBack(behavior = "pop-until-scaffold-value-change") {
2021
+ return this.#previousIndex(behavior) >= 0;
2022
+ }
2023
+ /** Returns true when there was a destination to go back to (else the history is cleared). */
2024
+ navigateBack(behavior = "pop-until-scaffold-value-change") {
2025
+ const previous = this.#previousIndex(behavior);
2026
+ if (previous < 0) {
2027
+ this.#history = [];
2028
+ this.#recalculate(true);
2029
+ return false;
2030
+ }
2031
+ this.#history.length = previous + 1;
2032
+ this.#recalculate(true);
2033
+ return true;
2034
+ }
2035
+ #recalculate(force = false) {
2036
+ const next = this.#calculate(this.#history.length - 1);
2037
+ const changed = force || !sameThreePaneScaffoldValue(next, this.#value);
2038
+ this.#value = next;
2039
+ if (changed) for (const listener of [...this.#listeners]) listener();
2040
+ }
2041
+ /** getPreviousDestinationIndex (L430-466). */
2042
+ #previousIndex(behavior) {
2043
+ const history = this.#history;
2044
+ if (history.length <= 1) return -1;
2045
+ const last = history.length - 1;
2046
+ const current = history[last];
2047
+ for (let i = last - 1; i >= 0; i--) {
2048
+ const item = history[i];
2049
+ if (!item) continue;
2050
+ switch (behavior) {
2051
+ case "pop-latest":
2052
+ return i;
2053
+ case "pop-until-scaffold-value-change":
2054
+ if (!sameThreePaneScaffoldValue(this.#calculate(i), this.#value)) return i;
2055
+ break;
2056
+ case "pop-until-current-destination-change":
2057
+ if (item.pane !== current?.pane) return i;
2058
+ break;
2059
+ case "pop-until-content-change":
2060
+ if (!Object.is(item.contentKey, current?.contentKey)) return i;
2061
+ if (!sameThreePaneScaffoldValue(this.#calculate(i), this.#value)) return i;
2062
+ break;
2063
+ }
2064
+ }
2065
+ return -1;
2066
+ }
2067
+ /** calculateScaffoldValue (L468-490). */
2068
+ #calculate(index) {
2069
+ const { maxHorizontalPartitions, maxVerticalPartitions } = this.#directive;
2070
+ const history = index === -1 ? [] : this.#historyAware ? this.#history.slice(0, index + 1) : this.#history.slice(index, index + 1);
2071
+ return calculateThreePaneScaffoldValue(
2072
+ maxHorizontalPartitions,
2073
+ this.#strategies,
2074
+ history,
2075
+ maxVerticalPartitions
2076
+ );
2077
+ }
2078
+ };
2079
+ function threePaneScaffoldLayout(input) {
2080
+ const { width: W, height: H, directive, value, order } = input;
2081
+ const present = input.present ?? THREE_PANE_SCAFFOLD_ROLES;
2082
+ const make = (role) => ({
2083
+ role,
2084
+ width: input.preferredWidths?.[role] ?? directive.defaultPanePreferredWidth,
2085
+ height: input.preferredHeights?.[role] ?? directive.defaultPanePreferredHeight,
2086
+ bounds: null
2087
+ });
2088
+ const select = (pick2) => order.filter((r) => present.includes(r) && pick2(value[r])).map(make);
2089
+ const expanded = select((v) => v === "expanded");
2090
+ const reflowed = select((v) => v === "reflowed");
2091
+ const spacer = directive.horizontalPartitionSpacerSize;
2092
+ const vSpacer = directive.verticalPartitionSpacerSize;
2093
+ const outer = { x: 0, y: 0, width: W, height: H };
2094
+ const right = (r) => r.x + r.width;
2095
+ const between = (left, rightEdge) => ({
2096
+ x: left,
2097
+ y: 0,
2098
+ width: rightEdge - left,
2099
+ height: H
2100
+ });
2101
+ const inPartition = (partition, pane) => {
2102
+ const flowed = reflowed[0];
2103
+ const strategy = flowed ? input.adaptStrategies[flowed.role] : "hide";
2104
+ if (flowed && strategy !== "hide" && strategy.reflowUnder === pane.role) {
2105
+ const available = partition.height - vSpacer;
2106
+ pane.height = Math.max(available - flowed.height, Math.trunc(available / 2));
2107
+ flowed.height = available - pane.height;
2108
+ flowed.bounds = {
2109
+ x: partition.x,
2110
+ y: partition.y + pane.height + vSpacer,
2111
+ width: partition.width,
2112
+ height: partition.height - pane.height - vSpacer
2113
+ };
2114
+ } else {
2115
+ pane.height = partition.height;
2116
+ }
2117
+ pane.bounds = { ...partition, height: pane.height };
2118
+ };
2119
+ const partitions = (bounds, panes2) => {
2120
+ if (panes2.length === 0) return;
2121
+ const allocatable = bounds.width - (panes2.length - 1) * spacer;
2122
+ const total = panes2.reduce((sum, p) => sum + p.width, 0);
2123
+ if (allocatable > total) {
2124
+ const top = panes2.reduce((a, b) => PRIORITY[b.role] > PRIORITY[a.role] ? b : a);
2125
+ top.width += allocatable - total;
2126
+ } else if (allocatable < total) {
2127
+ const scale = Math.fround(allocatable / total);
2128
+ for (const p of panes2) p.width = Math.trunc(Math.fround(p.width * scale));
2129
+ }
2130
+ let x = bounds.x;
2131
+ for (const p of panes2) {
2132
+ inPartition({ x, y: bounds.y, width: p.width, height: bounds.height }, p);
2133
+ x += p.width + spacer;
2134
+ }
2135
+ };
2136
+ const expansion = input.expansion;
2137
+ const first = expanded[0];
2138
+ const second = expanded[1];
2139
+ const dragging = expansion?.draggingOffset;
2140
+ const resting = expansion?.firstPaneWidth;
2141
+ if (expanded.length === 2 && first && second && (dragging !== void 0 || resting !== void 0)) {
2142
+ const half = Math.trunc(spacer / 2);
2143
+ if (dragging !== void 0) {
2144
+ if (dragging <= half)
2145
+ inPartition({ ...outer, x: dragging * 2, width: W - dragging * 2 }, second);
2146
+ else if (dragging >= W - half) inPartition({ ...outer, width: dragging * 2 - W }, first);
2147
+ else {
2148
+ inPartition(between(0, dragging - half), first);
2149
+ inPartition(between(dragging + half, W), second);
2150
+ }
2151
+ } else if (resting !== void 0) {
2152
+ const firstWidth = Math.max(0, Math.min(resting, W));
2153
+ if (firstWidth === 0) inPartition(outer, second);
2154
+ else if (firstWidth >= W - spacer) inPartition(outer, first);
2155
+ else {
2156
+ inPartition(between(0, firstWidth), first);
2157
+ inPartition(between(firstWidth + spacer, W), second);
2158
+ }
2159
+ }
2160
+ } else {
2161
+ partitions(outer, expanded);
2162
+ }
2163
+ let handleOffset = null;
2164
+ if (expanded.length === 2 && first && second) {
2165
+ if (dragging !== void 0) handleOffset = dragging;
2166
+ else if (first.bounds && second.bounds)
2167
+ handleOffset = Math.trunc((right(first.bounds) + second.bounds.x) / 2);
2168
+ else if (first.bounds) handleOffset = right(first.bounds);
2169
+ else if (second.bounds) handleOffset = 0;
2170
+ }
2171
+ const panes = {};
2172
+ for (const p of [...expanded, ...reflowed]) {
2173
+ panes[p.role] = p.bounds ?? { x: 0, y: 0, width: 0, height: 0 };
2174
+ }
2175
+ return { panes, handleOffset };
2176
+ }
2177
+ var motionType = (motion) => motion === "none" ? "hidden" : motion === "animate-bounds" ? "shown" : motion.startsWith("enter") ? "entering" : "exiting";
2178
+ function typeOf(previous, current) {
2179
+ const was = previous !== "hidden";
2180
+ const is = current !== "hidden";
2181
+ return was && is ? "shown" : was ? "exiting" : is ? "entering" : "hidden";
2182
+ }
2183
+ function calculatePaneMotion(previous, current, order) {
2184
+ const n = order.length;
2185
+ const types = order.map((r) => typeOf(previous[r], current[r]));
2186
+ const motions = order.map(() => "none");
2187
+ let firstShown = n;
2188
+ let firstEntering = n;
2189
+ let lastShown = -1;
2190
+ let lastEntering = -1;
2191
+ types.forEach((t, i) => {
2192
+ if (t === "shown") {
2193
+ firstShown = Math.min(firstShown, i);
2194
+ lastShown = Math.max(lastShown, i);
2195
+ motions[i] = "animate-bounds";
2196
+ } else if (t === "entering") {
2197
+ firstEntering = Math.min(firstEntering, i);
2198
+ lastEntering = Math.max(lastEntering, i);
2199
+ }
2200
+ });
2201
+ let exitRight = false;
2202
+ let exitLeft = false;
2203
+ let firstExitRight = n;
2204
+ let lastExitLeft = -1;
2205
+ types.forEach((t, i) => {
2206
+ if (t !== "exiting") return;
2207
+ const shownLeft = firstShown < i;
2208
+ const enteringLeft = firstEntering < i;
2209
+ const shownRight = lastShown > i;
2210
+ const enteringRight = lastEntering > i;
2211
+ const toRight = () => {
2212
+ exitRight = true;
2213
+ firstExitRight = Math.min(firstExitRight, i);
2214
+ motions[i] = "exit-to-right";
2215
+ };
2216
+ const toLeft = () => {
2217
+ exitLeft = true;
2218
+ lastExitLeft = Math.max(lastExitLeft, i);
2219
+ motions[i] = "exit-to-left";
2220
+ };
2221
+ if (!shownRight && !enteringRight) toRight();
2222
+ else if (!shownLeft && !enteringLeft) toLeft();
2223
+ else if (!shownRight) toRight();
2224
+ else if (!shownLeft) toLeft();
2225
+ else motions[i] = "exit-with-shrink";
2226
+ });
2227
+ types.forEach((t, i) => {
2228
+ if (t !== "entering") return;
2229
+ const freeRight = !(lastShown > i) && !(lastExitLeft > i);
2230
+ const freeLeft = !(firstShown < i) && !(firstExitRight < i);
2231
+ motions[i] = freeRight && !exitRight ? "enter-from-right" : freeLeft && !exitLeft ? "enter-from-left" : freeRight ? "enter-from-right-delayed" : freeLeft ? "enter-from-left-delayed" : "enter-with-expand";
2232
+ });
2233
+ const out = { primary: "none", secondary: "none", tertiary: "none" };
2234
+ order.forEach((r, i) => {
2235
+ out[r] = motions[i] ?? "none";
2236
+ });
2237
+ return out;
2238
+ }
2239
+ var PANE_MOTION_DELAYED_RATIO = 0.1;
2240
+ function paneTransitions(motions, order, origin, target, scaffoldWidth) {
2241
+ const zero = { x: 0, y: 0, width: 0, height: 0 };
2242
+ const t = (r) => target[r] ?? origin[r] ?? zero;
2243
+ const o = (r) => origin[r] ?? target[r] ?? zero;
2244
+ const type = (r) => motionType(motions[r]);
2245
+ const shown = (r, other) => type(r) === "shown" || type(r) === other;
2246
+ const reversed = [...order].reverse();
2247
+ const slideInFromLeft = () => {
2248
+ let previous = null;
2249
+ for (const r of reversed) {
2250
+ const m = motions[r];
2251
+ if (m === "enter-from-left" || m === "enter-from-left-delayed")
2252
+ return -(previous ? t(previous).x : t(r).x + t(r).width);
2253
+ if (shown(r, "entering")) previous = r;
2254
+ }
2255
+ return 0;
2256
+ };
2257
+ const slideInFromRight = () => {
2258
+ let previous = null;
2259
+ for (const r of order) {
2260
+ const m = motions[r];
2261
+ if (m === "enter-from-right" || m === "enter-from-right-delayed")
2262
+ return scaffoldWidth - (previous ? t(previous).x + t(previous).width : t(r).x);
2263
+ if (shown(r, "entering")) previous = r;
2264
+ }
2265
+ return 0;
2266
+ };
2267
+ const slideOutToLeft = () => {
2268
+ let previous = null;
2269
+ for (const r of reversed) {
2270
+ if (motions[r] === "exit-to-left") return -(previous ? o(previous).x : o(r).x + o(r).width);
2271
+ if (shown(r, "exiting")) previous = r;
2272
+ }
2273
+ return 0;
2274
+ };
2275
+ const slideOutToRight = () => {
2276
+ let previous = null;
2277
+ for (const r of order) {
2278
+ if (motions[r] === "exit-to-right")
2279
+ return scaffoldWidth - (previous ? o(previous).x + o(previous).width : o(r).x);
2280
+ if (shown(r, "exiting")) previous = r;
2281
+ }
2282
+ return 0;
2283
+ };
2284
+ const leftEdge = (role, other, rect) => {
2285
+ let edge = 0;
2286
+ for (const r of order) {
2287
+ if (r === role) return edge;
2288
+ if (shown(r, other)) edge = rect(r).x + rect(r).width;
2289
+ }
2290
+ return edge;
2291
+ };
2292
+ const out = {};
2293
+ for (const r of order) {
2294
+ const motion = motions[r];
2295
+ const to2 = t(r);
2296
+ const from = o(r);
2297
+ const shift = (rect, dx) => ({ ...rect, x: rect.x + dx });
2298
+ let transition = null;
2299
+ switch (motion) {
2300
+ case "animate-bounds":
2301
+ transition = { motion, from, to: to2, delayed: false };
2302
+ break;
2303
+ case "enter-from-left":
2304
+ case "enter-from-left-delayed":
2305
+ transition = {
2306
+ motion,
2307
+ from: shift(to2, slideInFromLeft()),
2308
+ to: to2,
2309
+ delayed: motion.endsWith("delayed")
2310
+ };
2311
+ break;
2312
+ case "enter-from-right":
2313
+ case "enter-from-right-delayed":
2314
+ transition = {
2315
+ motion,
2316
+ from: shift(to2, slideInFromRight()),
2317
+ to: to2,
2318
+ delayed: motion.endsWith("delayed")
2319
+ };
2320
+ break;
2321
+ case "enter-with-expand":
2322
+ transition = {
2323
+ motion,
2324
+ from: { ...to2, x: leftEdge(r, "exiting", o), width: 0 },
2325
+ to: to2,
2326
+ delayed: false
2327
+ };
2328
+ break;
2329
+ case "exit-to-left":
2330
+ transition = { motion, from, to: shift(from, slideOutToLeft()), delayed: false };
2331
+ break;
2332
+ case "exit-to-right":
2333
+ transition = { motion, from, to: shift(from, slideOutToRight()), delayed: false };
2334
+ break;
2335
+ case "exit-with-shrink":
2336
+ transition = {
2337
+ motion,
2338
+ from,
2339
+ to: { ...from, x: leftEdge(r, "entering", t), width: 0 },
2340
+ delayed: false
2341
+ };
2342
+ break;
2343
+ }
2344
+ if (transition) out[r] = transition;
2345
+ }
2346
+ return out;
2347
+ }
2348
+ var PANE_EXPANSION_SAMPLE_ANCHORS = [
2349
+ { proportion: 0 },
2350
+ { offsetFromStart: 240 },
2351
+ { proportion: 0.5 },
2352
+ { offsetFromEnd: 240 },
2353
+ { proportion: 1 }
2354
+ ];
2355
+ var PANE_EXPANSION_ANCHORING_VELOCITY_THRESHOLD = 200;
2356
+ function paneExpansionAnchorPosition(anchor, width, rtl = false) {
2357
+ const offset = "proportion" in anchor ? Math.min(Math.max(Math.round(width * anchor.proportion), 0), width) : "offsetFromStart" in anchor ? Math.round(anchor.offsetFromStart) : width - Math.round(anchor.offsetFromEnd);
2358
+ return rtl ? width - offset : offset;
2359
+ }
2360
+ function closestPaneExpansionAnchor(anchors, width, position, velocity, rtl = false) {
2361
+ let best = -1;
2362
+ let bestScore = Infinity;
2363
+ const candidates2 = [];
2364
+ anchors.forEach((anchor, index) => {
2365
+ const at2 = paneExpansionAnchorPosition(anchor, width, rtl);
2366
+ let score;
2367
+ if (velocity >= PANE_EXPANSION_ANCHORING_VELOCITY_THRESHOLD) {
2368
+ const delta = at2 - position;
2369
+ score = delta < 0 ? width - delta : delta;
2370
+ } else if (velocity <= -PANE_EXPANSION_ANCHORING_VELOCITY_THRESHOLD) {
2371
+ const delta = position - at2;
2372
+ score = delta < 0 ? width - delta : delta;
2373
+ } else score = Math.abs(position - at2);
2374
+ candidates2.push({ at: at2, index, score });
2375
+ });
2376
+ candidates2.sort((a, b) => a.at - b.at || a.index - b.index);
2377
+ for (const c of candidates2) {
2378
+ if (c.score < bestScore) {
2379
+ best = c.index;
2380
+ bestScore = c.score;
2381
+ }
2382
+ }
2383
+ return best;
2384
+ }
2385
+ function nextPaneExpansionAnchor(anchors, width, position, rtl = false) {
2386
+ const sorted = anchors.map((anchor, index) => ({ at: paneExpansionAnchorPosition(anchor, width, rtl), index })).sort((a, b) => a.at - b.at || a.index - b.index);
2387
+ return (sorted.find((a) => position < a.at) ?? sorted[0])?.index ?? -1;
2388
+ }
2389
+ var PANE_MOTION_VISIBILITY_THRESHOLD = 1;
2390
+ var KEYS = ["x", "y", "width", "height"];
2391
+ var ThreePaneScaffoldAnimation = class {
2392
+ #panes = /* @__PURE__ */ new Map();
2393
+ start(transitions, spec, now) {
2394
+ const next = /* @__PURE__ */ new Map();
2395
+ for (const role of THREE_PANE_SCAFFOLD_ROLES) {
2396
+ const transition = transitions[role];
2397
+ if (!transition) continue;
2398
+ const { from, to: to2 } = transition;
2399
+ const previous = this.#panes.get(role);
2400
+ if (previous) for (const k of KEYS) previous.springs[k].sample(now);
2401
+ const springs = previous?.springs ?? Object.fromEntries(
2402
+ KEYS.map((k) => [k, new SpringAnimatable(from[k], PANE_MOTION_VISIBILITY_THRESHOLD)])
2403
+ );
2404
+ const pane = { springs, to: to2, spec, delayUntil: null };
2405
+ if (transition.delayed && spec !== null && !previous) {
2406
+ const duration = Math.max(
2407
+ ...KEYS.map(
2408
+ (k) => springDurationMillis(spec, from[k], to2[k], 0, PANE_MOTION_VISIBILITY_THRESHOLD)
2409
+ )
2410
+ );
2411
+ pane.delayUntil = now + Math.trunc(duration * PANE_MOTION_DELAYED_RATIO);
2412
+ } else {
2413
+ for (const k of KEYS) springs[k].animateTo(to2[k], spec, now);
2414
+ }
2415
+ next.set(role, pane);
2416
+ }
2417
+ this.#panes = next;
2418
+ }
2419
+ /** Jumps every pane to its target. */
2420
+ finish() {
2421
+ for (const pane of this.#panes.values()) {
2422
+ pane.delayUntil = null;
2423
+ for (const k of KEYS) pane.springs[k].snapTo(pane.to[k]);
2424
+ }
2425
+ }
2426
+ sample(now) {
2427
+ const panes = {};
2428
+ let running = false;
2429
+ for (const [role, pane] of this.#panes) {
2430
+ const s = pane.springs;
2431
+ if (pane.delayUntil !== null && now >= pane.delayUntil) {
2432
+ for (const k of KEYS) s[k].animateTo(pane.to[k], pane.spec, pane.delayUntil);
2433
+ pane.delayUntil = null;
2434
+ }
2435
+ panes[role] = {
2436
+ x: s.x.sample(now),
2437
+ y: s.y.sample(now),
2438
+ width: Math.max(0, s.width.sample(now)),
2439
+ height: Math.max(0, s.height.sample(now))
2440
+ };
2441
+ if (pane.delayUntil !== null || KEYS.some((k) => s[k].isRunning)) running = true;
2442
+ }
2443
+ return { panes, running };
2444
+ }
2445
+ };
2446
+
2447
+ export { AmplitudeAnimation, DEFAULT_DISPLACEMENT_THRESHOLD, DRAWER_POSITIONAL_THRESHOLD, DRAWER_SETTLE_MILLIS, DRAWER_VELOCITY_THRESHOLD, DrawerAnimation, FAST_OUT_LINEAR_IN_EASING, LIST_DETAIL_ADAPT_STRATEGIES, LIST_DETAIL_INITIAL_HISTORY, LIST_DETAIL_PANE_ORDER, ListDetailPaneScaffoldRole, MODAL_RAIL_EXPANDED_PROGRESS, NAVIGATION_SUITE_EXPANDED_FROM, NAVIGATION_SUITE_TYPES, NavigationSuiteScaffoldAnimation, PANE_EXPANSION_ANCHORING_VELOCITY_THRESHOLD, PANE_EXPANSION_SAMPLE_ANCHORS, PANE_MOTION_DELAYED_RATIO, PANE_MOTION_VISIBILITY_THRESHOLD, RECOMMENDED_MAX_PANES, SEARCH_BAR_EXPANDED_THRESHOLD, SEARCH_DROPDOWN_VISIBLE_PROGRESS, SLIDER_KEY_DIVISIONS, SLIDER_PAGE_DIVISOR, SLIDER_PAGE_MAX_STEPS, SUPPORTING_PANE_ADAPT_STRATEGIES, SUPPORTING_PANE_INITIAL_HISTORY, SUPPORTING_PANE_ORDER, SearchBarAnimation, SpringAnimatable, SpringSimulation, SupportingPaneScaffoldRole, TAB_INDICATOR_MIN_WIDTH, THREE_PANE_SCAFFOLD_ROLES, TOP_TITLE_ALPHA_EASING, TYPEAHEAD_TIMEOUT_MS, TabIndicatorAnimation, TabScrollAnimation, ThreePaneScaffoldAnimation, ThreePaneScaffoldNavigator, TweenAnimatable, WINDOW_HEIGHT_BREAKPOINTS, WINDOW_WIDTH_BREAKPOINTS, WideNavigationRailAnimation, animatedInt, appBarScrollState, buttonGroupVisibleCount, buttonGroupWidths, calculatePaneMotion, calculateThreePaneScaffoldValue, circularIndeterminateFrame, closestPaneExpansionAnchor, collapsedFraction, cubicBezier, dampingCoefficient, dampingRatioFromCoefficient, drawerSettlesOpen, estimateAnimationDurationMillis, estimateAnimationDurationMillisDouble, expandedPanes, exponentialDecayTarget, fabMenuItemVisible, floatingToolbarScrollState, indeterminateFrame, indicatorAmplitude, initialIndeterminateFrame, isAtLeastBreakpoint, isHeightAtLeastBreakpoint, isNavigationBarType, isScrolledUnder, isWidthAtLeastBreakpoint, linearIndeterminateFractions, menuNavigationTarget, menuPosition, menuTransformOrigin, morphSpringDurationMillis, navigationSuiteOffset, navigationSuiteType, nextPaneExpansionAnchor, overlappedFraction, paneExpansionAnchorPosition, paneScaffoldDirective, paneTransitions, parseCubicBezier, sameThreePaneScaffoldValue, sameWindowSizeClass, scrollAppBar, scrollFloatingToolbar, scrollToolbarExpansion, scrollableTabOffset, searchNavigationTarget, searchViewFrame, settleTarget, sliderClosestThumb, sliderFraction, sliderKeyAction, sliderKeyDelta, sliderKeyValue, sliderPageSteps, sliderSnap, sliderSteps, sliderThumbBounds, sliderThumbValue, sliderTickFractions, sliderTrackGeometry, sliderValueAt, springDurationMillis, springToLinear, springValue, springVelocity, tabIndicatorShift, tabIndicatorTarget, tabPositions, threePaneScaffoldDirective, threePaneScaffoldLayout, toolbarCollapsedFraction, toolbarExpansionScroll, toolbarNavigationTarget, toolbarSettleTarget, twoRowsFrame, typeSelectTarget, waveOffset, waveTravelMillis, wideNavigationRailItemWidth, wideNavigationRailWidth, windowHeightSizeClass, windowSizeClass, windowWidthSizeClass, withHeight, withHeightOffset, withToolbarOffset, withToolbarOffsetLimit };
1035
2448
  //# sourceMappingURL=index.js.map
1036
2449
  //# sourceMappingURL=index.js.map