@magmonium/one 0.2.36 → 0.2.38
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/assets/buttons/confirm_cancel.json +5 -0
- package/assets/index.json +1 -1
- package/fesm2022/{magmonium-one-magmonium-one-BiogYqpG.mjs → magmonium-one-magmonium-one-BOkBE_Fl.mjs} +458 -233
- package/fesm2022/magmonium-one-magmonium-one-BOkBE_Fl.mjs.map +1 -0
- package/fesm2022/{magmonium-one-otp-B4nZEh_m.mjs → magmonium-one-otp-JmUyDNPb.mjs} +2 -2
- package/fesm2022/{magmonium-one-otp-B4nZEh_m.mjs.map → magmonium-one-otp-JmUyDNPb.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-password-MtQpTJX1.mjs → magmonium-one-password-DmEMAVca.mjs} +2 -2
- package/fesm2022/{magmonium-one-password-MtQpTJX1.mjs.map → magmonium-one-password-DmEMAVca.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-toggle-F27rRHhf.mjs → magmonium-one-toggle-wEeMiUQz.mjs} +2 -2
- package/fesm2022/{magmonium-one-toggle-F27rRHhf.mjs.map → magmonium-one-toggle-wEeMiUQz.mjs.map} +1 -1
- package/fesm2022/magmonium-one.mjs +1 -1
- package/package.json +1 -1
- package/types/magmonium-one.d.ts +148 -37
- package/fesm2022/magmonium-one-magmonium-one-BiogYqpG.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, inject, Injectable, signal, computed, DestroyRef, DOCUMENT, ApplicationRef, RendererFactory2, createComponent, EnvironmentInjector, Pipe, ChangeDetectorRef, untracked, ElementRef, afterNextRender, input, ChangeDetectionStrategy, Component, effect, Injector, reflectComponentType, model, HostListener, Renderer2, Directive, output, viewChild, ViewEncapsulation, forwardRef, contentChild, TemplateRef, ViewContainerRef, inputBinding, outputBinding, linkedSignal, afterRenderEffect, runInInjectionContext, Input, booleanAttribute, HostAttributeToken, EventEmitter, Output, ViewChild, ContentChild, provideZonelessChangeDetection, makeEnvironmentProviders, HostBinding, provideAppInitializer, provideBrowserGlobalErrorListeners, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
3
3
|
import { HttpClient, HttpParams, provideHttpClient, withFetch, withInterceptors } from '@angular/common/http';
|
|
4
|
-
import { firstValueFrom, of, tap, catchError, throwError, shareReplay, finalize, map, forkJoin, Observable, pipe, interval, fromEvent, switchMap as switchMap$1, filter, EMPTY,
|
|
4
|
+
import { firstValueFrom, of, tap, catchError, throwError, shareReplay, finalize, map, forkJoin, Observable, pipe, interval, fromEvent, switchMap as switchMap$1, filter, EMPTY, Subject, combineLatest, race, take, from } from 'rxjs';
|
|
5
5
|
import { rxResource, toObservable, toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
6
|
import { signalStore, withState, withMethods, patchState, withHooks, withComputed, withProps } from '@ngrx/signals';
|
|
7
7
|
import { rxMethod } from '@ngrx/signals/rxjs-interop';
|
|
@@ -3172,6 +3172,14 @@ const NotificationStore = signalStore({ providedIn: 'root' }, withState(initialN
|
|
|
3172
3172
|
* Nav model — see libs/one/CONTEXT.md (NavId, NavKind, Address, Anchor, NavRef)
|
|
3173
3173
|
* and docs/adr/0014.
|
|
3174
3174
|
*/
|
|
3175
|
+
/**
|
|
3176
|
+
* The parameter name a `dynamic` Nav carries when it authored none. One
|
|
3177
|
+
* constant because the emitted route, the Address a NavRef renders and the row
|
|
3178
|
+
* that fills it are the same string.
|
|
3179
|
+
*/
|
|
3180
|
+
const DEFAULT_NAV_PARAM = 'id';
|
|
3181
|
+
/** The parameter a `dynamic` Nav contributes, authored or defaulted. */
|
|
3182
|
+
const navParamOf = (nav) => nav?.param ?? DEFAULT_NAV_PARAM;
|
|
3175
3183
|
const ROOT_NAV$1 = 'root';
|
|
3176
3184
|
/**
|
|
3177
3185
|
* The segment a Nav carries when it *is* its parent's own content — the route
|
|
@@ -3248,8 +3256,9 @@ const splitNavId = (navId, navMap) => {
|
|
|
3248
3256
|
const anchorNavId = (navId, navMap) => splitNavId(navId, navMap).url.join(NAV_ID_SEP) || ROOT_NAV$1;
|
|
3249
3257
|
/**
|
|
3250
3258
|
* Route path for the Url part of a NavId. `root` -> `/`. A `dynamic` Nav
|
|
3251
|
-
* contributes
|
|
3252
|
-
* rendered against a live location (see
|
|
3259
|
+
* contributes `:id` alone — its own segment is a name, not an address — which
|
|
3260
|
+
* is why a concrete path can only be rendered against a live location (see
|
|
3261
|
+
* `renderAddress`).
|
|
3253
3262
|
*/
|
|
3254
3263
|
const navIdToRoutePath = (navId, navMap) => {
|
|
3255
3264
|
const segments = navIdToSegments(navId).slice(1);
|
|
@@ -3263,12 +3272,11 @@ const navIdToRoutePath = (navId, navMap) => {
|
|
|
3263
3272
|
// no segment of its own — `app → default → trending` is `/app/trending`,
|
|
3264
3273
|
// the address the generated route table already answers at.
|
|
3265
3274
|
const path = segment === DEFAULT_NAV_SEGMENT ? '' : (nav?.path ?? segment);
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3275
|
+
// A dynamic Nav *is* the parameter: it contributes `:id` and no segment
|
|
3276
|
+
// of its own, so `comics → issue` (dynamic) is `/comics/:issueId`. The
|
|
3277
|
+
// Nav's own name stays a name — it never reaches the URL.
|
|
3278
|
+
return nav?.presentation === 'dynamic' ? `:${navParamOf(nav)}` : path;
|
|
3269
3279
|
})
|
|
3270
|
-
// A dynamic Nav mounted at its app's own root declares `path: ''` — it
|
|
3271
|
-
// contributes `:id` and no segment of its own.
|
|
3272
3280
|
.flatMap((part) => part.split(URL_SEP).filter(Boolean));
|
|
3273
3281
|
return parts.length ? URL_SEP + parts.join(URL_SEP) : URL_SEP;
|
|
3274
3282
|
};
|
|
@@ -3410,6 +3418,9 @@ const NAV_MAIN_BUTTONS = new InjectionToken('NAV_MAIN_BUTTONS');
|
|
|
3410
3418
|
function isNavMenuConfig(entry) {
|
|
3411
3419
|
return typeof entry === 'object' && 'navMenu' in entry;
|
|
3412
3420
|
}
|
|
3421
|
+
function isNavRowsConfig(entry) {
|
|
3422
|
+
return typeof entry === 'object' && 'navRows' in entry;
|
|
3423
|
+
}
|
|
3413
3424
|
/**
|
|
3414
3425
|
* Multi-provided, and resolved **last-wins**: the library provides its own
|
|
3415
3426
|
* Platform Nav panels first so an app registering at the same NavId replaces
|
|
@@ -3452,147 +3463,6 @@ function getNavWidgetEntry(appId) {
|
|
|
3452
3463
|
return windowRegistry().get(appId);
|
|
3453
3464
|
}
|
|
3454
3465
|
|
|
3455
|
-
const emptyResult = () => ({
|
|
3456
|
-
breadcrumb: { header: { label: '', id: '' }, trail: [] },
|
|
3457
|
-
navMenus: [],
|
|
3458
|
-
});
|
|
3459
|
-
/**
|
|
3460
|
-
* One trail/menu entry. `nav` names where it goes by NavId — the NavKind on the
|
|
3461
|
-
* target decides whether following it routes or opens a panel, so nothing here
|
|
3462
|
-
* chooses a link kind (ADR 0014).
|
|
3463
|
-
*/
|
|
3464
|
-
const toTrailItem = (navId, navMap, anchor) => {
|
|
3465
|
-
const nav = navMap[navId];
|
|
3466
|
-
return {
|
|
3467
|
-
id: navId,
|
|
3468
|
-
label: nav?.title ?? navIdSegment(navId),
|
|
3469
|
-
icon: nav?.icon,
|
|
3470
|
-
nav: navId,
|
|
3471
|
-
address: renderAddress(navId, navMap, anchor),
|
|
3472
|
-
};
|
|
3473
|
-
};
|
|
3474
|
-
/** A Nav that *is* its parent's own content rather than a place beside it. */
|
|
3475
|
-
const isDefaultNav = (navId) => navIdSegment(navId) === DEFAULT_NAV_SEGMENT;
|
|
3476
|
-
/**
|
|
3477
|
-
* The Nav the User is standing on as the nav shows it. A `default` node names
|
|
3478
|
-
* no place of its own — it is the route answering its parent's empty path — so
|
|
3479
|
-
* landing on `root_app_default` is standing on `root_app`, and the panel says
|
|
3480
|
-
* so rather than naming a segment that is on no menu.
|
|
3481
|
-
*/
|
|
3482
|
-
const visibleNavId = (navId) => {
|
|
3483
|
-
let id = navId;
|
|
3484
|
-
while (id !== ROOT_NAV$1 && isDefaultNav(id))
|
|
3485
|
-
id = parentNavId(id) ?? ROOT_NAV$1;
|
|
3486
|
-
return id;
|
|
3487
|
-
};
|
|
3488
|
-
/**
|
|
3489
|
-
* The direct children of a Nav. `children` is the authored list, but a Nav that
|
|
3490
|
-
* lists none is not childless: the map already holds every node fetched for
|
|
3491
|
-
* this descent, and a child is named by its own id. Reading the map when the
|
|
3492
|
-
* list is empty is what keeps a generated tree — whose `root.yml` names the app
|
|
3493
|
-
* and nothing else — from titling a leaf over an empty panel.
|
|
3494
|
-
*/
|
|
3495
|
-
const childIdsOf = (navId, navMap) => {
|
|
3496
|
-
const declared = navMap[navId]?.children;
|
|
3497
|
-
if (declared?.length)
|
|
3498
|
-
return declared;
|
|
3499
|
-
return Object.keys(navMap).filter((id) => parentNavId(id) === navId);
|
|
3500
|
-
};
|
|
3501
|
-
/**
|
|
3502
|
-
* The children a menu may draw. A Nav needs a title to be a row at all, and a
|
|
3503
|
-
* `default` node is not a row: it is its parent's own content, so it is
|
|
3504
|
-
* *transparent* — its own children take its place in the list, spliced where
|
|
3505
|
-
* it stood. `app → default → { trending, latest }` is one list of two rows
|
|
3506
|
-
* under app, which is the tree the User was drawing when they put a `default`
|
|
3507
|
-
* in the middle of it. Filtering the node out without adopting its children
|
|
3508
|
-
* left that app with no rows at all.
|
|
3509
|
-
*/
|
|
3510
|
-
const menuChildIds = (navId, navMap) => childIdsOf(navId, navMap).flatMap((childId) => {
|
|
3511
|
-
if (isDefaultNav(childId))
|
|
3512
|
-
return menuChildIds(childId, navMap);
|
|
3513
|
-
return navMap[childId]?.title ? [childId] : [];
|
|
3514
|
-
});
|
|
3515
|
-
/**
|
|
3516
|
-
* Whose children the menu draws. A Nav with rows of its own draws them — that
|
|
3517
|
-
* is the descent. A leaf has none, and descending into nothing left the panel
|
|
3518
|
-
* on an empty state; it draws its *siblings* instead, so the menu stays the
|
|
3519
|
-
* list the User moved through and the row they are on is the one marked
|
|
3520
|
-
* active. Root is the floor: its own children are the last list there is.
|
|
3521
|
-
*/
|
|
3522
|
-
const navMenuOwnerId = (navId, navMap, hasOwnContent = false) => {
|
|
3523
|
-
const visible = visibleNavId(navId);
|
|
3524
|
-
if (visible === ROOT_NAV$1 || menuChildIds(visible, navMap).length) {
|
|
3525
|
-
return visible;
|
|
3526
|
-
}
|
|
3527
|
-
// A panel that answers with a widget of its own keeps its own title —
|
|
3528
|
-
// titling it after its parent while showing its own content reads as the
|
|
3529
|
-
// wrong panel. Being a Murl is not that proof: a Murl leaf nothing is
|
|
3530
|
-
// registered for draws nothing, and an empty panel must not name itself.
|
|
3531
|
-
if (hasOwnContent)
|
|
3532
|
-
return visible;
|
|
3533
|
-
// Nothing of its own and no rows under it: hand the panel to the nearest
|
|
3534
|
-
// ancestor that has rows, so the User reads the list they are in with their
|
|
3535
|
-
// own row marked. Where no ancestor lists anything there is no better title
|
|
3536
|
-
// than the one we are on — a mistitled empty panel is worse than a titled one.
|
|
3537
|
-
for (let ancestor = parentNavId(visible); ancestor; ancestor = parentNavId(ancestor)) {
|
|
3538
|
-
const owner = visibleNavId(ancestor);
|
|
3539
|
-
if (menuChildIds(owner, navMap).length)
|
|
3540
|
-
return owner;
|
|
3541
|
-
if (owner === ROOT_NAV$1)
|
|
3542
|
-
break;
|
|
3543
|
-
}
|
|
3544
|
-
return visible;
|
|
3545
|
-
};
|
|
3546
|
-
const buildNavMenus = (navId, navMap, anchor) => menuChildIds(navId, navMap).map((childId) => toTrailItem(childId, navMap, anchor));
|
|
3547
|
-
/**
|
|
3548
|
-
* Merges a widget's emitted trail over the derived one, matching by depth.
|
|
3549
|
-
* With a single keyspace there is nothing to translate — an emitted entry is
|
|
3550
|
-
* already in the same ids everything else uses.
|
|
3551
|
-
*/
|
|
3552
|
-
const mergeTrail = (derived, override, derivedHeader) => {
|
|
3553
|
-
const depth = (id) => navIdChain(id).length;
|
|
3554
|
-
const trail = derived.map((item) => {
|
|
3555
|
-
const emitted = override.trail?.find((e) => depth(e.id) === depth(item.id));
|
|
3556
|
-
return emitted ? { ...item, ...emitted } : item;
|
|
3557
|
-
});
|
|
3558
|
-
return { trail, header: override.header ?? derivedHeader };
|
|
3559
|
-
};
|
|
3560
|
-
function deriveBreadcrumb(params) {
|
|
3561
|
-
const { navId, navMap, anchor, breadcrumb, navMenu, hasOwnContent } = params;
|
|
3562
|
-
if (!navId)
|
|
3563
|
-
return emptyResult();
|
|
3564
|
-
// The header and the trail belong to whichever Nav owns the menu below them:
|
|
3565
|
-
// on a leaf that is the parent, so the User reads the list they are in with
|
|
3566
|
-
// their own row marked, rather than a title over an empty panel.
|
|
3567
|
-
const ownerId = navMenuOwnerId(navId, navMap, hasOwnContent);
|
|
3568
|
-
// An emitted breadcrumb names the panel it was emitted for. Once the panel
|
|
3569
|
-
// has been handed up to an ancestor it is no longer that panel, so the
|
|
3570
|
-
// override would title the ancestor's list after the leaf we left.
|
|
3571
|
-
const ownPanel = ownerId === visibleNavId(navId);
|
|
3572
|
-
const chain = navIdChain(ownerId);
|
|
3573
|
-
const derivedTrail = chain
|
|
3574
|
-
.slice(0, -1)
|
|
3575
|
-
.filter((id) => !isDefaultNav(id))
|
|
3576
|
-
.map((id) => toTrailItem(id, navMap, anchor));
|
|
3577
|
-
const nav = navMap[ownerId];
|
|
3578
|
-
const derivedHeader = {
|
|
3579
|
-
id: ownerId,
|
|
3580
|
-
label: nav?.title ?? (ownerId === ROOT_NAV$1 ? '' : navIdSegment(ownerId)),
|
|
3581
|
-
icon: nav?.icon,
|
|
3582
|
-
nav: ownerId,
|
|
3583
|
-
address: renderAddress(ownerId, navMap, anchor),
|
|
3584
|
-
};
|
|
3585
|
-
const { trail, header } = breadcrumb && ownPanel
|
|
3586
|
-
? mergeTrail(derivedTrail, breadcrumb, derivedHeader)
|
|
3587
|
-
: { trail: derivedTrail, header: derivedHeader };
|
|
3588
|
-
return {
|
|
3589
|
-
breadcrumb: { trail, header },
|
|
3590
|
-
navMenus: navMenu?.length && ownPanel
|
|
3591
|
-
? navMenu
|
|
3592
|
-
: buildNavMenus(ownerId, navMap, anchor),
|
|
3593
|
-
};
|
|
3594
|
-
}
|
|
3595
|
-
|
|
3596
3466
|
/**
|
|
3597
3467
|
* Platform Nav — the chrome this library owns (CONTEXT.md Platform Nav,
|
|
3598
3468
|
* ADR 0016).
|
|
@@ -3610,9 +3480,9 @@ function deriveBreadcrumb(params) {
|
|
|
3610
3480
|
* overrides by registering at the same NavId.
|
|
3611
3481
|
*/
|
|
3612
3482
|
/**
|
|
3613
|
-
* Platform Navs
|
|
3614
|
-
* in the menubar, settings in the footer.
|
|
3615
|
-
*
|
|
3483
|
+
* Platform Navs reached by a chrome button rather than a root row — search,
|
|
3484
|
+
* notification and user in the menubar, settings in the footer. Kept out of
|
|
3485
|
+
* root's rows at runtime so the menu does not repeat the menubar.
|
|
3616
3486
|
*/
|
|
3617
3487
|
const PLATFORM_BUTTON_NAV_IDS = [
|
|
3618
3488
|
'root_search',
|
|
@@ -3621,12 +3491,12 @@ const PLATFORM_BUTTON_NAV_IDS = [
|
|
|
3621
3491
|
'root_settings',
|
|
3622
3492
|
];
|
|
3623
3493
|
/**
|
|
3624
|
-
* Platform children rendered as rows in the root panel
|
|
3625
|
-
*
|
|
3626
|
-
*
|
|
3627
|
-
*
|
|
3494
|
+
* Platform children rendered as rows in the root panel. Empty on purpose —
|
|
3495
|
+
* every Platform Nav carries a button of its own, and a row beside the icon
|
|
3496
|
+
* that already opens it is the same NavRef twice. Root's runtime rows are App
|
|
3497
|
+
* Navs only.
|
|
3628
3498
|
*/
|
|
3629
|
-
const PLATFORM_ROOT_CHILDREN = [
|
|
3499
|
+
const PLATFORM_ROOT_CHILDREN = [];
|
|
3630
3500
|
/**
|
|
3631
3501
|
* Root carries no title of its own — an app's `navs/root.yml` names the app,
|
|
3632
3502
|
* and that is the one field of root the asset owns outright.
|
|
@@ -3732,8 +3602,9 @@ const createPlatformNavMap = () => Object.fromEntries(Object.entries(PLATFORM_NA
|
|
|
3732
3602
|
* same id. An extensible one merges: the asset contributes its App Nav
|
|
3733
3603
|
* children (and, at `root`, the app's own `title` / `logo` / `icon`), the
|
|
3734
3604
|
* platform children follow, and NavKind and NavPresentation stay the
|
|
3735
|
-
* library's — so an asset cannot delete chrome
|
|
3736
|
-
* and shipping a closed Platform NavId cannot
|
|
3605
|
+
* library's — so an asset cannot delete chrome (settings still exists even
|
|
3606
|
+
* though it is not a root row), and shipping a closed Platform NavId cannot
|
|
3607
|
+
* redefine it.
|
|
3737
3608
|
*/
|
|
3738
3609
|
const mergePlatformNav = (nav, navId) => {
|
|
3739
3610
|
const platform = PLATFORM_NAV_MAP[navId];
|
|
@@ -3742,9 +3613,10 @@ const mergePlatformNav = (nav, navId) => {
|
|
|
3742
3613
|
if (!isExtensiblePlatformNavId(navId))
|
|
3743
3614
|
return { ...platform };
|
|
3744
3615
|
const platformChildren = platform.children ?? [];
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3616
|
+
const appChildren = (nav.children ?? []).filter((childId) => !platformChildren.includes(childId) &&
|
|
3617
|
+
// Chrome-button Navs stay addressable but never become root menu rows,
|
|
3618
|
+
// even when an older asset still listed them under root.
|
|
3619
|
+
!(navId === ROOT_NAV$1 && PLATFORM_BUTTON_NAV_IDS.includes(childId)));
|
|
3748
3620
|
return {
|
|
3749
3621
|
...nav,
|
|
3750
3622
|
kind: platform.kind,
|
|
@@ -3766,6 +3638,206 @@ const unfetchedPlatformNav = (navId) => {
|
|
|
3766
3638
|
: undefined;
|
|
3767
3639
|
};
|
|
3768
3640
|
|
|
3641
|
+
const emptyResult = () => ({
|
|
3642
|
+
breadcrumb: { header: { label: '', id: '' }, trail: [] },
|
|
3643
|
+
navMenus: [],
|
|
3644
|
+
});
|
|
3645
|
+
/**
|
|
3646
|
+
* One trail/menu entry. `nav` names where it goes by NavId — the NavKind on the
|
|
3647
|
+
* target decides whether following it routes or opens a panel, so nothing here
|
|
3648
|
+
* chooses a link kind (ADR 0014).
|
|
3649
|
+
*/
|
|
3650
|
+
const toTrailItem = (navId, navMap, anchor,
|
|
3651
|
+
/** A dynamic node standing on an instance reads that row's own label. */
|
|
3652
|
+
label) => {
|
|
3653
|
+
const nav = navMap[navId];
|
|
3654
|
+
return {
|
|
3655
|
+
id: navId,
|
|
3656
|
+
label: label ?? nav?.title ?? navIdSegment(navId),
|
|
3657
|
+
icon: nav?.icon,
|
|
3658
|
+
nav: navId,
|
|
3659
|
+
address: renderAddress(navId, navMap, anchor),
|
|
3660
|
+
};
|
|
3661
|
+
};
|
|
3662
|
+
/**
|
|
3663
|
+
* One resolved NavRow as a menu row. `nav` is the dynamic **node**, never a
|
|
3664
|
+
* per-instance id nothing registers — a NavRef names a node and the instance
|
|
3665
|
+
* rides alongside as the param this Nav declared, which is what `renderAddress`
|
|
3666
|
+
* fills. `id` carries the value only so the list has stable keys.
|
|
3667
|
+
*/
|
|
3668
|
+
const navRowTrailItem = (navId, nav, row, navMap, anchor) => ({
|
|
3669
|
+
id: `${navId}${NAV_ID_SEP}${row.value}`,
|
|
3670
|
+
label: row.label,
|
|
3671
|
+
icon: row.icon ?? nav.icon,
|
|
3672
|
+
nav: navId,
|
|
3673
|
+
address: renderAddress(navId, navMap, anchor, {
|
|
3674
|
+
[navParamOf(nav)]: row.value,
|
|
3675
|
+
}),
|
|
3676
|
+
});
|
|
3677
|
+
/** A Nav that *is* its parent's own content rather than a place beside it. */
|
|
3678
|
+
const isDefaultNav = (navId) => navIdSegment(navId) === DEFAULT_NAV_SEGMENT;
|
|
3679
|
+
/**
|
|
3680
|
+
* The Nav the User is standing on as the nav shows it. A `default` node names
|
|
3681
|
+
* no place of its own — it is the route answering its parent's empty path — so
|
|
3682
|
+
* landing on `root_app_default` is standing on `root_app`, and the panel says
|
|
3683
|
+
* so rather than naming a segment that is on no menu.
|
|
3684
|
+
*/
|
|
3685
|
+
const visibleNavId = (navId) => {
|
|
3686
|
+
let id = navId;
|
|
3687
|
+
while (id !== ROOT_NAV$1 && isDefaultNav(id))
|
|
3688
|
+
id = parentNavId(id) ?? ROOT_NAV$1;
|
|
3689
|
+
return id;
|
|
3690
|
+
};
|
|
3691
|
+
/**
|
|
3692
|
+
* The direct children of a Nav. `children` is the authored list, but a Nav that
|
|
3693
|
+
* lists none is not childless: the map already holds every node fetched for
|
|
3694
|
+
* this descent, and a child is named by its own id. Reading the map when the
|
|
3695
|
+
* list is empty is what keeps a generated tree — whose `root.yml` names the app
|
|
3696
|
+
* and nothing else — from titling a leaf over an empty panel.
|
|
3697
|
+
*
|
|
3698
|
+
* The Platform Navs reached by a chrome button are the one exclusion: root
|
|
3699
|
+
* seeds `children: []` so they are never rows beside the icons that already
|
|
3700
|
+
* open them, and discovering them off the map would put them back.
|
|
3701
|
+
*/
|
|
3702
|
+
const childIdsOf = (navId, navMap) => {
|
|
3703
|
+
const declared = navMap[navId]?.children;
|
|
3704
|
+
if (declared?.length)
|
|
3705
|
+
return declared;
|
|
3706
|
+
return Object.keys(navMap).filter((id) => parentNavId(id) === navId && !PLATFORM_BUTTON_NAV_IDS.includes(id));
|
|
3707
|
+
};
|
|
3708
|
+
/**
|
|
3709
|
+
* The children a menu may draw. A Nav needs a title to be a row at all, and a
|
|
3710
|
+
* `default` node is not a row: it is its parent's own content, so it is
|
|
3711
|
+
* *transparent* — its own children take its place in the list, spliced where
|
|
3712
|
+
* it stood. `app → default → { trending, latest }` is one list of two rows
|
|
3713
|
+
* under app, which is the tree the User was drawing when they put a `default`
|
|
3714
|
+
* in the middle of it. Filtering the node out without adopting its children
|
|
3715
|
+
* left that app with no rows at all.
|
|
3716
|
+
*/
|
|
3717
|
+
const menuChildIds = (navId, navMap) => childIdsOf(navId, navMap).flatMap((childId) => {
|
|
3718
|
+
if (isDefaultNav(childId))
|
|
3719
|
+
return menuChildIds(childId, navMap);
|
|
3720
|
+
return navMap[childId]?.title ? [childId] : [];
|
|
3721
|
+
});
|
|
3722
|
+
/**
|
|
3723
|
+
* Whose children the menu draws. A Nav with rows of its own draws them — that
|
|
3724
|
+
* is the descent. A leaf has none, and descending into nothing left the panel
|
|
3725
|
+
* on an empty state; it draws its *siblings* instead, so the menu stays the
|
|
3726
|
+
* list the User moved through and the row they are on is the one marked
|
|
3727
|
+
* active. Root is the floor: its own children are the last list there is.
|
|
3728
|
+
*/
|
|
3729
|
+
const navMenuOwnerId = (navId, navMap, hasOwnContent = false) => {
|
|
3730
|
+
const visible = visibleNavId(navId);
|
|
3731
|
+
if (visible === ROOT_NAV$1 || menuChildIds(visible, navMap).length) {
|
|
3732
|
+
return visible;
|
|
3733
|
+
}
|
|
3734
|
+
// A panel that answers with a widget of its own keeps its own title —
|
|
3735
|
+
// titling it after its parent while showing its own content reads as the
|
|
3736
|
+
// wrong panel. Being a Murl is not that proof: a Murl leaf nothing is
|
|
3737
|
+
// registered for draws nothing, and an empty panel must not name itself.
|
|
3738
|
+
if (hasOwnContent)
|
|
3739
|
+
return visible;
|
|
3740
|
+
// Nothing of its own and no rows under it: hand the panel to the nearest
|
|
3741
|
+
// ancestor that has rows, so the User reads the list they are in with their
|
|
3742
|
+
// own row marked. Where no ancestor lists anything there is no better title
|
|
3743
|
+
// than the one we are on — a mistitled empty panel is worse than a titled one.
|
|
3744
|
+
for (let ancestor = parentNavId(visible); ancestor; ancestor = parentNavId(ancestor)) {
|
|
3745
|
+
const owner = visibleNavId(ancestor);
|
|
3746
|
+
if (menuChildIds(owner, navMap).length)
|
|
3747
|
+
return owner;
|
|
3748
|
+
if (owner === ROOT_NAV$1)
|
|
3749
|
+
break;
|
|
3750
|
+
}
|
|
3751
|
+
return visible;
|
|
3752
|
+
};
|
|
3753
|
+
/**
|
|
3754
|
+
* The rows one panel draws. A `dynamic` child with a NavRowSource behind it is
|
|
3755
|
+
* **transparent** the way a Default Nav is: its resolved rows are spliced where
|
|
3756
|
+
* its own row stood, so the User reads the categories rather than a row named
|
|
3757
|
+
* after the node that lists them.
|
|
3758
|
+
*
|
|
3759
|
+
* Three states and not two. Rows: splice them. No source registered at all:
|
|
3760
|
+
* the Nav is an ordinary row, which is what a `dynamic` Nav was before a source
|
|
3761
|
+
* could be authored. A source that resolved *nothing*: splice nothing — falling
|
|
3762
|
+
* back to the node's own row would draw a link into a list that is empty, and
|
|
3763
|
+
* falling through to the static siblings around it would show a panel that
|
|
3764
|
+
* looks correct and is not.
|
|
3765
|
+
*/
|
|
3766
|
+
const buildNavMenus = (navId, navMap, anchor, dynamicRows = {}) => menuChildIds(navId, navMap).flatMap((childId) => {
|
|
3767
|
+
const nav = navMap[childId];
|
|
3768
|
+
const resolved = nav && dynamicRows[childId];
|
|
3769
|
+
if (!nav || nav.presentation !== 'dynamic' || !resolved) {
|
|
3770
|
+
return [toTrailItem(childId, navMap, anchor)];
|
|
3771
|
+
}
|
|
3772
|
+
return resolved.rows.map((row) => navRowTrailItem(childId, nav, row, navMap, anchor));
|
|
3773
|
+
});
|
|
3774
|
+
/**
|
|
3775
|
+
* Merges a widget's emitted trail over the derived one, matching by depth.
|
|
3776
|
+
* With a single keyspace there is nothing to translate — an emitted entry is
|
|
3777
|
+
* already in the same ids everything else uses.
|
|
3778
|
+
*/
|
|
3779
|
+
const mergeTrail = (derived, override, derivedHeader) => {
|
|
3780
|
+
const depth = (id) => navIdChain(id).length;
|
|
3781
|
+
const trail = derived.map((item) => {
|
|
3782
|
+
const emitted = override.trail?.find((e) => depth(e.id) === depth(item.id));
|
|
3783
|
+
return emitted ? { ...item, ...emitted } : item;
|
|
3784
|
+
});
|
|
3785
|
+
return { trail, header: override.header ?? derivedHeader };
|
|
3786
|
+
};
|
|
3787
|
+
function deriveBreadcrumb(params) {
|
|
3788
|
+
const { navId, navMap, anchor, breadcrumb, navMenu, hasOwnContent, dynamicRows, routeParams, } = params;
|
|
3789
|
+
if (!navId)
|
|
3790
|
+
return emptyResult();
|
|
3791
|
+
/**
|
|
3792
|
+
* The label a dynamic node wears while the User stands on one of its rows.
|
|
3793
|
+
* Falls back to the node's own title when nothing matches — a deep link that
|
|
3794
|
+
* arrived before the rows did, or a row that has since gone — because a raw
|
|
3795
|
+
* segment is a worse answer than the node's name but a better one than a
|
|
3796
|
+
* blank.
|
|
3797
|
+
*/
|
|
3798
|
+
const rowLabel = (id) => {
|
|
3799
|
+
const nav = navMap[id];
|
|
3800
|
+
if (nav?.presentation !== 'dynamic')
|
|
3801
|
+
return undefined;
|
|
3802
|
+
const value = routeParams?.[navParamOf(nav)];
|
|
3803
|
+
if (!value)
|
|
3804
|
+
return undefined;
|
|
3805
|
+
return dynamicRows?.[id]?.rows.find((row) => row.value === value)?.label;
|
|
3806
|
+
};
|
|
3807
|
+
// The header and the trail belong to whichever Nav owns the menu below them:
|
|
3808
|
+
// on a leaf that is the parent, so the User reads the list they are in with
|
|
3809
|
+
// their own row marked, rather than a title over an empty panel.
|
|
3810
|
+
const ownerId = navMenuOwnerId(navId, navMap, hasOwnContent);
|
|
3811
|
+
// An emitted breadcrumb names the panel it was emitted for. Once the panel
|
|
3812
|
+
// has been handed up to an ancestor it is no longer that panel, so the
|
|
3813
|
+
// override would title the ancestor's list after the leaf we left.
|
|
3814
|
+
const ownPanel = ownerId === visibleNavId(navId);
|
|
3815
|
+
const chain = navIdChain(ownerId);
|
|
3816
|
+
const derivedTrail = chain
|
|
3817
|
+
.slice(0, -1)
|
|
3818
|
+
.filter((id) => !isDefaultNav(id))
|
|
3819
|
+
.map((id) => toTrailItem(id, navMap, anchor, rowLabel(id)));
|
|
3820
|
+
const nav = navMap[ownerId];
|
|
3821
|
+
const derivedHeader = {
|
|
3822
|
+
id: ownerId,
|
|
3823
|
+
label: rowLabel(ownerId) ??
|
|
3824
|
+
nav?.title ??
|
|
3825
|
+
(ownerId === ROOT_NAV$1 ? '' : navIdSegment(ownerId)),
|
|
3826
|
+
icon: nav?.icon,
|
|
3827
|
+
nav: ownerId,
|
|
3828
|
+
address: renderAddress(ownerId, navMap, anchor),
|
|
3829
|
+
};
|
|
3830
|
+
const { trail, header } = breadcrumb && ownPanel
|
|
3831
|
+
? mergeTrail(derivedTrail, breadcrumb, derivedHeader)
|
|
3832
|
+
: { trail: derivedTrail, header: derivedHeader };
|
|
3833
|
+
return {
|
|
3834
|
+
breadcrumb: { trail, header },
|
|
3835
|
+
navMenus: navMenu?.length && ownPanel
|
|
3836
|
+
? navMenu
|
|
3837
|
+
: buildNavMenus(ownerId, navMap, anchor, dynamicRows),
|
|
3838
|
+
};
|
|
3839
|
+
}
|
|
3840
|
+
|
|
3769
3841
|
class GetNavService {
|
|
3770
3842
|
httpService = inject(HttpService);
|
|
3771
3843
|
assetStore = inject(AssetStore);
|
|
@@ -3861,6 +3933,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
3861
3933
|
const initialState$3 = {
|
|
3862
3934
|
path: '/',
|
|
3863
3935
|
routeNavId: undefined,
|
|
3936
|
+
routeParams: {},
|
|
3864
3937
|
murl: [],
|
|
3865
3938
|
appLink: undefined,
|
|
3866
3939
|
appNavId: undefined,
|
|
@@ -3883,6 +3956,21 @@ const routeNavIdOf = (root) => {
|
|
|
3883
3956
|
}
|
|
3884
3957
|
return navId;
|
|
3885
3958
|
};
|
|
3959
|
+
/**
|
|
3960
|
+
* Every path parameter on the matched chain, deepest last. Merged rather than
|
|
3961
|
+
* read off the leaf: two dynamic Navs on one path each contribute their own
|
|
3962
|
+
* (`:id/:issueId`), and only the chain holds both.
|
|
3963
|
+
*/
|
|
3964
|
+
const routeParamsOf = (root) => {
|
|
3965
|
+
const params = {};
|
|
3966
|
+
for (let r = root; r; r = r.firstChild) {
|
|
3967
|
+
for (const [key, value] of Object.entries(r.params ?? {})) {
|
|
3968
|
+
if (typeof value === 'string')
|
|
3969
|
+
params[key] = value;
|
|
3970
|
+
}
|
|
3971
|
+
}
|
|
3972
|
+
return params;
|
|
3973
|
+
};
|
|
3886
3974
|
const murlOf = (root) => {
|
|
3887
3975
|
const raw = root.queryParams?.[MURL_PARAM];
|
|
3888
3976
|
return typeof raw === 'string' ? raw.split(MURL_SEP).filter(Boolean) : [];
|
|
@@ -3940,32 +4028,69 @@ const NavStore = signalStore({ providedIn: 'root' }, withState(initialState$3),
|
|
|
3940
4028
|
* selector from the Angular tag used to create an unregistered custom
|
|
3941
4029
|
* element and leave theme / language blank.
|
|
3942
4030
|
*/
|
|
3943
|
-
|
|
4031
|
+
/**
|
|
4032
|
+
* One NavId against every registered map, Remote first. Split out of
|
|
4033
|
+
* `widgetEntry` because a `dynamic` Nav's rows are looked up by *its own*
|
|
4034
|
+
* id while the User stands on its parent — the rows draw in the parent's
|
|
4035
|
+
* panel, so the candidate list the open panel walks would never reach them.
|
|
4036
|
+
*/
|
|
4037
|
+
const entryAt = (candidate) => {
|
|
3944
4038
|
const appNavId = store.appNavId();
|
|
3945
4039
|
const appLink = store.appLink();
|
|
3946
4040
|
const maps = navWidgetMaps ?? [];
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
return { entry, remote: true, navId: candidate };
|
|
3956
|
-
}
|
|
3957
|
-
}
|
|
3958
|
-
for (let i = maps.length - 1; i >= 0; i--) {
|
|
3959
|
-
const entry = maps[i]()[navId];
|
|
3960
|
-
if (entry !== undefined)
|
|
3961
|
-
return { entry, remote: false, navId: candidate };
|
|
4041
|
+
const navId = candidate;
|
|
4042
|
+
if (appLink && appNavId) {
|
|
4043
|
+
const registered = store.remoteWidgets()[appLink];
|
|
4044
|
+
const localId = toLocalNavId(navId, appNavId);
|
|
4045
|
+
if (registered && localId) {
|
|
4046
|
+
const entry = registered.widgetMap()[localId];
|
|
4047
|
+
if (entry)
|
|
4048
|
+
return { entry, remote: true };
|
|
3962
4049
|
}
|
|
3963
4050
|
}
|
|
4051
|
+
for (let i = maps.length - 1; i >= 0; i--) {
|
|
4052
|
+
const entry = maps[i]()[navId];
|
|
4053
|
+
if (entry !== undefined)
|
|
4054
|
+
return { entry, remote: false };
|
|
4055
|
+
}
|
|
4056
|
+
return undefined;
|
|
4057
|
+
};
|
|
4058
|
+
const widgetEntry = computed(() => {
|
|
4059
|
+
for (const candidate of widgetNavIds()) {
|
|
4060
|
+
const hit = entryAt(candidate);
|
|
4061
|
+
if (hit)
|
|
4062
|
+
return { ...hit, navId: candidate };
|
|
4063
|
+
}
|
|
3964
4064
|
return undefined;
|
|
3965
4065
|
}, ...(ngDevMode ? [{ debugName: "widgetEntry" }] : /* istanbul ignore next */ []));
|
|
4066
|
+
/**
|
|
4067
|
+
* Every `dynamic` Nav with a NavRowSource behind it, resolved. Walks the
|
|
4068
|
+
* whole map rather than the open panel's own descent: the rows are drawn by
|
|
4069
|
+
* whichever ancestor owns the panel, and reading each source's signal here
|
|
4070
|
+
* is what makes the panel recompute when the store behind it fills.
|
|
4071
|
+
*/
|
|
4072
|
+
const dynamicRows = computed(() => {
|
|
4073
|
+
const out = {};
|
|
4074
|
+
for (const nav of Object.values(store.navMap())) {
|
|
4075
|
+
if (nav.presentation !== 'dynamic')
|
|
4076
|
+
continue;
|
|
4077
|
+
const hit = entryAt(nav.navId);
|
|
4078
|
+
if (!hit || !isNavRowsConfig(hit.entry))
|
|
4079
|
+
continue;
|
|
4080
|
+
out[nav.navId] = {
|
|
4081
|
+
rows: hit.entry.navRows() ?? [],
|
|
4082
|
+
loading: hit.entry.loading?.(),
|
|
4083
|
+
};
|
|
4084
|
+
}
|
|
4085
|
+
return out;
|
|
4086
|
+
}, ...(ngDevMode ? [{ debugName: "dynamicRows" }] : /* istanbul ignore next */ []));
|
|
3966
4087
|
const resolvedWidget = computed(() => {
|
|
3967
4088
|
const hit = widgetEntry();
|
|
3968
|
-
|
|
4089
|
+
// Neither of the two row-shaped entries fills a panel with a component:
|
|
4090
|
+
// one replaces a panel's rows, the other contributes rows to its
|
|
4091
|
+
// parent's, and `normalizeNavWidgetEntry` would read a `content` off
|
|
4092
|
+
// neither.
|
|
4093
|
+
if (!hit || isNavMenuConfig(hit.entry) || isNavRowsConfig(hit.entry))
|
|
3969
4094
|
return null;
|
|
3970
4095
|
const config = normalizeNavWidgetEntry(hit.entry);
|
|
3971
4096
|
if (!config.content)
|
|
@@ -4016,6 +4141,8 @@ const NavStore = signalStore({ providedIn: 'root' }, withState(initialState$3),
|
|
|
4016
4141
|
navId: panelNavId(),
|
|
4017
4142
|
navMap: store.navMap(),
|
|
4018
4143
|
anchor: { navId: store.routeNavId() ?? ROOT_NAV$1, path: store.path() },
|
|
4144
|
+
dynamicRows: dynamicRows(),
|
|
4145
|
+
routeParams: store.routeParams(),
|
|
4019
4146
|
breadcrumb: menuConfig?.breadcramb?.() ??
|
|
4020
4147
|
(typeof widgetConfig?.breadcramb === 'function'
|
|
4021
4148
|
? widgetConfig.breadcramb()
|
|
@@ -4119,6 +4246,7 @@ const NavStore = signalStore({ providedIn: 'root' }, withState(initialState$3),
|
|
|
4119
4246
|
*/
|
|
4120
4247
|
const syncFromRouter = rxMethod(pipe(filter((s) => !!s), tap((snapshot) => {
|
|
4121
4248
|
const routeNavId = routeNavIdOf(snapshot.root);
|
|
4249
|
+
const routeParams = routeParamsOf(snapshot.root);
|
|
4122
4250
|
const murl = murlOf(snapshot.root);
|
|
4123
4251
|
const path = router.url.split(MURL_SEP)[0].split('?')[0];
|
|
4124
4252
|
untracked(() => {
|
|
@@ -4127,6 +4255,7 @@ const NavStore = signalStore({ providedIn: 'root' }, withState(initialState$3),
|
|
|
4127
4255
|
patchState(store, {
|
|
4128
4256
|
path,
|
|
4129
4257
|
routeNavId,
|
|
4258
|
+
routeParams,
|
|
4130
4259
|
murl,
|
|
4131
4260
|
// Address changes clear the icon-opened flag (ADR 0013), except
|
|
4132
4261
|
// an explicit `keepPanel` goToNav (AppLogo while open).
|
|
@@ -6642,7 +6771,7 @@ class SectionFormItemComponent extends ConfigComponent {
|
|
|
6642
6771
|
break;
|
|
6643
6772
|
}
|
|
6644
6773
|
case InputType.TOGGLE: {
|
|
6645
|
-
const { ToggleInputComponent } = await import('./magmonium-one-toggle-
|
|
6774
|
+
const { ToggleInputComponent } = await import('./magmonium-one-toggle-wEeMiUQz.mjs');
|
|
6646
6775
|
this.createDynamicComponent(seq, ToggleInputComponent, [], true);
|
|
6647
6776
|
break;
|
|
6648
6777
|
}
|
|
@@ -6654,12 +6783,12 @@ class SectionFormItemComponent extends ConfigComponent {
|
|
|
6654
6783
|
break;
|
|
6655
6784
|
}
|
|
6656
6785
|
case InputType.PASSWORD: {
|
|
6657
|
-
const { PasswordInputComponent } = await import('./magmonium-one-password-
|
|
6786
|
+
const { PasswordInputComponent } = await import('./magmonium-one-password-DmEMAVca.mjs');
|
|
6658
6787
|
this.createDynamicComponent(seq, PasswordInputComponent);
|
|
6659
6788
|
break;
|
|
6660
6789
|
}
|
|
6661
6790
|
case InputType.OTP: {
|
|
6662
|
-
const { OtpInputComponent } = await import('./magmonium-one-otp-
|
|
6791
|
+
const { OtpInputComponent } = await import('./magmonium-one-otp-JmUyDNPb.mjs');
|
|
6663
6792
|
this.createDynamicComponent(seq, OtpInputComponent);
|
|
6664
6793
|
break;
|
|
6665
6794
|
}
|
|
@@ -8104,28 +8233,31 @@ class MenuComponent {
|
|
|
8104
8233
|
const hide = this.hide();
|
|
8105
8234
|
const extra = this.extra();
|
|
8106
8235
|
const isAdmin = this.isAdmin();
|
|
8107
|
-
let result = [];
|
|
8108
|
-
if (back) {
|
|
8109
|
-
result = back.options ?? async ?? [];
|
|
8110
|
-
}
|
|
8111
|
-
else {
|
|
8112
|
-
result = async ?? config ?? [];
|
|
8113
|
-
}
|
|
8114
|
-
if (!isAdmin) {
|
|
8115
|
-
result = result.map((group) => group.filter((item) => !item.adminOnly));
|
|
8116
|
-
}
|
|
8117
|
-
if (hide?.length) {
|
|
8118
|
-
result = result.map((group) => group.filter((item) => !hide.includes(item.id)));
|
|
8119
|
-
}
|
|
8120
8236
|
const vRule = this.visibilityRule();
|
|
8121
8237
|
const data = this.extraData();
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8238
|
+
// Filtering recurses so a parent is judged by what survives under it: a row
|
|
8239
|
+
// whose every child was hidden would open an empty box, which reads as a
|
|
8240
|
+
// broken menu rather than an unavailable one. A `file` parent is exempt —
|
|
8241
|
+
// its options are fetched on drill and there is nothing here to count.
|
|
8242
|
+
const filterGroups = (groups) => groups
|
|
8243
|
+
.map((group) => group.filter((item) => {
|
|
8244
|
+
if (!isAdmin && item.adminOnly)
|
|
8245
|
+
return false;
|
|
8246
|
+
if (hide?.length && hide.includes(item.id))
|
|
8247
|
+
return false;
|
|
8248
|
+
if (vRule && !vRule(item.visibilityKey ?? item.id, data)) {
|
|
8249
|
+
return false;
|
|
8250
|
+
}
|
|
8251
|
+
if (item.options)
|
|
8252
|
+
return filterGroups(item.options).length > 0;
|
|
8253
|
+
return true;
|
|
8254
|
+
}))
|
|
8255
|
+
.filter((group) => group.length > 0);
|
|
8256
|
+
const source = back
|
|
8257
|
+
? back.options ?? async ?? []
|
|
8258
|
+
: async ?? config ?? [];
|
|
8259
|
+
const result = filterGroups(source);
|
|
8260
|
+
return extra?.length && !back ? [...result, extra] : result;
|
|
8129
8261
|
}, ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
8130
8262
|
isLoading = computed(() => this.#asyncOptions.isLoading(), ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
|
|
8131
8263
|
// --- Handlers ---
|
|
@@ -8185,6 +8317,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
8185
8317
|
|
|
8186
8318
|
class ContextMenuBoxComponent {
|
|
8187
8319
|
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
8320
|
+
hide = input(...(ngDevMode ? [undefined, { debugName: "hide" }] : /* istanbul ignore next */ []));
|
|
8188
8321
|
file = input(...(ngDevMode ? [undefined, { debugName: "file" }] : /* istanbul ignore next */ []));
|
|
8189
8322
|
width = input('250px', ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
8190
8323
|
height = input('auto', ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
|
|
@@ -8197,12 +8330,12 @@ class ContextMenuBoxComponent {
|
|
|
8197
8330
|
this.action.emit(item);
|
|
8198
8331
|
};
|
|
8199
8332
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContextMenuBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8200
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ContextMenuBoxComponent, isStandalone: true, selector: "m-context-menu-box", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, file: { classPropertyName: "file", publicName: "file", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, isAdmin: { classPropertyName: "isAdmin", publicName: "isAdmin", isSignal: true, isRequired: false, transformFunction: null }, visibilityRule: { classPropertyName: "visibilityRule", publicName: "visibilityRule", isSignal: true, isRequired: false, transformFunction: null }, disableRule: { classPropertyName: "disableRule", publicName: "disableRule", isSignal: true, isRequired: false, transformFunction: null }, extraData: { classPropertyName: "extraData", publicName: "extraData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, ngImport: i0, template: "<div class=\"m-context-menu-box\" [style.width]=\"width()\" [style.max-height]=\"height()\">\n <m-menu\n [config]=\"options()\"\n [file]=\"file()\"\n [isAdmin]=\"isAdmin()\"\n [visibilityRule]=\"visibilityRule()\"\n [disableRule]=\"disableRule()\"\n [extraData]=\"extraData()\"\n (action)=\"emitAction($event)\"\n />\n</div>\n", styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}.m-context-menu-box{overflow-y:auto;border-radius:0;border:1px solid var(--m-mm);background:var(--m-background);animation:context-menu-in .2s ease-out}@keyframes context-menu-in{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}:host-context(.align-bottom){display:block;width:100%!important;max-width:100%!important}:host-context(.align-bottom) .m-context-menu-box{width:100%!important;max-width:100%!important;max-height:70vh!important;border-left:none;border-right:none;border-bottom:none}\n"], dependencies: [{ kind: "component", type: MenuComponent, selector: "m-menu", inputs: ["config", "file", "root", "url", "extra", "hide", "hideLink", "isAdmin", "visibilityRule", "disableRule", "extraData"], outputs: ["action"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8333
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ContextMenuBoxComponent, isStandalone: true, selector: "m-context-menu-box", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, hide: { classPropertyName: "hide", publicName: "hide", isSignal: true, isRequired: false, transformFunction: null }, file: { classPropertyName: "file", publicName: "file", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, isAdmin: { classPropertyName: "isAdmin", publicName: "isAdmin", isSignal: true, isRequired: false, transformFunction: null }, visibilityRule: { classPropertyName: "visibilityRule", publicName: "visibilityRule", isSignal: true, isRequired: false, transformFunction: null }, disableRule: { classPropertyName: "disableRule", publicName: "disableRule", isSignal: true, isRequired: false, transformFunction: null }, extraData: { classPropertyName: "extraData", publicName: "extraData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, ngImport: i0, template: "<div class=\"m-context-menu-box\" [style.width]=\"width()\" [style.max-height]=\"height()\">\n <m-menu\n [config]=\"options()\"\n [hide]=\"hide()\"\n [file]=\"file()\"\n [isAdmin]=\"isAdmin()\"\n [visibilityRule]=\"visibilityRule()\"\n [disableRule]=\"disableRule()\"\n [extraData]=\"extraData()\"\n (action)=\"emitAction($event)\"\n />\n</div>\n", styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}.m-context-menu-box{overflow-y:auto;border-radius:0;border:1px solid var(--m-mm);background:var(--m-background);animation:context-menu-in .2s ease-out}@keyframes context-menu-in{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}:host-context(.align-bottom){display:block;width:100%!important;max-width:100%!important}:host-context(.align-bottom) .m-context-menu-box{width:100%!important;max-width:100%!important;max-height:70vh!important;border-left:none;border-right:none;border-bottom:none}\n"], dependencies: [{ kind: "component", type: MenuComponent, selector: "m-menu", inputs: ["config", "file", "root", "url", "extra", "hide", "hideLink", "isAdmin", "visibilityRule", "disableRule", "extraData"], outputs: ["action"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8201
8334
|
}
|
|
8202
8335
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContextMenuBoxComponent, decorators: [{
|
|
8203
8336
|
type: Component,
|
|
8204
|
-
args: [{ selector: 'm-context-menu-box', imports: [MenuComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"m-context-menu-box\" [style.width]=\"width()\" [style.max-height]=\"height()\">\n <m-menu\n [config]=\"options()\"\n [file]=\"file()\"\n [isAdmin]=\"isAdmin()\"\n [visibilityRule]=\"visibilityRule()\"\n [disableRule]=\"disableRule()\"\n [extraData]=\"extraData()\"\n (action)=\"emitAction($event)\"\n />\n</div>\n", styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}.m-context-menu-box{overflow-y:auto;border-radius:0;border:1px solid var(--m-mm);background:var(--m-background);animation:context-menu-in .2s ease-out}@keyframes context-menu-in{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}:host-context(.align-bottom){display:block;width:100%!important;max-width:100%!important}:host-context(.align-bottom) .m-context-menu-box{width:100%!important;max-width:100%!important;max-height:70vh!important;border-left:none;border-right:none;border-bottom:none}\n"] }]
|
|
8205
|
-
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], file: [{ type: i0.Input, args: [{ isSignal: true, alias: "file", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], isAdmin: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAdmin", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], visibilityRule: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibilityRule", required: false }] }], disableRule: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableRule", required: false }] }], extraData: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraData", required: false }] }] } });
|
|
8337
|
+
args: [{ selector: 'm-context-menu-box', imports: [MenuComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"m-context-menu-box\" [style.width]=\"width()\" [style.max-height]=\"height()\">\n <m-menu\n [config]=\"options()\"\n [hide]=\"hide()\"\n [file]=\"file()\"\n [isAdmin]=\"isAdmin()\"\n [visibilityRule]=\"visibilityRule()\"\n [disableRule]=\"disableRule()\"\n [extraData]=\"extraData()\"\n (action)=\"emitAction($event)\"\n />\n</div>\n", styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}.m-context-menu-box{overflow-y:auto;border-radius:0;border:1px solid var(--m-mm);background:var(--m-background);animation:context-menu-in .2s ease-out}@keyframes context-menu-in{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}:host-context(.align-bottom){display:block;width:100%!important;max-width:100%!important}:host-context(.align-bottom) .m-context-menu-box{width:100%!important;max-width:100%!important;max-height:70vh!important;border-left:none;border-right:none;border-bottom:none}\n"] }]
|
|
8338
|
+
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], hide: [{ type: i0.Input, args: [{ isSignal: true, alias: "hide", required: false }] }], file: [{ type: i0.Input, args: [{ isSignal: true, alias: "file", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], isAdmin: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAdmin", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], visibilityRule: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibilityRule", required: false }] }], disableRule: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableRule", required: false }] }], extraData: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraData", required: false }] }] } });
|
|
8206
8339
|
|
|
8207
8340
|
class ContextMenuComponent extends ConfigComponent {
|
|
8208
8341
|
toggle = model(...(ngDevMode ? [undefined, { debugName: "toggle" }] : /* istanbul ignore next */ []));
|
|
@@ -8231,15 +8364,11 @@ class ContextMenuComponent extends ConfigComponent {
|
|
|
8231
8364
|
label: 'actions',
|
|
8232
8365
|
inverted: this.inverted() ?? this.contextMenuConfig().inverted,
|
|
8233
8366
|
}), ...(ngDevMode ? [{ debugName: "triggerButtonConfig" }] : /* istanbul ignore next */ []));
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
if (!exclude || !exclude.length)
|
|
8240
|
-
return options;
|
|
8241
|
-
return options.map((group) => group.filter((item) => !exclude.includes(item.id)));
|
|
8242
|
-
}, ...(ngDevMode ? [{ debugName: "contextMenuOptions" }] : /* istanbul ignore next */ []));
|
|
8367
|
+
// `exclude` is not applied here: a menu nests, and a filter run once over the
|
|
8368
|
+
// root groups cannot reach an item a layer down, nor one a `file` parent has
|
|
8369
|
+
// not fetched yet. It is handed to the menu as `hide` instead, which the menu
|
|
8370
|
+
// re-applies at whatever depth is on screen.
|
|
8371
|
+
contextMenuOptions = computed(() => this.contextMenuConfig().options ?? [], ...(ngDevMode ? [{ debugName: "contextMenuOptions" }] : /* istanbul ignore next */ []));
|
|
8243
8372
|
selectorConfig = computed(() => ({
|
|
8244
8373
|
component: ContextMenuBoxComponent,
|
|
8245
8374
|
base: 'm-context-menu',
|
|
@@ -8249,6 +8378,7 @@ class ContextMenuComponent extends ConfigComponent {
|
|
|
8249
8378
|
toggle: true,
|
|
8250
8379
|
bindings: [
|
|
8251
8380
|
inputBinding('options', this.contextMenuOptions),
|
|
8381
|
+
inputBinding('hide', this.exclude),
|
|
8252
8382
|
inputBinding('visibilityRule', this.visibilityRule),
|
|
8253
8383
|
inputBinding('disableRule', this.disableRule),
|
|
8254
8384
|
inputBinding('extraData', this.extraData),
|
|
@@ -15464,6 +15594,11 @@ const initialModalState = {
|
|
|
15464
15594
|
activePanel: undefined,
|
|
15465
15595
|
};
|
|
15466
15596
|
const ModalStore = signalStore({ providedIn: 'root' }, withState(initialModalState), withMethods((state, domService = inject(DomService), deviceService = inject(DeviceService)) => {
|
|
15597
|
+
// Every modal that has gone, by id. A modal is dismissed from two places —
|
|
15598
|
+
// its own close affordance and this store — and only one of those runs
|
|
15599
|
+
// through a ModalRef, so a caller waiting on an answer would otherwise wait
|
|
15600
|
+
// forever on the other.
|
|
15601
|
+
const closed = new Subject();
|
|
15467
15602
|
const modalComp = inject(MODAL_COMPONENT);
|
|
15468
15603
|
const panelComp = inject(PANEL_COMPONENT);
|
|
15469
15604
|
const confirmComp = inject(CONFIRM_COMPONENT);
|
|
@@ -15515,6 +15650,7 @@ const ModalStore = signalStore({ providedIn: 'root' }, withState(initialModalSta
|
|
|
15515
15650
|
? remaining[remaining.length - 1]
|
|
15516
15651
|
: undefined,
|
|
15517
15652
|
});
|
|
15653
|
+
closed.next(modalId);
|
|
15518
15654
|
};
|
|
15519
15655
|
/**
|
|
15520
15656
|
* The panel a dock request would displace: whatever currently holds the edge.
|
|
@@ -15651,26 +15787,69 @@ const ModalStore = signalStore({ providedIn: 'root' }, withState(initialModalSta
|
|
|
15651
15787
|
const cleanupPanelsOnClose = rxMethod(pipe(filter((panelMap) => !Object.keys(panelMap).length), tap(() => {
|
|
15652
15788
|
domService.cleanup(state.panelParentClassName());
|
|
15653
15789
|
})));
|
|
15654
|
-
|
|
15790
|
+
/**
|
|
15791
|
+
* The question as a value: subscribing asks it, and the single emission is
|
|
15792
|
+
* the answer — `true` for the commit, `false` for a refusal and for a
|
|
15793
|
+
* dismissal, which is a refusal by another route. Completes with that
|
|
15794
|
+
* emission, so a `switchMap` over it moves on rather than holding the
|
|
15795
|
+
* modal's answer open.
|
|
15796
|
+
*
|
|
15797
|
+
* Unsubscribing before it answers takes the modal away with it: the caller
|
|
15798
|
+
* that asked is gone, and a dialog nothing is waiting on is a dialog whose
|
|
15799
|
+
* answer lands nowhere.
|
|
15800
|
+
*/
|
|
15801
|
+
const ask = (opts) => new Observable((subscriber) => {
|
|
15655
15802
|
const modalRef = new ModalRef();
|
|
15656
|
-
|
|
15803
|
+
let settled = false;
|
|
15804
|
+
let id = '';
|
|
15805
|
+
const settle = (result, dismiss) => {
|
|
15806
|
+
if (settled)
|
|
15807
|
+
return;
|
|
15808
|
+
settled = true;
|
|
15809
|
+
watch.unsubscribe();
|
|
15810
|
+
if (dismiss)
|
|
15811
|
+
close(id);
|
|
15812
|
+
subscriber.next(result);
|
|
15813
|
+
subscriber.complete();
|
|
15814
|
+
};
|
|
15815
|
+
const watch = closed
|
|
15816
|
+
.pipe(filter((closedId) => closedId === id))
|
|
15817
|
+
.subscribe(() => settle(false, false));
|
|
15818
|
+
id = open({
|
|
15657
15819
|
component: confirmComp,
|
|
15658
15820
|
providers: [{ provide: MODAL_REF, useValue: modalRef }],
|
|
15659
15821
|
bindings: [
|
|
15660
15822
|
inputBinding('header', () => opts.header ?? ''),
|
|
15661
15823
|
inputBinding('body', () => opts.body ?? ''),
|
|
15824
|
+
inputBinding('params', () => opts.params ?? {}),
|
|
15662
15825
|
inputBinding('type', () => opts.type ?? 'info'),
|
|
15826
|
+
inputBinding('kind', () => opts.kind ?? 'yes'),
|
|
15827
|
+
inputBinding('confirmLabel', () => opts.confirmLabel ?? ''),
|
|
15828
|
+
inputBinding('cancelLabel', () => opts.cancelLabel ?? ''),
|
|
15663
15829
|
],
|
|
15664
15830
|
});
|
|
15665
|
-
modalRef.onClose((result) =>
|
|
15831
|
+
modalRef.onClose((result) => settle(!!result, true));
|
|
15832
|
+
return () => {
|
|
15833
|
+
if (settled)
|
|
15834
|
+
return;
|
|
15835
|
+
settled = true;
|
|
15836
|
+
watch.unsubscribe();
|
|
15837
|
+
close(id);
|
|
15838
|
+
};
|
|
15839
|
+
});
|
|
15840
|
+
// The callback form, kept for every caller drawn against it. One
|
|
15841
|
+
// implementation underneath: a refusal runs nothing, which is what an
|
|
15842
|
+
// `onConfirm` that never fires already meant.
|
|
15843
|
+
const confirm = (opts, onConfirm) => {
|
|
15844
|
+
ask(opts).subscribe((result) => {
|
|
15666
15845
|
if (result)
|
|
15667
15846
|
onConfirm();
|
|
15668
|
-
close(id);
|
|
15669
15847
|
});
|
|
15670
15848
|
};
|
|
15671
15849
|
return {
|
|
15672
15850
|
open,
|
|
15673
15851
|
close,
|
|
15852
|
+
ask,
|
|
15674
15853
|
confirm,
|
|
15675
15854
|
openPanel,
|
|
15676
15855
|
closePanel,
|
|
@@ -16069,16 +16248,41 @@ function injectAuthenticate() {
|
|
|
16069
16248
|
class ConfirmComponent {
|
|
16070
16249
|
header = input('', ...(ngDevMode ? [{ debugName: "header" }] : /* istanbul ignore next */ []));
|
|
16071
16250
|
body = input('', ...(ngDevMode ? [{ debugName: "body" }] : /* istanbul ignore next */ []));
|
|
16251
|
+
/**
|
|
16252
|
+
* The MessageVariable values the two keys above name — a row's name or id the
|
|
16253
|
+
* asker knows and the message asks about. Values and never text: they reach
|
|
16254
|
+
* `TranslatePipe` as params rather than spliced into the key, so the message
|
|
16255
|
+
* still resolves per language. Empty is a message with no slots, which is
|
|
16256
|
+
* every confirmation drawn before this.
|
|
16257
|
+
*/
|
|
16258
|
+
params = input({}, ...(ngDevMode ? [{ debugName: "params" }] : /* istanbul ignore next */ []));
|
|
16072
16259
|
type = input('info', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
16260
|
+
/**
|
|
16261
|
+
* Whether the question can be refused. `yes` is an acknowledgement — the one
|
|
16262
|
+
* button commits and there is nothing else to press — and stays the default,
|
|
16263
|
+
* which is what every ConfirmComponent drawn before this was.
|
|
16264
|
+
*/
|
|
16265
|
+
kind = input('yes', ...(ngDevMode ? [{ debugName: "kind" }] : /* istanbul ignore next */ []));
|
|
16266
|
+
/**
|
|
16267
|
+
* The wording of each button, as a TranslationAsset key. Empty falls back to
|
|
16268
|
+
* the library's own — derived from `type` for the commit, `cancel` for the
|
|
16269
|
+
* refusal — so a caller that has nothing to say about the buttons says
|
|
16270
|
+
* nothing.
|
|
16271
|
+
*/
|
|
16272
|
+
confirmLabel = input('', ...(ngDevMode ? [{ debugName: "confirmLabel" }] : /* istanbul ignore next */ []));
|
|
16273
|
+
cancelLabel = input('', ...(ngDevMode ? [{ debugName: "cancelLabel" }] : /* istanbul ignore next */ []));
|
|
16073
16274
|
#modalRef = inject(MODAL_REF);
|
|
16074
|
-
|
|
16275
|
+
confirmText = computed(() => {
|
|
16276
|
+
if (this.confirmLabel())
|
|
16277
|
+
return this.confirmLabel();
|
|
16075
16278
|
switch (this.type()) {
|
|
16076
16279
|
case 'danger':
|
|
16077
16280
|
return 'delete';
|
|
16078
16281
|
default:
|
|
16079
16282
|
return 'okay';
|
|
16080
16283
|
}
|
|
16081
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
16284
|
+
}, ...(ngDevMode ? [{ debugName: "confirmText" }] : /* istanbul ignore next */ []));
|
|
16285
|
+
cancelText = computed(() => this.cancelLabel() || 'cancel', ...(ngDevMode ? [{ debugName: "cancelText" }] : /* istanbul ignore next */ []));
|
|
16082
16286
|
iconName = computed(() => {
|
|
16083
16287
|
switch (this.type()) {
|
|
16084
16288
|
case 'danger':
|
|
@@ -16094,26 +16298,39 @@ class ConfirmComponent {
|
|
|
16094
16298
|
accept() {
|
|
16095
16299
|
this.#modalRef.close(true);
|
|
16096
16300
|
}
|
|
16301
|
+
// The refusal is a result like any other, so it closes with `false` rather
|
|
16302
|
+
// than dismissing: a caller waiting on the answer gets one either way.
|
|
16303
|
+
decline() {
|
|
16304
|
+
this.#modalRef.close(false);
|
|
16305
|
+
}
|
|
16097
16306
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ConfirmComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
16098
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ConfirmComponent, isStandalone: true, selector: "m-confirm", inputs: { header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, body: { classPropertyName: "body", publicName: "body", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
16307
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ConfirmComponent, isStandalone: true, selector: "m-confirm", inputs: { header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, body: { classPropertyName: "body", publicName: "body", isSignal: true, isRequired: false, transformFunction: null }, params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, kind: { classPropertyName: "kind", publicName: "kind", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
16099
16308
|
<div class="confirm confirm--{{ type() }}">
|
|
16100
16309
|
<div class="confirm__header">
|
|
16101
16310
|
<div class="confirm__icon">
|
|
16102
16311
|
<m-icon [name]="iconName()" />
|
|
16103
16312
|
</div>
|
|
16104
16313
|
@if (header()) {
|
|
16105
|
-
|
|
16314
|
+
<!-- The heading takes the key and its values rather than projected
|
|
16315
|
+
text: m-header translates its own label, and a MessageVariable
|
|
16316
|
+
fills the same way it does everywhere else. -->
|
|
16317
|
+
<m-header [level]="3" [label]="header()" [params]="params()" />
|
|
16106
16318
|
}
|
|
16107
16319
|
</div>
|
|
16108
16320
|
|
|
16109
16321
|
<div class="confirm__content">
|
|
16110
16322
|
@if (body()) {
|
|
16111
|
-
<p class="confirm__body" [innerHTML]="body() | translate"></p>
|
|
16323
|
+
<p class="confirm__body" [innerHTML]="body() | translate: params()"></p>
|
|
16112
16324
|
}
|
|
16113
16325
|
</div>
|
|
16114
16326
|
|
|
16115
16327
|
<div class="confirm__actions">
|
|
16116
|
-
|
|
16328
|
+
@if (kind() === 'yes-no') {
|
|
16329
|
+
<!-- asset: buttons/confirm_cancel.yml -->
|
|
16330
|
+
<m-one-button name="confirm_cancel" [label]="cancelText()" (clicked)="decline()" />
|
|
16331
|
+
}
|
|
16332
|
+
<!-- asset: buttons/okay.yml -->
|
|
16333
|
+
<m-one-button name="okay" [label]="confirmText()" (clicked)="accept()" />
|
|
16117
16334
|
</div>
|
|
16118
16335
|
</div>
|
|
16119
16336
|
`, isInline: true, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}.confirm{display:flex;flex-direction:column;min-width:320px;max-width:440px;padding:2.5rem;background:var(--m-backdrop-modal, rgba(255, 255, 255, .85));backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:0;position:relative;overflow:hidden}.confirm__header{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.9375rem;margin-bottom:1.5rem}.confirm__icon{width:64px;height:64px;border-radius:1.6rem;display:flex;align-items:center;justify-content:center;font-size:2rem;background:var(--m-backdrop-mm, rgba(65, 105, 225, .1));color:var(--m-mm, #4169e1)}.confirm__icon .m-icon{width:32px;height:32px}.confirm__title{margin:0;font-size:1.375rem;font-weight:700;color:var(--m-text-900);letter-spacing:-.02em}.confirm__content{text-align:center;margin-bottom:2rem}.confirm__body{margin:0;font-size:1rem;line-height:1.6;color:var(--m-text-600)}.confirm__actions{width:100%;margin-top:auto;display:flex;justify-content:center;gap:1rem}.confirm--danger .confirm__icon{background:var(--m-backdrop-error, rgba(235, 25, 26, .1));color:var(--m-error, #EB191A)}.confirm--warning .confirm__icon{background:var(--m-backdrop-warning, rgba(247, 122, 2, .1));color:var(--m-warning, #F77A02)}.confirm--success .confirm__icon{background:var(--m-backdrop-success, rgba(109, 168, 47, .1));color:var(--m-success, #6da82f)}.confirm--info .confirm__icon{background:var(--m-info-lite, rgba(3, 102, 214, .1));color:var(--m-info, #0366d6)}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "m-button,m-one-button", inputs: ["config", "color", "labelClass", "fullWidth", "nav", "navParams", "href", "disabled", "variant", "name", "baseUrl", "one", "remote", "label", "noTranslate", "params", "noNative", "icon", "isRightIcon", "iconOnly", "stacked", "imgSrc", "nonClickable", "inverted", "isSubmit", "tabindex"], outputs: ["configChange", "clicked"] }, { kind: "component", type: IconComponent, selector: "m-icon, m-one-icon", inputs: ["config", "name", "color", "size", "one", "baseUrl", "remote"], outputs: ["configChange"] }, { kind: "component", type: HeaderComponent$1, selector: "m-header", inputs: ["level", "label", "actionButton", "actionLabel", "noTranslate", "params"], outputs: ["actionClick"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
@@ -16127,22 +16344,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
16127
16344
|
<m-icon [name]="iconName()" />
|
|
16128
16345
|
</div>
|
|
16129
16346
|
@if (header()) {
|
|
16130
|
-
|
|
16347
|
+
<!-- The heading takes the key and its values rather than projected
|
|
16348
|
+
text: m-header translates its own label, and a MessageVariable
|
|
16349
|
+
fills the same way it does everywhere else. -->
|
|
16350
|
+
<m-header [level]="3" [label]="header()" [params]="params()" />
|
|
16131
16351
|
}
|
|
16132
16352
|
</div>
|
|
16133
16353
|
|
|
16134
16354
|
<div class="confirm__content">
|
|
16135
16355
|
@if (body()) {
|
|
16136
|
-
<p class="confirm__body" [innerHTML]="body() | translate"></p>
|
|
16356
|
+
<p class="confirm__body" [innerHTML]="body() | translate: params()"></p>
|
|
16137
16357
|
}
|
|
16138
16358
|
</div>
|
|
16139
16359
|
|
|
16140
16360
|
<div class="confirm__actions">
|
|
16141
|
-
|
|
16361
|
+
@if (kind() === 'yes-no') {
|
|
16362
|
+
<!-- asset: buttons/confirm_cancel.yml -->
|
|
16363
|
+
<m-one-button name="confirm_cancel" [label]="cancelText()" (clicked)="decline()" />
|
|
16364
|
+
}
|
|
16365
|
+
<!-- asset: buttons/okay.yml -->
|
|
16366
|
+
<m-one-button name="okay" [label]="confirmText()" (clicked)="accept()" />
|
|
16142
16367
|
</div>
|
|
16143
16368
|
</div>
|
|
16144
16369
|
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@keyframes toggle-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.02)}}@keyframes thumb-slide{0%{transform:translate(0) scale(1)}50%{transform:translate(.3em) scale(.9)}to{transform:translate(.6em) scale(1)}}.confirm{display:flex;flex-direction:column;min-width:320px;max-width:440px;padding:2.5rem;background:var(--m-backdrop-modal, rgba(255, 255, 255, .85));backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:0;position:relative;overflow:hidden}.confirm__header{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.9375rem;margin-bottom:1.5rem}.confirm__icon{width:64px;height:64px;border-radius:1.6rem;display:flex;align-items:center;justify-content:center;font-size:2rem;background:var(--m-backdrop-mm, rgba(65, 105, 225, .1));color:var(--m-mm, #4169e1)}.confirm__icon .m-icon{width:32px;height:32px}.confirm__title{margin:0;font-size:1.375rem;font-weight:700;color:var(--m-text-900);letter-spacing:-.02em}.confirm__content{text-align:center;margin-bottom:2rem}.confirm__body{margin:0;font-size:1rem;line-height:1.6;color:var(--m-text-600)}.confirm__actions{width:100%;margin-top:auto;display:flex;justify-content:center;gap:1rem}.confirm--danger .confirm__icon{background:var(--m-backdrop-error, rgba(235, 25, 26, .1));color:var(--m-error, #EB191A)}.confirm--warning .confirm__icon{background:var(--m-backdrop-warning, rgba(247, 122, 2, .1));color:var(--m-warning, #F77A02)}.confirm--success .confirm__icon{background:var(--m-backdrop-success, rgba(109, 168, 47, .1));color:var(--m-success, #6da82f)}.confirm--info .confirm__icon{background:var(--m-info-lite, rgba(3, 102, 214, .1));color:var(--m-info, #0366d6)}\n"] }]
|
|
16145
|
-
}], propDecorators: { header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], body: [{ type: i0.Input, args: [{ isSignal: true, alias: "body", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }] } });
|
|
16370
|
+
}], propDecorators: { header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], body: [{ type: i0.Input, args: [{ isSignal: true, alias: "body", required: false }] }], params: [{ type: i0.Input, args: [{ isSignal: true, alias: "params", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], kind: [{ type: i0.Input, args: [{ isSignal: true, alias: "kind", required: false }] }], confirmLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmLabel", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }] } });
|
|
16146
16371
|
|
|
16147
16372
|
function injectInstallApp() {
|
|
16148
16373
|
const modalStore = inject(ModalStore);
|
|
@@ -20062,7 +20287,7 @@ class WrapperInputComponent extends ConfigComponent {
|
|
|
20062
20287
|
break;
|
|
20063
20288
|
}
|
|
20064
20289
|
case InputType.TOGGLE: {
|
|
20065
|
-
const { ToggleInputComponent } = await import('./magmonium-one-toggle-
|
|
20290
|
+
const { ToggleInputComponent } = await import('./magmonium-one-toggle-wEeMiUQz.mjs');
|
|
20066
20291
|
this.createDynamicComponent(seq, ToggleInputComponent, [], true);
|
|
20067
20292
|
break;
|
|
20068
20293
|
}
|
|
@@ -20074,12 +20299,12 @@ class WrapperInputComponent extends ConfigComponent {
|
|
|
20074
20299
|
break;
|
|
20075
20300
|
}
|
|
20076
20301
|
case InputType.PASSWORD: {
|
|
20077
|
-
const { PasswordInputComponent } = await import('./magmonium-one-password-
|
|
20302
|
+
const { PasswordInputComponent } = await import('./magmonium-one-password-DmEMAVca.mjs');
|
|
20078
20303
|
this.createDynamicComponent(seq, PasswordInputComponent);
|
|
20079
20304
|
break;
|
|
20080
20305
|
}
|
|
20081
20306
|
case InputType.OTP: {
|
|
20082
|
-
const { OtpInputComponent } = await import('./magmonium-one-otp-
|
|
20307
|
+
const { OtpInputComponent } = await import('./magmonium-one-otp-JmUyDNPb.mjs');
|
|
20083
20308
|
this.createDynamicComponent(seq, OtpInputComponent);
|
|
20084
20309
|
break;
|
|
20085
20310
|
}
|
|
@@ -34298,5 +34523,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
34298
34523
|
* Generated bundle index. Do not edit.
|
|
34299
34524
|
*/
|
|
34300
34525
|
|
|
34301
|
-
export {
|
|
34302
|
-
//# sourceMappingURL=magmonium-one-magmonium-one-
|
|
34526
|
+
export { DEFAULT_NAV_PARAM as $, ACCESS_DOMAINS as A, BaseInputComponent as B, COMPONENT_INPUT_REGISTRY as C, CardComponent as D, CardWrapperComponent as E, CarouselComponent as F, ChartComponent as G, CheckboxInputComponent as H, IS_DESIGN_MODE as I, ClearableInputComponent as J, ColComponent as K, LabelComponent as L, ColorPickerInputComponent as M, CommentItemComponent as N, CommentsApiService as O, CommentsComponent as P, CommentsStore as Q, ComponentInputComponent as R, ComponentStepperComponent as S, TranslatePipe as T, ConfigComponent as U, ConfirmComponent as V, ContextMenuComponent as W, CustomIconClass as X, CustomIconEditComponent as Y, DEFAULT_FILTER_RANGE_MODE as Z, DEFAULT_FILTER_VARIANT as _, BaseTextInputComponent as a, NAV_DEFAULT_MURL as a$, DEFAULT_NAV_SEGMENT as a0, DEFAULT_SIZE as a1, DashboardCardComponent as a2, DateInputComponent as a3, DatePickerComponent as a4, DeviceService as a5, DomService as a6, Domain as a7, DotGridComponent as a8, DragListDirective as a9, InputType as aA, InstrumentScoreComponent as aB, InterceptorObservables as aC, JumbotronComponent as aD, KeyValueComponent as aE, LAYOUT_ASSET_FOLDER as aF, LOGIN_COMPONENT as aG, LOGIN_STORE as aH, LanguageComponent as aI, LogoComponent as aJ, MAG_SOCKET_EVENT as aK, MHeroColorDirective as aL, MHeroComponent as aM, MODAL_REF as aN, MODAL_STORE_REF as aO, MRefDirective as aP, MStepComponent as aQ, MURL_PARAM as aR, MURL_SEP as aS, ManifestEnrichmentService as aT, MenuComponent as aU, ModalDirective as aV, ModalRef as aW, ModalStore as aX, MoneyPipe as aY, MultiRangeInputComponent as aZ, MurlUrlSerializer as a_, DragListItemDirective as aa, DraggableDirective as ab, DropdownInputComponent as ac, FILTER_GROUP_CONTEXT as ad, FILTER_RANGE_MODES as ae, FILTER_VARIANTS as af, FLEX_VARIANTS as ag, FOLDER_PICK_LISTENER as ah, FORM_ASSET_FOLDER as ai, FileService as aj, FileUploadDirective as ak, FileUploadInputComponent as al, FlexComponent as am, FlexItemComponent as an, FormGroupComponent as ao, FrameComponent as ap, FreezeService as aq, GRID_BREAKPOINTS as ar, GetNavService as as, HeaderComponent$1 as at, HighlightDirective as au, HttpService as av, ICON_SOURCE as aw, IS_SIDE_PANEL as ax, IconComponent as ay, ImgComponent as az, TextOutputComponent as b, SectionBackComponent as b$, NAV_ID_SEP as b0, NAV_MAIN_BUTTONS as b1, NAV_SEGMENT_RE as b2, NAV_STORE_REF as b3, NAV_WC_COMPONENTS as b4, NAV_WIDGET_MAP as b5, NavComponent as b6, NavDetailsComponent as b7, NavHeaderComponent as b8, NavMenuComponent as b9, PositionDirective as bA, PwaInstallComponent as bB, ROOT_NAV$1 as bC, RadioGroupComponent as bD, RadioInputComponent as bE, RangeInputComponent as bF, RatingInputComponent as bG, ReactiveElementComponent as bH, RemoteComponent as bI, RemoteLoaderService as bJ, ResizeElementComponent as bK, RouteContainer as bL, RowComponent as bM, SEARCH_QUERY as bN, SEARCH_RESULTS_EVENT as bO, SECTION_ACCORDION_GROUP as bP, SECTION_FORM_CONTEXT as bQ, SHARED_ICONS as bR, SIZE_CONTEXT as bS, ScoreComponent as bT, ScrollComponent as bU, ScrollService as bV, SearchPanelComponent as bW, SearchStore as bX, SearchUserPanelComponent as bY, SectionAccordionDirective as bZ, SectionAccordionGroupDirective as b_, NavStore as ba, NavTrailComponent as bb, NothingComponent as bc, NotificationElementComponent as bd, NotificationGroupComponent as be, NotificationPopupComponent as bf, NotificationService as bg, NotificationStore as bh, NotificationType as bi, NotificationWidgetComponent as bj, ONE_ASSET_BASE_URL as bk, OPTIONS_SOURCE as bl, OVERLAY_WIDGETS as bm, OneApp as bn, OptionsSourceDirective as bo, OverlayBodyComponent as bp, OverlayRef as bq, OverlayService as br, PLATFORM_BUTTON_NAV_IDS as bs, PLATFORM_EXTENSIBLE_NAV_IDS as bt, PLATFORM_NAV_MAP as bu, PLATFORM_ROOT_CHILDREN as bv, PaginationComponent as bw, PanelComponent as bx, PercentagePipe as by, PlaygroundComponent as bz, ButtonComponent as c, USER_TAB_MAP as c$, SectionBadgesComponent as c0, SectionButtonGroupComponent as c1, SectionCardComponent as c2, SectionCarouselComponent as c3, SectionComponent as c4, SectionFilterComponent as c5, SectionFilterGroupComponent as c6, SectionFilterMenuComponent as c7, SectionFilterPanelComponent as c8, SectionFilterRangePanelComponent as c9, StrokeLinecap as cA, StrokeLinejoin as cB, SummaryComponent as cC, SvgGeneratorComponent as cD, SvgGeneratorService as cE, SvgService as cF, TOTAL_COLUMNS as cG, TRANSLATION_SOURCE as cH, TableComponent as cI, TechnicalMeterComponent as cJ, TextInputComponent as cK, TextareaInputComponent as cL, ThemeComponent as cM, ThemeDataService as cN, ThemeService as cO, ThemeStore as cP, TimeAgoPipe as cQ, TimelineComponent as cR, ToggleButtonComponent as cS, ToggleInputComponent as cT, ToggleRadioInputComponent as cU, ToolTipDirective as cV, TooltipComponent as cW, TranslateService as cX, TreeGridComponent as cY, URL_SEP as cZ, USER_STORE_REF as c_, SectionFooterComponent as ca, SectionFormComponent as cb, SectionFormItemComponent as cc, SectionHeaderComponent as cd, SectionHeroComponent as ce, SectionPaginationComponent as cf, SectionSearchComponent as cg, SectionStepperComponent as ch, SectionTabsComponent as ci, SectionToggleComponent as cj, SectionToggleItemDirective as ck, SelectableCardInputComponent as cl, SelectorDirective as cm, SettingsSearchBarComponent as cn, SettingsSearchService as co, ShapeComponent as cp, SharedStoreRegistry as cq, SidePanelDirective as cr, Size as cs, SocketStore as ct, SortComponent as cu, StatComponent as cv, StepComponent as cw, StepperComponent as cx, StepsComponent as cy, StorageService as cz, APP_CONTEXT_REF as d, hasErrorComputed as d$, UlComponent as d0, UniverseComponent as d1, UserApiService as d2, UserAvatarComponent as d3, UserComponent as d4, UserNavComponent as d5, UserSettingsComponent as d6, UserStore as d7, WC_ROUTE_CHANGED_EVENT as d8, WC_SEARCH_GROUPS as d9, emailValidation as dA, evaluate as dB, evaluateBool as dC, filterHoldsList as dD, filterHoldsOneBound as dE, filterHoldsOptions as dF, filterHoldsRange as dG, filterList as dH, filterOne as dI, filterPanelOf as dJ, filterPanelWidth as dK, filterRange as dL, filterTreeGridRows as dM, filterValueList as dN, filterValues as dO, flattenTreeGridRows as dP, formatBadgeCount as dQ, fullName as dR, generateClipPath as dS, generateTransform as dT, getClassList as dU, getProperty as dV, getScrollParent as dW, getTierFromPreviewPath as dX, getTreeGridRow as dY, getUniqueId as dZ, getValue as d_, WIN_USER_TAB_HOOK as da, WIN_USER_TAB_KEY as db, WatermarkComponent as dc, WcRouterStore as dd, WrapperInputComponent as de, anchorNavId as df, applyColorsToElement as dg, bootstrapMagApp as dh, bootstrapPwaInstall as di, buildWcBaseUrl as dj, calculateLuminance as dk, calculateRanks as dl, cellText as dm, checkFilterCondition as dn, childNavId as dp, classListSignal as dq, coerceSize as dr, cornerEdge as ds, cornerSide as dt, createMap as du, createPlatformNavMap as dv, deriveAvatarGradient as dw, deriveContrastColor as dx, deriveOppositeColor as dy, derivePropertyName as dz, ASSET_BASE_URL as e, provideNavWidgets as e$, hexToRgb as e0, hslToRgb$1 as e1, initMagmoniumApp as e2, initialNotificationState as e3, initialState$2 as e4, initials as e5, injectAuthenticate as e6, injectInstallApp as e7, injectParentSize as e8, injectScrollSticky as e9, mergeUniqueWith as eA, minAgeValidation as eB, minLengthValidation as eC, minValidation as eD, miniMarkToHtml as eE, navIdChain as eF, navIdFor as eG, navIdSegment as eH, navIdToRoutePath as eI, navIdToSegments as eJ, navParamOf as eK, navToId as eL, parentNavId as eM, parseAddress as eN, parseColor as eO, parsePatternNames as eP, patternValidation as eQ, patternsValidation as eR, platformNavWidgets as eS, privateGuard as eT, processImageToSvg as eU, provideAppContext as eV, provideMagAppConfig as eW, provideMagWcConfig as eX, provideMagWcRoutes as eY, provideModalComponents as eZ, provideMurlUrlSerializer as e_, isButtonName as ea, isCancelledComputed as eb, isExtensiblePlatformNavId as ec, isJson as ed, isLoadingComputed as ee, isLocalhost as ef, isNavMenuConfig as eg, isNavRowsConfig as eh, isPlatformNavId as ei, isSize as ej, isTierPreview as ek, isUrlLocalhost as el, isValidNavId as em, isValidNavSegment as en, isWebComponent as eo, linkToId as ep, linkToNav as eq, loadingActions as er, mInterceptor as es, manualValidation as et, matchFieldValidation as eu, maxLengthValidation as ev, maxValidation as ew, mergePlatformNav as ex, mergeUnique as ey, mergeUniqueBy as ez, AccordionBodyDirective as f, provideOverlayWidgets as f0, providePlatformNavWidgets as f1, provideSearch as f2, provideSizeContext as f3, provideUserTabs as f4, publicGuard as f5, readFieldPatterns as f6, renderAddress as f7, requiredValidation as f8, resolveConfigAsset as f9, resolveIconSize as fa, resolvePallet as fb, resolvePatternRules as fc, resolveSize as fd, rgbToHex as fe, rgbToHsl as ff, rowHasChildren as fg, samePatterns as fh, segmentsToNavId as fi, setProperty as fj, setTreeGridChildren as fk, settingsWidgets as fl, shouldShowBadge as fm, splitNavId as fn, splitOnMatch as fo, stringToColor as fp, toAttrBool as fq, toAttrNumber as fr, toCssLength as fs, toHostNavId as ft, toLength$1 as fu, toLocalNavId as fv, toggleTreeGridRow as fw, unfetchedPlatformNav as fx, urlValidation as fy, AccordionComponent as g, AccordionGroupComponent as h, ActionComponent as i, AnimatedGraphsComponent as j, AppCardComponent as k, AppRelationType as l, AppTileComponent as m, AssetStore as n, AssetUrlPipe as o, Assets as p, AuthActivityPageComponent as q, AuthApiService as r, AuthStore as s, AutosizeDirective as t, BadgeComponent as u, BandingComponent as v, BaseArrayInputComponent as w, BaseRootWebComponent as x, BaseWebComponent as y, ButtonGroupComponent as z };
|
|
34527
|
+
//# sourceMappingURL=magmonium-one-magmonium-one-BOkBE_Fl.mjs.map
|