@nswds/app 1.45.2 → 1.46.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -56,6 +56,13 @@ var AlertDialogPrimitive = require('@radix-ui/react-alert-dialog');
56
56
  var reactDayPicker = require('react-day-picker');
57
57
  var useEmblaCarousel = require('embla-carousel-react');
58
58
  var inputOtp = require('input-otp');
59
+ var NextAuth = require('next-auth');
60
+ var MicrosoftEntraID = require('next-auth/providers/microsoft-entra-id');
61
+ var drizzleOrm = require('drizzle-orm');
62
+ var drizzleAdapter = require('@auth/drizzle-adapter');
63
+ var libsql = require('drizzle-orm/libsql');
64
+ var client$1 = require('@libsql/client');
65
+ var sqliteCore = require('drizzle-orm/sqlite-core');
59
66
  var slugify = require('@sindresorhus/slugify');
60
67
  var zustand = require('zustand');
61
68
  var middleware = require('zustand/middleware');
@@ -113,13 +120,20 @@ var RechartsPrimitive__namespace = /*#__PURE__*/_interopNamespace(RechartsPrimit
113
120
  var HoverCardPrimitives__namespace = /*#__PURE__*/_interopNamespace(HoverCardPrimitives);
114
121
  var AlertDialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(AlertDialogPrimitive);
115
122
  var useEmblaCarousel__default = /*#__PURE__*/_interopDefault(useEmblaCarousel);
123
+ var NextAuth__default = /*#__PURE__*/_interopDefault(NextAuth);
124
+ var MicrosoftEntraID__default = /*#__PURE__*/_interopDefault(MicrosoftEntraID);
116
125
 
126
+ var __defProp = Object.defineProperty;
117
127
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
118
128
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
119
129
  }) : x)(function(x) {
120
130
  if (typeof require !== "undefined") return require.apply(this, arguments);
121
131
  throw Error('Dynamic require of "' + x + '" is not supported');
122
132
  });
133
+ var __export = (target, all) => {
134
+ for (var name in all)
135
+ __defProp(target, name, { get: all[name], enumerable: true });
136
+ };
123
137
  var Icons = {
124
138
  account_circle: (props) => /* @__PURE__ */ jsxRuntime.jsx("svg", { fill: "currentColor", "data-slot": "icon", viewBox: "0 -960 960 960", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M234-276q51-39 114-61.5T480-360q69 0 132 22.5T726-276q35-41 54.5-93T800-480q0-133-93.5-226.5T480-800q-133 0-226.5 93.5T160-480q0 59 19.5 111t54.5 93Zm246-164q-59 0-99.5-40.5T340-580q0-59 40.5-99.5T480-720q59 0 99.5 40.5T620-580q0 59-40.5 99.5T480-440Zm0 360q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q53 0 100-15.5t86-44.5q-39-29-86-44.5T480-280q-53 0-100 15.5T294-220q39 29 86 44.5T480-160Zm0-360q26 0 43-17t17-43q0-26-17-43t-43-17q-26 0-43 17t-17 43q0 26 17 43t43 17Zm0-60Zm0 360Z" }) }),
125
139
  add: (props) => /* @__PURE__ */ jsxRuntime.jsx("svg", { fill: "currentColor", "data-slot": "icon", viewBox: "0 -960 960 960", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M440-440H240q-17 0-28.5-11.5T200-480q0-17 11.5-28.5T240-520h200v-200q0-17 11.5-28.5T480-760q17 0 28.5 11.5T520-720v200h200q17 0 28.5 11.5T760-480q0 17-11.5 28.5T720-440H520v200q0 17-11.5 28.5T480-200q-17 0-28.5-11.5T440-240v-200Z" }) }),
@@ -228,11 +242,11 @@ var Icons = {
228
242
  function cn(...inputs) {
229
243
  return tailwindMerge.twMerge(clsx21.clsx(inputs));
230
244
  }
231
- function truncate(text, maxLength) {
232
- if (text.length <= maxLength) {
233
- return text;
245
+ function truncate(text4, maxLength) {
246
+ if (text4.length <= maxLength) {
247
+ return text4;
234
248
  }
235
- return text.slice(0, maxLength) + "...";
249
+ return text4.slice(0, maxLength) + "...";
236
250
  }
237
251
  function kebabCase(str) {
238
252
  return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
@@ -696,7 +710,7 @@ var styles = {
696
710
  default: "px-[calc(--spacing(5)-1px)] py-[calc(--spacing(4)-1px)] sm:px-[calc(--spacing(4.5)-1px)] sm:py-[calc(--spacing(3)-1px)]",
697
711
  sm: "px-[calc(--spacing(4)-1px)] py-[calc(--spacing(3)-1px)] sm:px-[calc(--spacing(3.5)-1px)] sm:py-[calc(--spacing(2)-1px)]",
698
712
  lg: "px-[calc(--spacing(6)-1px)] py-[calc(--spacing(5)-1px)] sm:px-[calc(--spacing(5.5)-1px)] sm:py-[calc(--spacing(4)-1px)]",
699
- icon: "size-10"
713
+ icon: "w-10 h-10 flex-none"
700
714
  }
701
715
  };
702
716
  var buttonVariants = classVarianceAuthority.cva(styles.base, {
@@ -4623,7 +4637,7 @@ var colors = {
4623
4637
  hex: "#c99ac2",
4624
4638
  rgb: "rgb(201, 154, 194)",
4625
4639
  hsl: "hsl(308.94, 30.32%, 69.61%)",
4626
- name: "Lilli pilli Purple"
4640
+ name: "Lilli Pilli Purple"
4627
4641
  },
4628
4642
  {
4629
4643
  token: "nsw-aboriginal-purple-450",
@@ -5963,7 +5977,6 @@ function ThemeSelectorContent({
5963
5977
  availableAccentColors,
5964
5978
  colorThemes: colorThemes2
5965
5979
  }) {
5966
- const searchParams = navigation.useSearchParams();
5967
5980
  const [, copyToClipboardRaw] = usehooks.useCopyToClipboard();
5968
5981
  const [copied, setCopied] = React16.useState(false);
5969
5982
  const updateUrlParams = React16.useCallback(
@@ -5976,60 +5989,6 @@ function ThemeSelectorContent({
5976
5989
  },
5977
5990
  []
5978
5991
  );
5979
- React16.useEffect(() => {
5980
- const themeParam = searchParams.get("theme");
5981
- const primaryParam = searchParams.get("primary");
5982
- const accentParam = searchParams.get("accent");
5983
- let shouldUpdateUrl = false;
5984
- let newCategory = themeCategory;
5985
- let newPrimary = primaryColor;
5986
- let newAccent = accentColor;
5987
- if (themeParam && (themeParam === "brand" || themeParam === "aboriginal")) {
5988
- if (themeParam !== themeCategory) {
5989
- newCategory = themeParam;
5990
- shouldUpdateUrl = true;
5991
- const neutral = findGreyKey(colorThemes2[themeParam]);
5992
- if (neutral && neutral !== greyColor) {
5993
- setGreyColor(neutral);
5994
- }
5995
- }
5996
- }
5997
- const availableColors = Object.keys(colorThemes2[newCategory]);
5998
- if (primaryParam && availableColors.includes(primaryParam)) {
5999
- if (primaryParam !== primaryColor) {
6000
- newPrimary = primaryParam;
6001
- shouldUpdateUrl = true;
6002
- }
6003
- }
6004
- if (accentParam && availableColors.includes(accentParam) && accentParam !== newPrimary) {
6005
- if (accentParam !== accentColor) {
6006
- newAccent = accentParam;
6007
- shouldUpdateUrl = true;
6008
- }
6009
- } else {
6010
- const newAccentColor = availableColors.find((color2) => color2 !== newPrimary);
6011
- if (newAccentColor && newAccentColor !== accentColor) {
6012
- newAccent = newAccentColor;
6013
- shouldUpdateUrl = true;
6014
- }
6015
- }
6016
- if (shouldUpdateUrl) {
6017
- if (newCategory !== themeCategory) setThemeCategory(newCategory);
6018
- if (newPrimary !== primaryColor) setPrimaryColor(newPrimary);
6019
- if (newAccent !== accentColor) setAccentColor(newAccent);
6020
- }
6021
- }, [
6022
- searchParams,
6023
- themeCategory,
6024
- primaryColor,
6025
- accentColor,
6026
- greyColor,
6027
- colorThemes2,
6028
- setThemeCategory,
6029
- setPrimaryColor,
6030
- setAccentColor,
6031
- setGreyColor
6032
- ]);
6033
5992
  const handleCategoryChange = (newCategory) => {
6034
5993
  setThemeCategory(newCategory);
6035
5994
  const availableColors = Object.keys(colorThemes2[newCategory]);
@@ -6240,6 +6199,7 @@ function CodeDemoContent({ data, hide = {} }) {
6240
6199
  const themeParam = searchParams.get("theme");
6241
6200
  const primaryParam = searchParams.get("primary");
6242
6201
  const accentParam = searchParams.get("accent");
6202
+ const hasUrlParams = themeParam || primaryParam || accentParam;
6243
6203
  let newCategory = themeCategory;
6244
6204
  let newPrimary = primaryColor;
6245
6205
  let newAccent = accentColor;
@@ -6258,12 +6218,20 @@ function CodeDemoContent({ data, hide = {} }) {
6258
6218
  if (accentParam && availableColors.includes(accentParam) && accentParam !== newPrimary) {
6259
6219
  newAccent = accentParam;
6260
6220
  setAccentColor(accentParam);
6261
- } else {
6221
+ } else if (hasUrlParams) {
6262
6222
  const newAccentColor = availableColors.find((color2) => color2 !== newPrimary);
6263
6223
  if (newAccentColor) {
6264
6224
  newAccent = newAccentColor;
6265
6225
  setAccentColor(newAccent);
6266
6226
  }
6227
+ } else {
6228
+ if (!availableColors.includes(newAccent) || newAccent === newPrimary) {
6229
+ const newAccentColor = availableColors.find((color2) => color2 !== newPrimary);
6230
+ if (newAccentColor) {
6231
+ newAccent = newAccentColor;
6232
+ setAccentColor(newAccent);
6233
+ }
6234
+ }
6267
6235
  }
6268
6236
  const neutralKey = Object.keys(colorThemes[newCategory]).find(
6269
6237
  (k) => k.toLowerCase().includes("grey")
@@ -6361,6 +6329,27 @@ function CodeDemoContent({ data, hide = {} }) {
6361
6329
  const explicit = data.labels ?? {};
6362
6330
  return Object.fromEntries(variants.map((v) => [v, explicit[v] ?? humaniseVariant(v)]));
6363
6331
  }, [variants, data]);
6332
+ React16.useEffect(() => {
6333
+ if (!isThemeInitialized) return;
6334
+ const neutralKey = Object.keys(colorThemes[themeCategory]).find((k) => k.toLowerCase().includes("grey")) ?? "";
6335
+ if (neutralKey && neutralKey !== greyColor) {
6336
+ setGreyColor(neutralKey);
6337
+ }
6338
+ const availableColors = Object.keys(colorThemes[themeCategory]);
6339
+ if (!availableColors.includes(primaryColor)) {
6340
+ setPrimaryColor(availableColors[0]);
6341
+ if (availableColors.length > 1) {
6342
+ setAccentColor(availableColors[1]);
6343
+ }
6344
+ return;
6345
+ }
6346
+ if (accentColor === primaryColor || !availableColors.includes(accentColor)) {
6347
+ const newAccentColor = availableColors.find((color2) => color2 !== primaryColor);
6348
+ if (newAccentColor) {
6349
+ setAccentColor(newAccentColor);
6350
+ }
6351
+ }
6352
+ }, [themeCategory, primaryColor, accentColor, greyColor, isThemeInitialized]);
6364
6353
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8", children: [
6365
6354
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-grey-200 bg-grey-50 dark:border-grey-600 dark:bg-grey-700 w-full rounded-t-xl border p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 sm:grid-cols-3", children: [
6366
6355
  /* @__PURE__ */ jsxRuntime.jsx(EditOnGithubButton, { githubSlug: data.githubSlug }),
@@ -7809,7 +7798,7 @@ function Heading({
7809
7798
 
7810
7799
  // package.json
7811
7800
  var package_default = {
7812
- version: "1.44.0"};
7801
+ version: "1.46.0"};
7813
7802
  function Logo(props) {
7814
7803
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7815
7804
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "NSW Government" }),
@@ -7953,7 +7942,7 @@ function Header2({
7953
7942
  "data-scrolled": isScrolled,
7954
7943
  id: "nsw-header",
7955
7944
  className: clsx21__default.default(
7956
- "sticky top-0 z-50 flex flex-none flex-wrap items-center justify-between bg-white px-4 py-5 transition duration-500 sm:px-6 lg:px-12",
7945
+ "sticky top-0 z-50 flex hidden flex-none flex-wrap items-center justify-between bg-white px-4 py-5 transition duration-500 sm:px-6 lg:flex lg:px-12",
7957
7946
  shadow && "shadow-md shadow-slate-900/5 dark:shadow-none",
7958
7947
  isScrolled ? "dark:bg-slate-900/95 dark:backdrop-blur-sm dark:[@supports(backdrop-filter:blur(0))]:bg-slate-900/75" : "dark:bg-transparent"
7959
7948
  ),
@@ -13345,7 +13334,7 @@ function distance2D(a, b) {
13345
13334
 
13346
13335
  // node_modules/framer-motion/dist/es/gestures/pan/PanSession.mjs
13347
13336
  var PanSession = class {
13348
- constructor(event, handlers, { transformPagePoint, contextWindow, dragSnapToOrigin = false } = {}) {
13337
+ constructor(event, handlers2, { transformPagePoint, contextWindow, dragSnapToOrigin = false } = {}) {
13349
13338
  this.startEvent = null;
13350
13339
  this.lastMoveEvent = null;
13351
13340
  this.lastMoveEventInfo = null;
@@ -13390,7 +13379,7 @@ var PanSession = class {
13390
13379
  if (!isPrimaryPointer(event))
13391
13380
  return;
13392
13381
  this.dragSnapToOrigin = dragSnapToOrigin;
13393
- this.handlers = handlers;
13382
+ this.handlers = handlers2;
13394
13383
  this.transformPagePoint = transformPagePoint;
13395
13384
  this.contextWindow = contextWindow || window;
13396
13385
  const info = extractEventInfo(event);
@@ -13398,12 +13387,12 @@ var PanSession = class {
13398
13387
  const { point } = initialInfo;
13399
13388
  const { timestamp } = frameData;
13400
13389
  this.history = [{ ...point, timestamp }];
13401
- const { onSessionStart } = handlers;
13390
+ const { onSessionStart } = handlers2;
13402
13391
  onSessionStart && onSessionStart(event, getPanInfo(initialInfo, this.history));
13403
13392
  this.removeListeners = pipe(addPointerEvent(this.contextWindow, "pointermove", this.handlePointerMove), addPointerEvent(this.contextWindow, "pointerup", this.handlePointerUp), addPointerEvent(this.contextWindow, "pointercancel", this.handlePointerUp));
13404
13393
  }
13405
- updateHandlers(handlers) {
13406
- this.handlers = handlers;
13394
+ updateHandlers(handlers2) {
13395
+ this.handlers = handlers2;
13407
13396
  }
13408
13397
  end() {
13409
13398
  this.removeListeners && this.removeListeners();
@@ -17317,7 +17306,7 @@ var colors2 = {
17317
17306
  ]
17318
17307
  };
17319
17308
  function Switch2({
17320
- color: color2 = "dark/grey",
17309
+ color: color2 = "primary",
17321
17310
  className,
17322
17311
  ...props
17323
17312
  }) {
@@ -23034,6 +23023,534 @@ function DescriptionDetails({ className, ...props }) {
23034
23023
  }
23035
23024
  );
23036
23025
  }
23026
+ function generateLevelId() {
23027
+ return `level-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
23028
+ }
23029
+ function getMaxDepth(items, currentDepth = 1) {
23030
+ if (!items || !Array.isArray(items) || items.length === 0) {
23031
+ return currentDepth;
23032
+ }
23033
+ let maxDepth2 = currentDepth;
23034
+ for (const item of items) {
23035
+ if (item && item.links && Array.isArray(item.links) && item.links.length > 0) {
23036
+ const itemDepth = getMaxDepth(item.links, currentDepth + 1);
23037
+ maxDepth2 = Math.max(maxDepth2, itemDepth);
23038
+ }
23039
+ }
23040
+ return maxDepth2;
23041
+ }
23042
+ function findItemById(items, id3) {
23043
+ if (!items || !Array.isArray(items)) {
23044
+ return null;
23045
+ }
23046
+ for (const item of items) {
23047
+ if (!item) continue;
23048
+ if (item.id === id3) {
23049
+ return item;
23050
+ }
23051
+ if (item.links && Array.isArray(item.links)) {
23052
+ const found = findItemById(item.links, id3);
23053
+ if (found) return found;
23054
+ }
23055
+ }
23056
+ return null;
23057
+ }
23058
+ function findPathToItem(items, targetId, path = []) {
23059
+ if (!items || !Array.isArray(items)) {
23060
+ return null;
23061
+ }
23062
+ for (const item of items) {
23063
+ if (!item) continue;
23064
+ const currentPath = [...path, item];
23065
+ if (item.id === targetId) {
23066
+ return currentPath;
23067
+ }
23068
+ if (item.links && Array.isArray(item.links)) {
23069
+ const found = findPathToItem(item.links, targetId, currentPath);
23070
+ if (found) return found;
23071
+ }
23072
+ }
23073
+ return null;
23074
+ }
23075
+ function getTotalItemCount(items) {
23076
+ if (!items || !Array.isArray(items)) {
23077
+ return 0;
23078
+ }
23079
+ let count = items.length;
23080
+ for (const item of items) {
23081
+ if (item && item.links && Array.isArray(item.links)) {
23082
+ count += getTotalItemCount(item.links);
23083
+ }
23084
+ }
23085
+ return count;
23086
+ }
23087
+ function generateBreadcrumb(levels, maxLength = 50) {
23088
+ if (levels.length <= 1) return levels[0]?.title || "Menu";
23089
+ const breadcrumb = levels.map((level) => level.title).join(" \u203A ");
23090
+ if (breadcrumb.length <= maxLength) {
23091
+ return breadcrumb;
23092
+ }
23093
+ if (levels.length > 3) {
23094
+ const first = levels[0].title;
23095
+ const last = levels[levels.length - 1].title;
23096
+ const secondLast = levels[levels.length - 2].title;
23097
+ return `${first} \u203A ... \u203A ${secondLast} \u203A ${last}`;
23098
+ }
23099
+ return breadcrumb.substring(0, maxLength - 3) + "...";
23100
+ }
23101
+ function MultiLevelPushMenu({
23102
+ navigation: navigation$1,
23103
+ onItemClick,
23104
+ onNavigate,
23105
+ onClose,
23106
+ className = "",
23107
+ showHeader = true,
23108
+ showFooter = true,
23109
+ showBreadcrumbs = true,
23110
+ showStats = true,
23111
+ showBackButton = true,
23112
+ initialTitle = "Menu"
23113
+ }) {
23114
+ const pathname = navigation.usePathname();
23115
+ const [navigationHistory, setNavigationHistory] = React16.useState([
23116
+ { items: navigation$1 || [], title: initialTitle, depth: 1, id: generateLevelId() }
23117
+ ]);
23118
+ const [animationState, setAnimationState] = React16.useState("idle");
23119
+ const [isAnimationStarted, setIsAnimationStarted] = React16.useState(false);
23120
+ const containerRef = React16.useRef(null);
23121
+ const breadcrumb = React16.useMemo(() => {
23122
+ const levels = navigationHistory.map((level) => ({ title: level.title, depth: level.depth }));
23123
+ return generateBreadcrumb(levels);
23124
+ }, [navigationHistory]);
23125
+ const navigateToSubmenu = React16.useCallback(
23126
+ (item) => {
23127
+ if (item.links && item.links.length > 0 && animationState === "idle") {
23128
+ const newLevel = {
23129
+ items: item.links,
23130
+ title: item.title,
23131
+ parentItem: item,
23132
+ depth: navigationHistory[navigationHistory.length - 1].depth + 1,
23133
+ id: generateLevelId()
23134
+ };
23135
+ const newHistory = [...navigationHistory, newLevel];
23136
+ setNavigationHistory(newHistory);
23137
+ setAnimationState("sliding-forward");
23138
+ setIsAnimationStarted(false);
23139
+ requestAnimationFrame(() => {
23140
+ setIsAnimationStarted(true);
23141
+ });
23142
+ setTimeout(() => {
23143
+ setAnimationState("idle");
23144
+ setIsAnimationStarted(false);
23145
+ onNavigate?.(newLevel, newHistory);
23146
+ }, 300);
23147
+ }
23148
+ },
23149
+ [navigationHistory, animationState, onNavigate]
23150
+ );
23151
+ const navigateBack = React16.useCallback(() => {
23152
+ if (navigationHistory.length > 1 && animationState === "idle") {
23153
+ setAnimationState("sliding-backward");
23154
+ setTimeout(() => {
23155
+ const newHistory = navigationHistory.slice(0, -1);
23156
+ setNavigationHistory(newHistory);
23157
+ setAnimationState("idle");
23158
+ onNavigate?.(newHistory[newHistory.length - 1], newHistory);
23159
+ }, 300);
23160
+ }
23161
+ }, [navigationHistory, animationState, onNavigate]);
23162
+ const handleItemClick = React16.useCallback(
23163
+ (item, event) => {
23164
+ if (item.links && item.links.length > 0) {
23165
+ event?.preventDefault();
23166
+ navigateToSubmenu(item);
23167
+ } else {
23168
+ if (!item.href) {
23169
+ event?.preventDefault();
23170
+ }
23171
+ onItemClick?.(item);
23172
+ }
23173
+ },
23174
+ [navigateToSubmenu, onItemClick]
23175
+ );
23176
+ const currentLevel = navigationHistory[navigationHistory.length - 1];
23177
+ if (!currentLevel || !currentLevel.items) {
23178
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex items-center justify-center p-8 ${className}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
23179
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-2 text-lg font-semibold", children: "Navigation Error" }),
23180
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-grey-800 text-sm", children: "Unable to load navigation data." })
23181
+ ] }) });
23182
+ }
23183
+ const shouldShowBackButton = showBackButton && navigationHistory.length > 1;
23184
+ const isAnimating = animationState !== "idle";
23185
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: `relative h-full overflow-hidden ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative h-full", children: navigationHistory.map((level, index) => {
23186
+ const isCurrentLevel = index === navigationHistory.length - 1;
23187
+ let translateX = 0;
23188
+ if (animationState === "sliding-forward") {
23189
+ if (isCurrentLevel) {
23190
+ translateX = isAnimationStarted ? 0 : 100;
23191
+ } else {
23192
+ translateX = 0;
23193
+ }
23194
+ } else if (animationState === "sliding-backward") {
23195
+ if (isCurrentLevel) {
23196
+ translateX = 100;
23197
+ } else {
23198
+ translateX = 0;
23199
+ }
23200
+ } else {
23201
+ translateX = 0;
23202
+ }
23203
+ return /* @__PURE__ */ jsxRuntime.jsx(
23204
+ "div",
23205
+ {
23206
+ className: `absolute inset-0 h-full w-full will-change-transform`,
23207
+ style: {
23208
+ transform: `translateX(${translateX}%)`,
23209
+ transition: animationState === "sliding-forward" && isAnimationStarted ? "transform 300ms ease-out" : animationState === "sliding-backward" ? "transform 300ms ease-out" : "none",
23210
+ zIndex: index + 1
23211
+ },
23212
+ "data-level-id": level.id,
23213
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col bg-white", children: [
23214
+ shouldShowBackButton && !showHeader && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center bg-white px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", onClick: navigateBack, disabled: isAnimating, children: [
23215
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.west, {}),
23216
+ "Back"
23217
+ ] }) }),
23218
+ showHeader && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-grey-200 flex items-center justify-between border-b bg-white px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center justify-between", children: [
23219
+ shouldShowBackButton && /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", onClick: navigateBack, disabled: isAnimating, children: [
23220
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.west, {}),
23221
+ "Back"
23222
+ ] }),
23223
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
23224
+ navigationHistory.length === 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 2, size: 6, className: "truncate p-2 font-semibold", children: initialTitle }) }),
23225
+ navigationHistory.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", size: "icon", onClick: onClose, children: [
23226
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close panel" }),
23227
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.close, { "aria-hidden": "true", className: "h-6 w-6" })
23228
+ ] })
23229
+ ] })
23230
+ ] }) }),
23231
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden bg-white", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-auto", children: level.items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
23232
+ "div",
23233
+ {
23234
+ className: "divide-grey-200 ring-grey-200 divide-y overflow-hidden bg-white ring-1",
23235
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
23236
+ "button",
23237
+ {
23238
+ ...item.href && !item.links?.length ? { href: item.href } : {},
23239
+ onClick: (event) => handleItemClick(item, event),
23240
+ disabled: isAnimating,
23241
+ className: clsx21__default.default(
23242
+ "hover:bg-primary-800/10 hover:border-primary-800 relative flex w-full cursor-pointer items-center justify-between gap-x-6 border-l p-4 transition-colors",
23243
+ pathname === item.href ? "text-primary-800 bg-primary-800/10 border-primary-800 font-semibold" : "text-grey-800 border-transparent",
23244
+ isAnimating && "pointer-events-none"
23245
+ ),
23246
+ children: [
23247
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: item.title }) }) }),
23248
+ item.links && item.links.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Icons.chevron_right, { className: "h-5 w-5" })
23249
+ ]
23250
+ }
23251
+ )
23252
+ },
23253
+ item.id
23254
+ )) }) }),
23255
+ showFooter && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-grey-100 border-t bg-white px-4 py-2", children: [
23256
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-grey-800 flex items-center justify-between text-xs", children: [
23257
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
23258
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Layers, { className: "h-4 w-4" }),
23259
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
23260
+ "Level ",
23261
+ level.depth
23262
+ ] }),
23263
+ isAnimating && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary-800 animate-pulse", children: "\u2022" })
23264
+ ] }),
23265
+ showStats && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
23266
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Hash, { className: "h-3 w-3" }),
23267
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
23268
+ level.items.length,
23269
+ " items"
23270
+ ] })
23271
+ ] })
23272
+ ] }),
23273
+ level.depth > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1", children: [
23274
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1", children: [
23275
+ Array.from({ length: Math.min(level.depth, 10) }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(
23276
+ "div",
23277
+ {
23278
+ className: `bg-primary-800 h-1 w-2 rounded-full transition-colors duration-300`
23279
+ },
23280
+ i
23281
+ )),
23282
+ level.depth > 10 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-grey-800 ml-1 text-xs", children: [
23283
+ "+",
23284
+ level.depth - 10
23285
+ ] })
23286
+ ] }),
23287
+ showBreadcrumbs && navigationHistory.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex items-center justify-end gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-grey-800 truncate text-xs", children: breadcrumb }) })
23288
+ ] })
23289
+ ] })
23290
+ ] })
23291
+ },
23292
+ level.id
23293
+ );
23294
+ }) }) });
23295
+ }
23296
+ function MobileSearch({ navigation: navigation$1 }) {
23297
+ const [open, setOpen] = React16__namespace.useState(false);
23298
+ const router = navigation.useRouter();
23299
+ React16__namespace.useEffect(() => {
23300
+ const down = (e) => {
23301
+ if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
23302
+ e.preventDefault();
23303
+ setOpen((open2) => !open2);
23304
+ }
23305
+ };
23306
+ document.addEventListener("keydown", down);
23307
+ return () => document.removeEventListener("keydown", down);
23308
+ }, []);
23309
+ const runCommand = React16__namespace.useCallback((command) => {
23310
+ setOpen(false);
23311
+ command();
23312
+ }, []);
23313
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
23314
+ /* @__PURE__ */ jsxRuntime.jsx(
23315
+ Button2,
23316
+ {
23317
+ variant: "ghost",
23318
+ size: "icon",
23319
+ className: "relative m-4 h-10 w-10",
23320
+ onClick: () => setOpen(true),
23321
+ "aria-label": "Search site",
23322
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.search, { "aria-hidden": "true" })
23323
+ }
23324
+ ),
23325
+ /* @__PURE__ */ jsxRuntime.jsxs(CommandDialog, { open, onOpenChange: setOpen, children: [
23326
+ /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Type to search across the site..." }),
23327
+ /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
23328
+ /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No results found." }),
23329
+ navigation$1.map((page, index) => /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { heading: page.title, children: page.links && page.links.filter((link) => link.href && link.title).map((link) => /* @__PURE__ */ jsxRuntime.jsx(
23330
+ CommandItem,
23331
+ {
23332
+ onSelect: () => runCommand(() => router.push(link.href)),
23333
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: link.title })
23334
+ },
23335
+ link.href
23336
+ )) }, index))
23337
+ ] })
23338
+ ] })
23339
+ ] });
23340
+ }
23341
+ function MobileHeader({
23342
+ sitename,
23343
+ navigation,
23344
+ version = false,
23345
+ hide = {}
23346
+ }) {
23347
+ const [open, setOpen] = React16.useState(false);
23348
+ const { search = true } = hide;
23349
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:hidden", children: [
23350
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex w-full items-center justify-between", children: [
23351
+ /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", size: "icon", onClick: () => setOpen(true), className: "m-4", children: [
23352
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Main Navigation Menu" }),
23353
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.menu, { "aria-hidden": "true" })
23354
+ ] }),
23355
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex items-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
23356
+ Link10__default.default,
23357
+ {
23358
+ href: "/",
23359
+ "aria-label": "Home page",
23360
+ className: "flex flex-col items-center justify-between",
23361
+ children: [
23362
+ /* @__PURE__ */ jsxRuntime.jsx(Logo, { className: "m-2 h-12 w-auto transition-colors" }),
23363
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-center text-center", children: [
23364
+ /* @__PURE__ */ jsxRuntime.jsx(Heading, { level: 2, size: 6, className: "ml-6", children: sitename }),
23365
+ version && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "soft", color: "primary", className: "ml-2", children: package_default.version })
23366
+ ] })
23367
+ ]
23368
+ }
23369
+ ) }),
23370
+ search && /* @__PURE__ */ jsxRuntime.jsx(MobileSearch, { navigation })
23371
+ ] }),
23372
+ /* @__PURE__ */ jsxRuntime.jsxs(Headless4.Dialog, { open, onClose: setOpen, className: "relative z-50", children: [
23373
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0" }),
23374
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none fixed inset-y-0 left-0 flex max-w-full pr-10 sm:pr-16", children: /* @__PURE__ */ jsxRuntime.jsx(
23375
+ Headless4.DialogPanel,
23376
+ {
23377
+ transition: true,
23378
+ className: "pointer-events-auto w-screen max-w-md transform transition duration-500 ease-in-out data-[closed]:-translate-x-full sm:duration-300",
23379
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full flex-col overflow-y-scroll bg-white shadow-xl", children: /* @__PURE__ */ jsxRuntime.jsx(
23380
+ MultiLevelPushMenu,
23381
+ {
23382
+ navigation,
23383
+ showHeader: true,
23384
+ onClose: () => {
23385
+ setOpen(false);
23386
+ }
23387
+ }
23388
+ ) })
23389
+ }
23390
+ ) }) }) })
23391
+ ] })
23392
+ ] });
23393
+ }
23394
+
23395
+ // src/db/schema/users.ts
23396
+ var users_exports = {};
23397
+ __export(users_exports, {
23398
+ users: () => users
23399
+ });
23400
+ var users = sqliteCore.sqliteTable("user", {
23401
+ id: sqliteCore.text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
23402
+ name: sqliteCore.text("name"),
23403
+ email: sqliteCore.text("email").unique(),
23404
+ emailVerified: sqliteCore.integer("emailVerified", { mode: "timestamp_ms" }),
23405
+ image: sqliteCore.text("image"),
23406
+ role: sqliteCore.text("role", { enum: ["ADMIN", "USER"] }).default("USER")
23407
+ });
23408
+
23409
+ // src/db/schema/accounts.ts
23410
+ var accounts_exports = {};
23411
+ __export(accounts_exports, {
23412
+ accounts: () => accounts
23413
+ });
23414
+ var accounts = sqliteCore.sqliteTable(
23415
+ "account",
23416
+ {
23417
+ userId: sqliteCore.text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
23418
+ type: sqliteCore.text("type").$type().notNull(),
23419
+ provider: sqliteCore.text("provider").notNull(),
23420
+ providerAccountId: sqliteCore.text("providerAccountId").notNull(),
23421
+ refresh_token: sqliteCore.text("refresh_token"),
23422
+ access_token: sqliteCore.text("access_token"),
23423
+ expires_at: sqliteCore.integer("expires_at"),
23424
+ token_type: sqliteCore.text("token_type"),
23425
+ scope: sqliteCore.text("scope"),
23426
+ id_token: sqliteCore.text("id_token"),
23427
+ session_state: sqliteCore.text("session_state")
23428
+ },
23429
+ (table) => [
23430
+ sqliteCore.primaryKey({
23431
+ columns: [table.provider, table.providerAccountId],
23432
+ name: "accounts_pk"
23433
+ })
23434
+ ]
23435
+ );
23436
+
23437
+ // src/db/schema/sessions.ts
23438
+ var sessions_exports = {};
23439
+ __export(sessions_exports, {
23440
+ sessions: () => sessions
23441
+ });
23442
+ var sessions = sqliteCore.sqliteTable("session", {
23443
+ sessionToken: sqliteCore.text("sessionToken").primaryKey(),
23444
+ userId: sqliteCore.text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
23445
+ expires: sqliteCore.integer("expires", { mode: "timestamp_ms" }).notNull()
23446
+ });
23447
+
23448
+ // src/db/index.ts
23449
+ var client = client$1.createClient({
23450
+ url: process.env.TURSO_CONNECTION_URL,
23451
+ authToken: process.env.TURSO_AUTH_TOKEN
23452
+ });
23453
+ var db = libsql.drizzle(client, {
23454
+ schema: {
23455
+ ...users_exports,
23456
+ ...accounts_exports,
23457
+ ...sessions_exports
23458
+ }
23459
+ });
23460
+
23461
+ // src/auth.ts
23462
+ var { handlers, signIn, signOut, auth } = NextAuth__default.default({
23463
+ adapter: drizzleAdapter.DrizzleAdapter(db),
23464
+ providers: [
23465
+ MicrosoftEntraID__default.default({
23466
+ clientId: process.env.AUTH_MICROSOFT_ENTRA_ID_ID,
23467
+ clientSecret: process.env.AUTH_MICROSOFT_ENTRA_ID_SECRET,
23468
+ issuer: process.env.AUTH_MICROSOFT_ENTRA_ID_ISSUER,
23469
+ authorization: {
23470
+ params: {
23471
+ scope: "openid profile email User.Read offline_access",
23472
+ tenant: process.env.AUTH_MICROSOFT_ENTRA_ID_TENANT_ID
23473
+ }
23474
+ }
23475
+ })
23476
+ ],
23477
+ callbacks: {
23478
+ authorized: async ({ auth: auth2, request }) => {
23479
+ if (request.nextUrl.pathname.startsWith("/")) {
23480
+ return true;
23481
+ }
23482
+ return !!auth2;
23483
+ },
23484
+ jwt({ token, user }) {
23485
+ if (user) {
23486
+ token.id = user.id;
23487
+ }
23488
+ return token;
23489
+ },
23490
+ async session({ session, user }) {
23491
+ session.user.id = user.id;
23492
+ const [microsoftAccount] = await db.select().from(accounts).where(drizzleOrm.and(drizzleOrm.eq(accounts.userId, user.id), drizzleOrm.eq(accounts.provider, "microsoft-entra-id"))).limit(1);
23493
+ if (microsoftAccount && microsoftAccount.expires_at && microsoftAccount.expires_at * 1e3 < Date.now()) {
23494
+ try {
23495
+ const tokenEndpoint = `https://login.microsoftonline.com/${process.env.AUTH_MICROSOFT_ENTRA_ID_TENANT_ID}/oauth2/v2.0/token`;
23496
+ const response = await fetch(tokenEndpoint, {
23497
+ method: "POST",
23498
+ headers: {
23499
+ "Content-Type": "application/x-www-form-urlencoded"
23500
+ },
23501
+ body: new URLSearchParams({
23502
+ client_id: process.env.AUTH_MICROSOFT_ENTRA_ID_ID,
23503
+ client_secret: process.env.AUTH_MICROSOFT_ENTRA_ID_SECRET,
23504
+ grant_type: "refresh_token",
23505
+ refresh_token: microsoftAccount.refresh_token,
23506
+ scope: "openid profile email offline_access"
23507
+ })
23508
+ });
23509
+ const tokensOrError = await response.json();
23510
+ if (!response.ok) throw tokensOrError;
23511
+ const newTokens = tokensOrError;
23512
+ await db.update(accounts).set({
23513
+ access_token: newTokens.access_token,
23514
+ expires_at: Math.floor(Date.now() / 1e3 + newTokens.expires_in),
23515
+ refresh_token: newTokens.refresh_token ?? microsoftAccount.refresh_token,
23516
+ id_token: newTokens.id_token ?? microsoftAccount.id_token
23517
+ }).where(
23518
+ drizzleOrm.and(
23519
+ drizzleOrm.eq(accounts.provider, "microsoft-entra-id"),
23520
+ drizzleOrm.eq(accounts.providerAccountId, microsoftAccount.providerAccountId)
23521
+ )
23522
+ );
23523
+ } catch (error) {
23524
+ console.error("Error refreshing access_token", error);
23525
+ session.error = "RefreshTokenError";
23526
+ }
23527
+ }
23528
+ return session;
23529
+ }
23530
+ }
23531
+ });
23532
+
23533
+ // src/actions/auth-actions.ts
23534
+ async function signInWithEntra(formData) {
23535
+ const redirect = formData.get("redirect")?.toString() || "/dashboard";
23536
+ await signIn("microsoft-entra-id", { redirectTo: redirect });
23537
+ }
23538
+ async function signInGeneric(formData) {
23539
+ const redirect = formData.get("redirect")?.toString() || "/dashboard";
23540
+ await signIn(void 0, { redirectTo: redirect });
23541
+ }
23542
+ async function signOutAction() {
23543
+ await signOut();
23544
+ }
23545
+ function SignInButton() {
23546
+ return /* @__PURE__ */ jsxRuntime.jsx("form", { action: signInGeneric, children: /* @__PURE__ */ jsxRuntime.jsx(Button2, { type: "submit", variant: "outline", children: "Sign in" }) });
23547
+ }
23548
+ function SignOutButton() {
23549
+ return /* @__PURE__ */ jsxRuntime.jsx("form", { action: signOutAction, children: /* @__PURE__ */ jsxRuntime.jsx(Button2, { type: "submit", color: "danger", children: "Sign Out" }) });
23550
+ }
23551
+ function SignInWithEntraButton() {
23552
+ return /* @__PURE__ */ jsxRuntime.jsx("form", { action: signInWithEntra, children: /* @__PURE__ */ jsxRuntime.jsx(Button2, { type: "submit", children: "Sign in with Entra" }) });
23553
+ }
23037
23554
  var MOBILE_BREAKPOINT = 768;
23038
23555
  function useIsMobile() {
23039
23556
  const [isMobile, setIsMobile] = React16__namespace.useState(void 0);
@@ -23064,15 +23581,15 @@ function useDisableToc() {
23064
23581
  }, [setToc]);
23065
23582
  }
23066
23583
  function getNodeText(node) {
23067
- let text = "";
23584
+ let text4 = "";
23068
23585
  for (const child of node.children ?? []) {
23069
23586
  if ("type" in child && child.type === "text") {
23070
- text += child.attributes?.content ?? "";
23587
+ text4 += child.attributes?.content ?? "";
23071
23588
  } else if (child instanceof HTMLElement) {
23072
- text += getNodeText(child);
23589
+ text4 += getNodeText(child);
23073
23590
  }
23074
23591
  }
23075
- return text;
23592
+ return text4;
23076
23593
  }
23077
23594
  function domToSimple(node) {
23078
23595
  if (node.nodeType === Node.TEXT_NODE) {
@@ -23386,6 +23903,9 @@ exports.MenubarSub = MenubarSub;
23386
23903
  exports.MenubarSubContent = MenubarSubContent;
23387
23904
  exports.MenubarSubTrigger = MenubarSubTrigger;
23388
23905
  exports.MenubarTrigger = MenubarTrigger;
23906
+ exports.MobileHeader = MobileHeader;
23907
+ exports.MobileSearch = MobileSearch;
23908
+ exports.MultiLevelPushMenu = MultiLevelPushMenu;
23389
23909
  exports.Navbar = Navbar;
23390
23910
  exports.NavbarDivider = NavbarDivider;
23391
23911
  exports.NavbarItem = NavbarItem;
@@ -23447,6 +23967,9 @@ exports.SheetTitle = SheetTitle;
23447
23967
  exports.SheetTrigger = SheetTrigger;
23448
23968
  exports.SidebarLink = SidebarLink;
23449
23969
  exports.SidebarNavigation = SidebarNavigation;
23970
+ exports.SignInButton = SignInButton;
23971
+ exports.SignInWithEntraButton = SignInWithEntraButton;
23972
+ exports.SignOutButton = SignOutButton;
23450
23973
  exports.SiteSearch = SiteSearch;
23451
23974
  exports.Skeleton = Skeleton;
23452
23975
  exports.Slider = Slider;
@@ -23514,14 +24037,20 @@ exports.createColorData = createColorData;
23514
24037
  exports.createFormStore = createFormStore;
23515
24038
  exports.darkenColor = darkenColor;
23516
24039
  exports.domToSimple = domToSimple;
24040
+ exports.findItemById = findItemById;
24041
+ exports.findPathToItem = findPathToItem;
23517
24042
  exports.focusInput = focusInput;
23518
24043
  exports.focusRing = focusRing;
24044
+ exports.generateBreadcrumb = generateBreadcrumb;
23519
24045
  exports.generateColorThemes = generateColorThemes;
24046
+ exports.generateLevelId = generateLevelId;
23520
24047
  exports.getColorClassName = getColorClassName;
23521
24048
  exports.getColorValue = getColorValue;
23522
24049
  exports.getHeadings = getHeadings;
24050
+ exports.getMaxDepth = getMaxDepth;
23523
24051
  exports.getNodeText = getNodeText;
23524
24052
  exports.getSurroundingColors = getSurroundingColors;
24053
+ exports.getTotalItemCount = getTotalItemCount;
23525
24054
  exports.getYAxisDomain = getYAxisDomain;
23526
24055
  exports.hasErrorInput = hasErrorInput;
23527
24056
  exports.hasOnlyOneValueForKey = hasOnlyOneValueForKey;