@atlasauth/angular 0.1.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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/LICENSE +21 -0
  4. package/dist/README.md +195 -0
  5. package/dist/esm2022/atlasauth-angular.mjs +5 -0
  6. package/dist/esm2022/lib/appearance.mjs +92 -0
  7. package/dist/esm2022/lib/atlas.config.mjs +8 -0
  8. package/dist/esm2022/lib/atlas.service.mjs +329 -0
  9. package/dist/esm2022/lib/atlas.ui.mjs +36 -0
  10. package/dist/esm2022/lib/components/attempt-flow.component.mjs +180 -0
  11. package/dist/esm2022/lib/components/flow-controller.mjs +88 -0
  12. package/dist/esm2022/lib/components/organization-profile.component.mjs +56 -0
  13. package/dist/esm2022/lib/components/organization-switcher.component.mjs +63 -0
  14. package/dist/esm2022/lib/components/sign-in.component.mjs +59 -0
  15. package/dist/esm2022/lib/components/sign-up.component.mjs +54 -0
  16. package/dist/esm2022/lib/components/user-button.component.mjs +94 -0
  17. package/dist/esm2022/lib/components/user-profile.component.mjs +81 -0
  18. package/dist/esm2022/lib/directives/atlas-root.directive.mjs +42 -0
  19. package/dist/esm2022/lib/directives/loaded.directive.mjs +23 -0
  20. package/dist/esm2022/lib/directives/loading.directive.mjs +23 -0
  21. package/dist/esm2022/lib/directives/protect.directive.mjs +82 -0
  22. package/dist/esm2022/lib/directives/signed-in.directive.mjs +29 -0
  23. package/dist/esm2022/lib/directives/signed-out.directive.mjs +29 -0
  24. package/dist/esm2022/lib/directives/toggle.directive.mjs +42 -0
  25. package/dist/esm2022/lib/fapi.mjs +9 -0
  26. package/dist/esm2022/lib/guards/atlas.guard.mjs +54 -0
  27. package/dist/esm2022/lib/i18n.mjs +78 -0
  28. package/dist/esm2022/lib/protect.mjs +9 -0
  29. package/dist/esm2022/lib/provide-atlas.mjs +85 -0
  30. package/dist/esm2022/lib/types.mjs +6 -0
  31. package/dist/esm2022/public-api.mjs +35 -0
  32. package/dist/fesm2022/atlasauth-angular.mjs +1557 -0
  33. package/dist/fesm2022/atlasauth-angular.mjs.map +1 -0
  34. package/dist/index.d.ts +5 -0
  35. package/dist/lib/appearance.d.ts +85 -0
  36. package/dist/lib/atlas.config.d.ts +31 -0
  37. package/dist/lib/atlas.service.d.ts +127 -0
  38. package/dist/lib/atlas.ui.d.ts +22 -0
  39. package/dist/lib/components/attempt-flow.component.d.ts +48 -0
  40. package/dist/lib/components/flow-controller.d.ts +34 -0
  41. package/dist/lib/components/organization-profile.component.d.ts +16 -0
  42. package/dist/lib/components/organization-switcher.component.d.ts +15 -0
  43. package/dist/lib/components/sign-in.component.d.ts +21 -0
  44. package/dist/lib/components/sign-up.component.d.ts +21 -0
  45. package/dist/lib/components/user-button.component.d.ts +19 -0
  46. package/dist/lib/components/user-profile.component.d.ts +15 -0
  47. package/dist/lib/directives/atlas-root.directive.d.ts +26 -0
  48. package/dist/lib/directives/loaded.directive.d.ts +13 -0
  49. package/dist/lib/directives/loading.directive.d.ts +12 -0
  50. package/dist/lib/directives/protect.directive.d.ts +41 -0
  51. package/dist/lib/directives/signed-in.directive.d.ts +17 -0
  52. package/dist/lib/directives/signed-out.directive.d.ts +17 -0
  53. package/dist/lib/directives/toggle.directive.d.ts +25 -0
  54. package/dist/lib/fapi.d.ts +8 -0
  55. package/dist/lib/guards/atlas.guard.d.ts +43 -0
  56. package/dist/lib/i18n.d.ts +23 -0
  57. package/dist/lib/protect.d.ts +8 -0
  58. package/dist/lib/provide-atlas.d.ts +46 -0
  59. package/dist/lib/types.d.ts +48 -0
  60. package/dist/public-api.d.ts +28 -0
  61. package/package.json +58 -0
@@ -0,0 +1,88 @@
1
+ import { signal } from '@angular/core';
2
+ import { advance, flowFromPending, initialFlow, pollAttempt, shouldKeepPolling, } from '@atlasauth/js';
3
+ /**
4
+ * The server-driven sign-in / sign-up engine, shared by `<atlas-sign-in>` and
5
+ * `<atlas-sign-up>` — the Angular counterpart of React's `useFlow` hook.
6
+ *
7
+ * It owns no decision about what comes next: every status comes back from the
8
+ * server via `advance`, and this controller only posts whatever the current step
9
+ * needs and re-renders the returned status. State lives in a signal so templates
10
+ * update whether the app runs zoned or zoneless.
11
+ */
12
+ export class AtlasFlowController {
13
+ client;
14
+ reload;
15
+ state;
16
+ pollTimer = null;
17
+ constructor(client, reload, pending) {
18
+ this.client = client;
19
+ this.reload = reload;
20
+ // Seeded from a redirect that came back mid-flow (e.g. OAuth needing a second
21
+ // factor) so the user resumes at the demanded step instead of starting over.
22
+ this.state = signal(pending ? flowFromPending(pending) : initialFlow);
23
+ }
24
+ /**
25
+ * Advance the flow with the values the user typed. On completion, exchange the
26
+ * one-time ticket for cookies over a same-origin request (FAPI is cross-origin
27
+ * and cannot set the cookie on its own response), then re-boot so the rest of
28
+ * the app sees a signed-in user.
29
+ */
30
+ async submit(values) {
31
+ this.state.update((current) => ({ ...current, busy: true, errors: [] }));
32
+ const next = await advance(this.client, this.state(), values);
33
+ this.state.set(next);
34
+ if (next.attempt?.status === 'complete') {
35
+ if (next.ticket) {
36
+ await this.client.post('/v1/client/tickets/exchange', {
37
+ attempt_id: next.attempt.id,
38
+ ticket: next.ticket,
39
+ });
40
+ }
41
+ await this.reload();
42
+ }
43
+ else {
44
+ // A magic-link step may now be pollable (a link opened on another device).
45
+ this.syncPolling();
46
+ }
47
+ }
48
+ /** Start/stop the §5.3 magic-link poll to match the current state. */
49
+ syncPolling() {
50
+ if (shouldKeepPolling(this.state())) {
51
+ this.startPolling();
52
+ }
53
+ else {
54
+ this.stopPolling();
55
+ }
56
+ }
57
+ startPolling() {
58
+ if (this.pollTimer)
59
+ return;
60
+ this.pollTimer = setInterval(() => {
61
+ void (async () => {
62
+ const { state: next, ticket } = await pollAttempt(this.client, this.state());
63
+ this.state.set(next);
64
+ if (!ticket || !next.attempt)
65
+ return;
66
+ // The ticket is exchanged by a normal request, so no session token ever
67
+ // appears in a URL.
68
+ await this.client.post('/v1/client/tickets/exchange', {
69
+ attempt_id: next.attempt.id,
70
+ ticket,
71
+ });
72
+ await this.reload();
73
+ this.stopPolling();
74
+ })();
75
+ }, 2_000);
76
+ }
77
+ stopPolling() {
78
+ if (this.pollTimer) {
79
+ clearInterval(this.pollTimer);
80
+ this.pollTimer = null;
81
+ }
82
+ }
83
+ /** Release the poll timer — call from the component's `ngOnDestroy`. */
84
+ destroy() {
85
+ this.stopPolling();
86
+ }
87
+ }
88
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvdy1jb250cm9sbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL2Zsb3ctY29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWtCLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RCxPQUFPLEVBRUwsT0FBTyxFQUNQLGVBQWUsRUFDZixXQUFXLEVBQ1gsV0FBVyxFQUNYLGlCQUFpQixHQUVsQixNQUFNLGVBQWUsQ0FBQztBQUV2Qjs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sT0FBTyxtQkFBbUI7SUFLWDtJQUNBO0lBTFYsS0FBSyxDQUE0QjtJQUNsQyxTQUFTLEdBQTBDLElBQUksQ0FBQztJQUVoRSxZQUNtQixNQUFrQixFQUNsQixNQUEyQixFQUM1QyxPQUE4QztRQUY3QixXQUFNLEdBQU4sTUFBTSxDQUFZO1FBQ2xCLFdBQU0sR0FBTixNQUFNLENBQXFCO1FBRzVDLDhFQUE4RTtRQUM5RSw2RUFBNkU7UUFDN0UsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQVksT0FBTyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ25GLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBOEI7UUFDekMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFekUsTUFBTSxJQUFJLEdBQUcsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFckIsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUN4QyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDaEIsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsRUFBRTtvQkFDcEQsVUFBVSxFQUFHLElBQUksQ0FBQyxPQUEyQixDQUFDLEVBQUU7b0JBQ2hELE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtpQkFDcEIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELE1BQU0sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3RCLENBQUM7YUFBTSxDQUFDO1lBQ04sMkVBQTJFO1lBQzNFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyQixDQUFDO0lBQ0gsQ0FBQztJQUVELHNFQUFzRTtJQUN0RSxXQUFXO1FBQ1QsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3BDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN0QixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyQixDQUFDO0lBQ0gsQ0FBQztJQUVPLFlBQVk7UUFDbEIsSUFBSSxJQUFJLENBQUMsU0FBUztZQUFFLE9BQU87UUFDM0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1lBQ2hDLEtBQUssQ0FBQyxLQUFLLElBQUksRUFBRTtnQkFDZixNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUM3RSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDckIsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO29CQUFFLE9BQU87Z0JBRXJDLHdFQUF3RTtnQkFDeEUsb0JBQW9CO2dCQUNwQixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixFQUFFO29CQUNwRCxVQUFVLEVBQUcsSUFBSSxDQUFDLE9BQTJCLENBQUMsRUFBRTtvQkFDaEQsTUFBTTtpQkFDUCxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3BCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ1AsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ1osQ0FBQztJQUVPLFdBQVc7UUFDakIsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM5QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUVELHdFQUF3RTtJQUN4RSxPQUFPO1FBQ0wsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdyaXRhYmxlU2lnbmFsLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEZhcGlDbGllbnQsXG4gIGFkdmFuY2UsXG4gIGZsb3dGcm9tUGVuZGluZyxcbiAgaW5pdGlhbEZsb3csXG4gIHBvbGxBdHRlbXB0LFxuICBzaG91bGRLZWVwUG9sbGluZyxcbiAgdHlwZSBGbG93U3RhdGUsXG59IGZyb20gJ0BhdGxhc2F1dGgvanMnO1xuXG4vKipcbiAqIFRoZSBzZXJ2ZXItZHJpdmVuIHNpZ24taW4gLyBzaWduLXVwIGVuZ2luZSwgc2hhcmVkIGJ5IGA8YXRsYXMtc2lnbi1pbj5gIGFuZFxuICogYDxhdGxhcy1zaWduLXVwPmAg4oCUIHRoZSBBbmd1bGFyIGNvdW50ZXJwYXJ0IG9mIFJlYWN0J3MgYHVzZUZsb3dgIGhvb2suXG4gKlxuICogSXQgb3ducyBubyBkZWNpc2lvbiBhYm91dCB3aGF0IGNvbWVzIG5leHQ6IGV2ZXJ5IHN0YXR1cyBjb21lcyBiYWNrIGZyb20gdGhlXG4gKiBzZXJ2ZXIgdmlhIGBhZHZhbmNlYCwgYW5kIHRoaXMgY29udHJvbGxlciBvbmx5IHBvc3RzIHdoYXRldmVyIHRoZSBjdXJyZW50IHN0ZXBcbiAqIG5lZWRzIGFuZCByZS1yZW5kZXJzIHRoZSByZXR1cm5lZCBzdGF0dXMuIFN0YXRlIGxpdmVzIGluIGEgc2lnbmFsIHNvIHRlbXBsYXRlc1xuICogdXBkYXRlIHdoZXRoZXIgdGhlIGFwcCBydW5zIHpvbmVkIG9yIHpvbmVsZXNzLlxuICovXG5leHBvcnQgY2xhc3MgQXRsYXNGbG93Q29udHJvbGxlciB7XG4gIHJlYWRvbmx5IHN0YXRlOiBXcml0YWJsZVNpZ25hbDxGbG93U3RhdGU+O1xuICBwcml2YXRlIHBvbGxUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IEZhcGlDbGllbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSByZWxvYWQ6ICgpID0+IFByb21pc2U8dm9pZD4sXG4gICAgcGVuZGluZzogeyBpZDogc3RyaW5nOyBzdGF0dXM6IHN0cmluZyB9IHwgbnVsbCxcbiAgKSB7XG4gICAgLy8gU2VlZGVkIGZyb20gYSByZWRpcmVjdCB0aGF0IGNhbWUgYmFjayBtaWQtZmxvdyAoZS5nLiBPQXV0aCBuZWVkaW5nIGEgc2Vjb25kXG4gICAgLy8gZmFjdG9yKSBzbyB0aGUgdXNlciByZXN1bWVzIGF0IHRoZSBkZW1hbmRlZCBzdGVwIGluc3RlYWQgb2Ygc3RhcnRpbmcgb3Zlci5cbiAgICB0aGlzLnN0YXRlID0gc2lnbmFsPEZsb3dTdGF0ZT4ocGVuZGluZyA/IGZsb3dGcm9tUGVuZGluZyhwZW5kaW5nKSA6IGluaXRpYWxGbG93KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZHZhbmNlIHRoZSBmbG93IHdpdGggdGhlIHZhbHVlcyB0aGUgdXNlciB0eXBlZC4gT24gY29tcGxldGlvbiwgZXhjaGFuZ2UgdGhlXG4gICAqIG9uZS10aW1lIHRpY2tldCBmb3IgY29va2llcyBvdmVyIGEgc2FtZS1vcmlnaW4gcmVxdWVzdCAoRkFQSSBpcyBjcm9zcy1vcmlnaW5cbiAgICogYW5kIGNhbm5vdCBzZXQgdGhlIGNvb2tpZSBvbiBpdHMgb3duIHJlc3BvbnNlKSwgdGhlbiByZS1ib290IHNvIHRoZSByZXN0IG9mXG4gICAqIHRoZSBhcHAgc2VlcyBhIHNpZ25lZC1pbiB1c2VyLlxuICAgKi9cbiAgYXN5bmMgc3VibWl0KHZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPik6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc3RhdGUudXBkYXRlKChjdXJyZW50KSA9PiAoeyAuLi5jdXJyZW50LCBidXN5OiB0cnVlLCBlcnJvcnM6IFtdIH0pKTtcblxuICAgIGNvbnN0IG5leHQgPSBhd2FpdCBhZHZhbmNlKHRoaXMuY2xpZW50LCB0aGlzLnN0YXRlKCksIHZhbHVlcyk7XG4gICAgdGhpcy5zdGF0ZS5zZXQobmV4dCk7XG5cbiAgICBpZiAobmV4dC5hdHRlbXB0Py5zdGF0dXMgPT09ICdjb21wbGV0ZScpIHtcbiAgICAgIGlmIChuZXh0LnRpY2tldCkge1xuICAgICAgICBhd2FpdCB0aGlzLmNsaWVudC5wb3N0KCcvdjEvY2xpZW50L3RpY2tldHMvZXhjaGFuZ2UnLCB7XG4gICAgICAgICAgYXR0ZW1wdF9pZDogKG5leHQuYXR0ZW1wdCBhcyB7IGlkPzogc3RyaW5nIH0pLmlkLFxuICAgICAgICAgIHRpY2tldDogbmV4dC50aWNrZXQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5yZWxvYWQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQSBtYWdpYy1saW5rIHN0ZXAgbWF5IG5vdyBiZSBwb2xsYWJsZSAoYSBsaW5rIG9wZW5lZCBvbiBhbm90aGVyIGRldmljZSkuXG4gICAgICB0aGlzLnN5bmNQb2xsaW5nKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFN0YXJ0L3N0b3AgdGhlIMKnNS4zIG1hZ2ljLWxpbmsgcG9sbCB0byBtYXRjaCB0aGUgY3VycmVudCBzdGF0ZS4gKi9cbiAgc3luY1BvbGxpbmcoKTogdm9pZCB7XG4gICAgaWYgKHNob3VsZEtlZXBQb2xsaW5nKHRoaXMuc3RhdGUoKSkpIHtcbiAgICAgIHRoaXMuc3RhcnRQb2xsaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RvcFBvbGxpbmcoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0UG9sbGluZygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5wb2xsVGltZXIpIHJldHVybjtcbiAgICB0aGlzLnBvbGxUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIHZvaWQgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgeyBzdGF0ZTogbmV4dCwgdGlja2V0IH0gPSBhd2FpdCBwb2xsQXR0ZW1wdCh0aGlzLmNsaWVudCwgdGhpcy5zdGF0ZSgpKTtcbiAgICAgICAgdGhpcy5zdGF0ZS5zZXQobmV4dCk7XG4gICAgICAgIGlmICghdGlja2V0IHx8ICFuZXh0LmF0dGVtcHQpIHJldHVybjtcblxuICAgICAgICAvLyBUaGUgdGlja2V0IGlzIGV4Y2hhbmdlZCBieSBhIG5vcm1hbCByZXF1ZXN0LCBzbyBubyBzZXNzaW9uIHRva2VuIGV2ZXJcbiAgICAgICAgLy8gYXBwZWFycyBpbiBhIFVSTC5cbiAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQucG9zdCgnL3YxL2NsaWVudC90aWNrZXRzL2V4Y2hhbmdlJywge1xuICAgICAgICAgIGF0dGVtcHRfaWQ6IChuZXh0LmF0dGVtcHQgYXMgeyBpZD86IHN0cmluZyB9KS5pZCxcbiAgICAgICAgICB0aWNrZXQsXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCB0aGlzLnJlbG9hZCgpO1xuICAgICAgICB0aGlzLnN0b3BQb2xsaW5nKCk7XG4gICAgICB9KSgpO1xuICAgIH0sIDJfMDAwKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcFBvbGxpbmcoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucG9sbFRpbWVyKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMucG9sbFRpbWVyKTtcbiAgICAgIHRoaXMucG9sbFRpbWVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKiogUmVsZWFzZSB0aGUgcG9sbCB0aW1lciDigJQgY2FsbCBmcm9tIHRoZSBjb21wb25lbnQncyBgbmdPbkRlc3Ryb3lgLiAqL1xuICBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3RvcFBvbGxpbmcoKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,56 @@
1
+ import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
2
+ import { AtlasService } from '../atlas.service';
3
+ import { AtlasProtectDirective } from '../directives/protect.directive';
4
+ import { classFor } from '../appearance';
5
+ import { translate } from '../i18n';
6
+ import * as i0 from "@angular/core";
7
+ /**
8
+ * `<atlas-organization-profile>` — the active organization's surface. The
9
+ * Angular peer of React's `<OrganizationProfile/>`. Management controls are
10
+ * gated on the ACTIVE org role via `*atlasProtect`, matching the server's rule
11
+ * rather than duplicating a looser one. Renders nothing with no active org.
12
+ */
13
+ export class OrganizationProfileComponent {
14
+ atlas = inject(AtlasService);
15
+ t(key) {
16
+ return translate(this.atlas.localization, key);
17
+ }
18
+ cls(key, base) {
19
+ return classFor(key, this.atlas.appearance, base);
20
+ }
21
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OrganizationProfileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: OrganizationProfileComponent, isStandalone: true, selector: "atlas-organization-profile", ngImport: i0, template: `
23
+ @if (atlas.organization(); as membership) {
24
+ <div [class]="cls('card', 'atlas-card')">
25
+ <h1>{{ membership.organization.name }}</h1>
26
+ <p>{{ t('organization.roleLabel') }}: {{ membership.role }}</p>
27
+
28
+ <button *atlasProtect="{ permission: 'org:sys_memberships:manage' }">
29
+ {{ t('organization.invite') }}
30
+ </button>
31
+ </div>
32
+ }
33
+ `, isInline: true, dependencies: [{ kind: "directive", type: AtlasProtectDirective, selector: "[atlasProtect]", inputs: ["atlasProtect", "atlasProtectElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34
+ }
35
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OrganizationProfileComponent, decorators: [{
36
+ type: Component,
37
+ args: [{
38
+ selector: 'atlas-organization-profile',
39
+ standalone: true,
40
+ changeDetection: ChangeDetectionStrategy.OnPush,
41
+ imports: [AtlasProtectDirective],
42
+ template: `
43
+ @if (atlas.organization(); as membership) {
44
+ <div [class]="cls('card', 'atlas-card')">
45
+ <h1>{{ membership.organization.name }}</h1>
46
+ <p>{{ t('organization.roleLabel') }}: {{ membership.role }}</p>
47
+
48
+ <button *atlasProtect="{ permission: 'org:sys_memberships:manage' }">
49
+ {{ t('organization.invite') }}
50
+ </button>
51
+ </div>
52
+ }
53
+ `,
54
+ }]
55
+ }] });
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnYW5pemF0aW9uLXByb2ZpbGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL29yZ2FuaXphdGlvbi1wcm9maWxlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDeEUsT0FBTyxFQUFFLFFBQVEsRUFBbUIsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7QUFFcEM7Ozs7O0dBS0c7QUFtQkgsTUFBTSxPQUFPLDRCQUE0QjtJQUNwQixLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXRDLENBQUMsQ0FBQyxHQUFXO1FBQ3JCLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFUyxHQUFHLENBQUMsR0FBZSxFQUFFLElBQVk7UUFDekMsT0FBTyxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3BELENBQUM7d0dBVFUsNEJBQTRCOzRGQUE1Qiw0QkFBNEIsc0ZBYjdCOzs7Ozs7Ozs7OztHQVdULDREQVpTLHFCQUFxQjs7NEZBY3BCLDRCQUE0QjtrQkFsQnhDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLDRCQUE0QjtvQkFDdEMsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxPQUFPLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQztvQkFDaEMsUUFBUSxFQUFFOzs7Ozs7Ozs7OztHQVdUO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBdGxhc1NlcnZpY2UgfSBmcm9tICcuLi9hdGxhcy5zZXJ2aWNlJztcbmltcG9ydCB7IEF0bGFzUHJvdGVjdERpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvcHJvdGVjdC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgY2xhc3NGb3IsIHR5cGUgRWxlbWVudEtleSB9IGZyb20gJy4uL2FwcGVhcmFuY2UnO1xuaW1wb3J0IHsgdHJhbnNsYXRlIH0gZnJvbSAnLi4vaTE4bic7XG5cbi8qKlxuICogYDxhdGxhcy1vcmdhbml6YXRpb24tcHJvZmlsZT5gIOKAlCB0aGUgYWN0aXZlIG9yZ2FuaXphdGlvbidzIHN1cmZhY2UuIFRoZVxuICogQW5ndWxhciBwZWVyIG9mIFJlYWN0J3MgYDxPcmdhbml6YXRpb25Qcm9maWxlLz5gLiBNYW5hZ2VtZW50IGNvbnRyb2xzIGFyZVxuICogZ2F0ZWQgb24gdGhlIEFDVElWRSBvcmcgcm9sZSB2aWEgYCphdGxhc1Byb3RlY3RgLCBtYXRjaGluZyB0aGUgc2VydmVyJ3MgcnVsZVxuICogcmF0aGVyIHRoYW4gZHVwbGljYXRpbmcgYSBsb29zZXIgb25lLiBSZW5kZXJzIG5vdGhpbmcgd2l0aCBubyBhY3RpdmUgb3JnLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdGxhcy1vcmdhbml6YXRpb24tcHJvZmlsZScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbQXRsYXNQcm90ZWN0RGlyZWN0aXZlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICBAaWYgKGF0bGFzLm9yZ2FuaXphdGlvbigpOyBhcyBtZW1iZXJzaGlwKSB7XG4gICAgICA8ZGl2IFtjbGFzc109XCJjbHMoJ2NhcmQnLCAnYXRsYXMtY2FyZCcpXCI+XG4gICAgICAgIDxoMT57eyBtZW1iZXJzaGlwLm9yZ2FuaXphdGlvbi5uYW1lIH19PC9oMT5cbiAgICAgICAgPHA+e3sgdCgnb3JnYW5pemF0aW9uLnJvbGVMYWJlbCcpIH19OiB7eyBtZW1iZXJzaGlwLnJvbGUgfX08L3A+XG5cbiAgICAgICAgPGJ1dHRvbiAqYXRsYXNQcm90ZWN0PVwieyBwZXJtaXNzaW9uOiAnb3JnOnN5c19tZW1iZXJzaGlwczptYW5hZ2UnIH1cIj5cbiAgICAgICAgICB7eyB0KCdvcmdhbml6YXRpb24uaW52aXRlJykgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIE9yZ2FuaXphdGlvblByb2ZpbGVDb21wb25lbnQge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYXRsYXMgPSBpbmplY3QoQXRsYXNTZXJ2aWNlKTtcblxuICBwcm90ZWN0ZWQgdChrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRyYW5zbGF0ZSh0aGlzLmF0bGFzLmxvY2FsaXphdGlvbiwga2V5KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjbHMoa2V5OiBFbGVtZW50S2V5LCBiYXNlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBjbGFzc0ZvcihrZXksIHRoaXMuYXRsYXMuYXBwZWFyYW5jZSwgYmFzZSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,63 @@
1
+ import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
2
+ import { AtlasService } from '../atlas.service';
3
+ import { classFor } from '../appearance';
4
+ import { translate } from '../i18n';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * `<atlas-organization-switcher>` — switch the active organization (or the
8
+ * personal account). The Angular peer of React's `<OrganizationSwitcher/>`.
9
+ */
10
+ export class OrganizationSwitcherComponent {
11
+ atlas = inject(AtlasService);
12
+ t(key) {
13
+ return translate(this.atlas.localization, key);
14
+ }
15
+ cls(key, base) {
16
+ return classFor(key, this.atlas.appearance, base);
17
+ }
18
+ setActive(organizationId) {
19
+ void this.atlas.setActiveOrganization(organizationId);
20
+ }
21
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OrganizationSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: OrganizationSwitcherComponent, isStandalone: true, selector: "atlas-organization-switcher", ngImport: i0, template: `
23
+ <div [class]="cls('menu', 'atlas-menu')">
24
+ <button [class]="cls('menuItem', 'atlas-menu-item')" (click)="setActive(null)">
25
+ {{ t('organization.personal') }}
26
+ </button>
27
+ @for (membership of atlas.memberships(); track membership.organization.id) {
28
+ <button
29
+ [class]="cls('menuItem', 'atlas-menu-item')"
30
+ [disabled]="membership.organization.id === atlas.organization()?.organization?.id"
31
+ (click)="setActive(membership.organization.id)"
32
+ >
33
+ {{ membership.organization.name }}
34
+ </button>
35
+ }
36
+ </div>
37
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
38
+ }
39
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OrganizationSwitcherComponent, decorators: [{
40
+ type: Component,
41
+ args: [{
42
+ selector: 'atlas-organization-switcher',
43
+ standalone: true,
44
+ changeDetection: ChangeDetectionStrategy.OnPush,
45
+ template: `
46
+ <div [class]="cls('menu', 'atlas-menu')">
47
+ <button [class]="cls('menuItem', 'atlas-menu-item')" (click)="setActive(null)">
48
+ {{ t('organization.personal') }}
49
+ </button>
50
+ @for (membership of atlas.memberships(); track membership.organization.id) {
51
+ <button
52
+ [class]="cls('menuItem', 'atlas-menu-item')"
53
+ [disabled]="membership.organization.id === atlas.organization()?.organization?.id"
54
+ (click)="setActive(membership.organization.id)"
55
+ >
56
+ {{ membership.organization.name }}
57
+ </button>
58
+ }
59
+ </div>
60
+ `,
61
+ }]
62
+ }] });
63
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnYW5pemF0aW9uLXN3aXRjaGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9vcmdhbml6YXRpb24tc3dpdGNoZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsUUFBUSxFQUFtQixNQUFNLGVBQWUsQ0FBQztBQUMxRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sU0FBUyxDQUFDOztBQUVwQzs7O0dBR0c7QUFzQkgsTUFBTSxPQUFPLDZCQUE2QjtJQUNyQixLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXRDLENBQUMsQ0FBQyxHQUFXO1FBQ3JCLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFUyxHQUFHLENBQUMsR0FBZSxFQUFFLElBQVk7UUFDekMsT0FBTyxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFUyxTQUFTLENBQUMsY0FBNkI7UUFDL0MsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3hELENBQUM7d0dBYlUsNkJBQTZCOzRGQUE3Qiw2QkFBNkIsdUZBakI5Qjs7Ozs7Ozs7Ozs7Ozs7O0dBZVQ7OzRGQUVVLDZCQUE2QjtrQkFyQnpDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLDZCQUE2QjtvQkFDdkMsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7OztHQWVUO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBdGxhc1NlcnZpY2UgfSBmcm9tICcuLi9hdGxhcy5zZXJ2aWNlJztcbmltcG9ydCB7IGNsYXNzRm9yLCB0eXBlIEVsZW1lbnRLZXkgfSBmcm9tICcuLi9hcHBlYXJhbmNlJztcbmltcG9ydCB7IHRyYW5zbGF0ZSB9IGZyb20gJy4uL2kxOG4nO1xuXG4vKipcbiAqIGA8YXRsYXMtb3JnYW5pemF0aW9uLXN3aXRjaGVyPmAg4oCUIHN3aXRjaCB0aGUgYWN0aXZlIG9yZ2FuaXphdGlvbiAob3IgdGhlXG4gKiBwZXJzb25hbCBhY2NvdW50KS4gVGhlIEFuZ3VsYXIgcGVlciBvZiBSZWFjdCdzIGA8T3JnYW5pemF0aW9uU3dpdGNoZXIvPmAuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2F0bGFzLW9yZ2FuaXphdGlvbi1zd2l0Y2hlcicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgW2NsYXNzXT1cImNscygnbWVudScsICdhdGxhcy1tZW51JylcIj5cbiAgICAgIDxidXR0b24gW2NsYXNzXT1cImNscygnbWVudUl0ZW0nLCAnYXRsYXMtbWVudS1pdGVtJylcIiAoY2xpY2spPVwic2V0QWN0aXZlKG51bGwpXCI+XG4gICAgICAgIHt7IHQoJ29yZ2FuaXphdGlvbi5wZXJzb25hbCcpIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIEBmb3IgKG1lbWJlcnNoaXAgb2YgYXRsYXMubWVtYmVyc2hpcHMoKTsgdHJhY2sgbWVtYmVyc2hpcC5vcmdhbml6YXRpb24uaWQpIHtcbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIFtjbGFzc109XCJjbHMoJ21lbnVJdGVtJywgJ2F0bGFzLW1lbnUtaXRlbScpXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwibWVtYmVyc2hpcC5vcmdhbml6YXRpb24uaWQgPT09IGF0bGFzLm9yZ2FuaXphdGlvbigpPy5vcmdhbml6YXRpb24/LmlkXCJcbiAgICAgICAgICAoY2xpY2spPVwic2V0QWN0aXZlKG1lbWJlcnNoaXAub3JnYW5pemF0aW9uLmlkKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBtZW1iZXJzaGlwLm9yZ2FuaXphdGlvbi5uYW1lIH19XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBPcmdhbml6YXRpb25Td2l0Y2hlckNvbXBvbmVudCB7XG4gIHByb3RlY3RlZCByZWFkb25seSBhdGxhcyA9IGluamVjdChBdGxhc1NlcnZpY2UpO1xuXG4gIHByb3RlY3RlZCB0KGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdHJhbnNsYXRlKHRoaXMuYXRsYXMubG9jYWxpemF0aW9uLCBrZXkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNscyhrZXk6IEVsZW1lbnRLZXksIGJhc2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNsYXNzRm9yKGtleSwgdGhpcy5hdGxhcy5hcHBlYXJhbmNlLCBiYXNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXRBY3RpdmUob3JnYW5pemF0aW9uSWQ6IHN0cmluZyB8IG51bGwpOiB2b2lkIHtcbiAgICB2b2lkIHRoaXMuYXRsYXMuc2V0QWN0aXZlT3JnYW5pemF0aW9uKG9yZ2FuaXphdGlvbklkKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,59 @@
1
+ import { ChangeDetectionStrategy, Component, Input, inject, } from '@angular/core';
2
+ import { AtlasService } from '../atlas.service';
3
+ import { AttemptFlowComponent } from './attempt-flow.component';
4
+ import { AtlasFlowController } from './flow-controller';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * `<atlas-sign-in>` — the full, multi-step sign-in flow driven entirely by the
8
+ * server-side attempt status. The Angular peer of React's `<SignIn/>`.
9
+ *
10
+ * ```html
11
+ * <atlas-sign-in *atlasSignedOut afterUrl="/dashboard"></atlas-sign-in>
12
+ * ```
13
+ */
14
+ export class SignInComponent {
15
+ atlas = inject(AtlasService);
16
+ /** Where to send the user once the flow completes. Reserved for host routing. */
17
+ afterUrl;
18
+ flow = new AtlasFlowController(this.atlas.createFapiClient(), () => this.atlas.reload(),
19
+ // Resume mid-flow if an OAuth redirect came back owing a second factor.
20
+ this.atlas.pendingAttempt);
21
+ ngOnInit() {
22
+ // If seeded from a pending attempt that is already pollable, start polling.
23
+ this.flow.syncPolling();
24
+ }
25
+ ngOnDestroy() {
26
+ this.flow.destroy();
27
+ }
28
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignInComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
29
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SignInComponent, isStandalone: true, selector: "atlas-sign-in", inputs: { afterUrl: "afterUrl" }, ngImport: i0, template: `
30
+ <atlas-attempt-flow
31
+ [attempt]="flow.state().attempt"
32
+ [busy]="flow.state().busy"
33
+ [errors]="flow.state().errors"
34
+ titleKey="signIn.title"
35
+ (submitFlow)="flow.submit($event)"
36
+ ></atlas-attempt-flow>
37
+ `, isInline: true, dependencies: [{ kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "titleKey"], outputs: ["submitFlow"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
38
+ }
39
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignInComponent, decorators: [{
40
+ type: Component,
41
+ args: [{
42
+ selector: 'atlas-sign-in',
43
+ standalone: true,
44
+ changeDetection: ChangeDetectionStrategy.OnPush,
45
+ imports: [AttemptFlowComponent],
46
+ template: `
47
+ <atlas-attempt-flow
48
+ [attempt]="flow.state().attempt"
49
+ [busy]="flow.state().busy"
50
+ [errors]="flow.state().errors"
51
+ titleKey="signIn.title"
52
+ (submitFlow)="flow.submit($event)"
53
+ ></atlas-attempt-flow>
54
+ `,
55
+ }]
56
+ }], propDecorators: { afterUrl: [{
57
+ type: Input
58
+ }] } });
59
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi1pbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvc2lnbi1pbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsS0FBSyxFQUdMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7O0FBRXhEOzs7Ozs7O0dBT0c7QUFnQkgsTUFBTSxPQUFPLGVBQWU7SUFDVCxLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRTlDLGlGQUFpRjtJQUN4RSxRQUFRLENBQVU7SUFFUixJQUFJLEdBQUcsSUFBSSxtQkFBbUIsQ0FDL0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxFQUM3QixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRTtJQUN6Qix3RUFBd0U7SUFDeEUsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQzFCLENBQUM7SUFFRixRQUFRO1FBQ04sNEVBQTRFO1FBQzVFLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3RCLENBQUM7d0dBcEJVLGVBQWU7NEZBQWYsZUFBZSwyR0FWaEI7Ozs7Ozs7O0dBUVQsNERBVFMsb0JBQW9COzs0RkFXbkIsZUFBZTtrQkFmM0IsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsZUFBZTtvQkFDekIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxPQUFPLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQztvQkFDL0IsUUFBUSxFQUFFOzs7Ozs7OztHQVFUO2lCQUNGOzhCQUtVLFFBQVE7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIGluamVjdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBdGxhc1NlcnZpY2UgfSBmcm9tICcuLi9hdGxhcy5zZXJ2aWNlJztcbmltcG9ydCB7IEF0dGVtcHRGbG93Q29tcG9uZW50IH0gZnJvbSAnLi9hdHRlbXB0LWZsb3cuY29tcG9uZW50JztcbmltcG9ydCB7IEF0bGFzRmxvd0NvbnRyb2xsZXIgfSBmcm9tICcuL2Zsb3ctY29udHJvbGxlcic7XG5cbi8qKlxuICogYDxhdGxhcy1zaWduLWluPmAg4oCUIHRoZSBmdWxsLCBtdWx0aS1zdGVwIHNpZ24taW4gZmxvdyBkcml2ZW4gZW50aXJlbHkgYnkgdGhlXG4gKiBzZXJ2ZXItc2lkZSBhdHRlbXB0IHN0YXR1cy4gVGhlIEFuZ3VsYXIgcGVlciBvZiBSZWFjdCdzIGA8U2lnbkluLz5gLlxuICpcbiAqIGBgYGh0bWxcbiAqIDxhdGxhcy1zaWduLWluICphdGxhc1NpZ25lZE91dCBhZnRlclVybD1cIi9kYXNoYm9hcmRcIj48L2F0bGFzLXNpZ24taW4+XG4gKiBgYGBcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXRsYXMtc2lnbi1pbicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbQXR0ZW1wdEZsb3dDb21wb25lbnRdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxhdGxhcy1hdHRlbXB0LWZsb3dcbiAgICAgIFthdHRlbXB0XT1cImZsb3cuc3RhdGUoKS5hdHRlbXB0XCJcbiAgICAgIFtidXN5XT1cImZsb3cuc3RhdGUoKS5idXN5XCJcbiAgICAgIFtlcnJvcnNdPVwiZmxvdy5zdGF0ZSgpLmVycm9yc1wiXG4gICAgICB0aXRsZUtleT1cInNpZ25Jbi50aXRsZVwiXG4gICAgICAoc3VibWl0Rmxvdyk9XCJmbG93LnN1Ym1pdCgkZXZlbnQpXCJcbiAgICA+PC9hdGxhcy1hdHRlbXB0LWZsb3c+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIFNpZ25JbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSByZWFkb25seSBhdGxhcyA9IGluamVjdChBdGxhc1NlcnZpY2UpO1xuXG4gIC8qKiBXaGVyZSB0byBzZW5kIHRoZSB1c2VyIG9uY2UgdGhlIGZsb3cgY29tcGxldGVzLiBSZXNlcnZlZCBmb3IgaG9zdCByb3V0aW5nLiAqL1xuICBASW5wdXQoKSBhZnRlclVybD86IHN0cmluZztcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZmxvdyA9IG5ldyBBdGxhc0Zsb3dDb250cm9sbGVyKFxuICAgIHRoaXMuYXRsYXMuY3JlYXRlRmFwaUNsaWVudCgpLFxuICAgICgpID0+IHRoaXMuYXRsYXMucmVsb2FkKCksXG4gICAgLy8gUmVzdW1lIG1pZC1mbG93IGlmIGFuIE9BdXRoIHJlZGlyZWN0IGNhbWUgYmFjayBvd2luZyBhIHNlY29uZCBmYWN0b3IuXG4gICAgdGhpcy5hdGxhcy5wZW5kaW5nQXR0ZW1wdCxcbiAgKTtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyBJZiBzZWVkZWQgZnJvbSBhIHBlbmRpbmcgYXR0ZW1wdCB0aGF0IGlzIGFscmVhZHkgcG9sbGFibGUsIHN0YXJ0IHBvbGxpbmcuXG4gICAgdGhpcy5mbG93LnN5bmNQb2xsaW5nKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmZsb3cuZGVzdHJveSgpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,54 @@
1
+ import { ChangeDetectionStrategy, Component, Input, inject, } from '@angular/core';
2
+ import { AtlasService } from '../atlas.service';
3
+ import { AttemptFlowComponent } from './attempt-flow.component';
4
+ import { AtlasFlowController } from './flow-controller';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * `<atlas-sign-up>` — the full, server-driven sign-up flow. The Angular peer of
8
+ * React's `<SignUp/>`. It shares the exact flow engine with `<atlas-sign-in>`;
9
+ * only the title differs, because the sequence of steps is decided by the server.
10
+ *
11
+ * ```html
12
+ * <atlas-sign-up *atlasSignedOut></atlas-sign-up>
13
+ * ```
14
+ */
15
+ export class SignUpComponent {
16
+ atlas = inject(AtlasService);
17
+ /** Where to send the user once the flow completes. Reserved for host routing. */
18
+ afterUrl;
19
+ flow = new AtlasFlowController(this.atlas.createFapiClient(), () => this.atlas.reload(), this.atlas.pendingAttempt);
20
+ ngOnDestroy() {
21
+ this.flow.destroy();
22
+ }
23
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignUpComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
24
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SignUpComponent, isStandalone: true, selector: "atlas-sign-up", inputs: { afterUrl: "afterUrl" }, ngImport: i0, template: `
25
+ <atlas-attempt-flow
26
+ [attempt]="flow.state().attempt"
27
+ [busy]="flow.state().busy"
28
+ [errors]="flow.state().errors"
29
+ titleKey="signUp.title"
30
+ (submitFlow)="flow.submit($event)"
31
+ ></atlas-attempt-flow>
32
+ `, isInline: true, dependencies: [{ kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "titleKey"], outputs: ["submitFlow"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
33
+ }
34
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignUpComponent, decorators: [{
35
+ type: Component,
36
+ args: [{
37
+ selector: 'atlas-sign-up',
38
+ standalone: true,
39
+ changeDetection: ChangeDetectionStrategy.OnPush,
40
+ imports: [AttemptFlowComponent],
41
+ template: `
42
+ <atlas-attempt-flow
43
+ [attempt]="flow.state().attempt"
44
+ [busy]="flow.state().busy"
45
+ [errors]="flow.state().errors"
46
+ titleKey="signUp.title"
47
+ (submitFlow)="flow.submit($event)"
48
+ ></atlas-attempt-flow>
49
+ `,
50
+ }]
51
+ }], propDecorators: { afterUrl: [{
52
+ type: Input
53
+ }] } });
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi11cC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvc2lnbi11cC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsS0FBSyxFQUVMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7O0FBRXhEOzs7Ozs7OztHQVFHO0FBZ0JILE1BQU0sT0FBTyxlQUFlO0lBQ1QsS0FBSyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUU5QyxpRkFBaUY7SUFDeEUsUUFBUSxDQUFVO0lBRVIsSUFBSSxHQUFHLElBQUksbUJBQW1CLENBQy9DLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsRUFDN0IsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsRUFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQzFCLENBQUM7SUFFRixXQUFXO1FBQ1QsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUN0QixDQUFDO3dHQWRVLGVBQWU7NEZBQWYsZUFBZSwyR0FWaEI7Ozs7Ozs7O0dBUVQsNERBVFMsb0JBQW9COzs0RkFXbkIsZUFBZTtrQkFmM0IsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsZUFBZTtvQkFDekIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxPQUFPLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQztvQkFDL0IsUUFBUSxFQUFFOzs7Ozs7OztHQVFUO2lCQUNGOzhCQUtVLFFBQVE7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQXRsYXNTZXJ2aWNlIH0gZnJvbSAnLi4vYXRsYXMuc2VydmljZSc7XG5pbXBvcnQgeyBBdHRlbXB0Rmxvd0NvbXBvbmVudCB9IGZyb20gJy4vYXR0ZW1wdC1mbG93LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBBdGxhc0Zsb3dDb250cm9sbGVyIH0gZnJvbSAnLi9mbG93LWNvbnRyb2xsZXInO1xuXG4vKipcbiAqIGA8YXRsYXMtc2lnbi11cD5gIOKAlCB0aGUgZnVsbCwgc2VydmVyLWRyaXZlbiBzaWduLXVwIGZsb3cuIFRoZSBBbmd1bGFyIHBlZXIgb2ZcbiAqIFJlYWN0J3MgYDxTaWduVXAvPmAuIEl0IHNoYXJlcyB0aGUgZXhhY3QgZmxvdyBlbmdpbmUgd2l0aCBgPGF0bGFzLXNpZ24taW4+YDtcbiAqIG9ubHkgdGhlIHRpdGxlIGRpZmZlcnMsIGJlY2F1c2UgdGhlIHNlcXVlbmNlIG9mIHN0ZXBzIGlzIGRlY2lkZWQgYnkgdGhlIHNlcnZlci5cbiAqXG4gKiBgYGBodG1sXG4gKiA8YXRsYXMtc2lnbi11cCAqYXRsYXNTaWduZWRPdXQ+PC9hdGxhcy1zaWduLXVwPlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2F0bGFzLXNpZ24tdXAnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW1wb3J0czogW0F0dGVtcHRGbG93Q29tcG9uZW50XSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8YXRsYXMtYXR0ZW1wdC1mbG93XG4gICAgICBbYXR0ZW1wdF09XCJmbG93LnN0YXRlKCkuYXR0ZW1wdFwiXG4gICAgICBbYnVzeV09XCJmbG93LnN0YXRlKCkuYnVzeVwiXG4gICAgICBbZXJyb3JzXT1cImZsb3cuc3RhdGUoKS5lcnJvcnNcIlxuICAgICAgdGl0bGVLZXk9XCJzaWduVXAudGl0bGVcIlxuICAgICAgKHN1Ym1pdEZsb3cpPVwiZmxvdy5zdWJtaXQoJGV2ZW50KVwiXG4gICAgPjwvYXRsYXMtYXR0ZW1wdC1mbG93PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBTaWduVXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IGF0bGFzID0gaW5qZWN0KEF0bGFzU2VydmljZSk7XG5cbiAgLyoqIFdoZXJlIHRvIHNlbmQgdGhlIHVzZXIgb25jZSB0aGUgZmxvdyBjb21wbGV0ZXMuIFJlc2VydmVkIGZvciBob3N0IHJvdXRpbmcuICovXG4gIEBJbnB1dCgpIGFmdGVyVXJsPzogc3RyaW5nO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBmbG93ID0gbmV3IEF0bGFzRmxvd0NvbnRyb2xsZXIoXG4gICAgdGhpcy5hdGxhcy5jcmVhdGVGYXBpQ2xpZW50KCksXG4gICAgKCkgPT4gdGhpcy5hdGxhcy5yZWxvYWQoKSxcbiAgICB0aGlzLmF0bGFzLnBlbmRpbmdBdHRlbXB0LFxuICApO1xuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZmxvdy5kZXN0cm95KCk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,94 @@
1
+ import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';
2
+ import { AtlasService } from '../atlas.service';
3
+ import { classFor } from '../appearance';
4
+ import { translate } from '../i18n';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * `<atlas-user-button>` — the signed-in user's avatar with a drop-down that can
8
+ * sign them out. The Angular peer of React's `<UserButton/>`. Renders nothing
9
+ * when there is no user.
10
+ */
11
+ export class UserButtonComponent {
12
+ atlas = inject(AtlasService);
13
+ open = signal(false);
14
+ label = computed(() => {
15
+ const user = this.atlas.user();
16
+ if (!user)
17
+ return '';
18
+ return [user.first_name, user.last_name].filter(Boolean).join(' ') || user.username || '';
19
+ });
20
+ t(key) {
21
+ return translate(this.atlas.localization, key);
22
+ }
23
+ cls(key, base) {
24
+ return classFor(key, this.atlas.appearance, base);
25
+ }
26
+ toggle() {
27
+ this.open.update((o) => !o);
28
+ }
29
+ signOut() {
30
+ void this.atlas.signOut();
31
+ }
32
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UserButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: UserButtonComponent, isStandalone: true, selector: "atlas-user-button", ngImport: i0, template: `
34
+ @if (atlas.user(); as user) {
35
+ <div class="atlas-user-button">
36
+ <button
37
+ [class]="cls('avatar', 'atlas-avatar')"
38
+ [attr.aria-expanded]="open()"
39
+ (click)="toggle()"
40
+ >
41
+ @if (user.image_url) {
42
+ <img [src]="user.image_url" alt="" />
43
+ } @else {
44
+ <span>{{ label().slice(0, 1) }}</span>
45
+ }
46
+ </button>
47
+
48
+ @if (open()) {
49
+ <div [class]="cls('menu', 'atlas-menu')" role="menu">
50
+ <span [class]="cls('menuItem', 'atlas-menu-item')">{{ label() }}</span>
51
+ <button [class]="cls('menuItem', 'atlas-menu-item')" (click)="signOut()">
52
+ {{ t('userButton.signOut') }}
53
+ </button>
54
+ </div>
55
+ }
56
+ </div>
57
+ }
58
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
59
+ }
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UserButtonComponent, decorators: [{
61
+ type: Component,
62
+ args: [{
63
+ selector: 'atlas-user-button',
64
+ standalone: true,
65
+ changeDetection: ChangeDetectionStrategy.OnPush,
66
+ template: `
67
+ @if (atlas.user(); as user) {
68
+ <div class="atlas-user-button">
69
+ <button
70
+ [class]="cls('avatar', 'atlas-avatar')"
71
+ [attr.aria-expanded]="open()"
72
+ (click)="toggle()"
73
+ >
74
+ @if (user.image_url) {
75
+ <img [src]="user.image_url" alt="" />
76
+ } @else {
77
+ <span>{{ label().slice(0, 1) }}</span>
78
+ }
79
+ </button>
80
+
81
+ @if (open()) {
82
+ <div [class]="cls('menu', 'atlas-menu')" role="menu">
83
+ <span [class]="cls('menuItem', 'atlas-menu-item')">{{ label() }}</span>
84
+ <button [class]="cls('menuItem', 'atlas-menu-item')" (click)="signOut()">
85
+ {{ t('userButton.signOut') }}
86
+ </button>
87
+ </div>
88
+ }
89
+ </div>
90
+ }
91
+ `,
92
+ }]
93
+ }] });
94
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1idXR0b24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL3VzZXItYnV0dG9uLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsUUFBUSxFQUFtQixNQUFNLGVBQWUsQ0FBQztBQUMxRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sU0FBUyxDQUFDOztBQUVwQzs7OztHQUlHO0FBZ0NILE1BQU0sT0FBTyxtQkFBbUI7SUFDWCxLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzdCLElBQUksR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFckIsS0FBSyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDO0lBQzVGLENBQUMsQ0FBQyxDQUFDO0lBRU8sQ0FBQyxDQUFDLEdBQVc7UUFDckIsT0FBTyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVTLEdBQUcsQ0FBQyxHQUFlLEVBQUUsSUFBWTtRQUN6QyxPQUFPLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVTLE1BQU07UUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRVMsT0FBTztRQUNmLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM1QixDQUFDO3dHQXhCVSxtQkFBbUI7NEZBQW5CLG1CQUFtQiw2RUEzQnBCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJUOzs0RkFFVSxtQkFBbUI7a0JBL0IvQixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxtQkFBbUI7b0JBQzdCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJUO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgY29tcHV0ZWQsIGluamVjdCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBdGxhc1NlcnZpY2UgfSBmcm9tICcuLi9hdGxhcy5zZXJ2aWNlJztcbmltcG9ydCB7IGNsYXNzRm9yLCB0eXBlIEVsZW1lbnRLZXkgfSBmcm9tICcuLi9hcHBlYXJhbmNlJztcbmltcG9ydCB7IHRyYW5zbGF0ZSB9IGZyb20gJy4uL2kxOG4nO1xuXG4vKipcbiAqIGA8YXRsYXMtdXNlci1idXR0b24+YCDigJQgdGhlIHNpZ25lZC1pbiB1c2VyJ3MgYXZhdGFyIHdpdGggYSBkcm9wLWRvd24gdGhhdCBjYW5cbiAqIHNpZ24gdGhlbSBvdXQuIFRoZSBBbmd1bGFyIHBlZXIgb2YgUmVhY3QncyBgPFVzZXJCdXR0b24vPmAuIFJlbmRlcnMgbm90aGluZ1xuICogd2hlbiB0aGVyZSBpcyBubyB1c2VyLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdGxhcy11c2VyLWJ1dHRvbicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIEBpZiAoYXRsYXMudXNlcigpOyBhcyB1c2VyKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwiYXRsYXMtdXNlci1idXR0b25cIj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIFtjbGFzc109XCJjbHMoJ2F2YXRhcicsICdhdGxhcy1hdmF0YXInKVwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1leHBhbmRlZF09XCJvcGVuKClcIlxuICAgICAgICAgIChjbGljayk9XCJ0b2dnbGUoKVwiXG4gICAgICAgID5cbiAgICAgICAgICBAaWYgKHVzZXIuaW1hZ2VfdXJsKSB7XG4gICAgICAgICAgICA8aW1nIFtzcmNdPVwidXNlci5pbWFnZV91cmxcIiBhbHQ9XCJcIiAvPlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPHNwYW4+e3sgbGFiZWwoKS5zbGljZSgwLCAxKSB9fTwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgIEBpZiAob3BlbigpKSB7XG4gICAgICAgICAgPGRpdiBbY2xhc3NdPVwiY2xzKCdtZW51JywgJ2F0bGFzLW1lbnUnKVwiIHJvbGU9XCJtZW51XCI+XG4gICAgICAgICAgICA8c3BhbiBbY2xhc3NdPVwiY2xzKCdtZW51SXRlbScsICdhdGxhcy1tZW51LWl0ZW0nKVwiPnt7IGxhYmVsKCkgfX08L3NwYW4+XG4gICAgICAgICAgICA8YnV0dG9uIFtjbGFzc109XCJjbHMoJ21lbnVJdGVtJywgJ2F0bGFzLW1lbnUtaXRlbScpXCIgKGNsaWNrKT1cInNpZ25PdXQoKVwiPlxuICAgICAgICAgICAgICB7eyB0KCd1c2VyQnV0dG9uLnNpZ25PdXQnKSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgVXNlckJ1dHRvbkNvbXBvbmVudCB7XG4gIHByb3RlY3RlZCByZWFkb25seSBhdGxhcyA9IGluamVjdChBdGxhc1NlcnZpY2UpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgb3BlbiA9IHNpZ25hbChmYWxzZSk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxhYmVsID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IHVzZXIgPSB0aGlzLmF0bGFzLnVzZXIoKTtcbiAgICBpZiAoIXVzZXIpIHJldHVybiAnJztcbiAgICByZXR1cm4gW3VzZXIuZmlyc3RfbmFtZSwgdXNlci5sYXN0X25hbWVdLmZpbHRlcihCb29sZWFuKS5qb2luKCcgJykgfHwgdXNlci51c2VybmFtZSB8fCAnJztcbiAgfSk7XG5cbiAgcHJvdGVjdGVkIHQoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0cmFuc2xhdGUodGhpcy5hdGxhcy5sb2NhbGl6YXRpb24sIGtleSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xzKGtleTogRWxlbWVudEtleSwgYmFzZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY2xhc3NGb3Ioa2V5LCB0aGlzLmF0bGFzLmFwcGVhcmFuY2UsIGJhc2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHRvZ2dsZSgpOiB2b2lkIHtcbiAgICB0aGlzLm9wZW4udXBkYXRlKChvKSA9PiAhbyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2lnbk91dCgpOiB2b2lkIHtcbiAgICB2b2lkIHRoaXMuYXRsYXMuc2lnbk91dCgpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,81 @@
1
+ import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
2
+ import { AtlasService } from '../atlas.service';
3
+ import { classFor } from '../appearance';
4
+ import { translate } from '../i18n';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * `<atlas-user-profile>` — the signed-in user's account surface (emails,
8
+ * security). The Angular peer of React's `<UserProfile/>`. Renders nothing when
9
+ * there is no user.
10
+ */
11
+ export class UserProfileComponent {
12
+ atlas = inject(AtlasService);
13
+ t(key) {
14
+ return translate(this.atlas.localization, key);
15
+ }
16
+ cls(key, base) {
17
+ return classFor(key, this.atlas.appearance, base);
18
+ }
19
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UserProfileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: UserProfileComponent, isStandalone: true, selector: "atlas-user-profile", ngImport: i0, template: `
21
+ @if (atlas.user(); as user) {
22
+ <div [class]="cls('card', 'atlas-card')">
23
+ <h1>{{ t('userProfile.title') }}</h1>
24
+
25
+ <section>
26
+ <h2>{{ t('userProfile.emailsSection') }}</h2>
27
+ <ul>
28
+ @for (email of user.email_addresses ?? []; track email.id) {
29
+ <li>
30
+ {{ email.email_address }}
31
+ @if (!email.verified) {
32
+ <em> — {{ t('userProfile.unverified') }}</em>
33
+ }
34
+ </li>
35
+ }
36
+ </ul>
37
+ </section>
38
+
39
+ <section>
40
+ <h2>{{ t('userProfile.securitySection') }}</h2>
41
+ <p>{{ user.mfa_enabled ? '2FA on' : '2FA off' }}</p>
42
+ </section>
43
+ </div>
44
+ }
45
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
46
+ }
47
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UserProfileComponent, decorators: [{
48
+ type: Component,
49
+ args: [{
50
+ selector: 'atlas-user-profile',
51
+ standalone: true,
52
+ changeDetection: ChangeDetectionStrategy.OnPush,
53
+ template: `
54
+ @if (atlas.user(); as user) {
55
+ <div [class]="cls('card', 'atlas-card')">
56
+ <h1>{{ t('userProfile.title') }}</h1>
57
+
58
+ <section>
59
+ <h2>{{ t('userProfile.emailsSection') }}</h2>
60
+ <ul>
61
+ @for (email of user.email_addresses ?? []; track email.id) {
62
+ <li>
63
+ {{ email.email_address }}
64
+ @if (!email.verified) {
65
+ <em> — {{ t('userProfile.unverified') }}</em>
66
+ }
67
+ </li>
68
+ }
69
+ </ul>
70
+ </section>
71
+
72
+ <section>
73
+ <h2>{{ t('userProfile.securitySection') }}</h2>
74
+ <p>{{ user.mfa_enabled ? '2FA on' : '2FA off' }}</p>
75
+ </section>
76
+ </div>
77
+ }
78
+ `,
79
+ }]
80
+ }] });
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1wcm9maWxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy91c2VyLXByb2ZpbGUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsUUFBUSxFQUFtQixNQUFNLGVBQWUsQ0FBQztBQUMxRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sU0FBUyxDQUFDOztBQUVwQzs7OztHQUlHO0FBZ0NILE1BQU0sT0FBTyxvQkFBb0I7SUFDWixLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXRDLENBQUMsQ0FBQyxHQUFXO1FBQ3JCLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFUyxHQUFHLENBQUMsR0FBZSxFQUFFLElBQVk7UUFDekMsT0FBTyxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3BELENBQUM7d0dBVFUsb0JBQW9COzRGQUFwQixvQkFBb0IsOEVBM0JyQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCVDs7NEZBRVUsb0JBQW9CO2tCQS9CaEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsb0JBQW9CO29CQUM5QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCVDtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQXRsYXNTZXJ2aWNlIH0gZnJvbSAnLi4vYXRsYXMuc2VydmljZSc7XG5pbXBvcnQgeyBjbGFzc0ZvciwgdHlwZSBFbGVtZW50S2V5IH0gZnJvbSAnLi4vYXBwZWFyYW5jZSc7XG5pbXBvcnQgeyB0cmFuc2xhdGUgfSBmcm9tICcuLi9pMThuJztcblxuLyoqXG4gKiBgPGF0bGFzLXVzZXItcHJvZmlsZT5gIOKAlCB0aGUgc2lnbmVkLWluIHVzZXIncyBhY2NvdW50IHN1cmZhY2UgKGVtYWlscyxcbiAqIHNlY3VyaXR5KS4gVGhlIEFuZ3VsYXIgcGVlciBvZiBSZWFjdCdzIGA8VXNlclByb2ZpbGUvPmAuIFJlbmRlcnMgbm90aGluZyB3aGVuXG4gKiB0aGVyZSBpcyBubyB1c2VyLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdGxhcy11c2VyLXByb2ZpbGUnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGBcbiAgICBAaWYgKGF0bGFzLnVzZXIoKTsgYXMgdXNlcikge1xuICAgICAgPGRpdiBbY2xhc3NdPVwiY2xzKCdjYXJkJywgJ2F0bGFzLWNhcmQnKVwiPlxuICAgICAgICA8aDE+e3sgdCgndXNlclByb2ZpbGUudGl0bGUnKSB9fTwvaDE+XG5cbiAgICAgICAgPHNlY3Rpb24+XG4gICAgICAgICAgPGgyPnt7IHQoJ3VzZXJQcm9maWxlLmVtYWlsc1NlY3Rpb24nKSB9fTwvaDI+XG4gICAgICAgICAgPHVsPlxuICAgICAgICAgICAgQGZvciAoZW1haWwgb2YgdXNlci5lbWFpbF9hZGRyZXNzZXMgPz8gW107IHRyYWNrIGVtYWlsLmlkKSB7XG4gICAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAgICB7eyBlbWFpbC5lbWFpbF9hZGRyZXNzIH19XG4gICAgICAgICAgICAgICAgQGlmICghZW1haWwudmVyaWZpZWQpIHtcbiAgICAgICAgICAgICAgICAgIDxlbT4g4oCUIHt7IHQoJ3VzZXJQcm9maWxlLnVudmVyaWZpZWQnKSB9fTwvZW0+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvdWw+XG4gICAgICAgIDwvc2VjdGlvbj5cblxuICAgICAgICA8c2VjdGlvbj5cbiAgICAgICAgICA8aDI+e3sgdCgndXNlclByb2ZpbGUuc2VjdXJpdHlTZWN0aW9uJykgfX08L2gyPlxuICAgICAgICAgIDxwPnt7IHVzZXIubWZhX2VuYWJsZWQgPyAnMkZBIG9uJyA6ICcyRkEgb2ZmJyB9fTwvcD5cbiAgICAgICAgPC9zZWN0aW9uPlxuICAgICAgPC9kaXY+XG4gICAgfVxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBVc2VyUHJvZmlsZUNvbXBvbmVudCB7XG4gIHByb3RlY3RlZCByZWFkb25seSBhdGxhcyA9IGluamVjdChBdGxhc1NlcnZpY2UpO1xuXG4gIHByb3RlY3RlZCB0KGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdHJhbnNsYXRlKHRoaXMuYXRsYXMubG9jYWxpemF0aW9uLCBrZXkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNscyhrZXk6IEVsZW1lbnRLZXksIGJhc2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNsYXNzRm9yKGtleSwgdGhpcy5hdGxhcy5hcHBlYXJhbmNlLCBiYXNlKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,42 @@
1
+ import { Directive, ElementRef, Renderer2, RendererStyleFlags2, inject, } from '@angular/core';
2
+ import { AtlasService } from '../atlas.service';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * `atlasRoot` — apply the resolved appearance design tokens as `--atlas-*` CSS
6
+ * custom properties (and the `atlas-root` class) onto its host element, so the
7
+ * Atlas components rendered inside inherit them.
8
+ *
9
+ * React does this with the wrapping `<div className="atlas-root" style={…}>`
10
+ * inside `<AtlasProvider>`. Angular has no single wrapping element, so a
11
+ * consumer opts in by putting `atlasRoot` on whatever element encloses the
12
+ * Atlas UI (commonly the app root):
13
+ *
14
+ * ```html
15
+ * <div atlasRoot>
16
+ * <router-outlet></router-outlet>
17
+ * </div>
18
+ * ```
19
+ */
20
+ export class AtlasRootDirective {
21
+ atlas = inject(AtlasService);
22
+ el = inject(ElementRef);
23
+ renderer = inject(Renderer2);
24
+ ngOnInit() {
25
+ this.renderer.addClass(this.el.nativeElement, 'atlas-root');
26
+ const vars = this.atlas.appearanceVariables();
27
+ for (const [name, value] of Object.entries(vars)) {
28
+ // DashCase so a `--atlas-*` custom property is written verbatim, not camelCased.
29
+ this.renderer.setStyle(this.el.nativeElement, name, value, RendererStyleFlags2.DashCase);
30
+ }
31
+ }
32
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AtlasRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
33
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: AtlasRootDirective, isStandalone: true, selector: "[atlasRoot]", ngImport: i0 });
34
+ }
35
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AtlasRootDirective, decorators: [{
36
+ type: Directive,
37
+ args: [{
38
+ selector: '[atlasRoot]',
39
+ standalone: true,
40
+ }]
41
+ }] });
42
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRsYXMtcm9vdC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2RpcmVjdGl2ZXMvYXRsYXMtcm9vdC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxVQUFVLEVBRVYsU0FBUyxFQUNULG1CQUFtQixFQUNuQixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDOztBQUVoRDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFLSCxNQUFNLE9BQU8sa0JBQWtCO0lBQ1osS0FBSyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUM3QixFQUFFLEdBQUcsTUFBTSxDQUEwQixVQUFVLENBQUMsQ0FBQztJQUNqRCxRQUFRLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRTlDLFFBQVE7UUFDTixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUM1RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDOUMsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNqRCxpRkFBaUY7WUFDakYsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzRixDQUFDO0lBQ0gsQ0FBQzt3R0FaVSxrQkFBa0I7NEZBQWxCLGtCQUFrQjs7NEZBQWxCLGtCQUFrQjtrQkFKOUIsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsYUFBYTtvQkFDdkIsVUFBVSxFQUFFLElBQUk7aUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBPbkluaXQsXG4gIFJlbmRlcmVyMixcbiAgUmVuZGVyZXJTdHlsZUZsYWdzMixcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEF0bGFzU2VydmljZSB9IGZyb20gJy4uL2F0bGFzLnNlcnZpY2UnO1xuXG4vKipcbiAqIGBhdGxhc1Jvb3RgIOKAlCBhcHBseSB0aGUgcmVzb2x2ZWQgYXBwZWFyYW5jZSBkZXNpZ24gdG9rZW5zIGFzIGAtLWF0bGFzLSpgIENTU1xuICogY3VzdG9tIHByb3BlcnRpZXMgKGFuZCB0aGUgYGF0bGFzLXJvb3RgIGNsYXNzKSBvbnRvIGl0cyBob3N0IGVsZW1lbnQsIHNvIHRoZVxuICogQXRsYXMgY29tcG9uZW50cyByZW5kZXJlZCBpbnNpZGUgaW5oZXJpdCB0aGVtLlxuICpcbiAqIFJlYWN0IGRvZXMgdGhpcyB3aXRoIHRoZSB3cmFwcGluZyBgPGRpdiBjbGFzc05hbWU9XCJhdGxhcy1yb290XCIgc3R5bGU9e+KApn0+YFxuICogaW5zaWRlIGA8QXRsYXNQcm92aWRlcj5gLiBBbmd1bGFyIGhhcyBubyBzaW5nbGUgd3JhcHBpbmcgZWxlbWVudCwgc28gYVxuICogY29uc3VtZXIgb3B0cyBpbiBieSBwdXR0aW5nIGBhdGxhc1Jvb3RgIG9uIHdoYXRldmVyIGVsZW1lbnQgZW5jbG9zZXMgdGhlXG4gKiBBdGxhcyBVSSAoY29tbW9ubHkgdGhlIGFwcCByb290KTpcbiAqXG4gKiBgYGBodG1sXG4gKiA8ZGl2IGF0bGFzUm9vdD5cbiAqICAgPHJvdXRlci1vdXRsZXQ+PC9yb3V0ZXItb3V0bGV0PlxuICogPC9kaXY+XG4gKiBgYGBcbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2F0bGFzUm9vdF0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBBdGxhc1Jvb3REaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIHJlYWRvbmx5IGF0bGFzID0gaW5qZWN0KEF0bGFzU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZWwgPSBpbmplY3Q8RWxlbWVudFJlZjxIVE1MRWxlbWVudD4+KEVsZW1lbnRSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlbmRlcmVyID0gaW5qZWN0KFJlbmRlcmVyMik7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsICdhdGxhcy1yb290Jyk7XG4gICAgY29uc3QgdmFycyA9IHRoaXMuYXRsYXMuYXBwZWFyYW5jZVZhcmlhYmxlcygpO1xuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh2YXJzKSkge1xuICAgICAgLy8gRGFzaENhc2Ugc28gYSBgLS1hdGxhcy0qYCBjdXN0b20gcHJvcGVydHkgaXMgd3JpdHRlbiB2ZXJiYXRpbSwgbm90IGNhbWVsQ2FzZWQuXG4gICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgbmFtZSwgdmFsdWUsIFJlbmRlcmVyU3R5bGVGbGFnczIuRGFzaENhc2UpO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,23 @@
1
+ import { Directive } from '@angular/core';
2
+ import { AtlasToggleDirective } from './toggle.directive';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * `*atlasLoaded` — render the template only once the SDK has finished booting.
6
+ * The Angular peer of React's `<AtlasLoaded>`, the symmetric partner of
7
+ * `*atlasLoading`.
8
+ */
9
+ export class AtlasLoadedDirective extends AtlasToggleDirective {
10
+ source() {
11
+ return this.atlas.isLoaded$;
12
+ }
13
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AtlasLoadedDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive });
14
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: AtlasLoadedDirective, isStandalone: true, selector: "[atlasLoaded]", usesInheritance: true, ngImport: i0 });
15
+ }
16
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AtlasLoadedDirective, decorators: [{
17
+ type: Directive,
18
+ args: [{
19
+ selector: '[atlasLoaded]',
20
+ standalone: true,
21
+ }]
22
+ }] });
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZGVkLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZGlyZWN0aXZlcy9sb2FkZWQuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFMUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7O0FBRTFEOzs7O0dBSUc7QUFLSCxNQUFNLE9BQU8sb0JBQXFCLFNBQVEsb0JBQW9CO0lBQ3pDLE1BQU07UUFDdkIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztJQUM5QixDQUFDO3dHQUhVLG9CQUFvQjs0RkFBcEIsb0JBQW9COzs0RkFBcEIsb0JBQW9CO2tCQUpoQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxlQUFlO29CQUN6QixVQUFVLEVBQUUsSUFBSTtpQkFDakIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEF0bGFzVG9nZ2xlRGlyZWN0aXZlIH0gZnJvbSAnLi90b2dnbGUuZGlyZWN0aXZlJztcblxuLyoqXG4gKiBgKmF0bGFzTG9hZGVkYCDigJQgcmVuZGVyIHRoZSB0ZW1wbGF0ZSBvbmx5IG9uY2UgdGhlIFNESyBoYXMgZmluaXNoZWQgYm9vdGluZy5cbiAqIFRoZSBBbmd1bGFyIHBlZXIgb2YgUmVhY3QncyBgPEF0bGFzTG9hZGVkPmAsIHRoZSBzeW1tZXRyaWMgcGFydG5lciBvZlxuICogYCphdGxhc0xvYWRpbmdgLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbYXRsYXNMb2FkZWRdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgQXRsYXNMb2FkZWREaXJlY3RpdmUgZXh0ZW5kcyBBdGxhc1RvZ2dsZURpcmVjdGl2ZSB7XG4gIHByb3RlY3RlZCBvdmVycmlkZSBzb3VyY2UoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuYXRsYXMuaXNMb2FkZWQkO1xuICB9XG59XG4iXX0=