react-bootstrap-plugins 2.5.1 → 2.7.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.
@@ -0,0 +1,128 @@
1
+ # ConfirmDialog Plugin — Design Spec
2
+
3
+ > **Date:** 2026-08-19 | **Status:** Approved | **Package:** react-bootstrap-plugins
4
+
5
+ ## Overview
6
+
7
+ Add a `ConfirmDialog` component to `react-bootstrap-plugins` — a zero-dependency Bootstrap 5 confirmation modal with async loading state. Derived from the local `ConfirmDialog` used in `CBCAlevelReviewResults.jsx` of the SwiftPlus portal, restyled to a "Refined Minimal" premium direction (soft radius, thin border, variant-colored dot + left rule on the message).
8
+
9
+ **Decisions made during brainstorming:**
10
+
11
+ - Style direction: **B — Refined Minimal** (user-selected over Ledger Register and Dispatch Notice mockups).
12
+ - Rendering approach: **Bootstrap 5 modal markup via `createPortal`** — no react-bootstrap, no native `<dialog>`, preserving the package's zero-runtime-dependency contract.
13
+ - Features beyond the `nextPlugins.md` spec: **async loading state only**. Escape-close and static backdrop are baseline accessibility, not premium extras.
14
+ - **No animation** — dialog mounts/unmounts instantly with `show` (user decision).
15
+ - Scope: build the plugin **and** migrate the portal usage in `CBCAlevelReviewResults.jsx`.
16
+
17
+ ## API Design
18
+
19
+ ### Props
20
+
21
+ | Prop | Type | Default | Description |
22
+ |------|------|---------|-------------|
23
+ | `show` | `boolean` | required | Visibility — fully controlled by the caller |
24
+ | `title` | `ReactNode` | required | Dialog title |
25
+ | `message` | `ReactNode` | required | Body message (string or JSX) |
26
+ | `onConfirm` | `() => void \| Promise<void>` | required | Fired on confirm; may return a promise to drive the loading state |
27
+ | `onCancel` | `() => void` | required | Fired on Cancel button or Escape key |
28
+ | `label` | `ReactNode` | `"Confirm"` | Confirm button label |
29
+ | `variant` | `"primary" \| "danger" \| "success" \| "warning" \| "info"` | `"primary"` | Bootstrap color variant for the confirm button, dot, and message rule |
30
+ | `className` | `string` | — | Extra CSS classes on the dialog |
31
+
32
+ ### Async contract
33
+
34
+ - On confirm click: set pending, `await onConfirm()`, reset pending (try/finally — no catch).
35
+ - Pending state: `spinner-border spinner-border-sm` inside the confirm button, both buttons disabled, Escape ignored.
36
+ - On rejection: pending resets, dialog stays open, error propagates to the caller (callers handle their own error toasts inside `onConfirm`).
37
+
38
+ ### Controlled pattern
39
+
40
+ The plugin never closes itself. Callers close by setting `show={false}` — matches the existing usage where `handleDelete` clears `deleteConfirm` after the API call succeeds.
41
+
42
+ ## DOM Structure
43
+
44
+ ```html
45
+ <div class="confirmdialog-backdrop"></div> <!-- portaled to document.body -->
46
+ <div class="modal confirmdialog d-block" role="dialog" aria-modal="true"
47
+ aria-labelledby="cd-title" aria-describedby="cd-message" tabindex="-1">
48
+ <div class="modal-dialog modal-dialog-centered modal-sm">
49
+ <div class="modal-content">
50
+ <div class="confirmdialog-header">
51
+ <span class="confirmdialog-dot bg-{variant}" aria-hidden="true"></span>
52
+ <h5 class="modal-title" id="cd-title">{title}</h5>
53
+ </div>
54
+ <div class="confirmdialog-body" id="cd-message">{message}</div>
55
+ <div class="confirmdialog-footer">
56
+ <button type="button" class="btn btn-light" onClick={onCancel}>Cancel</button>
57
+ <button type="button" class="btn btn-{variant}" onClick={handleConfirm}>
58
+ {pending && <span class="spinner-border spinner-border-sm me-2" />}
59
+ {label}
60
+ </button>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ ```
66
+
67
+ Rendered via `createPortal(…, document.body)`. When `show` is `false`, nothing is rendered. No close ✕ button (confirm dialogs are resolved through the two actions). Unique ids via `React.useId()` to avoid collisions between multiple mounted dialogs.
68
+
69
+ ## Behavior
70
+
71
+ - **Backdrop click does nothing** — preserves the portal's current `backdrop="static"` behavior for destructive confirms.
72
+ - **Escape** fires `onCancel`, except while pending.
73
+ - **Focus management**:
74
+ - On open: focus the confirm button (the primary action).
75
+ - Trap: Tab / Shift+Tab cycle within the dialog (header, body, footer buttons) via a keydown handler on the dialog root.
76
+ - **Scroll lock**: set `document.body.style.overflow = "hidden"` while open; restore previous value on close; compensate `padding-right` when the scrollbar disappears.
77
+ - **Cleanup**: all listeners and body styles restored in the unmount cleanup.
78
+
79
+ ## Styling (plugins.css)
80
+
81
+ Appended to `src/css/plugins.css` under a `/* ConfirmDialog */` section, prefixed `.confirmdialog-*`, all colors via Bootstrap 5 CSS variables (theme-aware — dark mode works for free):
82
+
83
+ | Element | Treatment |
84
+ |---|---|
85
+ | Backdrop | Fixed, full-viewport, `background: rgba(0, 0, 0, 0.5)` (as CSS var default), `z-index: 1050` (below Bootstrap modal z-index 1055) |
86
+ | `.modal-content` | `border-radius: 12px`, `1px solid var(--bs-border-color)`, soft shadow `0 12px 40px rgba(0,0,0,.15)` |
87
+ | Header | Padding `16px 18px 12px`, no bottom border; inline 8px round dot using Bootstrap `bg-{variant}` class; semibold title |
88
+ | Body | Message in `var(--bs-secondary-color)`-ish muted text, `3px solid` left rule in the variant color, `padding: 4px 18px 16px 34px` (indented past the rule) |
89
+ | Footer | Padding `12px 18px 16px`, no top border, `justify-content: flex-end`, gap `8px` |
90
+ | Buttons | Native Bootstrap classes: `btn btn-light` (Cancel), `btn btn-{variant}` (Confirm, `fw-semibold`) |
91
+
92
+ Consumers must import `react-bootstrap-plugins/css/plugins.css` (same rule as DatePicker/SearchSelect) and have Bootstrap 5 CSS loaded.
93
+
94
+ ## Package Wiring
95
+
96
+ | File | Change |
97
+ |---|---|
98
+ | `src/components/ConfirmDialog.tsx` | New component — arrow function + `forwardRef`, named + default export, `displayName` |
99
+ | `src/css/plugins.css` | Append `.confirmdialog-*` styles |
100
+ | `tsup.config.ts` | Add entry `ConfirmDialog: 'src/components/ConfirmDialog.tsx'` |
101
+ | `package.json` | Add `./ConfirmDialog` export map entry (import/require + types); keywords `confirm-dialog`, `confirmation`, `modal`; bump version `2.6.0 → 2.7.0` |
102
+ | `src/index.ts` | Barrel export |
103
+ | `docs/CONFIRMDIALOG.md` | Component doc — API table, usage, CSS import note |
104
+ | `README.md` | Add to component list |
105
+
106
+ Follow the package conventions: relative imports only (no `@/`), internal `cn()` from `../lib/cn.js`, no new dependencies.
107
+
108
+ ## Portal Migration (allios-swiftplus-dashboard)
109
+
110
+ 1. `src/views/academics/CBCAlevelReviewResults.jsx`:
111
+ - Delete the local `ConfirmDialog` component (lines 150–166).
112
+ - Import `ConfirmDialog` from `react-bootstrap-plugins/ConfirmDialog`.
113
+ - At the call site: rename `confirmLabel` → `label`; `show`, `title`, `message`, `variant="danger"`, `onConfirm`, `onCancel` unchanged.
114
+ 2. Confirm `react-bootstrap-plugins/css/plugins.css` is imported in the portal (check `src/index.css` / layout); add if missing.
115
+ 3. Bump the portal's installed package to `2.7.0` (`pnpm add react-bootstrap-plugins@latest`).
116
+
117
+ ## Verification
118
+
119
+ - `pnpm run build` in `react-bootstrap-plugins` must pass (tsup bundles ESM+CJS, generates `.d.ts`/`.d.mts`/`.d.cts`, CSS copied by `scripts/build-css.mjs`).
120
+ - `pnpm publish --dry-run` shows the new entry files.
121
+ - Live smoke check in the portal (user runs the app): open the delete dialog on the CBC A-Level results page — confirm loading spinner on async delete, Escape cancel, backdrop click does nothing, Tab cycles within the dialog, dark mode renders correctly.
122
+ - No unit-test framework exists in the package (`"test": "echo 'Tests passed'"`) — verified by build + smoke check instead of the testing pyramid. **Documented deviation.**
123
+
124
+ ## Out of Scope
125
+
126
+ - Sizes beyond `modal-sm` (spec doesn't mention them; current usage is `size="sm"`).
127
+ - A close ✕ button, header icons beyond the variant dot, footer customization slots.
128
+ - Migration of any other local confirm modals in the portal (future follow-up).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-bootstrap-plugins",
3
- "version": "2.5.1",
3
+ "version": "2.7.0",
4
4
  "description": "Production-grade Bootstrap 5 UI plugins for React — DatePicker, SearchSelect, Label, TableLoading, InputCurrency, and more. Zero runtime dependencies beyond React.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -112,6 +112,26 @@
112
112
  "default": "./dist/ListGroup.cjs"
113
113
  }
114
114
  },
115
+ "./FormRow": {
116
+ "import": {
117
+ "types": "./dist/FormRow.d.ts",
118
+ "default": "./dist/FormRow.js"
119
+ },
120
+ "require": {
121
+ "types": "./dist/FormRow.d.ts",
122
+ "default": "./dist/FormRow.cjs"
123
+ }
124
+ },
125
+ "./ConfirmDialog": {
126
+ "import": {
127
+ "types": "./dist/ConfirmDialog.d.ts",
128
+ "default": "./dist/ConfirmDialog.js"
129
+ },
130
+ "require": {
131
+ "types": "./dist/ConfirmDialog.d.ts",
132
+ "default": "./dist/ConfirmDialog.cjs"
133
+ }
134
+ },
115
135
  "./css/plugins.css": "./dist/css/plugins.css",
116
136
  "./css/datepicker.css": "./dist/css/datepicker.css"
117
137
  },
@@ -130,15 +150,6 @@
130
150
  "LICENSE",
131
151
  "README.md"
132
152
  ],
133
- "scripts": {
134
- "build": "tsup && node scripts/build-css.mjs",
135
- "build:types": "tsup --dts-only",
136
- "dev": "tsup --watch",
137
- "prepublishOnly": "pnpm run build",
138
- "lint": "echo 'Lint passed'",
139
- "test": "echo 'Tests passed'",
140
- "push": "npm publish --no-git-checks"
141
- },
142
153
  "keywords": [
143
154
  "react",
144
155
  "bootstrap",
@@ -159,9 +170,14 @@
159
170
  "tabs",
160
171
  "list-group",
161
172
  "listgroup",
173
+ "confirm-dialog",
174
+ "confirmation",
175
+ "modal",
162
176
  "ui-components",
163
177
  "react-bootstrap",
164
178
  "form-controls",
179
+ "form-row",
180
+ "form-group",
165
181
  "tree-shakeable",
166
182
  "zero-dependencies",
167
183
  "input-currency",
@@ -202,5 +218,13 @@
202
218
  },
203
219
  "publishConfig": {
204
220
  "access": "public"
221
+ },
222
+ "scripts": {
223
+ "build": "tsup && node scripts/build-css.mjs",
224
+ "build:types": "tsup --dts-only",
225
+ "dev": "tsup --watch",
226
+ "lint": "echo 'Lint passed'",
227
+ "test": "echo 'Tests passed'",
228
+ "push": "pnpm publish --no-git-checks"
205
229
  }
206
- }
230
+ }
@@ -1,2 +0,0 @@
1
- 'use strict';var chunkNPQQDBFB_cjs=require('./chunk-NPQQDBFB.cjs'),o=require('react'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var o__namespace=/*#__PURE__*/_interopNamespace(o);var N=l=>l?typeof l=="string"?jsxRuntime.jsx("i",{className:chunkNPQQDBFB_cjs.a(l,"me-2")}):jsxRuntime.jsx("span",{className:"me-2 d-inline-flex align-middle",children:l}):null,r=o__namespace.forwardRef(({contain:l=false,active:c,pills:p,clear:v,onClick:m,className:t},i)=>{let s=(p??[]).map(a=>jsxRuntime.jsxs("button",{type:"button",className:chunkNPQQDBFB_cjs.a("nav-link text-center align-middle",a.key===c&&"active"),onClick:()=>m?.(a),children:[N(a.icon),jsxRuntime.jsx("span",{children:a.lbl??a.label}),a.clear&&jsxRuntime.jsx("span",{className:"badge navpills-badge-clear my-0 float-end ms-3",role:"button","aria-label":"Dismiss",onClick:d=>{d.stopPropagation(),v?.(a);},children:"\xD7"}),a.new&&jsxRuntime.jsx("span",{className:"badge navpills-badge-new float-end ms-4",children:"New"})]},String(a.key)));return l?jsxRuntime.jsx("div",{className:chunkNPQQDBFB_cjs.a("navpills-bar px-2 bg-light rounded-0 mb-0",t),children:jsxRuntime.jsx("nav",{ref:i,className:"container nav nav-pills overflow-x-auto flex-nowrap",children:s})}):jsxRuntime.jsx("nav",{ref:i,className:chunkNPQQDBFB_cjs.a("nav nav-pills overflow-x-auto flex-nowrap",t),children:s})});r.displayName="NavPills";var g=r;exports.a=r;exports.b=g;//# sourceMappingURL=chunk-G26VJJWL.cjs.map
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21wb25lbnRzL05hdlBpbGxzLnRzeCJdLCJuYW1lcyI6WyJyZW5kZXJJY29uIiwiaWNvbiIsImpzeCIsImNuIiwiTmF2UGlsbHMiLCJvIiwiY29udGFpbiIsImFjdGl2ZSIsInBpbGxzIiwiY2xlYXIiLCJvbkNsaWNrIiwiY2xhc3NOYW1lIiwicmVmIiwiaXRlbXMiLCJyIiwianN4cyIsImUiLCJOYXZQaWxsc19kZWZhdWx0Il0sIm1hcHBpbmdzIjoib2VBNkNBLElBQU1BLENBQUFBLENBQWNDLENBQUFBLEVBQ2JBLEVBQ0QsT0FBT0EsQ0FBQUEsRUFBUyxRQUFBLENBQWlCQyxjQUFBQSxDQUFDLEtBQUUsU0FBQSxDQUFXQyxtQkFBQUEsQ0FBR0YsQ0FBQUEsQ0FBTSxNQUFNLEVBQUcsQ0FBQSxDQUM5REMsY0FBQUEsQ0FBQyxNQUFBLENBQUEsQ0FBSyxTQUFBLENBQVUsa0NBQW1DLFFBQUEsQ0FBQUQsQ0FBQUEsQ0FBSyxDQUFBLENBRjdDLElBQUEsQ0FlZEcsRUFBaUJDLFlBQUEsQ0FBQSxVQUFBLENBQXVDLENBQUMsQ0FDN0QsT0FBQSxDQUFBQyxDQUFBQSxDQUFVLE1BQ1YsTUFBQSxDQUFBQyxDQUFBQSxDQUNBLEtBQUEsQ0FBQUMsQ0FBQUEsQ0FDQSxNQUFBQyxDQUFBQSxDQUNBLE9BQUEsQ0FBQUMsQ0FBQUEsQ0FDQSxTQUFBLENBQUFDLENBQ0YsQ0FBQSxDQUFHQyxDQUFBQSxHQUFRLENBQ1QsSUFBTUMsR0FBU0wsQ0FBQUEsRUFBUyxFQUFDLEVBQUcsR0FBQSxDQUFLTSxHQUMvQkMsZUFBQUEsQ0FBQyxRQUFBLENBQUEsQ0FFQyxJQUFBLENBQUssUUFBQSxDQUNMLFVBQVdaLG1CQUFBQSxDQUFHLG1DQUFBLENBQXFDVyxDQUFBQSxDQUFFLEdBQUEsR0FBUVAsR0FBVSxRQUFRLENBQUEsQ0FDL0UsT0FBQSxDQUFTLElBQU1HLElBQVVJLENBQUMsQ0FBQSxDQUV6QixVQUFBZCxDQUFBQSxDQUFXYyxDQUFBQSxDQUFFLElBQUksQ0FBQSxDQUNsQlosY0FBQUEsQ0FBQyxNQUFBLENBQUEsQ0FBTSxRQUFBLENBQUFZLEVBQUUsR0FBQSxFQUFPQSxDQUFBQSxDQUFFLEtBQUEsQ0FBTSxDQUFBLENBQ3ZCQSxFQUFFLEtBQUEsRUFDRFosY0FBQUEsQ0FBQyxNQUFBLENBQUEsQ0FDQyxTQUFBLENBQVUsaURBQ1YsSUFBQSxDQUFLLFFBQUEsQ0FDTCxZQUFBLENBQVcsU0FBQSxDQUNYLFFBQVVjLENBQUFBLEVBQU0sQ0FBRUEsQ0FBQUEsQ0FBRSxlQUFBLEdBQW1CUCxDQUFBQSxHQUFRSyxDQUFDLEVBQUUsQ0FBQSxDQUNuRCxnQkFFRCxDQUFBLENBRURBLENBQUFBLENBQUUsR0FBQSxFQUNEWixjQUFBQSxDQUFDLFFBQUssU0FBQSxDQUFVLHlDQUFBLENBQTBDLGVBQUcsQ0FBQSxDQUFBLENBQUEsQ0FsQjFELE1BQUEsQ0FBT1ksRUFBRSxHQUFHLENBb0JuQixDQUNELENBQUEsQ0FFRCxPQUFJUixDQUFBQSxDQUVBSixjQUFBQSxDQUFDLEtBQUEsQ0FBQSxDQUFJLFNBQUEsQ0FBV0Msb0JBQUcsMkNBQUEsQ0FBNkNRLENBQVMsQ0FBQSxDQUN2RSxRQUFBLENBQUFULGVBQUMsS0FBQSxDQUFBLENBQUksR0FBQSxDQUFLVSxFQUFLLFNBQUEsQ0FBVSxxREFBQSxDQUN0QixTQUFBQyxDQUFBQSxDQUNILENBQUEsQ0FDRixDQUFBLENBS0ZYLGNBQUFBLENBQUMsT0FBSSxHQUFBLENBQUtVLENBQUFBLENBQUssU0FBQSxDQUFXVCxtQkFBQUEsQ0FBRyw0Q0FBNkNRLENBQVMsQ0FBQSxDQUNoRixRQUFBLENBQUFFLENBQUFBLENBQ0gsQ0FFSixDQUFDLEVBRURULEVBQVMsV0FBQSxDQUFjLFVBQUEsS0FHaEJhLENBQUFBLENBQVFiIiwiZmlsZSI6ImNodW5rLUcyNlZKSldMLmNqcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgY24gfSBmcm9tICcuLi9saWIvY24uanMnXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuLyogIFR5cGVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgTmF2UGlsbCB7XG4gIC8qKiBVbmlxdWUgcGlsbCBpZGVudGlmaWVyIOKAlCBjb21wYXJlZCBhZ2FpbnN0IGBhY3RpdmVgICovXG4gIGtleTogc3RyaW5nIHwgbnVtYmVyXG4gIC8qKiBQaWxsIGxhYmVsIHRleHQgKi9cbiAgbGFiZWw/OiBSZWFjdC5SZWFjdE5vZGVcbiAgLyoqIExlZ2FjeSBhbGlhcyBmb3IgYGxhYmVsYCAodGFrZXMgcHJlY2VkZW5jZSB3aGVuIGJvdGggYXJlIHNldCkgKi9cbiAgbGJsPzogUmVhY3QuUmVhY3ROb2RlXG4gIC8qKlxuICAgKiBPcHRpb25hbCBsZWFkaW5nIGljb24uIEEgc3RyaW5nIGlzIHJlbmRlcmVkIGFzIGA8aSBjbGFzc05hbWU9e2ljb259IC8+YFxuICAgKiAocGFzcyB0aGUgZnVsbCBpY29uIGNsYXNzLCBlLmcuIGBcImZhcyBmYS11c2VyXCJgIG9yIGBcImJpIGJpLXBlcnNvblwiYCk7XG4gICAqIGEgUmVhY3ROb2RlIChlLmcuIGEgTHVjaWRlIGVsZW1lbnQpIGlzIHJlbmRlcmVkIGFzLWlzLlxuICAgKi9cbiAgaWNvbj86IHN0cmluZyB8IFJlYWN0LlJlYWN0Tm9kZVxuICAvKiogU2hvdyBhIGRpc21pc3MgYmFkZ2Ugb24gdGhpcyBwaWxsIOKAlCBjbGlja2luZyBpdCBmaXJlcyBgb25DbGVhcmAgKi9cbiAgY2xlYXI/OiBib29sZWFuXG4gIC8qKiBTaG93IGEgXCJOZXdcIiBiYWRnZSBvbiB0aGlzIHBpbGwgKi9cbiAgbmV3PzogYm9vbGVhblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5hdlBpbGxzUHJvcHMge1xuICAvKiogUGlsbHMgdG8gcmVuZGVyICovXG4gIHBpbGxzOiBOYXZQaWxsW11cbiAgLyoqIEtleSBvZiB0aGUgY3VycmVudGx5IGFjdGl2ZSBwaWxsICovXG4gIGFjdGl2ZT86IHN0cmluZyB8IG51bWJlclxuICAvKiogRmlyZWQgd2hlbiBhIHBpbGwgaXMgY2xpY2tlZCAqL1xuICBvbkNsaWNrPzogKHBpbGw6IE5hdlBpbGwpID0+IHZvaWRcbiAgLyoqIEZpcmVkIHdoZW4gYSBwaWxsJ3MgZGlzbWlzcyBiYWRnZSBpcyBjbGlja2VkIChyZXF1aXJlcyBgcGlsbC5jbGVhcmApICovXG4gIGNsZWFyPzogKHBpbGw6IE5hdlBpbGwpID0+IHZvaWRcbiAgLyoqIFdyYXAgdGhlIHBpbGxzIGluIGEgZnVsbC13aWR0aCBsaWdodCBiYXIgd2l0aCBhIGNlbnRlcmVkIGAuY29udGFpbmVyYCAqL1xuICBjb250YWluPzogYm9vbGVhblxuICAvKiogQWRkaXRpb25hbCBDU1MgY2xhc3NlcyAob24gdGhlIHdyYXBwZXIgd2hlbiBgY29udGFpbmAsIGVsc2Ugb24gdGhlIG5hdikgKi9cbiAgY2xhc3NOYW1lPzogc3RyaW5nXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuLyogIE5hdlBpbGxzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmNvbnN0IHJlbmRlckljb24gPSAoaWNvbjogTmF2UGlsbFsnaWNvbiddKTogUmVhY3QuUmVhY3ROb2RlID0+IHtcbiAgaWYgKCFpY29uKSByZXR1cm4gbnVsbFxuICBpZiAodHlwZW9mIGljb24gPT09ICdzdHJpbmcnKSByZXR1cm4gPGkgY2xhc3NOYW1lPXtjbihpY29uLCAnbWUtMicpfSAvPlxuICByZXR1cm4gPHNwYW4gY2xhc3NOYW1lPVwibWUtMiBkLWlubGluZS1mbGV4IGFsaWduLW1pZGRsZVwiPntpY29ufTwvc3Bhbj5cbn1cblxuLyoqXG4gKiBIb3Jpem9udGFsIEJvb3RzdHJhcCBuYXYtcGlsbHMgdGFiIHN0cmlwIHdpdGggb3B0aW9uYWwgaWNvbnMsXG4gKiBkaXNtaXNzaWJsZSBwaWxscywgYW5kIFwiTmV3XCIgYmFkZ2VzLiBTY3JvbGxzIGhvcml6b250YWxseSBvbiBvdmVyZmxvdy5cbiAqXG4gKiAqKkltcG9ydGFudDoqKiBUaGUgYWNjb21wYW55aW5nIENTUyAqKm11c3QqKiBiZSBpbXBvcnRlZCBmb3IgdGhlIGJhZGdlcyB0b1xuICogcmVuZGVyIGNvcnJlY3RseTpcbiAqIGBgYGpzXG4gKiBpbXBvcnQgJ3JlYWN0LWJvb3RzdHJhcC1wbHVnaW5zL2Nzcy9wbHVnaW5zLmNzcydcbiAqIGBgYFxuICovXG5jb25zdCBOYXZQaWxscyA9IFJlYWN0LmZvcndhcmRSZWY8SFRNTEVsZW1lbnQsIE5hdlBpbGxzUHJvcHM+KCh7XG4gIGNvbnRhaW4gPSBmYWxzZSxcbiAgYWN0aXZlLFxuICBwaWxscyxcbiAgY2xlYXIsXG4gIG9uQ2xpY2ssXG4gIGNsYXNzTmFtZSxcbn0sIHJlZikgPT4ge1xuICBjb25zdCBpdGVtcyA9IChwaWxscyA/PyBbXSkubWFwKChyKSA9PiAoXG4gICAgPGJ1dHRvblxuICAgICAga2V5PXtTdHJpbmcoci5rZXkpfVxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBjbGFzc05hbWU9e2NuKCduYXYtbGluayB0ZXh0LWNlbnRlciBhbGlnbi1taWRkbGUnLCByLmtleSA9PT0gYWN0aXZlICYmICdhY3RpdmUnKX1cbiAgICAgIG9uQ2xpY2s9eygpID0+IG9uQ2xpY2s/LihyKX1cbiAgICA+XG4gICAgICB7cmVuZGVySWNvbihyLmljb24pfVxuICAgICAgPHNwYW4+e3IubGJsID8/IHIubGFiZWx9PC9zcGFuPlxuICAgICAge3IuY2xlYXIgJiYgKFxuICAgICAgICA8c3BhblxuICAgICAgICAgIGNsYXNzTmFtZT1cImJhZGdlIG5hdnBpbGxzLWJhZGdlLWNsZWFyIG15LTAgZmxvYXQtZW5kIG1zLTNcIlxuICAgICAgICAgIHJvbGU9XCJidXR0b25cIlxuICAgICAgICAgIGFyaWEtbGFiZWw9XCJEaXNtaXNzXCJcbiAgICAgICAgICBvbkNsaWNrPXsoZSkgPT4geyBlLnN0b3BQcm9wYWdhdGlvbigpOyBjbGVhcj8uKHIpIH19XG4gICAgICAgID5cbiAgICAgICAgICAmdGltZXM7XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICl9XG4gICAgICB7ci5uZXcgJiYgKFxuICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJiYWRnZSBuYXZwaWxscy1iYWRnZS1uZXcgZmxvYXQtZW5kIG1zLTRcIj5OZXc8L3NwYW4+XG4gICAgICApfVxuICAgIDwvYnV0dG9uPlxuICApKVxuXG4gIGlmIChjb250YWluKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPXtjbignbmF2cGlsbHMtYmFyIHB4LTIgYmctbGlnaHQgcm91bmRlZC0wIG1iLTAnLCBjbGFzc05hbWUpfT5cbiAgICAgICAgPG5hdiByZWY9e3JlZn0gY2xhc3NOYW1lPVwiY29udGFpbmVyIG5hdiBuYXYtcGlsbHMgb3ZlcmZsb3cteC1hdXRvIGZsZXgtbm93cmFwXCI+XG4gICAgICAgICAge2l0ZW1zfVxuICAgICAgICA8L25hdj5cbiAgICAgIDwvZGl2PlxuICAgIClcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPG5hdiByZWY9e3JlZn0gY2xhc3NOYW1lPXtjbignbmF2IG5hdi1waWxscyBvdmVyZmxvdy14LWF1dG8gZmxleC1ub3dyYXAnLCBjbGFzc05hbWUpfT5cbiAgICAgIHtpdGVtc31cbiAgICA8L25hdj5cbiAgKVxufSlcblxuTmF2UGlsbHMuZGlzcGxheU5hbWUgPSAnTmF2UGlsbHMnXG5cbmV4cG9ydCB7IE5hdlBpbGxzIH1cbmV4cG9ydCBkZWZhdWx0IE5hdlBpbGxzXG4iXX0=
@@ -1,2 +0,0 @@
1
- import {a}from'./chunk-RR7TBRGI.js';import*as o from'react';import {jsxs,jsx}from'react/jsx-runtime';var N=l=>l?typeof l=="string"?jsx("i",{className:a(l,"me-2")}):jsx("span",{className:"me-2 d-inline-flex align-middle",children:l}):null,r=o.forwardRef(({contain:l=false,active:c,pills:p,clear:v,onClick:m,className:t},i)=>{let s=(p??[]).map(a$1=>jsxs("button",{type:"button",className:a("nav-link text-center align-middle",a$1.key===c&&"active"),onClick:()=>m?.(a$1),children:[N(a$1.icon),jsx("span",{children:a$1.lbl??a$1.label}),a$1.clear&&jsx("span",{className:"badge navpills-badge-clear my-0 float-end ms-3",role:"button","aria-label":"Dismiss",onClick:d=>{d.stopPropagation(),v?.(a$1);},children:"\xD7"}),a$1.new&&jsx("span",{className:"badge navpills-badge-new float-end ms-4",children:"New"})]},String(a$1.key)));return l?jsx("div",{className:a("navpills-bar px-2 bg-light rounded-0 mb-0",t),children:jsx("nav",{ref:i,className:"container nav nav-pills overflow-x-auto flex-nowrap",children:s})}):jsx("nav",{ref:i,className:a("nav nav-pills overflow-x-auto flex-nowrap",t),children:s})});r.displayName="NavPills";var g=r;export{r as a,g as b};//# sourceMappingURL=chunk-KVUHNUBG.js.map
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21wb25lbnRzL05hdlBpbGxzLnRzeCJdLCJuYW1lcyI6WyJyZW5kZXJJY29uIiwiaWNvbiIsImpzeCIsImNuIiwiTmF2UGlsbHMiLCJjb250YWluIiwiYWN0aXZlIiwicGlsbHMiLCJjbGVhciIsIm9uQ2xpY2siLCJjbGFzc05hbWUiLCJyZWYiLCJpdGVtcyIsInIiLCJqc3hzIiwiZSIsIk5hdlBpbGxzX2RlZmF1bHQiXSwibWFwcGluZ3MiOiJxR0E2Q0EsSUFBTUEsQ0FBQUEsQ0FBY0MsQ0FBQUEsRUFDYkEsRUFDRCxPQUFPQSxDQUFBQSxFQUFTLFFBQUEsQ0FBaUJDLEdBQUFBLENBQUMsS0FBRSxTQUFBLENBQVdDLENBQUFBLENBQUdGLENBQUFBLENBQU0sTUFBTSxFQUFHLENBQUEsQ0FDOURDLEdBQUFBLENBQUMsTUFBQSxDQUFBLENBQUssU0FBQSxDQUFVLGtDQUFtQyxRQUFBLENBQUFELENBQUFBLENBQUssQ0FBQSxDQUY3QyxJQUFBLENBZWRHLEVBQWlCLENBQUEsQ0FBQSxVQUFBLENBQXVDLENBQUMsQ0FDN0QsT0FBQSxDQUFBQyxDQUFBQSxDQUFVLE1BQ1YsTUFBQSxDQUFBQyxDQUFBQSxDQUNBLEtBQUEsQ0FBQUMsQ0FBQUEsQ0FDQSxNQUFBQyxDQUFBQSxDQUNBLE9BQUEsQ0FBQUMsQ0FBQUEsQ0FDQSxTQUFBLENBQUFDLENBQ0YsQ0FBQSxDQUFHQyxDQUFBQSxHQUFRLENBQ1QsSUFBTUMsR0FBU0wsQ0FBQUEsRUFBUyxFQUFDLEVBQUcsR0FBQSxDQUFLTSxLQUMvQkMsSUFBQUEsQ0FBQyxRQUFBLENBQUEsQ0FFQyxJQUFBLENBQUssUUFBQSxDQUNMLFVBQVdYLENBQUFBLENBQUcsbUNBQUEsQ0FBcUNVLEdBQUFBLENBQUUsR0FBQSxHQUFRUCxHQUFVLFFBQVEsQ0FBQSxDQUMvRSxPQUFBLENBQVMsSUFBTUcsSUFBVUksR0FBQyxDQUFBLENBRXpCLFVBQUFiLENBQUFBLENBQVdhLEdBQUFBLENBQUUsSUFBSSxDQUFBLENBQ2xCWCxHQUFBQSxDQUFDLE1BQUEsQ0FBQSxDQUFNLFFBQUEsQ0FBQVcsSUFBRSxHQUFBLEVBQU9BLEdBQUFBLENBQUUsS0FBQSxDQUFNLENBQUEsQ0FDdkJBLElBQUUsS0FBQSxFQUNEWCxHQUFBQSxDQUFDLE1BQUEsQ0FBQSxDQUNDLFNBQUEsQ0FBVSxpREFDVixJQUFBLENBQUssUUFBQSxDQUNMLFlBQUEsQ0FBVyxTQUFBLENBQ1gsUUFBVWEsQ0FBQUEsRUFBTSxDQUFFQSxDQUFBQSxDQUFFLGVBQUEsR0FBbUJQLENBQUFBLEdBQVFLLEdBQUMsRUFBRSxDQUFBLENBQ25ELGdCQUVELENBQUEsQ0FFREEsR0FBQUEsQ0FBRSxHQUFBLEVBQ0RYLEdBQUFBLENBQUMsUUFBSyxTQUFBLENBQVUseUNBQUEsQ0FBMEMsZUFBRyxDQUFBLENBQUEsQ0FBQSxDQWxCMUQsTUFBQSxDQUFPVyxJQUFFLEdBQUcsQ0FvQm5CLENBQ0QsQ0FBQSxDQUVELE9BQUlSLENBQUFBLENBRUFILEdBQUFBLENBQUMsS0FBQSxDQUFBLENBQUksU0FBQSxDQUFXQyxFQUFHLDJDQUFBLENBQTZDTyxDQUFTLENBQUEsQ0FDdkUsUUFBQSxDQUFBUixJQUFDLEtBQUEsQ0FBQSxDQUFJLEdBQUEsQ0FBS1MsRUFBSyxTQUFBLENBQVUscURBQUEsQ0FDdEIsU0FBQUMsQ0FBQUEsQ0FDSCxDQUFBLENBQ0YsQ0FBQSxDQUtGVixHQUFBQSxDQUFDLE9BQUksR0FBQSxDQUFLUyxDQUFBQSxDQUFLLFNBQUEsQ0FBV1IsQ0FBQUEsQ0FBRyw0Q0FBNkNPLENBQVMsQ0FBQSxDQUNoRixRQUFBLENBQUFFLENBQUFBLENBQ0gsQ0FFSixDQUFDLEVBRURSLEVBQVMsV0FBQSxDQUFjLFVBQUEsS0FHaEJZLENBQUFBLENBQVFaIiwiZmlsZSI6ImNodW5rLUtWVUhOVUJHLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBjbiB9IGZyb20gJy4uL2xpYi9jbi5qcydcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG4vKiAgVHlwZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuZXhwb3J0IGludGVyZmFjZSBOYXZQaWxsIHtcbiAgLyoqIFVuaXF1ZSBwaWxsIGlkZW50aWZpZXIg4oCUIGNvbXBhcmVkIGFnYWluc3QgYGFjdGl2ZWAgKi9cbiAga2V5OiBzdHJpbmcgfCBudW1iZXJcbiAgLyoqIFBpbGwgbGFiZWwgdGV4dCAqL1xuICBsYWJlbD86IFJlYWN0LlJlYWN0Tm9kZVxuICAvKiogTGVnYWN5IGFsaWFzIGZvciBgbGFiZWxgICh0YWtlcyBwcmVjZWRlbmNlIHdoZW4gYm90aCBhcmUgc2V0KSAqL1xuICBsYmw/OiBSZWFjdC5SZWFjdE5vZGVcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGxlYWRpbmcgaWNvbi4gQSBzdHJpbmcgaXMgcmVuZGVyZWQgYXMgYDxpIGNsYXNzTmFtZT17aWNvbn0gLz5gXG4gICAqIChwYXNzIHRoZSBmdWxsIGljb24gY2xhc3MsIGUuZy4gYFwiZmFzIGZhLXVzZXJcImAgb3IgYFwiYmkgYmktcGVyc29uXCJgKTtcbiAgICogYSBSZWFjdE5vZGUgKGUuZy4gYSBMdWNpZGUgZWxlbWVudCkgaXMgcmVuZGVyZWQgYXMtaXMuXG4gICAqL1xuICBpY29uPzogc3RyaW5nIHwgUmVhY3QuUmVhY3ROb2RlXG4gIC8qKiBTaG93IGEgZGlzbWlzcyBiYWRnZSBvbiB0aGlzIHBpbGwg4oCUIGNsaWNraW5nIGl0IGZpcmVzIGBvbkNsZWFyYCAqL1xuICBjbGVhcj86IGJvb2xlYW5cbiAgLyoqIFNob3cgYSBcIk5ld1wiIGJhZGdlIG9uIHRoaXMgcGlsbCAqL1xuICBuZXc/OiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmF2UGlsbHNQcm9wcyB7XG4gIC8qKiBQaWxscyB0byByZW5kZXIgKi9cbiAgcGlsbHM6IE5hdlBpbGxbXVxuICAvKiogS2V5IG9mIHRoZSBjdXJyZW50bHkgYWN0aXZlIHBpbGwgKi9cbiAgYWN0aXZlPzogc3RyaW5nIHwgbnVtYmVyXG4gIC8qKiBGaXJlZCB3aGVuIGEgcGlsbCBpcyBjbGlja2VkICovXG4gIG9uQ2xpY2s/OiAocGlsbDogTmF2UGlsbCkgPT4gdm9pZFxuICAvKiogRmlyZWQgd2hlbiBhIHBpbGwncyBkaXNtaXNzIGJhZGdlIGlzIGNsaWNrZWQgKHJlcXVpcmVzIGBwaWxsLmNsZWFyYCkgKi9cbiAgY2xlYXI/OiAocGlsbDogTmF2UGlsbCkgPT4gdm9pZFxuICAvKiogV3JhcCB0aGUgcGlsbHMgaW4gYSBmdWxsLXdpZHRoIGxpZ2h0IGJhciB3aXRoIGEgY2VudGVyZWQgYC5jb250YWluZXJgICovXG4gIGNvbnRhaW4/OiBib29sZWFuXG4gIC8qKiBBZGRpdGlvbmFsIENTUyBjbGFzc2VzIChvbiB0aGUgd3JhcHBlciB3aGVuIGBjb250YWluYCwgZWxzZSBvbiB0aGUgbmF2KSAqL1xuICBjbGFzc05hbWU/OiBzdHJpbmdcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG4vKiAgTmF2UGlsbHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuY29uc3QgcmVuZGVySWNvbiA9IChpY29uOiBOYXZQaWxsWydpY29uJ10pOiBSZWFjdC5SZWFjdE5vZGUgPT4ge1xuICBpZiAoIWljb24pIHJldHVybiBudWxsXG4gIGlmICh0eXBlb2YgaWNvbiA9PT0gJ3N0cmluZycpIHJldHVybiA8aSBjbGFzc05hbWU9e2NuKGljb24sICdtZS0yJyl9IC8+XG4gIHJldHVybiA8c3BhbiBjbGFzc05hbWU9XCJtZS0yIGQtaW5saW5lLWZsZXggYWxpZ24tbWlkZGxlXCI+e2ljb259PC9zcGFuPlxufVxuXG4vKipcbiAqIEhvcml6b250YWwgQm9vdHN0cmFwIG5hdi1waWxscyB0YWIgc3RyaXAgd2l0aCBvcHRpb25hbCBpY29ucyxcbiAqIGRpc21pc3NpYmxlIHBpbGxzLCBhbmQgXCJOZXdcIiBiYWRnZXMuIFNjcm9sbHMgaG9yaXpvbnRhbGx5IG9uIG92ZXJmbG93LlxuICpcbiAqICoqSW1wb3J0YW50OioqIFRoZSBhY2NvbXBhbnlpbmcgQ1NTICoqbXVzdCoqIGJlIGltcG9ydGVkIGZvciB0aGUgYmFkZ2VzIHRvXG4gKiByZW5kZXIgY29ycmVjdGx5OlxuICogYGBganNcbiAqIGltcG9ydCAncmVhY3QtYm9vdHN0cmFwLXBsdWdpbnMvY3NzL3BsdWdpbnMuY3NzJ1xuICogYGBgXG4gKi9cbmNvbnN0IE5hdlBpbGxzID0gUmVhY3QuZm9yd2FyZFJlZjxIVE1MRWxlbWVudCwgTmF2UGlsbHNQcm9wcz4oKHtcbiAgY29udGFpbiA9IGZhbHNlLFxuICBhY3RpdmUsXG4gIHBpbGxzLFxuICBjbGVhcixcbiAgb25DbGljayxcbiAgY2xhc3NOYW1lLFxufSwgcmVmKSA9PiB7XG4gIGNvbnN0IGl0ZW1zID0gKHBpbGxzID8/IFtdKS5tYXAoKHIpID0+IChcbiAgICA8YnV0dG9uXG4gICAgICBrZXk9e1N0cmluZyhyLmtleSl9XG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIGNsYXNzTmFtZT17Y24oJ25hdi1saW5rIHRleHQtY2VudGVyIGFsaWduLW1pZGRsZScsIHIua2V5ID09PSBhY3RpdmUgJiYgJ2FjdGl2ZScpfVxuICAgICAgb25DbGljaz17KCkgPT4gb25DbGljaz8uKHIpfVxuICAgID5cbiAgICAgIHtyZW5kZXJJY29uKHIuaWNvbil9XG4gICAgICA8c3Bhbj57ci5sYmwgPz8gci5sYWJlbH08L3NwYW4+XG4gICAgICB7ci5jbGVhciAmJiAoXG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgY2xhc3NOYW1lPVwiYmFkZ2UgbmF2cGlsbHMtYmFkZ2UtY2xlYXIgbXktMCBmbG9hdC1lbmQgbXMtM1wiXG4gICAgICAgICAgcm9sZT1cImJ1dHRvblwiXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIkRpc21pc3NcIlxuICAgICAgICAgIG9uQ2xpY2s9eyhlKSA9PiB7IGUuc3RvcFByb3BhZ2F0aW9uKCk7IGNsZWFyPy4ocikgfX1cbiAgICAgICAgPlxuICAgICAgICAgICZ0aW1lcztcbiAgICAgICAgPC9zcGFuPlxuICAgICAgKX1cbiAgICAgIHtyLm5ldyAmJiAoXG4gICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImJhZGdlIG5hdnBpbGxzLWJhZGdlLW5ldyBmbG9hdC1lbmQgbXMtNFwiPk5ldzwvc3Bhbj5cbiAgICAgICl9XG4gICAgPC9idXR0b24+XG4gICkpXG5cbiAgaWYgKGNvbnRhaW4pIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9e2NuKCduYXZwaWxscy1iYXIgcHgtMiBiZy1saWdodCByb3VuZGVkLTAgbWItMCcsIGNsYXNzTmFtZSl9PlxuICAgICAgICA8bmF2IHJlZj17cmVmfSBjbGFzc05hbWU9XCJjb250YWluZXIgbmF2IG5hdi1waWxscyBvdmVyZmxvdy14LWF1dG8gZmxleC1ub3dyYXBcIj5cbiAgICAgICAgICB7aXRlbXN9XG4gICAgICAgIDwvbmF2PlxuICAgICAgPC9kaXY+XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIChcbiAgICA8bmF2IHJlZj17cmVmfSBjbGFzc05hbWU9e2NuKCduYXYgbmF2LXBpbGxzIG92ZXJmbG93LXgtYXV0byBmbGV4LW5vd3JhcCcsIGNsYXNzTmFtZSl9PlxuICAgICAge2l0ZW1zfVxuICAgIDwvbmF2PlxuICApXG59KVxuXG5OYXZQaWxscy5kaXNwbGF5TmFtZSA9ICdOYXZQaWxscydcblxuZXhwb3J0IHsgTmF2UGlsbHMgfVxuZXhwb3J0IGRlZmF1bHQgTmF2UGlsbHNcbiJdfQ==